Java tutorial
/** * For copyright information see the LICENSE document. */ package gwlpr.mapshard; import gwlpr.database.jpa.MapJpaController; import gwlpr.mapshard.models.ClientBean; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import gwlpr.database.entities.Map; import gwlpr.mapshard.controllers.CharacterCreation; import gwlpr.mapshard.controllers.Chat; import gwlpr.mapshard.controllers.ClientDisconnect; import gwlpr.mapshard.controllers.LatencyAndSynchonization; import gwlpr.mapshard.controllers.InstanceLoad; import gwlpr.mapshard.controllers.MoveRotateClick; import gwlpr.mapshard.controllers.ClientConnect; import gwlpr.mapshard.controllers.ShutDown; import gwlpr.mapshard.entitysystem.EntityManager; import gwlpr.mapshard.entitysystem.systems.AgentVisibilitySystem; import gwlpr.mapshard.entitysystem.systems.ChatSystem; import gwlpr.mapshard.entitysystem.systems.CommandSystem; import gwlpr.mapshard.entitysystem.systems.MovementSystem; import gwlpr.mapshard.entitysystem.systems.SchedulingSystem; import gwlpr.mapshard.entitysystem.systems.SpawningSystem; import gwlpr.mapshard.events.HeartBeatEvent; import gwlpr.mapshard.events.SystemsUpdateEvent; import gwlpr.mapshard.models.HandleRegistryNotificationDecorator; import gwlpr.mapshard.models.Pacemaker; import gwlpr.mapshard.models.WorldBean; import gwlpr.protocol.handshake.EncryptionOptions; import gwlpr.protocol.intershard.utils.DistrictLanguage; import gwlpr.protocol.intershard.utils.DistrictRegion; import realityshard.container.events.EventAggregator; import realityshard.container.gameapp.GameAppContext; import realityshard.container.gameapp.GameAppFactory; import realityshard.container.util.Handle; import realityshard.container.util.HandleRegistry; /** * Produces map shards. * * @author _rusty */ public class MapShardFactory implements GameAppFactory { private static final int UPDATE_INTERVAL = 30; // ms private static final int HEARTBEAT_INTERVAL = 250; // ms @Override public String getName() { return "MapShard"; } @Override public boolean isStartup() { return false; } @Override public Channel getServerChannel(ServerBootstrap bootstrap) throws InterruptedException { // set the attributes for new channels bootstrap.childAttr(ClientBean.HANDLE_KEY, null); // create the pipeline-factory bootstrap.childHandler(new MapShardChannelInitializer(EncryptionOptions.Enable)); // finally, bind and sync return bootstrap.bind(9112).sync().channel(); } @Override public boolean initGameApp(Handle<GameAppContext> thisContext, Handle<GameAppContext> parentContext, java.util.Map<String, String> additionalParams) { // failcheck if (parentContext == null || additionalParams.isEmpty()) { return false; } // TODO: create db stuff // parse the parameters for the worldbean Map mapEntity = MapJpaController.get().findMap(Integer.parseInt(additionalParams.get("MapId"))); boolean isPvP = Boolean.parseBoolean(additionalParams.get("IsPvP")); boolean isOutpost = Boolean.parseBoolean(additionalParams.get("IsOutpost")); int instanceNum = Integer.parseInt(additionalParams.get("InstanceNumber")); DistrictRegion region = DistrictRegion.valueOf(additionalParams.get("DistrictRegion")); DistrictLanguage language = DistrictLanguage.valueOf(additionalParams.get("DistrictLanguage")); // failcheck if (mapEntity == null) { return false; } WorldBean world = new WorldBean(mapEntity, instanceNum, region, language, isPvP, isOutpost); // create all the objects needed by controllers and systems EventAggregator eventAgg = thisContext.get().getEventAggregator(); HandleRegistry<ClientBean> clientRegistry = new HandleRegistryNotificationDecorator<>(eventAgg); EntityManager entityManager = new EntityManager(); // now lets do the server ticks: // there is two of them, one that updates the systems of the CES // and one thats used to pump out the state of the server in // discrete time intervalls Pacemaker<SystemsUpdateEvent> sysUpdate = new Pacemaker<>(eventAgg, new SystemsUpdateEvent(), UPDATE_INTERVAL); Pacemaker<HeartBeatEvent> heartbeat = new Pacemaker<>(eventAgg, new HeartBeatEvent(), HEARTBEAT_INTERVAL); // register the controllers thisContext.get().getEventAggregator() // register for container related events .register(new ClientConnect(thisContext, parentContext, clientRegistry, world)) .register(new ClientDisconnect(thisContext, parentContext, entityManager)) .register(new ShutDown(thisContext, parentContext, sysUpdate, heartbeat)) // register for gw-protocol related events .register(new LatencyAndSynchonization(clientRegistry)).register(new CharacterCreation()) .register(new Chat(eventAgg)).register(new InstanceLoad(world, entityManager)) .register(new MoveRotateClick(eventAgg, clientRegistry, entityManager)) // register the CE systems .register(new AgentVisibilitySystem(eventAgg, entityManager)) .register(new ChatSystem(eventAgg, clientRegistry)) .register(new CommandSystem(eventAgg, entityManager, clientRegistry)) .register(new MovementSystem(eventAgg, entityManager, clientRegistry)) .register(new SchedulingSystem(eventAgg)).register(new SpawningSystem(eventAgg, clientRegistry)); // start the pacemakers sysUpdate.start(); heartbeat.start(); return true; } }