package jk_5.nailed.server; import jk_5.eventbus.Event; import jk_5.nailed.api.GameMode; import jk_5.nailed.api.chat.BaseComponent; import jk_5.nailed.api.chat.ChatColor; import jk_5.nailed.api.chat.ComponentBuilder; import jk_5.nailed.api.command.sender.CommandSender; import jk_5.nailed.api.event.PlatformEvent; import jk_5.nailed.api.event.player.*; import jk_5.nailed.api.event.server.ServerPostTickEvent; import jk_5.nailed.api.event.server.ServerPreTickEvent; import jk_5.nailed.api.event.world.WorldPostTickEvent; import jk_5.nailed.api.event.world.WorldPreTickEvent; import jk_5.nailed.api.map.Map; import jk_5.nailed.api.mappack.Mappack; import jk_5.nailed.api.player.Player; import jk_5.nailed.api.util.Location; import jk_5.nailed.server.command.NailedCommandManager; import jk_5.nailed.server.command.sender.CommandBlockCommandSender; import jk_5.nailed.server.command.sender.ConsoleCommandSender; import jk_5.nailed.server.event.EntityDamageEvent; import jk_5.nailed.server.event.EntityFallEvent; import jk_5.nailed.server.map.NailedMap; import jk_5.nailed.server.network.NettyChannelInitializer; import jk_5.nailed.server.player.NailedPlayer; import jk_5.nailed.server.scoreboard.PlayerScoreboardManager; import jk_5.nailed.server.tileentity.TileEntityStatEmitter; import jk_5.nailed.server.utils.ItemStackConverter; import jk_5.nailed.server.world.NailedDimensionManager; import jk_5.nailed.server.world.NailedWorld; import net.minecraft.command.ICommandSender; import net.minecraft.command.server.CommandBlockLogic; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.network.play.server.S05PacketSpawnPosition; import net.minecraft.network.play.server.S07PacketRespawn; import net.minecraft.network.play.server.S1FPacketSetExperience; import net.minecraft.network.rcon.RConConsoleSource; import net.minecraft.server.MinecraftServer; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.management.ItemInWorldManager; import net.minecraft.util.BlockPos; import net.minecraft.util.DamageSource; import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraft.world.WorldSettings; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.util.List; public class NailedEventFactory { private static final ServerPreTickEvent preTickEvent = new ServerPreTickEvent(); private static final ServerPostTickEvent postTickEvent = new ServerPostTickEvent(); private static final Logger logger = LogManager.getLogger(); private static int subtitleCounter; public static ConsoleCommandSender serverCommandSender; public static <T extends Event> T fireEvent(T event){ if(event instanceof PlatformEvent){ if(((PlatformEvent) event).getPlatform() == null){ ((PlatformEvent) event).setPlatform(NailedPlatform.instance()); } } NailedPlatform.instance().getEventBus().post(event); return event; } public static WorldPreTickEvent firePreWorldTick(MinecraftServer server, WorldServer world){ return fireEvent(new WorldPreTickEvent(NailedPlatform.instance().getWorld(world.provider.getDimensionId()))); } public static WorldPostTickEvent firePostWorldTick(MinecraftServer server, WorldServer world){ return fireEvent(new WorldPostTickEvent(NailedPlatform.instance().getWorld(world.provider.getDimensionId()))); } public static ServerPreTickEvent firePreServerTick(MinecraftServer server){ return fireEvent(preTickEvent); } public static ServerPostTickEvent firePostServerTick(MinecraftServer server){ if(subtitleCounter == 15){ for (Player player : NailedPlatform.instance().getOnlinePlayers()) { NailedPlayer p = ((NailedPlayer) player); BaseComponent[] sub = p.getSubtitle(); if(sub != null){ p.displaySubtitle(sub); } } subtitleCounter = 0; }else{ subtitleCounter += 1; } return fireEvent(postTickEvent); } public static void fireServerStartBeforeConfig(DedicatedServer server){ NailedPlatform.instance().preLoad(server); serverCommandSender = new ConsoleCommandSender(); } public static void fireServerStarted(DedicatedServer server){ NettyChannelInitializer.serverStarting = false; NailedPlatform.instance().load(); } public static void fireStartBeforeWorldLoad(DedicatedServer server){ } public static int fireCommand(ICommandSender sender, String input){ CommandSender wrapped = null; if(sender instanceof EntityPlayerMP){ wrapped = NailedPlatform.instance().getPlayer(((EntityPlayerMP) sender).getGameProfile().getId()); }else if(sender instanceof CommandBlockLogic){ wrapped = new CommandBlockCommandSender(((CommandBlockLogic) sender)); //TODO: replace this with our own api }else if(sender instanceof RConConsoleSource){ //wrapped = new RConCommandSender(((RConConsoleSource) sender)); }else if(sender instanceof MinecraftServer){ wrapped = serverCommandSender; } if(wrapped == null){ return -1; } return NailedCommandManager.fireCommand((wrapped instanceof Player) ? input.substring(1) : input, wrapped, sender); } public static List<String> fireTabCompletion(ICommandSender sender, String input){ CommandSender wrapped = null; if(sender instanceof EntityPlayerMP){ wrapped = NailedPlatform.instance().getPlayer(((EntityPlayerMP) sender).getGameProfile().getId()); }else if(sender instanceof CommandBlockLogic){ wrapped = new CommandBlockCommandSender(((CommandBlockLogic) sender)); //TODO: replace this with our own api }else if(sender instanceof RConConsoleSource){ //wrapped = new RConCommandSender(((RConConsoleSource) sender)); }else if(sender instanceof MinecraftServer){ wrapped = serverCommandSender; } if(wrapped == null){ return null; } return NailedCommandManager.fireAutocompletion(input, wrapped, sender); } public static void fireWorldLoad(World world){ } public static void fireWorldUnload(World world){ } public static void fireEntityInPortal(Entity entity){ } public static void firePlayerJoined(EntityPlayerMP playerEntity){ NailedPlayer player = NailedPlatform.instance().getOrCreatePlayer(playerEntity); player.entity = playerEntity; player.isOnline = true; player.world = NailedPlatform.instance().getWorld(playerEntity.dimension); player.map = player.world.getMap(); player.netHandler = playerEntity.playerNetServerHandler; player.world.onPlayerJoined(player); if(player.map != null){ ((NailedMap) player.map).onPlayerJoined(player); } ((PlayerScoreboardManager) player.getScoreboardManager()).onJoinedServer(); player.sendSupportedChannels(); PlayerJoinServerEvent e = fireEvent(new PlayerJoinServerEvent(player)); NailedPlatform.instance().broadcastMessage(e.getMessage()); if(player.map != null){ firePlayerJoinMap(player, player.map); } firePlayerJoinWorld(player, player.world); } public static void firePlayerLeft(EntityPlayerMP playerEntity){ NailedPlayer player = NailedPlatform.instance().getOrCreatePlayer(playerEntity); player.isOnline = false; PlayerLeaveServerEvent e = fireEvent(new PlayerLeaveServerEvent(player)); if(player.map != null){ firePlayerLeftMap(player, player.map); } firePlayerLeftWorld(player, player.world); ((PlayerScoreboardManager) player.getScoreboardManager()).onLeftServer(); player.world.onPlayerLeft(player); if(player.map != null){ ((NailedMap) player.map).onPlayerLeft(player); } player.entity = null; player.world = null; player.map = null; player.netHandler = null; NailedPlatform.instance().broadcastMessage(e.getMessage()); } public static String firePlayerChat(EntityPlayerMP playerEntity, String message){ Player player = NailedPlatform.instance().getPlayerFromEntity(playerEntity); PlayerChatEvent e = fireEvent(new PlayerChatEvent(player, message)); return e.isCanceled() ? null : e.getMessage(); } public static boolean fireOnRightClick(EntityPlayer playerEntity, World world, ItemStack is, BlockPos pos, EnumFacing side, float bX, float bY, float bZ){ NailedPlayer player = ((NailedPlayer) NailedPlatform.instance().getPlayerFromEntity(((EntityPlayerMP) playerEntity))); int xC = pos.getX() + side.getFrontOffsetX(); int yC = pos.getY() + side.getFrontOffsetY(); int zC = pos.getZ() + side.getFrontOffsetZ(); //TODO boolean canceled = false;//fireEvent(new BlockPlaceEvent(xC, yC, zC, NailedDimensionManager.getWorld(world.provider.getDimensionId), player)).isCanceled boolean ret; if(canceled){ //Send the slot content to the client because the client decreases the stack size by 1 when it places a block //was sendContainerAndContentsToPlayer player.getEntity().updateCraftingInventory(player.getEntity().inventoryContainer, player.getEntity().inventoryContainer.getInventory()); ret = true; }else{ ret = false; } if(ret){ return true; } //TODO: allow to do this in an event handler if(is.getTagCompound() != null && is.getTagCompound().getBoolean("IsStatemitter")){ if(player.getGameMode() != GameMode.CREATIVE){ player.sendMessage(new ComponentBuilder("You must be in creative mode to use Stat Emitters!").color(ChatColor.RED).create()); //was sendContainerAndContentsToPlayer player.getEntity().updateCraftingInventory(player.getEntity().inventoryContainer, player.getEntity().inventoryContainer.getInventory()); return true; } BlockPos pos1 = new BlockPos(xC, yC, zC); world.setBlockState(pos1, Blocks.command_block.getDefaultState()); world.setTileEntity(pos1, new TileEntityStatEmitter()); if(is.getTagCompound().hasKey("Content")){ ((TileEntityStatEmitter) world.getTileEntity(pos1)).getCommandBlockLogic().setCommand(is.getTagCompound().getString("Content")); } return true; } return ret; } public static boolean fireOnBlockBroken(World world, WorldSettings.GameType gameType, EntityPlayerMP playerEntity, int x, int y, int z){ boolean preCancel = false; /*if(gameType.isAdventure && !playerEntity.isCurrentToolAdventureModeExempt(x, y, z)){ preCancel = true }else if(gameType.isCreative && playerEntity.getHeldItem != null && playerEntity.getHeldItem.getItem.isInstanceOf[ItemSword]){ preCancel = true }*/ // Tell client the block is gone immediately then process events /*if(world.getTileEntity(x, y, z) == null){ val packet = new S23PacketBlockChange(x, y, z, world) packet.field_148883_d = Blocks.air packet.field_148884_e = 0 playerEntity.playerNetServerHandler.sendPacket(packet) }*/ //Post the block break event /*val player = Server.getInstance.getPlayer(playerEntity.getGameProfile.getId).get val block = world.getBlock(x, y, z) val meta = world.getBlockMetadata(x, y, z) val event = new BlockBreakEvent(x, y, z, NailedDimensionManager.getWorld(world.provider.func_177502_q()), Material.getMaterial(Block.getIdFromBlock(block)), meta.toByte, player) event.setCanceled(preCancel) fireEvent(event)*/ /*if(event.isCanceled){ //Let the client know the block still exists playerEntity.playerNetServerHandler.sendPacket(new S23PacketBlockChange(x, y, z, world)) //Also update the TileEntity val tile = world.getTileEntity(x, y, z) if(tile != null){ val desc = tile.getDescriptionPacket if(desc != null){ playerEntity.playerNetServerHandler.sendPacket(desc) } } true }else false*/ return false; } public static boolean firePlayerDropStack(EntityPlayerMP player, boolean fullStack){ //Return false to cancel return !fireEvent(new PlayerThrowItemEvent(NailedPlatform.instance().getPlayerFromEntity(player), ItemStackConverter.toNailed(player.getCurrentEquippedItem()))).isCanceled(); } public static PlayerLeaveWorldEvent firePlayerLeftWorld(Player player, jk_5.nailed.api.world.World world){ return fireEvent(new PlayerLeaveWorldEvent(player, world)); } public static PlayerJoinWorldEvent firePlayerJoinWorld(Player player, jk_5.nailed.api.world.World world){ return fireEvent(new PlayerJoinWorldEvent(player, world)); } public static PlayerLeaveMapEvent firePlayerLeftMap(Player player, Map map){ return fireEvent(new PlayerLeaveMapEvent(player, map)); } public static PlayerJoinMapEvent firePlayerJoinMap(Player player, Map map){ return fireEvent(new PlayerJoinMapEvent(player, map)); } public static boolean fireOnItemRightClick(EntityPlayer player, World world, ItemStack stack){ return fireEvent(new PlayerRightClickItemEvent(NailedPlatform.instance().getPlayerFromEntity(((EntityPlayerMP) player)), ItemStackConverter.toNailed(stack))).isCanceled(); } public static void onPlayerRespawn(EntityPlayerMP ent){ MinecraftServer server = MinecraftServer.getServer(); NailedPlayer player = ((NailedPlayer) NailedPlatform.instance().getPlayerFromEntity(ent)); NailedWorld destWorld = NailedDimensionManager.instance().getWorld(ent.dimension); NailedWorld currentWorld = NailedDimensionManager.instance().getWorld(ent.dimension); Map destMap = destWorld.getMap(); currentWorld.getWrapped().getEntityTracker().removePlayerFromTrackers(ent); //Remove from EntityTracker currentWorld.getWrapped().getEntityTracker().untrackEntity(ent); //Notify other players of entity death currentWorld.getWrapped().getPlayerManager().removePlayer(ent); //Remove player's ChunkLoader server.getConfigurationManager().playerEntityList.remove(ent); //Remove from the global player list currentWorld.getWrapped().removePlayerEntityDangerously(ent); //Force the entity to be removed from it's current world Mappack mappack = destMap != null ? destMap.mappack() : null; Location pos = mappack == null ? new Location(destWorld, 0, 64, 0) : Location.builder().copy(destWorld.getConfig().spawnPoint()).setWorld(destWorld).build(); if(destMap != null && destMap.getGameManager().isGameRunning()){ if(destMap.getPlayerTeam(player) == null){ //TODO: random spawnpoints /*if(mappack != null && mappack.getMetadata.isChoosingRandomSpawnpointAtRespawn()){ List<Location> spawnpoints = mappack.getMappackMetadata().getRandomSpawnpoints(); pos = spawnpoints.get(NailedAPI.getMapLoader().getRandomSpawnpointSelector().nextInt(spawnpoints.size())); }*/ }else{ Location p = destMap.getPlayerTeam(player).getSpawnPoint(); if(p != null) pos = p; } } ent.dimension = destWorld.getDimensionId(); ItemInWorldManager worldManager = new ItemInWorldManager(destWorld.getWrapped()); EntityPlayerMP newPlayer = new EntityPlayerMP(server, destWorld.getWrapped(), ent.getGameProfile(), worldManager); newPlayer.playerNetServerHandler = ent.playerNetServerHandler; newPlayer.clonePlayer(ent, false); newPlayer.dimension = destWorld.getDimensionId(); newPlayer.setEntityId(ent.getEntityId()); worldManager.setGameType(ent.theItemInWorldManager.getGameType()); newPlayer.setLocationAndAngles(pos.getX(), pos.getY(), pos.getZ(), pos.getYaw(), pos.getPitch()); destWorld.getWrapped().theChunkProviderServer.loadChunk((int)(newPlayer.posX) >> 4, (int)(newPlayer.posZ) >> 4); player.sendPacket(new S07PacketRespawn(destWorld.getConfig().dimension().getId(), destWorld.getWrapped().getDifficulty(), destWorld.getWrapped().getWorldInfo().getTerrainType(), worldManager.getGameType())); player.netHandler.setPlayerLocation(pos.getX(), pos.getY(), pos.getZ(), pos.getYaw(), pos.getPitch()); player.sendPacket(new S05PacketSpawnPosition(new BlockPos(pos.getX(), pos.getY(), pos.getZ()))); player.sendPacket(new S1FPacketSetExperience(newPlayer.experience, newPlayer.experienceTotal, newPlayer.experienceLevel)); server.getConfigurationManager().updateTimeAndWeatherForPlayer(newPlayer, destWorld.getWrapped()); destWorld.getWrapped().getPlayerManager().addPlayer(newPlayer); destWorld.getWrapped().spawnEntityInWorld(newPlayer); //noinspection unchecked ((List<EntityPlayer>) server.getConfigurationManager().playerEntityList).add(newPlayer); newPlayer.addSelfToInternalCraftingInventory(); newPlayer.setHealth(newPlayer.getHealth()); player.netHandler.playerEntity = newPlayer; player.entity = newPlayer; //TODO: respawn event } public static float onLivingFall(EntityLivingBase entity, Float distance){ EntityFallEvent event = new EntityFallEvent(entity, distance); //TODO: api event return fireEvent(event).isCanceled() ? 0 : event.getDistance(); } public static float onEntityDamage(EntityLivingBase entity, DamageSource source, float amount){ EntityDamageEvent event = new EntityDamageEvent(entity, source, amount); //TODO: api event return fireEvent(event).isCanceled() ? 0 : event.getAmount(); } public static boolean firePlayerRightClickAir(EntityPlayerMP player){ //return true to cancel PlayerInteractEvent event = new PlayerInteractEvent(NailedPlatform.instance().getPlayerFromEntity(player), PlayerInteractEvent.Action.RIGHT_CLICK_AIR); return fireEvent(event).isCanceled(); } public static boolean firePlayerRightClickBlock(EntityPlayerMP player, int x, int y, int z){ //return true to cancel PlayerInteractEvent event = new PlayerInteractEvent(NailedPlatform.instance().getPlayerFromEntity(player), PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK, new Location(x, y, z)); //TODO: include world return fireEvent(event).isCanceled(); } public static void firePlayerLeftClickAir(EntityPlayerMP player){ PlayerInteractEvent event = new PlayerInteractEvent(NailedPlatform.instance().getPlayerFromEntity(player), PlayerInteractEvent.Action.LEFT_CLICK_AIR); fireEvent(event); } public static boolean firePlayerLeftClickBlock(EntityPlayerMP player, int x, int y, int z){ //return true to cancel PlayerInteractEvent event = new PlayerInteractEvent(NailedPlatform.instance().getPlayerFromEntity(player), PlayerInteractEvent.Action.LEFT_CLICK_BLOCK, new Location(x, y, z)); //TODO: include world return fireEvent(event).isCanceled(); } public static void firePlayerRegisterChannelEvent(NailedPlayer player, String channel){ //TODO } public static void firePlayerUnregisterChannelEvent(NailedPlayer player, String channel){ //TODO } }