3
0

Some portion of optimizations:

* Clear outgoing packet queue after player disconnect
* Disable sleep between chunk saving
* Put 2x4096 bytes instead 2048x4 bytes for region file aligment
* Using map to search player by name instead iterating over all players
* Some tweaks for decorations (item frames, maps)
This commit is contained in:
Prototik 2015-10-18 23:58:28 +07:00
parent 299cf0ed96
commit 7defe0bb29
17 changed files with 225 additions and 41 deletions

View File

@ -173,6 +173,7 @@ def generateManifest(boolean legacy = false) {
'KCauldron-Channel' : project.name,
'KCauldron-Version' : project.version,
'KCauldron-Legacy' : legacy,
'KCauldron-Official' : project.hasProperty('officialBuild'),
'Implementation-Vendor' : 'Prototik',
'Implementation-Title' : project.name,
'Implementation-Version': project.version,

Binary file not shown.

View File

@ -1,6 +1,6 @@
#Tue Jun 16 17:21:00 KRAT 2015
#Fri Oct 16 21:29:47 KRAT 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-bin.zip

6
gradlew vendored
View File

@ -42,11 +42,6 @@ case "`uname`" in
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@ -114,6 +109,7 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`

View File

@ -14,6 +14,15 @@
this.func_146065_b(p_70097_1_.getEntity(), false);
this.setDisplayedItem((ItemStack)null);
}
@@ -115,7 +122,7 @@
if (p_110131_1_.getItem() == Items.filled_map)
{
MapData mapdata = ((ItemMap)p_110131_1_.getItem()).getMapData(p_110131_1_, this.worldObj);
- mapdata.playersVisibleOnMap.remove("frame-" + this.getEntityId());
+ mapdata.playersVisibleOnMap.remove(java.util.UUID.nameUUIDFromBytes(("frame-" + this.getEntityId()).getBytes(org.apache.commons.codec.Charsets.US_ASCII)));
}
p_110131_1_.setItemFrame((EntityItemFrame)null);
@@ -203,4 +210,11 @@
return true;

View File

@ -608,7 +608,7 @@
}
+ // CraftBukkit start
+ if (p_147359_1_ == null)
+ if (p_147359_1_ == null || this.processedDisconnect) // KCauldron
+ {
+ return;
+ }
@ -1822,7 +1822,7 @@
{
packetbuffer = new PacketBuffer(Unpooled.wrappedBuffer(p_147349_1_.func_149558_e()));
@@ -1093,16 +2409,18 @@
{
if (itemstack.getItem() == Items.writable_book && itemstack.getItem() == itemstack1.getItem())
{
- itemstack1.setTagInfo("pages", itemstack.getTagCompound().getTagList("pages", 8));
@ -1845,7 +1845,7 @@
finally
{
@@ -1135,19 +2453,18 @@
{
if (itemstack.getItem() == Items.written_book && itemstack1.getItem() == Items.writable_book)
{
- itemstack1.setTagInfo("author", new NBTTagString(this.playerEntity.getCommandSenderName()));

View File

@ -77,7 +77,7 @@
packet.processPacket(this.netHandler);
}
@@ -225,6 +257,8 @@
@@ -225,8 +257,11 @@
public void closeChannel(IChatComponent p_150718_1_)
{
@ -85,8 +85,11 @@
+
if (this.channel.isOpen())
{
+ this.outboundPacketsQueue.clear(); // KCauldron
this.channel.close();
@@ -254,7 +288,7 @@
this.terminationReason = p_150718_1_;
}
@@ -254,7 +289,7 @@
{
;
}
@ -95,7 +98,7 @@
try
{
p_initChannel_1_.config().setOption(ChannelOption.TCP_NODELAY, Boolean.valueOf(false));
@@ -322,6 +356,13 @@
@@ -322,6 +357,13 @@
return channel;
}

View File

@ -58,12 +58,13 @@
protected int maxPlayers;
private int viewDistance;
private WorldSettings.GameType gameType;
@@ -91,8 +115,17 @@
@@ -91,8 +115,18 @@
private int playerPingIndex;
private static final String __OBFID = "CL_00001423";
+ // CraftBukkit start
+ private CraftServer cserver;
+ private final Map<String,EntityPlayerMP> playersByName = new org.spigotmc.CaseInsensitiveMap<EntityPlayerMP>(); // KCauldron
+
public ServerConfigurationManager(MinecraftServer p_i1500_1_)
{
@ -76,7 +77,7 @@
this.bannedPlayers = new UserListBans(field_152613_a);
this.bannedIPs = new BanList(field_152614_b);
this.ops = new UserListOps(field_152615_c);
@@ -131,12 +164,32 @@
@@ -131,12 +165,32 @@
s1 = p_72355_1_.getSocketAddress().toString();
}
@ -111,7 +112,7 @@
nethandlerplayserver.sendPacket(new S3FPacketCustomPayload("MC|Brand", this.getServerInstance().getServerModName().getBytes(Charsets.UTF_8)));
nethandlerplayserver.sendPacket(new S05PacketSpawnPosition(chunkcoordinates.posX, chunkcoordinates.posY, chunkcoordinates.posZ));
nethandlerplayserver.sendPacket(new S39PacketPlayerAbilities(p_72355_2_.capabilities));
@@ -145,6 +198,7 @@
@@ -145,6 +199,7 @@
p_72355_2_.func_147099_x().func_150884_b(p_72355_2_);
this.func_96456_a((ServerScoreboard)worldserver.getScoreboard(), p_72355_2_);
this.mcServer.func_147132_au();
@ -119,7 +120,7 @@
ChatComponentTranslation chatcomponenttranslation;
if (!p_72355_2_.getCommandSenderName().equalsIgnoreCase(s))
@@ -158,6 +212,7 @@
@@ -158,6 +213,7 @@
chatcomponenttranslation.getChatStyle().setColor(EnumChatFormatting.YELLOW);
this.sendChatMsg(chatcomponenttranslation);
@ -127,7 +128,7 @@
this.playerLoggedIn(p_72355_2_);
nethandlerplayserver.setPlayerLocation(p_72355_2_.posX, p_72355_2_.posY, p_72355_2_.posZ, p_72355_2_.rotationYaw, p_72355_2_.rotationPitch);
this.updateTimeAndWeatherForPlayer(p_72355_2_, worldserver);
@@ -192,7 +247,7 @@
@@ -192,7 +248,7 @@
}
}
@ -136,7 +137,7 @@
{
HashSet hashset = new HashSet();
Iterator iterator = p_96456_1_.getTeams().iterator();
@@ -225,6 +280,7 @@
@@ -225,6 +281,7 @@
public void setPlayerManager(WorldServer[] p_72364_1_)
{
@ -144,7 +145,7 @@
this.playerNBTManagerObj = p_72364_1_[0].getSaveHandler().getSaveHandler();
}
@@ -248,7 +304,7 @@
@@ -248,7 +305,7 @@
public NBTTagCompound readPlayerDataFromFile(EntityPlayerMP p_72380_1_)
{
@ -153,7 +154,7 @@
NBTTagCompound nbttagcompound1;
if (p_72380_1_.getCommandSenderName().equals(this.mcServer.getServerOwner()) && nbttagcompound != null)
@@ -294,18 +350,61 @@
@@ -294,18 +351,62 @@
public void playerLoggedIn(EntityPlayerMP p_72377_1_)
{
@ -161,6 +162,7 @@
+ cserver.detectListNameConflict(p_72377_1_); // CraftBukkit
+ // this.sendPacketToAllPlayers(new S38PacketPlayerListItem(p_72377_1_.getCommandSenderName(), true, 1000)); // CraftBukkit - replaced with loop below
this.playerEntityList.add(p_72377_1_);
+ this.playersByName.put(p_72377_1_.getCommandSenderName(), p_72377_1_);
WorldServer worldserver = this.mcServer.worldServerForDimension(p_72377_1_.dimension);
+ // CraftBukkit start
+ PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(this.cserver.getPlayer(p_72377_1_), "\u00A7e" + p_72377_1_.getCommandSenderName()
@ -219,7 +221,7 @@
}
public void updatePlayerPertinentChunks(EntityPlayerMP p_72358_1_)
@@ -313,14 +412,33 @@
@@ -313,14 +414,33 @@
p_72358_1_.getServerForPlayer().getPlayerManager().updatePlayerPertinentChunks(p_72358_1_);
}
@ -255,13 +257,14 @@
{
worldserver.removePlayerEntityDangerously(p_72367_1_.ridingEntity);
logger.debug("removing player mount");
@@ -329,9 +447,35 @@
@@ -329,9 +449,36 @@
worldserver.removeEntity(p_72367_1_);
worldserver.getPlayerManager().removePlayer(p_72367_1_);
this.playerEntityList.remove(p_72367_1_);
- this.field_148547_k.remove(p_72367_1_.getUniqueID());
- net.minecraftforge.common.chunkio.ChunkIOExecutor.adjustPoolSize(this.getCurrentPlayerCount());
- this.sendPacketToAllPlayers(new S38PacketPlayerListItem(p_72367_1_.getCommandSenderName(), false, 9999));
+ this.playersByName.remove(p_72367_1_.getCommandSenderName());
+ this.field_148547_k.remove(p_72367_1_.getCommandSenderName());
+ ChunkIOExecutor.adjustPoolSize(this.getCurrentPlayerCount()); // CraftBukkit
+ // CraftBukkit start - .name -> .listName, replace sendAll with loop
@ -294,7 +297,7 @@
}
public String allowUserToConnect(SocketAddress p_148542_1_, GameProfile p_148542_2_)
@@ -372,6 +516,71 @@
@@ -372,6 +519,71 @@
}
}
@ -366,7 +369,7 @@
public EntityPlayerMP createPlayerForUser(GameProfile p_148545_1_)
{
UUID uuid = EntityPlayer.func_146094_a(p_148545_1_);
@@ -410,80 +619,199 @@
@@ -410,80 +622,201 @@
return new EntityPlayerMP(this.mcServer, this.mcServer.worldServerForDimension(0), p_148545_1_, (ItemInWorldManager)object);
}
@ -482,6 +485,7 @@
+ // par1EntityPlayerMP.getServerForPlayer().getEntityTracker().removeEntityFromAllTrackingPlayers(par1EntityPlayerMP); // CraftBukkit
+ par1EntityPlayerMP.getServerForPlayer().getPlayerManager().removePlayer(par1EntityPlayerMP);
+ this.playerEntityList.remove(par1EntityPlayerMP);
+ this.playersByName.remove(par1EntityPlayerMP.getCommandSenderName());
+ this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension).removePlayerEntityDangerously(par1EntityPlayerMP);
+
+ // Phase 4 - handle bed spawn
@ -594,6 +598,7 @@
+ targetWorld.getPlayerManager().addPlayer(entityplayermp1);
+ targetWorld.spawnEntityInWorld(entityplayermp1);
this.playerEntityList.add(entityplayermp1);
+ this.playersByName.put(entityplayermp1.getCommandSenderName(), entityplayermp1);
entityplayermp1.addSelfToInternalCraftingInventory();
entityplayermp1.setHealth(entityplayermp1.getHealth());
- FMLCommonHandler.instance().firePlayerRespawnEvent(entityplayermp1);
@ -606,7 +611,7 @@
return entityplayermp1;
}
@@ -492,34 +820,112 @@
@@ -492,34 +825,112 @@
transferPlayerToDimension(p_72356_1_, p_72356_2_, mcServer.worldServerForDimension(p_72356_2_).getDefaultTeleporter());
}
@ -738,7 +743,7 @@
}
public void transferEntityToWorld(Entity p_82448_1_, int p_82448_2_, WorldServer p_82448_3_, WorldServer p_82448_4_, Teleporter teleporter)
@@ -605,6 +1011,109 @@
@@ -605,6 +1016,109 @@
p_82448_1_.setWorld(p_82448_4_);
}
@ -848,7 +853,7 @@
public void sendPlayerInfoToAllPlayers()
{
if (++this.playerPingIndex > 600)
@@ -612,11 +1121,13 @@
@@ -612,11 +1126,13 @@
this.playerPingIndex = 0;
}
@ -862,7 +867,26 @@
}
public void sendPacketToAllPlayers(Packet p_148540_1_)
@@ -877,13 +1388,24 @@
@@ -719,7 +1235,7 @@
public EntityPlayerMP func_152612_a(String p_152612_1_)
{
- Iterator iterator = this.playerEntityList.iterator();
+ /*Iterator iterator = this.playerEntityList.iterator(); // KCauldron
EntityPlayerMP entityplayermp;
do
@@ -733,7 +1249,8 @@
}
while (!entityplayermp.getCommandSenderName().equalsIgnoreCase(p_152612_1_));
- return entityplayermp;
+ return entityplayermp;*/ // KCauldron
+ return playersByName.get(p_152612_1_);
}
public List findPlayers(ChunkCoordinates p_82449_1_, int p_82449_2_, int p_82449_3_, int p_82449_4_, int p_82449_5_, int p_82449_6_, int p_82449_7_, Map p_82449_8_, String p_82449_9_, String p_82449_10_, World p_82449_11_)
@@ -877,13 +1394,24 @@
for (int j = 0; j < this.playerEntityList.size(); ++j)
{
EntityPlayerMP entityplayermp = (EntityPlayerMP)this.playerEntityList.get(j);
@ -889,7 +913,7 @@
if (d4 * d4 + d5 * d5 + d6 * d6 < p_148543_8_ * p_148543_8_)
{
entityplayermp.playerNetServerHandler.sendPacket(p_148543_11_);
@@ -941,13 +1463,16 @@
@@ -941,13 +1469,16 @@
p_72354_1_.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(1, 0.0F));
p_72354_1_.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(7, p_72354_2_.getRainStrength(1.0F)));
p_72354_1_.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(8, p_72354_2_.getWeightedThunderStrength(1.0F)));
@ -907,7 +931,7 @@
p_72385_1_.playerNetServerHandler.sendPacket(new S09PacketHeldItemChange(p_72385_1_.inventory.currentItem));
}
@@ -961,9 +1486,17 @@
@@ -961,9 +1492,17 @@
return this.maxPlayers;
}
@ -926,7 +950,7 @@
}
public void setWhiteListEnabled(boolean p_72371_1_)
@@ -1032,12 +1565,30 @@
@@ -1032,12 +1571,30 @@
public void removeAllPlayers()
{

View File

@ -0,0 +1,33 @@
--- ../src-base/minecraft/net/minecraft/world/chunk/storage/RegionFile.java
+++ ../src-work/minecraft/net/minecraft/world/chunk/storage/RegionFile.java
@@ -43,7 +43,8 @@
if (this.dataFile.length() < 4096L)
{
- for (i = 0; i < 1024; ++i)
+ // KCauldron start
+ /*for (i = 0; i < 1024; ++i)
{
this.dataFile.writeInt(0);
}
@@ -51,7 +52,10 @@
for (i = 0; i < 1024; ++i)
{
this.dataFile.writeInt(0);
- }
+ }*/
+ dataFile.write(emptySector);
+ dataFile.write(emptySector);
+ // KCauldron end
this.sizeDelta += 8192;
}
@@ -209,7 +213,7 @@
public DataOutputStream getChunkDataOutputStream(int p_76710_1_, int p_76710_2_)
{
- return this.outOfBounds(p_76710_1_, p_76710_2_) ? null : new DataOutputStream(new DeflaterOutputStream(new RegionFile.ChunkBuffer(p_76710_1_, p_76710_2_)));
+ return this.outOfBounds(p_76710_1_, p_76710_2_) ? null : new DataOutputStream(new java.io.BufferedOutputStream(new DeflaterOutputStream(new RegionFile.ChunkBuffer(p_76710_1_, p_76710_2_)))); // KCauldron
}
protected synchronized void write(int p_76706_1_, int p_76706_2_, byte[] p_76706_3_, int p_76706_4_)

View File

@ -15,10 +15,12 @@
public class MapData extends WorldSavedData
{
public int xCenter;
@@ -24,11 +32,21 @@
@@ -23,12 +31,22 @@
public byte[] colors = new byte[16384];
public List playersArrayList = new ArrayList();
private Map playersHashMap = new HashMap();
public Map playersVisibleOnMap = new LinkedHashMap();
- public Map playersVisibleOnMap = new LinkedHashMap();
+ public Map<UUID, MapData.MapCoord> playersVisibleOnMap = new LinkedHashMap();
+
+ // CraftBukkit start
+ public final CraftMapView mapView;
@ -37,7 +39,7 @@
}
public void readFromNBT(NBTTagCompound p_76184_1_)
@@ -107,7 +125,7 @@
@@ -107,14 +125,14 @@
{
if (!this.playersHashMap.containsKey(p_76191_1_))
{
@ -46,6 +48,41 @@
this.playersHashMap.put(p_76191_1_, mapinfo);
this.playersArrayList.add(mapinfo);
}
if (!p_76191_1_.inventory.hasItemStack(p_76191_2_))
{
- this.playersVisibleOnMap.remove(p_76191_1_.getCommandSenderName());
+ this.playersVisibleOnMap.remove(p_76191_1_.getUniqueID());
}
for (int i = 0; i < this.playersArrayList.size(); ++i)
@@ -166,7 +184,7 @@
{
if (Math.abs(f) >= 320.0F || Math.abs(f1) >= 320.0F)
{
- this.playersVisibleOnMap.remove(p_82567_3_);
+ this.playersVisibleOnMap.remove(java.util.UUID.nameUUIDFromBytes(p_82567_3_.getBytes(org.apache.commons.codec.Charsets.US_ASCII)));
return;
}
@@ -194,7 +212,7 @@
}
}
- this.playersVisibleOnMap.put(p_82567_3_, new MapData.MapCoord((byte)p_82567_1_, b0, b1, b2));
+ this.playersVisibleOnMap.put(java.util.UUID.nameUUIDFromBytes(p_82567_3_.getBytes(org.apache.commons.codec.Charsets.US_ASCII)), new MapData.MapCoord((byte)p_82567_1_, b0, b1, b2));
}
public byte[] getUpdatePacketData(ItemStack p_76193_1_, World p_76193_2_, EntityPlayer p_76193_3_)
@@ -250,7 +268,7 @@
byte b3 = p_76192_1_[i * 3 + 2];
byte b0 = p_76192_1_[i * 3 + 3];
byte b1 = (byte)(p_76192_1_[i * 3 + 1] & 15);
- this.playersVisibleOnMap.put("icon-" + i, new MapData.MapCoord(b2, b3, b0, b1));
+ this.playersVisibleOnMap.put(java.util.UUID.nameUUIDFromBytes(("icon-" + i).getBytes(org.apache.commons.codec.Charsets.US_ASCII)), new MapData.MapCoord(b2, b3, b0, b1));
}
}
else if (p_76192_1_[0] == 2)
@@ -265,7 +283,7 @@
if (mapinfo == null)

View File

@ -0,0 +1,19 @@
--- ../src-base/minecraft/net/minecraft/world/storage/ThreadedFileIOBase.java
+++ ../src-work/minecraft/net/minecraft/world/storage/ThreadedFileIOBase.java
@@ -39,14 +39,14 @@
++this.savedIOCounter;
}
- try
+ /*try // KCauldron start
{
Thread.sleep(this.isThreadWaiting ? 0L : 10L);
}
catch (InterruptedException interruptedexception1)
{
interruptedexception1.printStackTrace();
- }
+ }*/ // KCauldron end
}
if (this.threadedIOQueue.isEmpty())

View File

@ -41,6 +41,8 @@ public class KCauldron {
sGroup = manifest.getProperty("KCauldron-Group");
sBranch = manifest.getProperty("KCauldron-Branch");
sChannel = manifest.getProperty("KCauldron-Channel");
sLegacy = Boolean.parseBoolean(manifest.getProperty("KCauldron-Legacy"));
sOfficial = Boolean.parseBoolean(manifest.getProperty("KCauldron-Official"));
break;
}
manifest.clear();
@ -100,6 +102,18 @@ public class KCauldron {
return sChannel;
}
private static boolean sLegacy, sOfficial;
public static boolean isLegacy() {
parseManifest();
return sLegacy;
}
public static boolean isOfficial() {
parseManifest();
return sOfficial;
}
public static File sNewServerLocation;
public static String sNewServerVersion;
public static boolean sUpdateInProgress;

View File

@ -6,6 +6,7 @@ import kcauldron.updater.KVersionRetriever.IVersionCheckCallback;
import net.minecraft.server.MinecraftServer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerJoinEvent;
@ -19,13 +20,21 @@ public class DefaultUpdateCallback implements IVersionCheckCallback {
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
if (mHasUpdate && hasPermission(player)) {
if (hasPermission(player)) {
if (KCauldron.isLegacy()) {
player.sendMessage(ChatColor.YELLOW + "We're running on legacy version on KCauldron, please update your version");
}
if (!KCauldron.isOfficial()) {
player.sendMessage(ChatColor.YELLOW + "We're running on non-official version on KCauldron, please update your version");
}
if (mHasUpdate) {
sendUpdate(player);
}
}
}
private boolean hasPermission(CommandSender player) {
return player.hasPermission(KCauldronCommand.UPDATE);
return player.hasPermission(KCauldronCommand.UPDATE) || player.isOp();
}
private void sendUpdate(CommandSender player) {

View File

@ -83,6 +83,7 @@ public class KVersionRetriever implements Runnable, UncaughtExceptionHandler {
.get()
.setUri("https://api.prok.pw/repo/version/" + mGroup + "/"
+ mName)
.addParameter("version", KCauldron.getCurrentVersion())
.addParameter("hostname", sServer.getHostname())
.addParameter("port", "" + sServer.getPort()).build();
HttpResponse response = HttpClientBuilder.create()

View File

@ -1,6 +1,9 @@
package org.bukkit.craftbukkit.map;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.map.MapCanvas;
@ -8,6 +11,8 @@ import org.bukkit.map.MapCursorCollection;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
import net.minecraft.world.storage.MapData;
public class CraftMapRenderer extends MapRenderer {
private final net.minecraft.world.storage.MapData worldMap;
@ -32,14 +37,14 @@ public class CraftMapRenderer extends MapRenderer {
cursors.removeCursor(cursors.getCursor(0));
}
for (Object key : worldMap.playersVisibleOnMap.keySet()) {
for (Map.Entry<UUID, MapData.MapCoord> key : worldMap.playersVisibleOnMap.entrySet()) {
// If this cursor is for a player check visibility with vanish system
Player other = Bukkit.getPlayerExact((String) key);
Player other = Bukkit.getPlayer(key.getKey());
if (other != null && !player.canSee(other)) {
continue;
}
net.minecraft.world.storage.MapData.MapCoord decoration = (net.minecraft.world.storage.MapData.MapCoord) worldMap.playersVisibleOnMap.get(key);
MapData.MapCoord decoration = key.getValue();
cursors.addCursor(decoration.centerX, decoration.centerZ, (byte) (decoration.iconRotation & 15), decoration.iconSize);
}
}

View File

@ -0,0 +1,18 @@
package org.spigotmc;
import gnu.trove.strategy.HashingStrategy;
class CaseInsensitiveHashingStrategy implements HashingStrategy<String> {
private static final long serialVersionUID = -9212222772914758878L;
static final CaseInsensitiveHashingStrategy INSTANCE = new CaseInsensitiveHashingStrategy();
@Override
public int computeHashCode(String object) {
return object.toLowerCase().hashCode();
}
@Override
public boolean equals(String o1, String o2) {
return o1.equalsIgnoreCase(o2);
}
}

View File

@ -0,0 +1,15 @@
package org.spigotmc;
import gnu.trove.map.hash.TCustomHashMap;
import java.util.Map;
public class CaseInsensitiveMap<V> extends TCustomHashMap<String, V> {
public CaseInsensitiveMap() {
super(CaseInsensitiveHashingStrategy.INSTANCE);
}
public CaseInsensitiveMap(Map<? extends String, ? extends V> map) {
super(CaseInsensitiveHashingStrategy.INSTANCE, map);
}
}