Welcome to SyncServers
This page applies to MaxBans v1.3+ only. It is an advanced feature, and only applies if you want to ban players using a webpage, or have more than one server and want to sync their bans. Most server owners will never need this feature.
What is Ban Syncing?
It is broadcasting messages from server to server, like a request to ban someone or unmute someone else. Because of how the MaxBans database works, editing the database while the server is running will likely cause errors at best unless the server is off. This is because the database is cached in memory for fast access. This means, that if I connect two servers up to the same database, I'll run into trouble!
What is a SyncServer?
A "SyncServer" as I've dubbed it in the code, is a central server chosen to coordinate any bans/unbans for server owners with more than one server. It is *NOT* like MCBans, as MCBans is a public network of bans that only works with premium servers.
The SyncServer runs in the plugin background (Only if sync is enabled, and the server is configured to do so) while Bukkit is running (You can also run it standalone, without Bukkit). Now, one or more Syncers can connect to the server.
What is a Syncer?
A "Syncer" as I've dubbed, again, is the counterpart of a SyncServer. There can only be one SyncServer in a group, but there can be many Syncers. When a player is banned by a command, the Syncer notifies the SyncServer of it, which then tells every other Syncer "Hey, ban this guy because Syncer#1 said so." A similar thing happens for all mutes, unmutes, unbans, ipbans, tempbans, warns and IP tracking.
How does it work?
It uses java network sockets to send and receive data.
Can it be hacked?
Possibly. I wrote 2400 lines of code in the last 48 hours with about three major rewrites. I have tested it, and I can't hack it nomatter how I try it.
I'm going to try and break this down as much as I can.
- sync.use This config option enables/disables Syncing totally. If this is false, Syncing will not occur, at all.
- sync.server If this option is true, then this server is the SyncServer. If it is false, then it is a regular Syncer.
- sync.host This defines the IP of the host. If Sync.Server is true, then this should be 127.0.0.1, or localhost. Otherwise, this is the IP of the SyncServer (the server with sync.server: true in its config)
- sync.port The port for the syncer to connect using, or the SyncServer to be hosted on, if running in server mode. This is *NOT* your servers port address! (Eg, it is NOT 25565!)
- sync.pass The password required to connect to the SyncServer.
First, you must have a SyncServer. There will be a standalone version of this (= No bukkit required), but the simple version is you must have ONE and ONLY ONE running in server mode (=sync.server: true).
The rest of the servers must have sync.server: false, and the correct details.
If the database is the same for two or more servers, all servers must have database.read-only:true except for one, in the config. This is because only one server should write changes to the database, while the rest should only ever read data when starting up. If two servers are running off of one database, all of them except one must have read-only: true in their configs!
Banning players from a website
Using this, you can ban a player from a website, or infact, any coding language with access to sockets and the like. A typical request goes like this:
(Client makes connection request to server through a regular socket) [Client => Server] @connect -pass MY_ENCRYPTED_PASSWORD //Sends passwd [Server => Client] @connect //Receiving @connect from the server means success! [Client => Server] @ban -name NewGuy -reason Potty mouth -banner MrGrumpyGills -broadcast [Server => OTHER_CLIENTS] @ban -name NewGuy -reason Potty mouth -banner MrGrumpyGills [Client => Server] @disconnect -reason Plugin is being disabled (Client drops connection, server drops connection)
This can be replicated using a PHP script with some know how (I haven't done it before, but I know it can be done).
CHANGED IN V2.0! Technical Info:
- Data is written with the CharSet "ISO-8859-1", so in java, data is read like String s = new String(dataRead, "ISO-8859-1");
- Data must also be written using the same CharSet, so out.write(s.getBytes("ISO-8859-1"));
- Strings are NULL TERMINATED, just like C strings. That means, add a NULL (ASCII value 0, NOTE that this isn't the character '0', it is the byte 0!) character to the end of each String you send! Eg: out.write(s.getBytes("ISO-8859-1")); out.write(0); will correctly send the String.
- Create a regular socket and connect to the SyncServer
- Send the string "@connect -pass MY_ENCRYPTED_PASSWORD", no quotes.
- Wait for the string "@connect", no quotes. If you receive this string, you've been accepted!
- If you receive the string "@disconnect", you've been declined. This sometimes comes with a reason value.
It goes in this form: @COMMAND_NAME -VARIABLE_NAME VALUE OF VARIABLE -OTHER_VARIABLE_NAME VALUE OF OTHER VARIABLE
Where: COMMAND_NAME is the command name. Commands are available here: https://github.com/netherfoam/MaxBans/blob/master/MaxBans/src/org/maxgamer/maxbans/sync/ClientToServerConnection.java (Example: msg, setip, ban, unban, tempban, unmute are all valid).
VARIABLE_NAME is the name of the next variable. E.g. "reason", "name", and "banner" are sent as variable names for a ban sync request.
VALUE OF VARIABLE is the value of the variable (supplied above). These may have multiple words.
Any command that has " -broadcast" in it will broadcast the given string to every server connected (Excluding the one that sent the request, ofcourse) Example: "@unmute -name NewGuy -broadcast" would unmute NewGuy on all connected Syncers.
Here's a list of Commands and their variables:
|msg||Prints the given String to remote server||string|
|announce||Writes the given String to all players on the remote server. If 'silent' param, only people with perms are notified||string||silent|
|unwarn||Removes the players latest warning||name|
|setip||Updates the given players latest IP address||ip||name|
|setname||Updates the capitalization of the given players name||name|
|dnsbl||Modifies DNSBL blackist. Status = DENIED or ALLOWED||ip||status||created|
|clearwarnings||Clears all warnings from the player||name|
|addhistory||Logs a /history message||string||name||banner|
|rangeban||Bans the given IP range, start = start of range (An IP), end = end of range.||reason||start||end||banner||created|
|unrangeban||Lifts a RangeBan. Start & End must be exact||start||end|
|whitelist||Whitelists the given username against IP restrictions||name||white|
|kickip||Kicks everyone on the given IP||ip||reason|
|setimmunity||Sets the player to immune to punishments. If immune is given, enables this. Otherwise disables.||name||immune|
- If a property is interpreted as a Boolean, then the result is true if the Packet contains the property, and false if it is does not. Eg, writing @cmd silent false, will mean silent is true, but just writing @cmd will mean silent is false.
- IP's are in String form (Eg "127.0.0.1")
- Names may be any case
- Banner is the name of the person to ban the player or who executed the action. 'Console' is used for the console.
- Times are in milliseconds (epoch time)
- 'created' and 'expires' are times in milliseconds.
- If the property 'broadcast' exists, the packet will be forwarded to all servers. This is generally the case if you want to ban a player or mute someone, etc. Eg, @ban -name TestGuy -reason Misconduct -banner Console -broadcast will ban TestGuy on all servers.
Lastly, your password is encrypted after being taken from the config file. The encryption looks like this: <pre>$encrypted_pass = MD5(MD5($pass) + "fuQJ7_q#eF78A&D"));</pre>
Where MD5() is a function that returns the MD5 hash of the given string. The double MD5 plus salt makes it very difficult to reverse the encryption using a rainbow table (There's no actual way of decrypting MD5, all you can do is create a set of billions of passwords, find their MD5 equivilants, and then hope the MD5 of the password you're trying to find is in the giant set of MD5 equivilants, then find the password linked to it), as its been encrypted, had salt added, and encrypted again. However, NOTHING beats a strong password!