chanserv.java
来自「这是整套横扫千军3D版游戏的源码」· Java 代码 · 共 1,468 行 · 第 1/4 页
JAVA
1,468 行
/*
* Created on 4.3.2006
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*
*
* For the list of commands, see commands.html!
*
* *** LINKS ****
* * http://java.sun.com/docs/books/tutorial/extra/regex/test_harness.html
* (how to use regex in java to match a pattern)
*
* * http://www.regular-expressions.info/floatingpoint.html
* (how to properly match a floating value in regex)
*
* *** NOTES ***
* * ChanServ MUST use account with admin privileges (not just moderator privileges)
* or else it won't be able to join locked channels and won't work correct!
* * Use Vector for thread-safe list (ArrayList and similar classes aren't thread-safe!)
*
* *** TODO QUICK NOTES ***
* * diff between synchronized(object) {...} and using a Semaphore... ?
*
*/
/**
* @author Betalord
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
import java.io.*;
import java.net.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.*;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.w3c.dom.*;
import java.util.*;
import java.util.regex.*;
import java.util.concurrent.*;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
class KeepAliveTask extends TimerTask {
public void run() {
try {
ChanServ.configLock.acquire();
ChanServ.sendLine("PING");
// also save config on regular intervals:
ChanServ.saveConfig(ChanServ.CONFIG_FILENAME);
} catch (InterruptedException e) {
ChanServ.forceDisconnect();
return ;
} finally {
ChanServ.configLock.release();
}
}
}
public class ChanServ {
static final String VERSION = "0.1";
static final String CONFIG_FILENAME = "settings.xml";
static final boolean DEBUG = false;
static private boolean connected = false; // are we connected to the TASServer?
static Document config;
static String serverAddress = "";
static int serverPort;
static String username = "";
static String password = "";
static Socket socket = null;
static PrintWriter sockout = null;
static BufferedReader sockin = null;
static Timer keepAliveTimer;
static Timer logCleanerTimer;
static boolean timersStarted = false;
static Semaphore configLock = new Semaphore(1, true); // we use it when there is a danger of config object being used by main and TaskTimer threads simultaneously
static RemoteAccessServer remoteAccessServer;
static int remoteAccessPort;
static Vector/*Client*/ clients = new Vector();
static Vector/*Channel*/ channels = new Vector();
static Vector/*String*/ lastMuteList = new Vector(); // list of mute entries for a specified channel (see lastMuteListChannel)
static String lastMuteListChannel; // name of channel for which we are currently receiving (or we already did receive) mute list from the server
static Vector/*MuteListRequest*/ forwardMuteList = new Vector(); // list of current requests for mute lists.
// database related:
public static DBInterface database;
private static String DB_URL = "jdbc:mysql://127.0.0.1/ChanServLogs";
private static String DB_username = "";
private static String DB_password = "";
public static void closeAndExit() {
closeAndExit(0);
}
public static void closeAndExit(int returncode) {
AntiSpamSystem.uninitialize();
if (timersStarted) {
try {
stopTimers();
} catch (Exception e) {
// ignore
}
}
Log.log("Program stopped.");
System.exit(returncode);
}
public static void forceDisconnect() {
try {
socket.close();
} catch (IOException e) {
//
}
}
public static boolean isConnected() {
return connected;
}
private static void loadConfig(String fname)
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//factory.setValidating(true);
//factory.setNamespaceAware(true);
try {
DocumentBuilder builder = factory.newDocumentBuilder();
config = builder.parse(new File(fname));
XPath xpath = XPathFactory.newInstance().newXPath();
Node node, node2;
//node = (Node)xpath.evaluate("config/account/username", config, XPathConstants.NODE);
serverAddress = (String)xpath.evaluate("config/account/serveraddress/text()", config, XPathConstants.STRING);
serverPort = Integer.parseInt((String)xpath.evaluate("config/account/serverport/text()", config, XPathConstants.STRING));
remoteAccessPort = Integer.parseInt((String)xpath.evaluate("config/account/remoteaccessport/text()", config, XPathConstants.STRING));
username = (String)xpath.evaluate("config/account/username/text()", config, XPathConstants.STRING);
password = (String)xpath.evaluate("config/account/password/text()", config, XPathConstants.STRING);
//node = (Node)xpath.evaluate("config/account/username", config, XPathConstants.NODE);
//node.setTextContent("this is a test!");
// read database info:
DB_URL = (String)xpath.evaluate("config/database/url/text()", config, XPathConstants.STRING);
DB_username = (String)xpath.evaluate("config/database/username/text()", config, XPathConstants.STRING);
DB_password = (String)xpath.evaluate("config/database/password/text()", config, XPathConstants.STRING);
// load remote access accounts:
node = (Node)xpath.evaluate("config/remoteaccessaccounts", config, XPathConstants.NODE);
if (node == null) {
Log.error("Bad XML document. Path config/remoteaccessaccounts does not exist. Exiting ...");
closeAndExit(1);
}
node = node.getFirstChild();
while (node != null) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
RemoteAccessServer.remoteAccounts.add(((Element)node).getAttribute("key"));
}
node = node.getNextSibling();
}
// load static channel list:
Channel chan;
node = (Node)xpath.evaluate("config/channels/static", config, XPathConstants.NODE);
if (node == null) {
Log.error("Bad XML document. Path config/channels/static does not exist. Exiting ...");
closeAndExit(1);
}
node = node.getFirstChild();
while (node != null) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
chan = new Channel(((Element)node).getAttribute("name"));
chan.antispam = ((Element)node).getAttribute("antispam").equals("yes") ? true : false;
chan.antispamSettings = ((Element)node).getAttribute("antispamsettings");
if (!SpamSettings.validateSpamSettingsString(chan.antispamSettings)) {
Log.log("Fixing invalid spam settings for #" + chan.name + " ...");
chan.antispamSettings = SpamSettings.spamSettingsToString(SpamSettings.DEFAULT_SETTINGS);
}
channels.add(chan);
// apply anti-spam settings:
AntiSpamSystem.setSpamSettingsForChannel(chan.name, chan.antispamSettings);
}
node = node.getNextSibling();
}
// load registered channel list:
node = (Node)xpath.evaluate("config/channels/registered", config, XPathConstants.NODE);
if (node == null) {
Log.error("Bad XML document. Path config/channels/registered does not exist. Exiting ...");
closeAndExit(1);
}
node = node.getFirstChild();
while (node != null) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
// this is "channel" element
chan = new Channel(((Element)node).getAttribute("name"));
chan.isStatic = false;
chan.topic = ((Element)node).getAttribute("topic");
chan.key = ((Element)node).getAttribute("key");
chan.founder = ((Element)node).getAttribute("founder");
chan.antispam = ((Element)node).getAttribute("antispam").equals("yes") ? true : false;
chan.antispamSettings = ((Element)node).getAttribute("antispamsettings");
if (!SpamSettings.validateSpamSettingsString(chan.antispamSettings)) {
Log.log("Fixing invalid spam settings for #" + chan.name + " ...");
chan.antispamSettings = SpamSettings.spamSettingsToString(SpamSettings.DEFAULT_SETTINGS);
}
channels.add(chan);
// load this channel's operator list:
node2 = node.getFirstChild();
while (node2 != null) {
if (node2.getNodeType() == Node.ELEMENT_NODE) {
// this is "operator" element
chan.addOperator(((Element)node2).getAttribute("name"));
//***Log.debug("OPERATOR: " + ((Element)node2).getAttribute("name") + " (chan " + ((Element)node).getAttribute("name") + ")");
}
node2 = node2.getNextSibling();
}
// apply anti-spam settings:
AntiSpamSystem.setSpamSettingsForChannel(chan.name, chan.antispamSettings);
}
node = node.getNextSibling();
}
Log.log("Config file read.");
} catch (SAXException sxe) {
// Error generated during parsing
Log.error("Error during parsing xml document: " + fname);
closeAndExit(1);
/*
Exception x = sxe;
if (sxe.getException() != null)
x = sxe.getException();
x.printStackTrace();
*/
} catch (ParserConfigurationException pce) {
// Parser with specified options can't be built
Log.error("Unable to build specified xml parser");
closeAndExit(1);
//pce.printStackTrace();
} catch (IOException ioe) {
// I/O error
Log.error("I/O error while accessing " + fname);
closeAndExit(1);
//ioe.printStackTrace();
} catch (XPathExpressionException e) {
Log.error("Error: XPath expression exception - XML document is malformed.");
e.printStackTrace();
closeAndExit(1);
} catch (Exception e) {
Log.error("Unknown exception while reading config file: " + fname);
e.printStackTrace();
closeAndExit(1);
//e.printStackTrace();
}
}
public static void saveConfig(String fname) {
try {
XPath xpath = XPathFactory.newInstance().newXPath();
Node root;
Node node;
Node temp;
Element elem, elem2;
//Text text; // text node
Channel chan;
try {
// remove all static channels from config and replace it with current static channel list:
root = (Node)xpath.evaluate("config/channels/static", config, XPathConstants.NODE);
if (root == null) {
Log.error("Bad XML document. Path config/channels/static does not exist. Exiting ...");
closeAndExit(1);
}
// delete all static channels:
root.getChildNodes();
node = root.getFirstChild();
while (node != null) {
//if (node.getNodeType() == Node.ELEMENT_NODE) {
temp = node;
node = node.getNextSibling();
root.removeChild(temp);
//}
}
// add new static channels:
for (int i = 0; i < channels.size(); i++) {
chan = (Channel)channels.get(i);
if (!chan.isStatic) continue;
root.appendChild(config.createTextNode(Misc.EOL + Misc.enumSpaces(6)));
elem = config.createElement("channel");
elem.setAttribute("name", chan.name);
elem.setAttribute("antispam", chan.antispam ? "yes" : "no");
elem.setAttribute("antispamsettings", chan.antispamSettings);
//elem.setTextContent(chan.name);
root.appendChild(elem);
}
root.appendChild(config.createTextNode(Misc.EOL + Misc.enumSpaces(4)));
// remove all registered channels from config and replace it with current registered channel list:
root = (Node)xpath.evaluate("config/channels/registered", config, XPathConstants.NODE);
if (root == null) {
Log.error("Bad XML document. Path config/channels/registered does not exist. Exiting ...");
closeAndExit(1);
}
// delete all channels:
root.getChildNodes();
node = root.getFirstChild();
while (node != null) {
temp = node;
node = node.getNextSibling();
root.removeChild(temp);
}
// add new channels:
for (int i = 0; i < channels.size(); i++) {
chan = (Channel)channels.get(i);
if (chan.isStatic) continue;
root.appendChild(config.createTextNode(Misc.EOL + Misc.enumSpaces(6)));
elem = config.createElement("channel");
elem.setAttribute("name", chan.name);
elem.setAttribute("topic", chan.topic);
elem.setAttribute("key", chan.key);
elem.setAttribute("founder", chan.founder);
elem.setAttribute("antispam", chan.antispam ? "yes" : "no");
elem.setAttribute("antispamsettings", chan.antispamSettings);
// write operator list:
if (chan.getOperatorList().size() > 0) {
elem.appendChild(config.createTextNode(Misc.EOL + Misc.enumSpaces(8)));
for (int j = 0; j < chan.getOperatorList().size(); j++) {
elem2 = config.createElement("operator");
elem2.setAttribute("name", (String)chan.getOperatorList().get(j));
elem.appendChild(elem2);
if (j != chan.getOperatorList().size()-1)
elem.appendChild(config.createTextNode(Misc.EOL + Misc.enumSpaces(8)));
}
elem.appendChild(config.createTextNode(Misc.EOL + Misc.enumSpaces(6)));
}
root.appendChild(elem);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?