📄 mazeserver.java
字号:
import java.awt.BorderLayout;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Random;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
public class MazeServer extends JDialog implements Runnable {
private static final long serialVersionUID = 1214952909615483237L;
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MazeServer(new javax.swing.JFrame(), true).setVisible(true);
}
});
}
public MazeServer(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();
setLookAndFeel("Windows");
setSize(640, 480);
}
private void initComponents() {
getContentPane().setLayout(new java.awt.BorderLayout());
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle("Maze Server");
setResizable(false);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
MazeServer.isRunning = false;
System.exit(1);
}
});
JPanel jpToolbar = new JPanel();
getContentPane().add(jpToolbar, BorderLayout.NORTH);
jbRun = new javax.swing.JButton();
jbRun.setText("Run");
jbRun.setName("jbtnRun");
jbRun.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jbRunActionPerformed(evt);
jbRun.setEnabled(false);
}
});
jpToolbar.add(jbRun);
jbStop = new javax.swing.JButton();
jbStop.setText("Stop");
jbStop.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
MazeServer.isRunning = false;
out("服务器停止运行");
jbRun.setEnabled(true);
}
});
jpToolbar.add(jbStop);
jbExit = new javax.swing.JButton();
jbExit.setText("Exit");
jbExit.setName("jbtnExit");
jbExit.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
MazeServer.isRunning = false;
close();
System.exit(1);
}
});
jpToolbar.add(jbExit);
JPanel jpClient = new JPanel();
jpClient.setLayout(new java.awt.BorderLayout());
jtaMsg = new javax.swing.JTextArea();
jpClient.add(jtaMsg);
JScrollPane jsp = new JScrollPane(jpClient);
jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
getContentPane().add(jsp, BorderLayout.CENTER);
pack();
}
private void jbRunActionPerformed(java.awt.event.ActionEvent evt) {
new Thread(this).start();
out("服务器开始运行");
new Thread() {
public void run() {
handleIncomingCmd();
}
}.start();
}
private void setLookAndFeel(String look) {
UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels();
for (int i = 0; i < lafs.length; i++) {
if (lafs[i].getName().equals(look)) {
try {
UIManager.setLookAndFeel(lafs[i].getClassName());
} catch (Exception e) {
System.out.println("Can not set look and feel as " + look);
return;
}
return;
}
}
}
private void out(String msg) {
System.out.println(msg);
jtaMsg.append(msg + "\n");
}
/**
* 通过轮循,处理客户端的命令
*
*/
private void handleIncomingCmd() {
while(isRunning) {
try {
Thread.sleep(100);
} catch(Exception e) {}
Enumeration e = clients.elements();
while (e.hasMoreElements()) {
Client cc = (Client)e.nextElement();
try {
//如果socket关闭,那么删除客户端
if (!cc.socket.isConnected() ||
(cc.socket.isInputShutdown()) ||
(cc.socket.isOutputShutdown())) {
out(cc.getAccount() + " 离开");
cleanupUser(cc);
} else if (cc.dis.available()>0) {
handleCmd(cc);
}
} catch (Exception ee) {
continue;
}
}
}
}
/**
* 处理客户端命令
* @param client 客户端对象
*/
private void handleCmd(Client client) throws IOException {
try {
byte cmd = client.dis.readByte();
out("收到命令: " + cmd);
switch(cmd) {
case MazeProtocol.CMD_USERLIST:
sendUserList(client);
break;
case MazeProtocol.CMD_EXIT:
cleanupUser(client);
client.dos.writeByte(MazeProtocol.RESP_OK);
client.dos.flush();
break;
case MazeProtocol.CMD_SIT:
handleSitDown(client);
break;
case MazeProtocol.CMD_STAND:
handleStandUp(client);
break;
case MazeProtocol.CMD_STARTGAME:
handleStartGame(client);
break;
case MazeProtocol.CMD_WIN:
handleWin(client);
break;
case MazeProtocol.CMD_MOVE:
handleMove(client);
break;
case MazeProtocol.CMD_ENDGAME:
handleEndGame(client);
break;
}
}catch(Exception e) {
cleanupUser(client);
return;
}
}
/**
* 用户退出游戏时,或者网络超时时,清除用户状态
* <p>
* @param client 要被清除的用户
*/
private void cleanupUser(Client client) throws IOException {
//首先检查用户是否在游戏状态
int tn = client.table_num;
if (tn<0) {
return;
}
Integer key = new Integer(tn);
if (tables.containsKey(key)) {
//在桌子就座,但是没有在游戏状态
//设置离开桌子,退出游戏
sendAllExit(client);
client.table_num = -1;
tables.remove(key);
}
//在游戏大厅,但是没有坐下时
client.close();
clients.remove(client.getAccount());
client = null;
}
private void sendAllExit(Client client) throws IOException {
Enumeration e = clients.elements();
while (e.hasMoreElements()) {
Client c = (Client)e.nextElement();
if (c != client) {
sendExit(c, client);
}
}
}
private void sendExit(Client c, Client client) throws IOException {
c.dos.writeByte(MazeProtocol.CMD_EXIT);
c.dos.writeInt(client.table_num);
byte[] data = client.getAccount().getBytes("UTF-8");
c.dos.writeInt(data.length);
c.dos.write(data);
c.dos.flush();
}
private void handleEndGame(Client client) throws IOException {
//首先检查用户是否在游戏状态
int tn = client.table_num;
if (tn<0) {
return;
}
Integer key = new Integer(tn);
if (tables.containsKey(key)) {
seats = (Client[])tables.get(key);
if (seats[0]!=null && seats[1]!=null) {
//在游戏状态
sendOK(client);
//累加积分
if (seats[0] == client) {
seats[1].score++;
//保存到数据库中
save2DB(seats[1]);
//通知另外的客户端
sendExit(seats[1], seats[0]);
} else {
seats[0].score++;
//保存到数据库中
save2DB(seats[0]);
//通知另外的客户端
sendExit(seats[0], seats[1]);
}
} else {
sendError(client);
}
} else {
sendError(client);
}
}
/**
* 处理客户端的起立请求
*
*/
private void handleStandUp(Client client) throws IOException {
int number = -1;
byte pos = 0;
int size = 0;
byte[] data = null;
number = client.dis.readInt();
client.table_num = number;
pos = client.dis.readByte();
size = client.dis.readInt();
data = new byte[size];
client.dis.read(data);
out("处理起立命令");
Integer iNum = new Integer(number);
seats = (Client[])tables.get(iNum);
if (seats == null) {
return;
}
seats[pos].table_num = -1;
seats[pos] = null;
if (seats[0] == null && seats[1]==null) {
tables.remove(iNum);
}
sendOK(client);
//通知其他客户端,更新状态
Enumeration e = clients.elements();
while (e.hasMoreElements()) {
Client c = (Client)e.nextElement();
if (c != client) {
c.dos.writeByte(
MazeProtocol.CMD_STAND);
c.dos.writeInt(number);
c.dos.writeByte(pos);
c.dos.writeInt(size);
c.dos.write(data);
c.dos.flush();
}
}
out("起立命令处理处理");
}
/**
* 处理客户端的坐下请求
*
*/
private void handleSitDown(Client client) throws IOException {
int number = -1;
byte pos = 0;
int size = 0;
byte[] data = null;
number = client.dis.readInt();
client.table_num = number;
pos = client.dis.readByte();
size = client.dis.readInt();
data = new byte[size];
client.dis.read(data);
out("处理坐下命令");
Integer iNum = new Integer(number);
if (tables.containsKey(iNum)) {
seats = (Client[])tables.get(iNum);
if (seats[pos] == null) {
client.table_num = number;
seats[pos] = client;
//坐下后,发送CMD_OK响应
sendOK(client);
//通知其他的用户显示新用户
notifyAllSitOrStand(client,
MazeProtocol.CMD_SIT,
number, pos, size, data);
out("坐下命令处理完毕");
//开始游戏
if (seats[0] != null &&
seats[1] != null) {
sendStartGame(seats);
}
} else {
//已有人坐,则发送CMD_ERROR响应
sendError(client);
}
} else {
//添加桌子
seats = new Client[2];
seats[0] = null;
seats[1] = null;
client.table_num = number;
seats[pos] = client;
tables.put(iNum, seats);
//坐下后,发送CMD_OK响应
sendOK(client);
//通知其他的用户显示新用户
notifyAllSitOrStand(client,
MazeProtocol.CMD_SIT,
number, pos, size, data);
out("坐下命令处理完毕");
}
}
private void notifyAllSitOrStand(Client client,
byte cmd, int number,
byte pos, int size, byte[] data) throws IOException {
Enumeration e = clients.elements();
while (e.hasMoreElements()) {
Client c = (Client)e.nextElement();
if (c != client) {
c.dos.writeByte(cmd);
c.dos.writeInt(number);
c.dos.writeByte(pos);
c.dos.writeInt(size);
c.dos.write(data);
c.dos.flush();
}
}
}
/*
* 开始游戏
*/
private void handleStartGame(Client client) throws IOException{
Integer iNum = new Integer(client.table_num);
if (tables.containsKey(iNum)) {
seats = (Client[])tables.get(iNum);
if (seats[0] != null &&
seats[1] != null &&
(seats[0] == client || seats[1]== client)) {
sendStartGame(seats);
}
}
}
private void handleWin(Client client) throws IOException{
Integer iNum = new Integer(client.table_num);
if (tables.containsKey(iNum)) {
seats = (Client[])tables.get(iNum);
if (seats[0] != null &&
seats[1] != null &&
(seats[0] == client || seats[1]== client)) {
sendOK(client);
//发送CMD_WIM命令到另外的一端
if (seats[0]==client) {
seats[0].score++;
//保存到数据库中
save2DB(seats[0]);
seats[1].dos.writeByte(MazeProtocol.CMD_WIN);
seats[1].dos.flush();
} else {
seats[1].score++;
//保存到数据库中
save2DB(seats[1]);
seats[0].dos.writeByte(MazeProtocol.CMD_WIN);
seats[0].dos.flush();
}
}
} else {
sendError(client);
}
}
private void handleMove(Client client) throws IOException{
Integer iNum = new Integer(client.table_num);
int carX = client.dis.readInt();
int carY = client.dis.readInt();
if (tables.containsKey(iNum)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -