chanserv.java
来自「这是整套横扫千军3D版游戏的源码」· Java 代码 · 共 1,468 行 · 第 1/4 页
JAVA
1,468 行
}
root.appendChild(config.createTextNode(Misc.EOL + Misc.enumSpaces(4)));
} catch (XPathExpressionException e) {
e.printStackTrace();
closeAndExit(1);
}
// ok save it now:
config.normalize(); //*** is this needed?
DOMSource source = new DOMSource(config);
StreamResult result = new StreamResult(new FileOutputStream(fname));
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
transformer.transform(source, result);
if (DEBUG) Log.log("Config file saved to " + fname);
} catch (Exception e) {
Log.error("Unable to save config file to " + fname + "! Ignoring ...");
}
}
// multiple threads may call this method
public static synchronized void sendLine(String s) {
if (DEBUG) Log.log("Client: \"" + s + "\"");
sockout.println(s);
}
private static boolean tryToConnect() {
try {
Log.log("Connecting to " + serverAddress + ":" + serverPort + " ...");
socket = new Socket(serverAddress, serverPort);
sockout = new PrintWriter(socket.getOutputStream(), true);
sockin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
Log.error("Unknown host error: " + serverAddress);
return false;
} catch (IOException e) {
Log.error("Couldn't get I/O for the connection to: " + serverAddress);
return false;
}
Log.log("Now connected to " + serverAddress);
return true;
}
public static void messageLoop() {
String line;
while (true) {
try {
line = sockin.readLine();
} catch (IOException e) {
Log.error("Connection with server closed with exception.");
break;
}
if (line == null) break;
if (DEBUG) Log.log("Server: \"" + line + "\"");
// parse command and respond to it:
try {
configLock.acquire();
execRemoteCommand(line);
} catch (InterruptedException e) {
//return ;
} finally {
configLock.release();
}
}
try {
sockout.close();
sockin.close();
socket.close();
} catch (IOException e) {
// do nothing
}
Log.log("Connection with server closed.");
}
// processes messages that were only sent to server admins. "message" parameter must be a
// message string withouth the "[broadcast to all admins]: " part.
public static void processAdminBroadcast(String message) {
Log.debug("admin broadcast: '" + message + "'");
// let's check if some channel founder/operator has just renamed his account:
if (message.matches("User <[^>]{1,}> has just renamed his account to <[^>]{1,}>")) {
String oldNick = message.substring(message.indexOf('<')+1, message.indexOf('>'));
String newNick = message.substring(message.indexOf('<', message.indexOf('>'))+1, message.indexOf('>', message.indexOf('>')+1));
// lets rename all founder/operator entries for this user:
for (int i = 0; i < channels.size(); i++) {
Channel chan = (Channel)channels.get(i);
if (chan.isFounder(oldNick)) {
chan.renameFounder(newNick);
Log.log("Founder <" + oldNick + "> of #" + chan.name + " renamed to <" + newNick + ">");
}
if (chan.isOperator(oldNick)) {
chan.renameOperator(oldNick, newNick);
Log.log("Operator <" + oldNick + "> of #" + chan.name + " renamed to <" + newNick + ">");
}
}
}
}
public static boolean execRemoteCommand(String command) {
if (command.trim().equals("")) return false;
// try to extract message ID if present:
if (command.charAt(0) == '#') try {
if (!command.matches("^#\\d+\\s[\\s\\S]*")) return false; // malformed command
int ID = Integer.parseInt(command.substring(1).split("\\s")[0]);
// remove ID field from the rest of command:
command = command.replaceFirst("#\\d+\\s", "");
// forward the command to the waiting thread:
synchronized (remoteAccessServer.threads) {
for (int i = 0; i < remoteAccessServer.threads.size(); i++) {
if (((RemoteClientThread)remoteAccessServer.threads.get(i)).ID == ID) {
((RemoteClientThread)remoteAccessServer.threads.get(i)).replyQueue.put(command);
return true;
}
}
}
return false; // no suitable thread found! Perhaps thread already finished before it could read the response (not a problem)
} catch (NumberFormatException e) {
return false; // this means that the command is malformed
} catch (PatternSyntaxException e) {
return false; // this means that the command is malformed
}
String[] commands = command.split(" ");
commands[0] = commands[0].toUpperCase();
if (commands[0].equals("TASSERVER")) {
sendLine("LOGIN " + username + " " + password + " 0 * ChanServ " + VERSION);
} else if (commands[0].equals("ACCEPTED")) {
Log.log("Login accepted.");
// join registered and static channels:
for (int i = 0; i < channels.size(); i++)
sendLine("JOIN " + ((Channel)channels.get(i)).name);
} else if (commands[0].equals("DENIED")) {
Log.log("Login denied. Reason: " + Misc.makeSentence(commands, 1));
closeAndExit();
} else if (commands[0].equals("AGREEMENT")) {
// not done yet. Should respond with CONFIRMAGREEMENT and then resend LOGIN command.
Log.log("Server is requesting agreement confirmation. Cancelling ...");
closeAndExit();
} else if (commands[0].equals("ADDUSER")) {
clients.add(new Client(commands[1]));
} else if (commands[0].equals("REMOVEUSER")) {
for (int i = 0; i < clients.size(); i++) if (((Client)clients.get(i)).name.equals(commands[1])) {
clients.remove(i);
break;
}
} else if (commands[0].equals("CLIENTSTATUS")) {
for (int i = 0; i < clients.size(); i++) if (((Client)clients.get(i)).name.equals(commands[1])) {
Client client = (Client)clients.get(i);
client.setStatus(Integer.parseInt(commands[2]));
AntiSpamSystem.processClientStatusChange(client);
break;
}
} else if (commands[0].equals("JOIN")) {
Log.log("Joined #" + commands[1]);
Channel chan = getChannel(commands[1]);
if (chan == null) return false; // this could happen just after we unregistered the channel (since there is always some lag between us and the server)
chan.joined = true;
chan.clearClients();
// set topic, lock channel, ... :
if (!chan.isStatic) {
if (!chan.key.equals(""))
sendLine("SETCHANNELKEY " + chan.name + " " + chan.key);
if (chan.topic.equals(""))
sendLine("CHANNELTOPIC " + chan.name + " *");
else
sendLine("CHANNELTOPIC " + chan.name + " " + chan.topic);
}
} else if (commands[0].equals("CLIENTS")) {
Channel chan = getChannel(commands[1]);
if (chan == null) return false; // this could happen just after we unregistered the channel (since there is always some lag between us and the server)
for (int i = 2; i < commands.length; i++) {
chan.addClient(commands[i]);
}
} else if (commands[0].equals("JOINED")) {
Channel chan = getChannel(commands[1]);
if (chan == null) return false; // this could happen just after we unregistered the channel (since there is always some lag between us and the server)
chan.addClient(commands[2]);
Log.toFile(chan.logFileName, "* " + commands[2] + " has joined " + "#" + chan.name);
} else if (commands[0].equals("LEFT")) {
Channel chan = getChannel(commands[1]);
if (chan == null) return false; // this could happen just after we unregistered the channel (since there is always some lag between us and the server)
chan.removeClient(commands[2]);
String out = "* " + commands[2] + " has left " + "#" + chan.name;
if (commands.length > 3)
out = out + " (" + Misc.makeSentence(commands, 3) + ")";
Log.toFile(chan.logFileName, out);
} else if (commands[0].equals("JOINFAILED")) {
channels.add(new Channel(commands[1]));
Log.log("Failed to join #" + commands[1] + ". Reason: " + Misc.makeSentence(commands, 2));
} else if (commands[0].equals("CHANNELTOPIC")) {
Channel chan = getChannel(commands[1]);
if (chan == null) return false; // this could happen just after we unregistered the channel (since there is always some lag between us and the server)
chan.topic = Misc.makeSentence(commands, 4);
Log.toFile(chan.logFileName, "* Channel topic is '" + chan.topic + "' set by " + commands[2]);
} else if (commands[0].equals("SAID")) {
Channel chan = getChannel(commands[1]);
if (chan == null) return false; // this could happen just after we unregistered the channel (since there is always some lag between us and the server)
String user = commands[2];
String msg = Misc.makeSentence(commands, 3);
if (chan.antispam) AntiSpamSystem.processUserMsg(chan.name, user, msg);
Log.toFile(chan.logFileName, "<" + user + "> " + msg);
if ((msg.length() > 0) && (msg.charAt(0) == '!')) processUserCommand(msg.substring(1, msg.length()), getClient(user), chan);
} else if (commands[0].equals("SAIDEX")) {
Channel chan = getChannel(commands[1]);
if (chan == null) return false; // this could happen just after we unregistered the channel (since there is always some lag between us and the server)
String user = commands[2];
String msg = Misc.makeSentence(commands, 3);
if (chan.antispam) AntiSpamSystem.processUserMsg(chan.name, user, msg);
Log.toFile(chan.logFileName, "* " + user + " " + msg);
} else if (commands[0].equals("SAIDPRIVATE")) {
String user = commands[1];
String msg = Misc.makeSentence(commands, 2);
Log.toFile(user + ".log", "<" + user + "> " + msg);
if ((msg.length() > 0) && (msg.charAt(0)) == '!') processUserCommand(msg.substring(1, msg.length()), getClient(user), null);
} else if (commands[0].equals("SERVERMSG")) {
Log.log("Message from server: " + Misc.makeSentence(commands, 1));
if (Misc.makeSentence(commands, 1).startsWith("[broadcast to all admins]")) processAdminBroadcast(Misc.makeSentence(commands, 1).substring("[broadcast to all admins]: ".length(), Misc.makeSentence(commands, 1).length()));
} else if (commands[0].equals("SERVERMSGBOX")) {
Log.log("MsgBox from server: " + Misc.makeSentence(commands, 1));
} else if (commands[0].equals("CHANNELMESSAGE")) {
Channel chan = getChannel(commands[1]);
if (chan != null) {
String out = "* Channel message: " + Misc.makeSentence(commands, 2);
Log.toFile(chan.logFileName, out);
}
} else if (commands[0].equals("BROADCAST")) {
Log.log("*** Broadcast from server: " + Misc.makeSentence(commands, 1));
} else if (commands[0].equals("MUTELISTBEGIN")) {
lastMuteList.clear();
lastMuteListChannel = commands[1];
} else if (commands[0].equals("MUTELIST")) {
lastMuteList.add(Misc.makeSentence(commands, 1));
} else if (commands[0].equals("MUTELISTEND")) {
int i = 0;
while (i < forwardMuteList.size()) {
MuteListRequest request = (MuteListRequest)forwardMuteList.get(i);
if (!request.chanName.equals(lastMuteListChannel)) {
i++;
continue;
}
Client target = getClient(request.sendTo);
if (target == null) { // user who made the request has already gone offline!
forwardMuteList.remove(i);
continue;
}
if (System.currentTimeMillis() - request.requestTime > 10000) { // this request has already expired
forwardMuteList.remove(i);
continue;
}
// forward the mute list to the one who requested it:
if (lastMuteList.size() == 0) sendMessage(target, getChannel(request.replyToChan), "Mute list for #" + request.chanName + " is empty!");
else {
sendMessage(target, getChannel(request.replyToChan), "Mute list for #" + request.chanName+ " (" + lastMuteList.size() + " entries):");
for (int j = 0; j < lastMuteList.size(); j++) {
sendMessage(target, getChannel(request.replyToChan), (String)lastMuteList.get(j));
}
}
forwardMuteList.remove(i);
}
}
return true;
}
/* If the command was issued from a private chat, then "channel" parameter should be null */
public static void processUserCommand(String command, Client client, Channel channel) {
if (command.trim().equals("")) return ;
String[] params = command.split(" ");
params[0] = params[0].toUpperCase(); // params[0] is the base command
// remove all empty tokens to avoid any problems while parsing commands later on:
{
boolean done = false;
while (!done) {
for (int i = 0; i < params.length; i++)
if (params[i].equals("")) {
params = (String[])Misc.removeFromObjectArray(i, params);
break;
} else if (i == params.length-1) done = true;
}
}
if (params[0].equals("HELP")) {
// force the message to be sent to private chat rather than to the channel (to avoid unneccessary bloating the channel):
sendMessage(client, null, "Hello, " + client.name + "!");
sendMessage(client, null, "I am an automated channel service bot,");
sendMessage(client, null, "for the full list of commands, see http://taspring.clan-sy.com/dl/ChanServCommands.html");
sendMessage(client, null, "If you want to go ahead and register a new channel, please contact one of the server moderators!");
} else if (params[0].equals("INFO")) {
// if the command was issued from a channel:
if (channel != null) { // insert <channame> parameter so we don't have to handle two different situations for each command
params = (String[])Misc.insertIntoObjectArray("#" + channel.name, 1, params);
}
if (params.length != 2) {
sendMessage(client, channel, "Error: Invalid params!");
return ;
}
if (params[1].charAt(0) != '#') {
sendMessage(client, channel, "Error: Bad channel name (forgot #?)");
return ;
}
String chanName = params[1].substring(1, params[1].length());
Channel chan = getChannel(chanName);
if (chan == null) {
sendMessage(client, channel, "Channel #" + chanName + " is not registered!");
return ;
}
if (chan.isStatic) {
sendMessage(client, channel, "Channel #" + chanName + " is registered as a static channel, no further info available!");
return ;
}
String respond = "Channel #" + chan.name + " info: Anti-spam protection is " + (chan.antispam ? "on" : "off") + ". Founder is <" + chan.founder + ">, ";
Vector ops = chan.getOperatorList();
if (ops.size() == 0) respond = respond + "no operators are registered.";
else if (ops.size() == 1) respond = respond + "1 registered operator is <" + (String)ops.get(0) + ">.";
else {
respond = respond + ops.size() + " registered operators are ";
for (int i = 0; i < ops.size()-1; i++)
respond = respond + "<" + (String)ops.get(i) + ">, ";
respond = respond + "<" + (String)ops.get(ops.size()-1) + ">.";
}
sendMessage(client, channel, respond);
} else if (params[0].equals("REGISTER")) {
if (!client.isModerator()) {
sendMessage(client, channel, "Sorry, you'll have to contact one of the server moderators to register a channel for you!");
return ;
}
if (params.length != 3) {
sendMessage(client, channel, "Error: Invalid params!");
return ;
}
if (params[1].charAt(0) != '#') {
sendMessage(client, channel, "Error: Bad channel name (forgot #?)");
return ;
}
String chanName = params[1].substring(1, params[1].length());
String valid = Channel.isChanNameValid(chanName);
if (valid != null) {
sendMessage(client, channel, "Error: Bad channel name (" + valid + ")");
return ;
}
for (int i = 0; i < channels.size(); i++) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?