Make the forceOnePlayerNameCase much quicker and isolate it in an Engine class.
This commit is contained in:
parent
7f7f5db99d
commit
1b8ae6cf5f
131
src/com/massivecraft/mcore/EngineOfflineCase.java
Normal file
131
src/com/massivecraft/mcore/EngineOfflineCase.java
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
package com.massivecraft.mcore;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerLoginEvent;
|
||||||
|
import org.bukkit.event.player.PlayerLoginEvent.Result;
|
||||||
|
|
||||||
|
import com.massivecraft.mcore.util.MUtil;
|
||||||
|
import com.massivecraft.mcore.util.Txt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In minecraft a player name is case insensitive but has one and only one correct casing when written out.
|
||||||
|
* The correct casing is decided upon buying minecraft.
|
||||||
|
* If you register "Steve" noone else can register "stEvE".
|
||||||
|
*
|
||||||
|
* If you then try to log in using "STEVE" in the minecraft launcher the name will be corrected to "Steve".
|
||||||
|
* This feature does however only work in online mode.
|
||||||
|
*
|
||||||
|
* If you use a cracked client and an offline mode server you may log on to the server using both "Steve" and "STEVE".
|
||||||
|
* This cause unintended side effects. Some file systems (windows) are case insensitive and some (unix) are case sensitive.
|
||||||
|
* On Unix "Steve" and "STEVE" would have different inventories, locations etc. They would be considered different players.
|
||||||
|
* That would be confusing for the players.
|
||||||
|
* They would seem to lose their inventory when mistyping their name and this would only happen on some servers (those using unix).
|
||||||
|
*
|
||||||
|
* Additionally plugins may start acting weird if this rule is broken.
|
||||||
|
*
|
||||||
|
* The purpose of this "engine" is to enforce the use of the one and same casing for offline mode servers.
|
||||||
|
* You "register" the correct casing at the first login.
|
||||||
|
* After that you get kicked when using an incorrect casing.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class EngineOfflineCase implements Listener
|
||||||
|
{
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static EngineOfflineCase i = new EngineOfflineCase();
|
||||||
|
public static EngineOfflineCase get() { return i; }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// SETUP
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public void setup()
|
||||||
|
{
|
||||||
|
this.lowerToCorrect.clear();
|
||||||
|
|
||||||
|
for (Player player : Bukkit.getOnlinePlayers())
|
||||||
|
{
|
||||||
|
this.registerCase(player.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String pdname : MUtil.getPlayerDirectoryNames())
|
||||||
|
{
|
||||||
|
this.registerCase(pdname);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, MCore.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private Map<String, String> lowerToCorrect = new HashMap<String, String>();
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// UTIL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private void registerCase(String playerName)
|
||||||
|
{
|
||||||
|
this.lowerToCorrect.put(playerName.toLowerCase(), playerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// LISTENER
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
public void forceOnePlayerNameCase(PlayerLoginEvent event)
|
||||||
|
{
|
||||||
|
// Stop if the feature is disabled
|
||||||
|
if (!ConfServer.forceOnePlayerNameCase) return;
|
||||||
|
|
||||||
|
// Stop if we are using online mode
|
||||||
|
if (Bukkit.getOnlineMode()) return;
|
||||||
|
|
||||||
|
// Prepare some variables
|
||||||
|
final Player player = event.getPlayer();
|
||||||
|
final String playerName = player.getName();
|
||||||
|
final String playerNameLower = playerName.toLowerCase();
|
||||||
|
|
||||||
|
// Kick if the player already is online
|
||||||
|
// NOTE: Bukkit.getPlayerExact is case insensitive as it should be
|
||||||
|
final Player onlinePlayer = Bukkit.getPlayerExact(playerName);
|
||||||
|
if (onlinePlayer != null)
|
||||||
|
{
|
||||||
|
event.setResult(Result.KICK_OTHER);
|
||||||
|
event.setKickMessage(Txt.parse("<b>The player <h>%s <b>is already online.", onlinePlayer.getName()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consider dat case!
|
||||||
|
String correct = this.lowerToCorrect.get(playerNameLower);
|
||||||
|
if (correct == null)
|
||||||
|
{
|
||||||
|
// "Register"
|
||||||
|
this.registerCase(playerName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Kick if the case is wrong
|
||||||
|
if (!correct.equals(playerName))
|
||||||
|
{
|
||||||
|
event.setResult(Result.KICK_OTHER);
|
||||||
|
event.setKickMessage(Txt.parse("<b>Invalid uppercase and lowercase letters in name.\n<i>Please spell this name like \"<h>%s<i>\".", correct));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,14 +12,14 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.event.world.WorldLoadEvent;
|
import org.bukkit.event.world.WorldLoadEvent;
|
||||||
import org.bukkit.event.world.WorldUnloadEvent;
|
import org.bukkit.event.world.WorldUnloadEvent;
|
||||||
|
|
||||||
public class WorldNameSetEngine implements Listener
|
public class EngineWorldNameSet implements Listener
|
||||||
{
|
{
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// INSTANCE & CONSTRUCT
|
// INSTANCE & CONSTRUCT
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
private static WorldNameSetEngine i = new WorldNameSetEngine();
|
private static EngineWorldNameSet i = new EngineWorldNameSet();
|
||||||
public static WorldNameSetEngine get() { return i; }
|
public static EngineWorldNameSet get() { return i; }
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// SETUP
|
// SETUP
|
@ -31,10 +31,8 @@ import com.massivecraft.mcore.event.MCoreSenderUnregisterEvent;
|
|||||||
import com.massivecraft.mcore.mixin.Mixin;
|
import com.massivecraft.mcore.mixin.Mixin;
|
||||||
import com.massivecraft.mcore.store.Coll;
|
import com.massivecraft.mcore.store.Coll;
|
||||||
import com.massivecraft.mcore.store.SenderColl;
|
import com.massivecraft.mcore.store.SenderColl;
|
||||||
import com.massivecraft.mcore.util.MUtil;
|
|
||||||
import com.massivecraft.mcore.util.SenderUtil;
|
import com.massivecraft.mcore.util.SenderUtil;
|
||||||
import com.massivecraft.mcore.util.SmokeUtil;
|
import com.massivecraft.mcore.util.SmokeUtil;
|
||||||
import com.massivecraft.mcore.util.Txt;
|
|
||||||
import com.massivecraft.mcore.wrap.PlayerConnectionWrapMCore;
|
import com.massivecraft.mcore.wrap.PlayerConnectionWrapMCore;
|
||||||
|
|
||||||
public class InternalListener implements Listener
|
public class InternalListener implements Listener
|
||||||
@ -56,44 +54,6 @@ public class InternalListener implements Listener
|
|||||||
Bukkit.getPluginManager().registerEvents(this, MCore.get());
|
Bukkit.getPluginManager().registerEvents(this, MCore.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// FORCE ONE PLAYER NAME CASE
|
|
||||||
// -------------------------------------------- //
|
|
||||||
// This is used with offline servers to prevent bugs on case sensitive file systems.
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
|
||||||
public void forceOnePlayerNameCase(PlayerLoginEvent event)
|
|
||||||
{
|
|
||||||
// If we are enforcing one player name case ...
|
|
||||||
if (!ConfServer.forceOnePlayerNameCase) return;
|
|
||||||
|
|
||||||
// ... and the server is running in offline mode ...
|
|
||||||
if (Bukkit.getOnlineMode()) return;
|
|
||||||
|
|
||||||
// ... prepare vars ...
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
String playerName = player.getName();
|
|
||||||
|
|
||||||
// ... is the player already online? ...
|
|
||||||
for (Player onlinePlayer: Bukkit.getOnlinePlayers())
|
|
||||||
{
|
|
||||||
if (!playerName.equalsIgnoreCase(onlinePlayer.getName())) continue;
|
|
||||||
event.setResult(Result.KICK_OTHER);
|
|
||||||
event.setKickMessage(Txt.parse("<b>The player <h>%s <b>is already online.", onlinePlayer.getName()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... is the first found file name different?
|
|
||||||
for (String pdname : MUtil.getPlayerDirectoryNames())
|
|
||||||
{
|
|
||||||
if (!playerName.equalsIgnoreCase(pdname)) continue;
|
|
||||||
if (playerName.equals(pdname)) break;
|
|
||||||
event.setResult(Result.KICK_OTHER);
|
|
||||||
event.setKickMessage(Txt.parse("<b>Invalid uppercase and lowercase letters in name.\n<i>Please spell this name like \"<h>%s<i>\".", pdname));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// PLAYER CONNECTION WRAP INJECTION
|
// PLAYER CONNECTION WRAP INJECTION
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
@ -142,7 +142,8 @@ public class MCore extends MPlugin
|
|||||||
InternalListener.get().setup();
|
InternalListener.get().setup();
|
||||||
ScheduledTeleportEngine.get().setup();
|
ScheduledTeleportEngine.get().setup();
|
||||||
TeleportMixinCauseEngine.get().setup();
|
TeleportMixinCauseEngine.get().setup();
|
||||||
WorldNameSetEngine.get().setup();
|
EngineWorldNameSet.get().setup();
|
||||||
|
EngineOfflineCase.get().setup();
|
||||||
|
|
||||||
// Schedule the collection ticker.
|
// Schedule the collection ticker.
|
||||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, this.collTickTask, 1, 1);
|
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, this.collTickTask, 1, 1);
|
||||||
|
@ -47,7 +47,7 @@ import org.bukkit.potion.PotionEffectType;
|
|||||||
|
|
||||||
import com.massivecraft.mcore.InternalListener;
|
import com.massivecraft.mcore.InternalListener;
|
||||||
import com.massivecraft.mcore.MCore;
|
import com.massivecraft.mcore.MCore;
|
||||||
import com.massivecraft.mcore.WorldNameSetEngine;
|
import com.massivecraft.mcore.EngineWorldNameSet;
|
||||||
import com.massivecraft.mcore.util.extractor.Extractor;
|
import com.massivecraft.mcore.util.extractor.Extractor;
|
||||||
import com.massivecraft.mcore.util.extractor.ExtractorMoneyUniverse;
|
import com.massivecraft.mcore.util.extractor.ExtractorMoneyUniverse;
|
||||||
import com.massivecraft.mcore.util.extractor.ExtractorPlayer;
|
import com.massivecraft.mcore.util.extractor.ExtractorPlayer;
|
||||||
@ -394,7 +394,7 @@ public class MUtil
|
|||||||
|
|
||||||
public static Set<String> getLoadedWorldNames()
|
public static Set<String> getLoadedWorldNames()
|
||||||
{
|
{
|
||||||
return WorldNameSetEngine.get().getWorldNames();
|
return EngineWorldNameSet.get().getWorldNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
Loading…
Reference in New Issue
Block a user