package com.asteria.game; import java.util.ArrayDeque; import java.util.Queue; import com.asteria.Bootstrap; import com.asteria.game.character.player.content.RestoreStatTask; import com.asteria.game.character.player.minigame.MinigameHandler; import com.asteria.game.character.player.serialize.PlayerSerialization; import com.asteria.game.item.ItemNodeManager; import com.asteria.net.ConnectionHandler; import com.asteria.service.ServiceQueue; import com.asteria.utility.BackgroundLoader; import com.asteria.utility.json.EquipmentRequirementLoader; import com.asteria.utility.json.ItemDefinitionLoader; import com.asteria.utility.json.ItemNodeLoader; import com.asteria.utility.json.MessageOpcodeLoader; import com.asteria.utility.json.MessageSizeLoader; import com.asteria.utility.json.NpcDefinitionLoader; import com.asteria.utility.json.NpcDropCacheLoader; import com.asteria.utility.json.NpcDropTableLoader; import com.asteria.utility.json.NpcNodeLoader; import com.asteria.utility.json.ObjectNodeLoader; import com.asteria.utility.json.ObjectNodeRemoveLoader; import com.asteria.utility.json.ShopLoader; import com.asteria.utility.json.WeaponAnimationLoader; import com.asteria.utility.json.WeaponInterfaceLoader; import com.asteria.utility.json.WeaponPoisonLoader; /** * Initializes game {@link Object}s and prepares them to be created by the * {@link Bootstrap}. * * @author lare96 <http://github.org/lare96> */ public final class GameBuilder { /** * The background loader that will load various utilities in the background * while the bootstrap is preparing the server. */ private final BackgroundLoader backgroundLoader = new BackgroundLoader(); /** * The service queue that will run the {@link GameService}. */ private final ServiceQueue queue = new ServiceQueue(); /** * Initializes this game builder effectively preparing the background * startup tasks and game processing. * * @throws Exception * if any issues occur while starting the network. */ public void initialize() throws Exception { backgroundLoader.start(createBackgroundTasks()); queue.submit(World.getService()); World.submit(new ItemNodeManager()); World.submit(new RestoreStatTask()); World.submit(new MinigameHandler()); PlayerSerialization.getCache().init(); if (!backgroundLoader.awaitCompletion()) throw new IllegalStateException("Background load did not complete normally!"); } /** * Returns a queue containing all of the background tasks that will be * executed by the background loader. Please note that the loader may use * multiple threads to load the utilities concurrently, so utilities that * depend on each other <b>must</b> be executed in the same task to ensure * thread safety. * * @return the queue of background tasks. */ public Queue<Runnable> createBackgroundTasks() { Queue<Runnable> tasks = new ArrayDeque<>(); tasks.add(new NpcDefinitionLoader()); tasks.add(new ItemDefinitionLoader()); tasks.add(new WeaponPoisonLoader()); tasks.add(new MessageOpcodeLoader()); tasks.add(new MessageSizeLoader()); tasks.add(ConnectionHandler::parseIPBans); tasks.add(new NpcNodeLoader()); tasks.add(new ShopLoader()); tasks.add(new ItemNodeLoader()); tasks.add(new ObjectNodeLoader()); tasks.add(new NpcDropTableLoader()); tasks.add(new WeaponAnimationLoader()); tasks.add(new WeaponInterfaceLoader()); tasks.add(new EquipmentRequirementLoader()); tasks.add(new ObjectNodeRemoveLoader()); tasks.add(new NpcDropCacheLoader()); tasks.add(World.getPlugins()::init); return tasks; } }