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 + -
显示快捷键?