import java.io.PrintWriter;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.ServerSocket;
import java.util.Date;
public class tbServer {
private static final int maxque = 1;
private static final int port = 8051;
private static ServerSocket SERV=null;
static tbRobotInterface SEND=null;
public static void main(String A[]) {
try {
SERV= new ServerSocket(port, maxque);
SEND=new tbRobot();
SEND.start();
System.out.println("TELEBOT SERVICE STARTED!");
Log("server started");
while (true) {
new tbConnection(SERV.accept());
}
} catch (Exception e) {
System.out.println("ERROR: (server) "+e);
}
System.out.println("TELEBOT SERVICE STOPPED!");
SEND.stop();
Log("server stopped");
}
public static void terminate(int level) {
try {
SERV.close();
} catch (Exception e) {
System.out.println("SHUTDOWN: (server) "+e);
}
SEND.stop();
System.out.println("TELEBOT SERVICE TERMINATED!");
Log("server terminated");
System.exit(level);
}
public synchronized static void Log(String memo) {
try {
PrintWriter LOG=new PrintWriter(new FileWriter("tbLOG.txt", true));
LOG.println((new Date()).toString()+" : "+memo);
LOG.flush();
LOG.close();
} catch (Exception e) {
System.out.println("ERROR: (log file) "+e);
}
}
}
class tbConnection implements Runnable {
private static final int maxcon = 10;
private static tbConnection CLI[]=new tbConnection[maxcon+1];
static {
int c; for (c=0; c<=maxcon; c++) CLI[c]=null;
}
private static void SendAll(String msg) {
int c;
for (c=1; c<=maxcon; c++)
if (CLI[c]!=null)
CLI[c].Send(msg);
}
private int CO=0;
private Socket SO=null;
private BufferedReader SR=null;
private PrintWriter SW=null;
private String KTO="";
tbConnection(Socket client) {
SO=client;
for (CO=1; CO<=maxcon; CO++) if (CLI[CO]==null) break;
if (CO>maxcon) CO=0; else CLI[CO]=this;
(new Thread(this, "Serving a Client")).start();
}
private void Send(String msg) {
synchronized (SW) {
try {
SW.println(msg);
SW.flush();
} catch (Exception e) {
try {
SO.close();
} catch (Exception f) {}
}
}
}
private void CO_Server(String cmndline) {
if (cmndline.equalsIgnoreCase("/HELP")) CS_Help();
else if (cmndline.equals("/DATE")) CS_Date();
else if (cmndline.startsWith("/ECHO ")) CS_Echo(cmndline);
else if (cmndline.equals("/EXIT")) CS_Exit();
else if (cmndline.equals("/KICK")) CS_Kick("");
else if (cmndline.startsWith("/KICK ")) CS_Kick(cmndline);
else if (cmndline.equals("/KILL for good")) CS_Kill();
else if (cmndline.equals("/PING")) CS_Ping();
else if (cmndline.equals("/QUIT")) CS_Exit();
else if (cmndline.equals("/REST")) CS_Restart();
else if (cmndline.equals("/WHO")) CS_Who();
else Send("-ERR unrecognized command, type /HELP");
}
private void CS_Date() {
Send("+DATE "+(new Date()).toString());
}
private void CS_Echo(String echo) {
Send("+OK echo");
SendAll(CO+">>"+echo.substring(6));
}
private void CS_Exit() {
Send("+OK exit");
SendAll(CO+"> So long!");
try {
SO.close();
} catch (Exception e) {}
}
private void CS_Kick(String cmnd) {
if (cmnd.equals("")) {
Send("-ERR Kick who?");
} else {
Send("+OK kick");
SendAll(CO+"> Kick user #"+cmnd.substring(6));
}
}
private void CS_Kill() {
tbServer.Log("server killed by "+KTO);
System.out.println("killed by "+KTO);
Send("+OK kill");
SendAll("SERVER WILL BE SHUT DOWN");
tbServer.terminate(10);
}
private void CS_Ping() {
Send("+OK PONG");
}
private void CS_Help() {
Send( "HELP:\n\r"+
"Available server commands:\n\r"+
"/DATE /ECHO /EXIT /HELP /KICK /KILL /PING /QUIT /REST /WHO\n\r\n\r"+
(tbServer.SEND).help()
);
Send("+DONE help");
}
private void CS_Restart() {
tbServer.Log("reset requested by "+KTO);
System.out.println("restarting by "+KTO);
Send("+OK restart");
SendAll("SERVER RESTARTING\n\rPLEASE RECONNECT SOON");
tbServer.terminate(0);
}
private void CS_Who() {
int c;
for (c=1; c<=maxcon; c++)
if (CLI[c]!=null)
Send(c+"="+CLI[c].KTO);
Send("+DONE who");
}
private void CO_Robot(String cmndline) {
Send((tbServer.SEND).exec(cmndline));
SendAll(CO+"> "+cmndline);
}
private void CU_Rej() {
tbServer.Log("rejected (+) from "+KTO);
System.out.println("rejected (+) from "+KTO);
Send("-ERR server reached its capacity");
SendAll("# Server reached its capacity");
Send("# MAX NUMBER OF CLIENTS REACHED");
Send("# PLEASE TRY AGAIN LATER, SORRY");
}
private void CU_Bye() {
int c;
for (c=1; c<=maxcon; c++)
if (CLI[c]!=null) return;
(tbServer.SEND).reset();
}
public void run() {
try {
KTO=(SO.getInetAddress()).toString();
SR=new BufferedReader(new InputStreamReader(SO.getInputStream()));
SW=new PrintWriter (SO.getOutputStream());
Send("+OK connected");
SendAll(CO+"> Welcome all!");
if (CO>0) {
tbServer.Log("connected ("+CO+") from "+KTO);
System.out.println("connected ("+CO+") from "+KTO);
while (true) {
String line=SR.readLine();
if (line==null) break;
if (line.startsWith("/")) CO_Server(line);
else CO_Robot(line);
}
} else CU_Rej();
SO.close();
} catch (Exception e) {
System.out.println("ERROR: (connection) "+e);
tbServer.Log("broken con ("+CO+") from "+KTO+" because of "+e);
}
tbServer.Log("disconnect ("+CO+") from "+KTO);
System.out.println("disconnect ("+CO+") from "+KTO);
CLI[CO]=null;
SendAll(CO+"> Bye bye!");
CU_Bye();
}
}