mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-12-01 06:33:38 +01:00
Add support for 'use-player-login-ip', 'require-player-login-ip' - map player login IP addresses to web chat addresses
This commit is contained in:
parent
09fbf312ac
commit
e009aefb18
@ -6,11 +6,13 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -86,6 +88,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
private int config_hashcode; /* Used to signal need to reload web configuration (world changes, config update, etc) */
|
private int config_hashcode; /* Used to signal need to reload web configuration (world changes, config update, etc) */
|
||||||
private int fullrenderplayerlimit; /* Number of online players that will cause fullrender processing to pause */
|
private int fullrenderplayerlimit; /* Number of online players that will cause fullrender processing to pause */
|
||||||
private boolean didfullpause;
|
private boolean didfullpause;
|
||||||
|
private Map<String, LinkedList<String>> ids_by_ip = new HashMap<String, LinkedList<String>>();
|
||||||
|
private boolean persist_ids_by_ip = false;
|
||||||
|
|
||||||
public enum CompassMode {
|
public enum CompassMode {
|
||||||
PRE19, /* Default for 1.8 and earlier (east is Z+) */
|
PRE19, /* Default for 1.8 and earlier (east is Z+) */
|
||||||
@ -278,6 +282,10 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
compassmode = CompassMode.PRE19;
|
compassmode = CompassMode.PRE19;
|
||||||
/* Load full render processing player limit */
|
/* Load full render processing player limit */
|
||||||
fullrenderplayerlimit = configuration.getInteger("fullrenderplayerlimit", 0);
|
fullrenderplayerlimit = configuration.getInteger("fullrenderplayerlimit", 0);
|
||||||
|
/* If we're persisting ids-by-ip, load it */
|
||||||
|
persist_ids_by_ip = configuration.getBoolean("persist-ids-by-ip", true);
|
||||||
|
if(persist_ids_by_ip)
|
||||||
|
loadIDsByIP();
|
||||||
|
|
||||||
loadDebuggers();
|
loadDebuggers();
|
||||||
|
|
||||||
@ -290,6 +298,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
playerList.load();
|
playerList.load();
|
||||||
PlayerListener pl = new PlayerListener() {
|
PlayerListener pl = new PlayerListener() {
|
||||||
public void onPlayerJoin(PlayerJoinEvent evt) {
|
public void onPlayerJoin(PlayerJoinEvent evt) {
|
||||||
|
Player p = evt.getPlayer();
|
||||||
playerList.updateOnlinePlayers(null);
|
playerList.updateOnlinePlayers(null);
|
||||||
if(fullrenderplayerlimit > 0) {
|
if(fullrenderplayerlimit > 0) {
|
||||||
if((getServer().getOnlinePlayers().length+1) >= fullrenderplayerlimit) {
|
if((getServer().getOnlinePlayers().length+1) >= fullrenderplayerlimit) {
|
||||||
@ -300,6 +309,23 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Add player info to IP-to-ID table */
|
||||||
|
InetSocketAddress addr = p.getAddress();
|
||||||
|
if(addr != null) {
|
||||||
|
String ip = addr.getAddress().getHostAddress();
|
||||||
|
LinkedList<String> ids = ids_by_ip.get(ip);
|
||||||
|
if(ids == null) {
|
||||||
|
ids = new LinkedList<String>();
|
||||||
|
ids_by_ip.put(ip, ids);
|
||||||
|
}
|
||||||
|
String pid = p.getName();
|
||||||
|
/* See if not first in list */
|
||||||
|
int idx = ids.indexOf(pid);
|
||||||
|
if(idx > 0) {
|
||||||
|
ids.remove(idx);
|
||||||
|
}
|
||||||
|
ids.addFirst(pid); /* Put us first on list */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public void onPlayerQuit(PlayerQuitEvent evt) {
|
public void onPlayerQuit(PlayerQuitEvent evt) {
|
||||||
playerList.updateOnlinePlayers(evt.getPlayer());
|
playerList.updateOnlinePlayers(evt.getPlayer());
|
||||||
@ -412,6 +438,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
|
if(persist_ids_by_ip)
|
||||||
|
saveIDsByIP();
|
||||||
if (componentManager != null) {
|
if (componentManager != null) {
|
||||||
int componentCount = componentManager.components.size();
|
int componentCount = componentManager.components.size();
|
||||||
for(Component component : componentManager.components) {
|
for(Component component : componentManager.components) {
|
||||||
@ -767,7 +795,9 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
"resetstats",
|
"resetstats",
|
||||||
"sendtoweb",
|
"sendtoweb",
|
||||||
"pause",
|
"pause",
|
||||||
"purgequeue" }));
|
"purgequeue",
|
||||||
|
"ids-for-ip",
|
||||||
|
"ips-for-id" }));
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
|
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
|
||||||
@ -954,6 +984,31 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
msg += args[i] + " ";
|
msg += args[i] + " ";
|
||||||
}
|
}
|
||||||
this.sendBroadcastToWeb("dynmap", msg);
|
this.sendBroadcastToWeb("dynmap", msg);
|
||||||
|
} else if(c.equals("ids-for-ip") && checkPlayerPermission(sender, "ids-for-ip")) {
|
||||||
|
if(args.length > 1) {
|
||||||
|
List<String> ids = getIDsForIP(args[1]);
|
||||||
|
sender.sendMessage("IDs logged in from address " + args[1] + " (most recent to least):");
|
||||||
|
if(ids != null) {
|
||||||
|
for(String id : ids)
|
||||||
|
sender.sendMessage(" " + id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sender.sendMessage("IP address required as parameter");
|
||||||
|
}
|
||||||
|
} else if(c.equals("ips-for-id") && checkPlayerPermission(sender, "ips-for-id")) {
|
||||||
|
if(args.length > 1) {
|
||||||
|
sender.sendMessage("IP addresses logged for player " + args[1] + ":");
|
||||||
|
for(String ip: ids_by_ip.keySet()) {
|
||||||
|
LinkedList<String> ids = ids_by_ip.get(ip);
|
||||||
|
if((ids != null) && ids.contains(args[1])) {
|
||||||
|
sender.sendMessage(" " + ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sender.sendMessage("Player ID required as parameter");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1536,4 +1591,56 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
mapManager.pushUpdate(new Client.PlayerQuitMessage(player.getDisplayName(), player.getName()));
|
mapManager.pushUpdate(new Client.PlayerQuitMessage(player.getDisplayName(), player.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Get list of IDs seen on give IP (most recent to least recent)
|
||||||
|
*/
|
||||||
|
public List<String> getIDsForIP(InetAddress addr) {
|
||||||
|
return getIDsForIP(addr.getHostAddress());
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get list of IDs seen on give IP (most recent to least recent)
|
||||||
|
*/
|
||||||
|
public List<String> getIDsForIP(String ip) {
|
||||||
|
LinkedList<String> ids = ids_by_ip.get(ip);
|
||||||
|
if(ids != null)
|
||||||
|
return new ArrayList<String>(ids);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadIDsByIP() {
|
||||||
|
File f = new File(getDataFolder(), "ids-by-ip.txt");
|
||||||
|
if(f.exists() == false)
|
||||||
|
return;
|
||||||
|
YamlConfiguration fc = new YamlConfiguration();
|
||||||
|
try {
|
||||||
|
fc.load(new File(getDataFolder(), "ids-by-ip.txt"));
|
||||||
|
ids_by_ip.clear();
|
||||||
|
Map<String,Object> v = fc.getValues(false);
|
||||||
|
for(String k : v.keySet()) {
|
||||||
|
List<String> ids = fc.getStringList(k);
|
||||||
|
if(ids != null) {
|
||||||
|
k = k.replace("_", ".");
|
||||||
|
ids_by_ip.put(k, new LinkedList<String>(ids));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception iox) {
|
||||||
|
Log.severe("Error loading " + f.getPath() + " - " + iox.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void saveIDsByIP() {
|
||||||
|
File f = new File(getDataFolder(), "ids-by-ip.txt");
|
||||||
|
YamlConfiguration fc = new YamlConfiguration();
|
||||||
|
for(String k : ids_by_ip.keySet()) {
|
||||||
|
List<String> v = ids_by_ip.get(k);
|
||||||
|
if(v != null) {
|
||||||
|
k = k.replace(".", "_");
|
||||||
|
fc.set(k, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
fc.save(f);
|
||||||
|
} catch (Exception x) {
|
||||||
|
Log.severe("Error saving " + f.getPath() + " - " + x.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,13 @@ import static org.dynmap.JSONUtils.*;
|
|||||||
|
|
||||||
public class InternalClientUpdateComponent extends ClientUpdateComponent {
|
public class InternalClientUpdateComponent extends ClientUpdateComponent {
|
||||||
|
|
||||||
public InternalClientUpdateComponent(DynmapPlugin plugin, final ConfigurationNode configuration) {
|
public InternalClientUpdateComponent(final DynmapPlugin plugin, final ConfigurationNode configuration) {
|
||||||
super(plugin, configuration);
|
super(plugin, configuration);
|
||||||
final Boolean allowwebchat = configuration.getBoolean("allowwebchat", false);
|
final boolean allowwebchat = configuration.getBoolean("allowwebchat", false);
|
||||||
final Boolean hidewebchatip = configuration.getBoolean("hidewebchatip", false);
|
final boolean hidewebchatip = configuration.getBoolean("hidewebchatip", false);
|
||||||
final Boolean trust_client_name = configuration.getBoolean("trustclientname", false);
|
final boolean trust_client_name = configuration.getBoolean("trustclientname", false);
|
||||||
|
final boolean useplayerloginip = configuration.getBoolean("use-player-login-ip", true);
|
||||||
|
final boolean requireplayerloginip = configuration.getBoolean("require-player-login-ip", false);
|
||||||
final float webchatInterval = configuration.getFloat("webchat-interval", 1);
|
final float webchatInterval = configuration.getFloat("webchat-interval", 1);
|
||||||
final String spammessage = plugin.configuration.getString("spammessage", "You may only chat once every %interval% seconds.");
|
final String spammessage = plugin.configuration.getString("spammessage", "You may only chat once every %interval% seconds.");
|
||||||
|
|
||||||
@ -31,7 +33,10 @@ public class InternalClientUpdateComponent extends ClientUpdateComponent {
|
|||||||
maximumMessageInterval = (int)(webchatInterval * 1000);
|
maximumMessageInterval = (int)(webchatInterval * 1000);
|
||||||
spamMessage = "\""+spammessage+"\"";
|
spamMessage = "\""+spammessage+"\"";
|
||||||
hideip = hidewebchatip;
|
hideip = hidewebchatip;
|
||||||
|
this.plug_in = plugin;
|
||||||
this.trustclientname = trust_client_name;
|
this.trustclientname = trust_client_name;
|
||||||
|
this.use_player_login_ip = useplayerloginip;
|
||||||
|
this.require_player_login_ip = requireplayerloginip;
|
||||||
onMessageReceived.addListener(new Listener<SendMessageHandler.Message>() {
|
onMessageReceived.addListener(new Listener<SendMessageHandler.Message>() {
|
||||||
@Override
|
@Override
|
||||||
public void triggered(Message t) {
|
public void triggered(Message t) {
|
||||||
|
@ -9,6 +9,7 @@ import java.io.Reader;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
@ -26,7 +27,10 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
|
|||||||
protected long currentTimestamp = 0;
|
protected long currentTimestamp = 0;
|
||||||
protected long lastTimestamp = 0;
|
protected long lastTimestamp = 0;
|
||||||
protected JSONParser parser = new JSONParser();
|
protected JSONParser parser = new JSONParser();
|
||||||
private Boolean hidewebchatip;
|
private boolean hidewebchatip;
|
||||||
|
private boolean useplayerloginip;
|
||||||
|
private boolean requireplayerloginip;
|
||||||
|
private boolean trust_client_name;
|
||||||
|
|
||||||
private HashMap<String,String> useralias = new HashMap<String,String>();
|
private HashMap<String,String> useralias = new HashMap<String,String>();
|
||||||
private int aliasindex = 1;
|
private int aliasindex = 1;
|
||||||
@ -38,6 +42,10 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
|
|||||||
final boolean allowwebchat = configuration.getBoolean("allowwebchat", false);
|
final boolean allowwebchat = configuration.getBoolean("allowwebchat", false);
|
||||||
jsonInterval = (long)(configuration.getFloat("writeinterval", 1) * 1000);
|
jsonInterval = (long)(configuration.getFloat("writeinterval", 1) * 1000);
|
||||||
hidewebchatip = configuration.getBoolean("hidewebchatip", false);
|
hidewebchatip = configuration.getBoolean("hidewebchatip", false);
|
||||||
|
useplayerloginip = configuration.getBoolean("use-player-login-ip", true);
|
||||||
|
requireplayerloginip = configuration.getBoolean("require-player-login-ip", false);
|
||||||
|
trust_client_name = configuration.getBoolean("trustclientname", false);
|
||||||
|
|
||||||
MapManager.scheduleDelayedJob(new Runnable() {
|
MapManager.scheduleDelayedJob(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -211,7 +219,24 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
|
|||||||
if(ts.equals("null")) ts = "0";
|
if(ts.equals("null")) ts = "0";
|
||||||
if (Long.parseLong(ts) >= (lastTimestamp)) {
|
if (Long.parseLong(ts) >= (lastTimestamp)) {
|
||||||
String name = String.valueOf(o.get("name"));
|
String name = String.valueOf(o.get("name"));
|
||||||
if(hidewebchatip) {
|
String ip = String.valueOf(o.get("ip"));
|
||||||
|
boolean isip = true;
|
||||||
|
if((!trust_client_name) || (name == null) || (name.equals(""))) {
|
||||||
|
if(ip != null)
|
||||||
|
name = ip;
|
||||||
|
}
|
||||||
|
if(useplayerloginip) { /* Try to match using IPs of player logins */
|
||||||
|
List<String> ids = plugin.getIDsForIP(name);
|
||||||
|
if(ids != null) {
|
||||||
|
name = ids.get(0);
|
||||||
|
isip = false;
|
||||||
|
}
|
||||||
|
else if(requireplayerloginip) {
|
||||||
|
Log.info("Ignore message from '" + name + "' - no matching player login recorded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hidewebchatip && isip) {
|
||||||
String n = useralias.get(name);
|
String n = useralias.get(name);
|
||||||
if(n == null) { /* Make ID */
|
if(n == null) { /* Make ID */
|
||||||
n = String.format("web-%03d", aliasindex);
|
n = String.format("web-%03d", aliasindex);
|
||||||
|
@ -4,9 +4,12 @@ import java.io.InputStreamReader;
|
|||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.dynmap.DynmapPlugin;
|
||||||
import org.dynmap.Event;
|
import org.dynmap.Event;
|
||||||
|
import org.dynmap.Log;
|
||||||
import org.dynmap.web.HttpField;
|
import org.dynmap.web.HttpField;
|
||||||
import org.dynmap.web.HttpHandler;
|
import org.dynmap.web.HttpHandler;
|
||||||
import org.dynmap.web.HttpMethod;
|
import org.dynmap.web.HttpMethod;
|
||||||
@ -25,6 +28,9 @@ public class SendMessageHandler implements HttpHandler {
|
|||||||
public int maximumMessageInterval = 1000;
|
public int maximumMessageInterval = 1000;
|
||||||
public boolean hideip = false;
|
public boolean hideip = false;
|
||||||
public boolean trustclientname = false;
|
public boolean trustclientname = false;
|
||||||
|
public boolean use_player_login_ip = false;
|
||||||
|
public boolean require_player_login_ip = false;
|
||||||
|
public DynmapPlugin plug_in;
|
||||||
public String spamMessage = "\"You may only chat once every %interval% seconds.\"";
|
public String spamMessage = "\"You may only chat once every %interval% seconds.\"";
|
||||||
private HashMap<String, WebUser> disallowedUsers = new HashMap<String, WebUser>();
|
private HashMap<String, WebUser> disallowedUsers = new HashMap<String, WebUser>();
|
||||||
private LinkedList<WebUser> disallowedUserQueue = new LinkedList<WebUser>();
|
private LinkedList<WebUser> disallowedUserQueue = new LinkedList<WebUser>();
|
||||||
@ -45,10 +51,12 @@ public class SendMessageHandler implements HttpHandler {
|
|||||||
JSONObject o = (JSONObject)parser.parse(reader);
|
JSONObject o = (JSONObject)parser.parse(reader);
|
||||||
final Message message = new Message();
|
final Message message = new Message();
|
||||||
|
|
||||||
|
message.name = "";
|
||||||
if(trustclientname) {
|
if(trustclientname) {
|
||||||
message.name = String.valueOf(o.get("name"));
|
message.name = String.valueOf(o.get("name"));
|
||||||
}
|
}
|
||||||
else {
|
boolean isip = true;
|
||||||
|
if((message.name == null) || message.name.equals("")) {
|
||||||
/* If proxied client address, get original */
|
/* If proxied client address, get original */
|
||||||
if(request.fields.containsKey("X-Forwarded-For"))
|
if(request.fields.containsKey("X-Forwarded-For"))
|
||||||
message.name = request.fields.get("X-Forwarded-For");
|
message.name = request.fields.get("X-Forwarded-For");
|
||||||
@ -58,7 +66,18 @@ public class SendMessageHandler implements HttpHandler {
|
|||||||
else
|
else
|
||||||
message.name = request.rmtaddr.getAddress().getHostAddress();
|
message.name = request.rmtaddr.getAddress().getHostAddress();
|
||||||
}
|
}
|
||||||
if(hideip) { /* If hiding IP, find or assign alias */
|
if(use_player_login_ip) {
|
||||||
|
List<String> ids = plug_in.getIDsForIP(message.name);
|
||||||
|
if(ids != null) {
|
||||||
|
message.name = ids.get(0);
|
||||||
|
isip = false;
|
||||||
|
}
|
||||||
|
else if(require_player_login_ip) {
|
||||||
|
Log.info("Ignore message from '" + message.name + "' - no matching player login recorded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hideip && isip) { /* If hiding IP, find or assign alias */
|
||||||
synchronized(disallowedUsersLock) {
|
synchronized(disallowedUsersLock) {
|
||||||
String n = useralias.get(message.name);
|
String n = useralias.get(message.name);
|
||||||
if(n == null) { /* Make ID */
|
if(n == null) { /* Make ID */
|
||||||
|
@ -27,6 +27,10 @@ components:
|
|||||||
hidewebchatip: false
|
hidewebchatip: false
|
||||||
trustclientname: false
|
trustclientname: false
|
||||||
includehiddenplayers: false
|
includehiddenplayers: false
|
||||||
|
# (optional) if true, player login IDs will be used for web chat when their IPs match
|
||||||
|
use-player-login-ip: true
|
||||||
|
# (optional) if use-player-login-ip is true, setting this to true will cause chat messages not matching a known player IP to be ignored
|
||||||
|
require-player-login-ip: false
|
||||||
# # Optional - make players hidden when they are inside/underground/in shadows (#=light level: 0=full shadow,15=sky)
|
# # Optional - make players hidden when they are inside/underground/in shadows (#=light level: 0=full shadow,15=sky)
|
||||||
# hideifshadow: 4
|
# hideifshadow: 4
|
||||||
# # Optional - make player hidden when they are under cover (#=sky light level,0=underground,15=open to sky)
|
# # Optional - make player hidden when they are under cover (#=sky light level,0=underground,15=open to sky)
|
||||||
@ -39,8 +43,10 @@ components:
|
|||||||
# webchat-interval: 5
|
# webchat-interval: 5
|
||||||
# hidewebchatip: false
|
# hidewebchatip: false
|
||||||
# includehiddenplayers: false
|
# includehiddenplayers: false
|
||||||
# hideifshadow: 4
|
# use-player-login-ip: false
|
||||||
# hideifundercover: 14
|
# require-player-login-ip: false
|
||||||
|
# hideifshadow: 0
|
||||||
|
# hideifundercover: 0
|
||||||
|
|
||||||
- class: org.dynmap.SimpleWebChatComponent
|
- class: org.dynmap.SimpleWebChatComponent
|
||||||
allowchat: true
|
allowchat: true
|
||||||
@ -270,6 +276,9 @@ defaultmap: flat
|
|||||||
# Option to enable workaround for incorrectly encoded unicode in Cyrillic MC/Bukkit (not good for other code pages)
|
# Option to enable workaround for incorrectly encoded unicode in Cyrillic MC/Bukkit (not good for other code pages)
|
||||||
cyrillic-support: false
|
cyrillic-support: false
|
||||||
|
|
||||||
|
# If true, make persistent record of IP addresses used by player logins, to support web IP to player matching
|
||||||
|
persist-ids-by-ip: true
|
||||||
|
|
||||||
# NOTE: the 'templates' section is now found in the 'templates' directory
|
# NOTE: the 'templates' section is now found in the 'templates' directory
|
||||||
# Templates CAN still be defined in configuration.txt, as before 0.20
|
# Templates CAN still be defined in configuration.txt, as before 0.20
|
||||||
templates:
|
templates:
|
||||||
|
@ -30,6 +30,7 @@ commands:
|
|||||||
/<command> purgequeue - Set tile update queue to empty
|
/<command> purgequeue - Set tile update queue to empty
|
||||||
/<command> pause - Show render pause state
|
/<command> pause - Show render pause state
|
||||||
/<command> pause <all|none|full|update> - Set render pause state
|
/<command> pause <all|none|full|update> - Set render pause state
|
||||||
|
/<command> ids-for-ip <ipaddress> - Show player IDs that have logged in from given IP address
|
||||||
|
|
||||||
dmarker:
|
dmarker:
|
||||||
description: Manipulate map markers
|
description: Manipulate map markers
|
||||||
@ -83,6 +84,8 @@ permissions:
|
|||||||
dynmap.resetstats: true
|
dynmap.resetstats: true
|
||||||
dynmap.sendtoweb: true
|
dynmap.sendtoweb: true
|
||||||
dynmap.purgequeue: true
|
dynmap.purgequeue: true
|
||||||
|
dynmap.ids-for-ip: true
|
||||||
|
dynmap.ips-for-id: true
|
||||||
dynmap.pause: true
|
dynmap.pause: true
|
||||||
dynmap.marker.add: true
|
dynmap.marker.add: true
|
||||||
dynmap.marker.update: true
|
dynmap.marker.update: true
|
||||||
@ -144,6 +147,12 @@ permissions:
|
|||||||
dynmap.pause:
|
dynmap.pause:
|
||||||
description: Allows /dynmap pause
|
description: Allows /dynmap pause
|
||||||
default: op
|
default: op
|
||||||
|
dynmap.ids-for-ip:
|
||||||
|
description: Allows /dynmap ids-for-ip
|
||||||
|
default: op
|
||||||
|
dynmap.ips-for-id:
|
||||||
|
description: Allows /dynmap ips-for-id
|
||||||
|
default: op
|
||||||
dynmap.marker.add:
|
dynmap.marker.add:
|
||||||
description: Allows /dmarker add
|
description: Allows /dmarker add
|
||||||
default: op
|
default: op
|
||||||
|
@ -11,6 +11,7 @@ if($_SERVER['REQUEST_METHOD'] == 'POST' && $_SESSION['lastchat'] < time())
|
|||||||
|
|
||||||
$data = json_decode(trim(file_get_contents('php://input')));
|
$data = json_decode(trim(file_get_contents('php://input')));
|
||||||
$data->timestamp = $timestamp;
|
$data->timestamp = $timestamp;
|
||||||
|
$data->ip = $_SERVER['REMOTE_ADDR'];
|
||||||
$old_messages = json_decode(file_get_contents('dynmap_webchat.json'), true);
|
$old_messages = json_decode(file_get_contents('dynmap_webchat.json'), true);
|
||||||
if(!empty($old_messages))
|
if(!empty($old_messages))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user