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.WorldUnloadEvent;
|
||||
|
||||
public class WorldNameSetEngine implements Listener
|
||||
public class EngineWorldNameSet implements Listener
|
||||
{
|
||||
// -------------------------------------------- //
|
||||
// INSTANCE & CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
private static WorldNameSetEngine i = new WorldNameSetEngine();
|
||||
public static WorldNameSetEngine get() { return i; }
|
||||
private static EngineWorldNameSet i = new EngineWorldNameSet();
|
||||
public static EngineWorldNameSet get() { return i; }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// SETUP
|
@ -31,10 +31,8 @@ import com.massivecraft.mcore.event.MCoreSenderUnregisterEvent;
|
||||
import com.massivecraft.mcore.mixin.Mixin;
|
||||
import com.massivecraft.mcore.store.Coll;
|
||||
import com.massivecraft.mcore.store.SenderColl;
|
||||
import com.massivecraft.mcore.util.MUtil;
|
||||
import com.massivecraft.mcore.util.SenderUtil;
|
||||
import com.massivecraft.mcore.util.SmokeUtil;
|
||||
import com.massivecraft.mcore.util.Txt;
|
||||
import com.massivecraft.mcore.wrap.PlayerConnectionWrapMCore;
|
||||
|
||||
public class InternalListener implements Listener
|
||||
@ -56,44 +54,6 @@ public class InternalListener implements Listener
|
||||
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
|
||||
// -------------------------------------------- //
|
||||
|
@ -142,7 +142,8 @@ public class MCore extends MPlugin
|
||||
InternalListener.get().setup();
|
||||
ScheduledTeleportEngine.get().setup();
|
||||
TeleportMixinCauseEngine.get().setup();
|
||||
WorldNameSetEngine.get().setup();
|
||||
EngineWorldNameSet.get().setup();
|
||||
EngineOfflineCase.get().setup();
|
||||
|
||||
// Schedule the collection ticker.
|
||||
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.MCore;
|
||||
import com.massivecraft.mcore.WorldNameSetEngine;
|
||||
import com.massivecraft.mcore.EngineWorldNameSet;
|
||||
import com.massivecraft.mcore.util.extractor.Extractor;
|
||||
import com.massivecraft.mcore.util.extractor.ExtractorMoneyUniverse;
|
||||
import com.massivecraft.mcore.util.extractor.ExtractorPlayer;
|
||||
@ -394,7 +394,7 @@ public class MUtil
|
||||
|
||||
public static Set<String> getLoadedWorldNames()
|
||||
{
|
||||
return WorldNameSetEngine.get().getWorldNames();
|
||||
return EngineWorldNameSet.get().getWorldNames();
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
|
Loading…
Reference in New Issue
Block a user