Merge branch 'develop' of https://github.com/Mineplex-LLC/Minecraft-PC into feature/party-v2

This commit is contained in:
TadahTech 2016-06-22 00:36:23 -05:00
commit d9c5e6323a
3 changed files with 274 additions and 296 deletions

View File

@ -256,33 +256,36 @@ public class MapUtil
@SuppressWarnings({ "rawtypes" })
public static boolean ClearWorldReferences(String worldName)
{
HashMap regionfiles = (HashMap) RegionFileCache.a;
try
synchronized (RegionFileCache.class)
{
for (Iterator<Object> iterator = regionfiles.entrySet().iterator(); iterator.hasNext();)
{
Map.Entry e = (Map.Entry) iterator.next();
RegionFile file = (RegionFile) e.getValue();
HashMap regionfiles = (HashMap) RegionFileCache.a;
try
try
{
for (Iterator<Object> iterator = regionfiles.entrySet().iterator(); iterator.hasNext(); )
{
file.c();
iterator.remove();
}
catch (Exception ex)
{
ex.printStackTrace();
Map.Entry e = (Map.Entry) iterator.next();
RegionFile file = (RegionFile) e.getValue();
try
{
file.c();
iterator.remove();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}
catch (Exception ex)
{
System.out.println("Exception while removing world reference for '" + worldName + "'!");
ex.printStackTrace();
}
catch (Exception ex)
{
System.out.println("Exception while removing world reference for '" + worldName + "'!");
ex.printStackTrace();
}
return true;
return true;
}
}
public static BlockPosition getBlockPos(int x, int y, int z)

View File

@ -1,8 +1,13 @@
package nautilus.game.arcade.game.games.uhc;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
@ -35,6 +40,19 @@ import nautilus.game.arcade.game.TeamGame;
import nautilus.game.arcade.game.Game.GameState;
import nautilus.game.arcade.kit.Kit;
import net.minecraft.server.v1_8_R3.BiomeCache;
import net.minecraft.server.v1_8_R3.ChunkCoordIntPair;
import net.minecraft.server.v1_8_R3.ChunkProviderServer;
import net.minecraft.server.v1_8_R3.EmptyChunk;
import net.minecraft.server.v1_8_R3.ExceptionWorldConflict;
import net.minecraft.server.v1_8_R3.FileIOThread;
import net.minecraft.server.v1_8_R3.IChunkLoader;
import net.minecraft.server.v1_8_R3.IChunkProvider;
import net.minecraft.server.v1_8_R3.LongHashMap;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import net.minecraft.server.v1_8_R3.NBTTagCompound;
import net.minecraft.server.v1_8_R3.World;
import net.minecraft.server.v1_8_R3.WorldChunkManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
@ -46,6 +64,9 @@ import org.bukkit.WorldBorder;
import org.bukkit.World.Environment;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.generator.NormalChunkGenerator;
import org.bukkit.craftbukkit.v1_8_R3.util.LongHash;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
@ -86,19 +107,21 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.spigotmc.WatchdogThread;
public class UHC extends TeamGame
{
private NautHashMap<Player, Player> _teamReqs = new NautHashMap<Player, Player>();
private NautHashMap<String, Long> _deathTime = new NautHashMap<String, Long>();
// private NautHashMap<String, Long> _combatTime = new NautHashMap<String, Long>();
private boolean _mapLoaded = false;
private double _mapLoadPercent = 0;
private int _chunksPerTick = 1;
private volatile boolean _mapLoaded = false;
private volatile double _mapLoadPercent = 0;
private volatile int _chunksPerTick = 1;
private volatile boolean stopGen = false;
private int _chunkTotal;
private Chunk _chunk = null;
private int _chunkX = 0;
private int _chunkZ = 0;
private int _chunksLoaded = 0;
@ -111,7 +134,7 @@ public class UHC extends TeamGame
private long _createTime;
private long _serverTime;
private boolean xrayDebug = false;
@ -139,21 +162,21 @@ public class UHC extends TeamGame
{
super(manager, type,
new Kit[]
{
new KitUHC(manager)
},
new Kit[]
{
new KitUHC(manager)
},
new String[]
{
"10 minutes of no PvP", "Only Golden Apples restore health", "Ores can only be found in caves",
"Borders shrink over time", "Last player/team alive wins!"
});
new String[]
{
"10 minutes of no PvP", "Only Golden Apples restore health", "Ores can only be found in caves",
"Borders shrink over time", "Last player/team alive wins!"
});
this.HideTeamSheep = true;
this.StrictAntiHack = true;
AnnounceStay = false;
this.GameTimeout = 10800000;
@ -203,7 +226,7 @@ public class UHC extends TeamGame
this.GadgetsDisabled = true;
WorldTimeSet = -1;
CraftRecipes();
// Disable Custom Mob Drops (and EXP Disable)
@ -225,8 +248,8 @@ public class UHC extends TeamGame
@Override
public void ParseData()
{
WorldData.World.setDifficulty(Difficulty.HARD);
WorldData.World.setDifficulty(Difficulty.HARD);
_chunkX = (int) -(_currentBorder / 16);
_chunkZ = (int) -(_currentBorder / 16);
_chunkTotal = (int) ((_currentBorder * 2 / 16) * (_currentBorder * 2 / 16));
@ -368,84 +391,6 @@ public class UHC extends TeamGame
return borders;
}
@EventHandler
public void loadMap(UpdateEvent event)
{
if (_mapLoaded)
return;
if (WorldData.World == null)
return;
if (GetState() != GameState.Recruit)
return;
// Print Debug
if (event.getType() == UpdateType.SLOWER)
{
Announce(C.cGreen + C.Bold + "Generating Map: " + C.cWhite + getMapLoadETA() + " Remaining...", false);
TimingManager.endTotal("UHC Generation", true);
return;
}
if (event.getType() != UpdateType.TICK)
return;
// Timings
TimingManager.startTotal("UHC Generation");
for (int i = 0; i < _chunksPerTick ; i++)
{
// Unload Previous
// if (_chunk != null)
// _chunk.unload(true);
// Load Chunks
_chunk = WorldData.World.getChunkAt(_chunkX, _chunkZ);
_chunk.load(true);
// Scan Map
if (_chunkX < _currentBorder / 16)
{
_chunkX++;
}
else if (_chunkZ < _currentBorder / 16)
{
_chunkX = (int) -(_currentBorder / 16);
_chunkZ++;
}
else
{
_mapLoaded = true;
System.out.println("Map Loading Finished!");
generateSpawns();
break;
}
_chunksLoaded++;
}
_mapLoadPercent = (double)_chunksLoaded / (double)_chunkTotal;
// Timings
TimingManager.stopTotal("UHC Generation");
}
@EventHandler
public void chunkUnload(ChunkUnloadEvent event)
{
//Allow unloading after players in
if (IsLive())
return;
if (WorldData.World != null && event.getWorld().equals(WorldData.World))
{
System.out.println("Disallowing Unload of World");
event.setCancelled(true);
}
}
public void generateSpawns()
{
// Wipe Spawns
@ -467,7 +412,7 @@ public class UHC extends TeamGame
double dist = (2 * _currentBorder) / (Math.sqrt(this.GetPlayers(true).size()) + 3);
// Ensure distance between Teams - 500 Attempts
for (int i=0 ; i<500 ; i++)
for (int i = 0; i < 500; i++)
{
boolean clash = false;
@ -500,7 +445,7 @@ public class UHC extends TeamGame
double dist = (2 * _currentBorder) / (Math.sqrt(GetTeamList().size()) + 3);
// Ensure distance between Teams - 500 Attempts
for (int i=0 ; i<500 ; i++)
for (int i = 0; i < 500; i++)
{
boolean clash = false;
@ -622,63 +567,183 @@ public class UHC extends TeamGame
}
}
/*@EventHandler
public void WorldBoundaryCheck(UpdateEvent event)
{
if (event.getType() != UpdateType.FASTER)
return;
for (Player player : GetPlayers(true))
{
//Damage
if (Math.abs(player.getLocation().getX()) > _borderSize || Math.abs(player.getLocation().getZ()) > _borderSize)
{
player.damage(0.75);
}
}
}
@EventHandler
public void WorldBoundaryShrink(UpdateEvent event)
public void generateWorld(GameStateChangeEvent event)
{
if (!IsLive())
if (event.GetState() == GameState.Dead)
{
stopGen = true;
return;
}
if (event.getType() == UpdateType.SLOW)
if (_borderSize > 16)
_borderSize--;
}
//@EventHandler
public void WorldBoundarySet(GameStateChangeEvent event)
{
if (event.GetState() != GameState.Recruit)
{
return;
}
long time = System.currentTimeMillis();
this.WorldData.MinX = -_borderSize;
this.WorldData.MaxX = _borderSize;
this.WorldData.MinZ = -_borderSize;
this.WorldData.MaxZ = _borderSize;
this.WorldData.MinY = -1000;
this.WorldData.MaxY = 1000;
//Find Y Max
for (int x=-16 ; x<16 ; x++)
for (int z=-16 ; z<16 ; z++)
new Thread(() ->
{
try
{
int y = UtilBlock.getHighest(WorldData.World, x, z).getY();
Field fileIOThreadB = FileIOThread.class.getDeclaredField("b");
fileIOThreadB.setAccessible(true);
if (y > _yMax)
_yMax = y;
// This list is the list of chunks to be saved on the File IO Thread
List list = (List) fileIOThreadB.get(FileIOThread.a());
net.minecraft.server.v1_8_R3.WorldServer worldServer = ((CraftWorld) WorldData.World).getHandle();
WorldChunkManager manager = worldServer.getWorldChunkManager();
Field biomeCacheField = manager.getClass().getDeclaredField("d");
biomeCacheField.setAccessible(true);
// A thread safe BiomeCache
// The implementation is literally a copy/paste from the original BiomeCache, but with some synchronization
// Reason being while the server is ticking the world (for some reason, if you want to dig through the entire Arcade codebase go for it)
// it stores stuff in the BiomeCache, and chunk gen needs that BiomeCache info too
// Causing desynchronization in the cache
biomeCacheField.set(manager, new BiomeCache(manager)
{
private final Object _lock = new Object();
private long _lastCleanTime; // b -> _lastCleanTime
private Map<Long, BiomeCacheBlock> _blockByCoord = new HashMap<>(); // LongHashMap -> HashMap, c -> _blockByCoord
private List<BiomeCache.BiomeCacheBlock> _blocks = new ArrayList<>(); // d -> _blocks
@Override
public BiomeCache.BiomeCacheBlock a(int x, int z)
{
x >>= 4;
z >>= 4;
long var3 = hash(x, z);
BiomeCache.BiomeCacheBlock var5 = this._blockByCoord.get(var3);
if (var5 == null)
{
var5 = new BiomeCache.BiomeCacheBlock(x, z);
synchronized (_lock)
{
this._blockByCoord.put(var3, var5);
this._blocks.add(var5);
}
}
var5.e = MinecraftServer.az();
return var5;
}
@Override
public void a()
{
long currentTime = MinecraftServer.az();
long deltaTime = currentTime - this._lastCleanTime;
if (deltaTime > 7500L || deltaTime < 0L)
{
this._lastCleanTime = currentTime;
synchronized (_lock)
{
for (int i = 0; i < this._blocks.size(); ++i)
{
BiomeCache.BiomeCacheBlock biomeCacheBlock = (BiomeCache.BiomeCacheBlock) this._blocks.get(i);
long var7 = currentTime - biomeCacheBlock.e;
if (var7 > 30000L || var7 < 0L)
{
this._blocks.remove(i--);
this._blockByCoord.remove(hash(biomeCacheBlock.c, biomeCacheBlock.d));
}
}
}
}
}
private long hash(int x, int z)
{
return (long) x & 4294967295L | ((long) z & 4294967295L) << 32;
}
});
ChunkProviderServer cps = worldServer.chunkProviderServer;
IChunkProvider icp = cps.chunkProvider;
System.out.println("Using chunk provider " + icp.getClass());
TimingManager.start("Map Generation");
long start = System.currentTimeMillis();
long last = start;
while (!stopGen)
{
long now = System.currentTimeMillis();
if ((now - last) >= 4000)
{
Announce(C.cGreen + C.Bold + "Generating Map: " + C.cWhite + getMapLoadETA() + " Remaining...", false);
last = now;
}
long hash = LongHash.toLong(_chunkX, _chunkZ);
// This is just a shortcut to how the Minecraft server would have generated a chunk if it doesn't exist.
// This should always create a chunk because we're not loading any chunks beforehand...
// /me looks at new maintainer
net.minecraft.server.v1_8_R3.Chunk chunk = icp.getOrCreateChunk(_chunkX, _chunkZ);
// Run the copypasted code for chunk saving.
cps.saveChunk(chunk);
cps.saveChunkNOP(chunk);
cps.unloadQueue.remove(_chunkX, _chunkZ);
cps.chunks.remove(hash);
if (_chunkX < _currentBorder / 16)
{
_chunkX++;
}
else if (_chunkZ < _currentBorder / 16)
{
_chunkX = (int) -(_currentBorder / 16);
_chunkZ++;
}
else
{
_mapLoaded = true;
System.out.println("Map Loading Finished! Took " + TimeUnit.MILLISECONDS.toSeconds(now - start) + " seconds");
break;
}
_chunksLoaded++;
// Clamp it so we don't get 101%
_mapLoadPercent = UtilMath.clamp((double) _chunksLoaded / (double) _chunkTotal, 0.0, 1.0);
_chunksPerTick = (int) (_chunksLoaded / ((now - start) / 50.0));
}
TimingManager.stop("Map Generation");
if (stopGen)
{
return;
}
TimingManager.start("Map Saving");
// Wait for all the chunks to save (but do we need this?)
while (!list.isEmpty())
{
Thread.sleep(100);
}
TimingManager.stop("Map Saving");
getArcadeManager().runSync(this::generateSpawns);
}
System.out.println("Y Max: " + _yMax);
System.out.println("Time: " + UtilTime.MakeStr(System.currentTimeMillis() - time));
}*/
catch (Throwable t)
{
// todo proper exception handling
// maybe force shutdown?
t.printStackTrace();
}
}, "WorldGen Thread").start();
}
@EventHandler
public void WorldBoundaryYLimit(BlockPlaceEvent event)
@ -865,45 +930,6 @@ public class UHC extends TeamGame
event.setLeaveMessage(null);
}
/*
@EventHandler(priority = EventPriority.LOWEST)
public void PlayerQuit(PlayerQuitEvent event)
{
Player player = event.getPlayer();
GameTeam team = GetTeam(player);
if (team == null) return;
if (!team.IsAlive(player))
return;
team.RemovePlayer(player);
if (player.isDead())
return;
if (true)
{
//Announcement
Announce(team.GetColor() + C.Bold + player.getName() + " was killed for disconnecting.");
player.damage(5000);
return;
}
if (_combatTime.containsKey(player.getName()) && !UtilTime.elapsed(_combatTime.get(player.getName()), 15000))
{
//Announcement
Announce(team.GetColor() + C.Bold + player.getName() + " was killed for disconnecting during combat.");
player.damage(5000);
return;
}
}
*/
@EventHandler
public void CreatureCull(UpdateEvent event)
{
@ -1074,37 +1100,6 @@ public class UHC extends TeamGame
}
}
/*
@EventHandler
public void HeadEat(PlayerInteractEvent event)
{
if (UtilGear.isMat(event.getPlayer().getItemInHand(), Material.SKULL_ITEM))
{
UtilPlayer.message(event.getPlayer(), "You ate " + event.getPlayer().getItemInHand().getItemMeta().getDisplayName() + ChatColor.RESET + ".");
(new PotionEffect(PotionEffectType.ABSORPTION, 2400, 0)).apply(event.getPlayer());
(new PotionEffect(PotionEffectType.REGENERATION, 200, 1)).apply(event.getPlayer());
event.getPlayer().setItemInHand(null);
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void DamageHealCancel(EntityDamageEvent event)
{
if (event.isCancelled())
return;
if (event.getEntity() instanceof Player)
{
Player player = (Player)event.getEntity();
player.removePotionEffect(PotionEffectType.REGENERATION);
UtilPlayer.message(player, "You took damage and lost " + F.elem(C.cGreen + "Regeneration") + ChatColor.RESET + ".");
}
}*/
@EventHandler
public void ConsumeHeadApple(PlayerItemConsumeEvent event)
{
@ -1139,30 +1134,6 @@ public class UHC extends TeamGame
{
if (event.getMessage().startsWith("/kill"))
event.setCancelled(true);
// if (event.getMessage().startsWith("/uhc time day"))
// {
// this.WorldTimeSet = 4000;
// event.setCancelled(true);
//
// Announce(event.getPlayer().getName() + " set time to Always Day!");
// }
//
// if (event.getMessage().startsWith("/uhc time night"))
// {
// this.WorldTimeSet = 16000;
// event.setCancelled(true);
//
// Announce(event.getPlayer().getName() + " set time to Always Night!");
// }
//
// if (event.getMessage().startsWith("/uhc time cycle"))
// {
// this.WorldTimeSet = -1;
// event.setCancelled(true);
//
// Announce(event.getPlayer().getName() + " set time to Day and Night!");
// }
}
@EventHandler(priority = EventPriority.LOWEST)
@ -1645,27 +1616,27 @@ public class UHC extends TeamGame
return _mapLoaded;
}
public String getMapLoadPercent()
public String getMapLoadPercent()
{
return (int)(_mapLoadPercent * 100) + "%";
return (int) (_mapLoadPercent * 100) + "%";
}
public String getMapLoadETA()
public String getMapLoadETA()
{
int chunksToGo = _chunkTotal - _chunksLoaded;
return UtilTime.MakeStr((long) ((double)chunksToGo / (double)(_chunksPerTick * 20) * 1000d), 1);
return UtilTime.MakeStr((long) ((double) chunksToGo / (double) (_chunksPerTick * 20) * 1000d), 1);
}
@EventHandler(priority = EventPriority.HIGH)
public void teamSelectInteract(PlayerInteractEntityEvent event)
{
if (GetState() != GameState.Recruit)
return;
if (event.getRightClicked() == null)
return;
if (!(event.getRightClicked() instanceof Player))
return;
@ -1678,34 +1649,34 @@ public class UHC extends TeamGame
return;
}
selectTeamMate(player, (Player)event.getRightClicked());
selectTeamMate(player, (Player) event.getRightClicked());
}
@EventHandler
public void teamSelectCommand(PlayerCommandPreprocessEvent event)
{
if (GetState() != GameState.Recruit)
return;
if (!event.getMessage().toLowerCase().startsWith("/team "))
return;
event.setCancelled(true);
Player target = UtilPlayer.searchOnline(event.getPlayer(), event.getMessage().split(" ")[1], true);
if (target == null)
return;
//Observer
if (Manager.IsObserver(event.getPlayer()))
{
UtilPlayer.message(event.getPlayer(), F.main("Game", "Spectators cannot partake in games."));
return;
}
if (event.getPlayer().equals(target))
return;
selectTeamMate(event.getPlayer(), target);
}
@ -1717,28 +1688,28 @@ public class UHC extends TeamGame
//Remove Prefs
_teamReqs.remove(player);
_teamReqs.remove(ally);
//Inform
UtilPlayer.message(player, F.main("Game", "You accepted " + ally.getName() + "'s Team Request!"));
UtilPlayer.message(ally, F.main("Game", player.getName() + " accepted your Team Request!"));
//Leave Old Teams
if (GetTeam(player) != null)
GetTeam(player).DisbandTeam();
if (GetTeam(ally) != null)
GetTeam(ally).DisbandTeam();
//Get Team
GameTeam team = getEmptyTeam();
if (team == null)
return;
team.setDisplayName(player.getName() + " & " + ally.getName());
team.setDisplayName(player.getName() + " & " + ally.getName());
//Join Team
SetPlayerTeam(player, team, true);
SetPlayerTeam(ally, team, true);
SetPlayerTeam(ally, team, true);
}
//Send Invite
else
@ -1747,33 +1718,33 @@ public class UHC extends TeamGame
if (GetTeam(player) != null)
if (GetTeam(player).HasPlayer(ally))
return;
//Inform Player
UtilPlayer.message(player, F.main("Game", "You sent a Team Request to " + ally.getName() + "!"));
//Inform Target
if (Recharge.Instance.use(player, "Team Req " + ally.getName(), 2000, false, false))
{
UtilPlayer.message(ally, F.main("Game", player.getName() + " sent you a Team Request!"));
UtilPlayer.message(ally, F.main("Game", "Type " + F.elem("/team " + player.getName()) + " to accept!"));
}
//Add Pref
_teamReqs.put(player, ally);
}
}
@EventHandler
public void teamQuit(PlayerQuitEvent event)
{
if (GetState() != GameState.Recruit)
return;
Player player = event.getPlayer();
if (GetTeam(player) != null)
GetTeam(player).DisbandTeam();
Iterator<Player> teamIter = _teamReqs.keySet().iterator();
while (teamIter.hasNext())
{
@ -1782,7 +1753,7 @@ public class UHC extends TeamGame
teamIter.remove();
}
}
public GameTeam getEmptyTeam()
{
for (GameTeam team : GetTeamList())
@ -1790,7 +1761,7 @@ public class UHC extends TeamGame
if (team.GetPlayers(false).isEmpty())
return team;
}
return null;
}
}

View File

@ -416,6 +416,10 @@ public class WorldData
public boolean LoadChunks(long maxMilliseconds)
{
if (Host instanceof UHC)
{
return true;
}
long startTime = System.currentTimeMillis();
for (; CurX <= MaxX; CurX += 16)