Sketcher2 source code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
6.9 KiB

package com.jotuntech.sketcher.server;
import java.awt.AlphaComposite;
import java.awt.Image;
import java.awt.image.ImageObserver;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.util.Properties;
import java.util.Map.Entry;
import javax.imageio.ImageIO;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import com.jotuntech.sketcher.common.Canvas;
import com.jotuntech.sketcher.common.Layer;
import com.jotuntech.sketcher.common.TwoWayHashMap;
import com.jotuntech.sketcher.common.User;
public class Service {
boolean canvasModified = false;
long motdLastModified = 0;
public static void main(String[] args) throws Throwable {
new Service().run(args);
}
private void run(String[] args) throws Throwable {
System.setProperty("java.net.preferIPv4Stack", "true");
BufferedReader pbr = new BufferedReader(new FileReader(args[0]));
String propertiesPath = pbr.readLine();
pbr.close();
Properties properties = new Properties();
properties.load(new FileInputStream(new File(propertiesPath)));
String serverName = properties.getProperty("server.name", "Rental");
int port = Integer.valueOf(properties.getProperty("server.port", "10000"));
final File talkFile = new File(properties.getProperty("server.talk", "talk.txt"));
final File userFile = new File(properties.getProperty("server.user", "user.txt"));
String motdFilename = properties.getProperty("server.motd", null);
final File motdFile = motdFilename == null ? null : new File(motdFilename);
String captureFilename = properties.getProperty("server.capture", "capture.jpg");
final File captureFile = new File(captureFilename);
final File captureTempFile = new File(captureFilename + ".tmp");
final File saveFile = new File(properties.getProperty("server.save", "save.canvas"));
final File secretFolder = new File(properties.getProperty("server.secret", "secret/"));
final File flagsFile = new File(properties.getProperty("server.flags", "server.flags"));
AccessController ac = new AccessController() {
public boolean isKickAllowed(Server server, User source, User target) {
try {
BufferedReader br = new BufferedReader(new FileReader(flagsFile));
String flags = br.readLine();
br.close();
if(flags.indexOf('k') >= 0) {
return true;
}
} catch (IOException e) { }
return false;
}
public boolean isLayerActionAllowed(Server server, User source) {
try {
BufferedReader br = new BufferedReader(new FileReader(flagsFile));
String flags = br.readLine();
br.close();
if(flags.indexOf('l') >= 0) {
return true;
}
} catch (IOException e) { }
return false;
}
public boolean isLoginAllowed(Server server, String login, String password) {
try {
File secretFile = new File(secretFolder, login);
BufferedReader br = new BufferedReader(new FileReader(secretFile));
String hash = br.readLine();
br.close();
secretFile.delete();
secretFile.createNewFile();
if(password.equals(hash)) {
return true;
}
} catch (IOException e) { }
return false;
}
public boolean isMessageAllowed(Server server, User source, String message) {
return true;
}
public boolean isViewer(Server server, User source) {
return false;
}
};
ImageObserver io = new ImageObserver() {
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
canvasModified = true;
return true;
}
};
final Server server = new Server(serverName, port, 2048, 1536);
server.setAccessController(ac);
server.getCanvas().addImageObserver(io);
if(saveFile.exists()) {
FileInputStream fis = new FileInputStream(saveFile);
ObjectInputStream ois = new ObjectInputStream(fis);
Canvas c = server.getCanvas();
TwoWayHashMap<Integer, Layer> layerMap = c.getLayerMap();
synchronized(layerMap) {
layerMap.clear();
layerMap.setNextKey(ois.readInt());
while(ois.available() > 0) {
int k = ois.readInt();
Layer l = (Layer) ois.readObject();
if(l.getAlphaRule() == 0) {
l.setAlphaRule(AlphaComposite.SRC_OVER);
}
layerMap.put(k, l);
}
}
c.imageUpdate(null, ImageObserver.ALLBITS, 0, 0, c.getWidth(), c.getHeight());
ois.close();
}
server.getConnectionMap().addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
try {
PrintWriter pw = new PrintWriter(new FileWriter(userFile));
for(User u : server.getUsers()) {
pw.println(u.getName());
}
pw.close();
} catch(Throwable e2) {
e2.printStackTrace();
}
}
});
server.start();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
FileOutputStream fos = new FileOutputStream(saveFile);
ObjectOutputStream oos = new ObjectOutputStream(fos);
TwoWayHashMap<Integer, Layer> layerMap = server.getCanvas().getLayerMap();
oos.writeInt(layerMap.getNextKey());
for(Entry<Integer, Layer> e : layerMap.entrySet()) {
int k = e.getKey();
Layer l = e.getValue();
oos.writeInt(k);
oos.writeObject(l);
}
oos.close();
} catch(Throwable e) {
e.printStackTrace();
}
}
});
if(!talkFile.exists()) {
talkFile.createNewFile();
}
int captureCounter = 0;
for(;;) {
if(canvasModified && captureCounter % 60 == 0) {
ImageIO.write(server.getImage(), "PNG", captureTempFile);
captureFile.delete();
captureTempFile.renameTo(captureFile);
canvasModified = false;
}
if(talkFile.length() > 0) {
BufferedReader br = new BufferedReader(new FileReader(talkFile));
String line = br.readLine();
if(line != null) {
if(line.startsWith("kick ")) {
server.kick(line.substring(5), "by room owner");
} else {
server.announce(line);
}
}
br.close();
talkFile.delete();
talkFile.createNewFile();
}
if(motdFile != null && motdFile.lastModified() > motdLastModified) {
motdLastModified = motdFile.lastModified();
StringBuffer buffer = new StringBuffer(1024);
char[] charBuffer = new char[1024];
FileReader fr = new FileReader(motdFile);
int charsRead = fr.read(charBuffer);
if(charsRead > 0) {
do {
buffer.append(charBuffer, 0, charsRead);
charsRead = fr.read(charBuffer);
} while(charsRead > 0);
server.setMOTD(buffer.toString());
}
fr.close();
}
Thread.sleep(5000);
++captureCounter;
}
}
}