📄 mazeserver.java
字号:
seats = (Client[])tables.get(iNum);
if (seats[0] != null &&
seats[1] != null &&
(seats[0] == client || seats[1]== client)) {
sendOK(client);
//发送CMD_MOVE命令到另外的一端
if (seats[0]==client) {
seats[1].dos.writeByte(MazeProtocol.CMD_MOVE);
seats[1].dos.writeInt(carX);
seats[1].dos.writeInt(carY);
seats[1].dos.flush();
} else {
seats[0].dos.writeByte(MazeProtocol.CMD_MOVE);
seats[0].dos.writeInt(carX);
seats[0].dos.writeInt(carY);
seats[0].dos.flush();
}
}
} else {
sendError(client);
}
}
private void sendStartGame(Client[] seats)
throws IOException{
out("启动游戏,发送地图数据");
int[][] map = generateMazeMap(35, 35);
if (map == null) {
out("产生地图数据出错");
return;
}
for(int i=0;i<seats.length;i++) {
seats[i].dos.writeByte(MazeProtocol.CMD_STARTGAME);
//获得地图数据
seats[i].dos.writeInt(map.length);
seats[i].dos.writeInt(map[0].length);
for(int m=0;m<map.length;m++) {
for(int n=0;n<map[0].length;n++) {
seats[i].dos.writeInt(map[m][n]);
}
}
seats[i].dos.flush();
}
}
private void sendError(Client client) throws IOException{
try {
client.dos.writeByte(MazeProtocol.RESP_ERROR);
client.dos.flush();
} catch (Exception e) {
//清除客户端
cleanupUser(client);
}
}
private void sendOK(Client client) throws IOException{
try {
client.dos.writeByte(MazeProtocol.RESP_OK);
client.dos.flush();
} catch (Exception e) {
//清除客户端
cleanupUser(client);
}
}
//----------------------------------------------------发送用户列表开始
private void sendUserList(Client client) throws IOException {
int num = tables.size();
try {
client.dos.writeInt(num);
Enumeration e = tables.elements();
while (e.hasMoreElements()) {
seats = (Client[])e.nextElement();
for(byte i=0;i<seats.length;i++) {
if (seats[i] != null) {
client.dos.writeInt(seats[i].table_num);
client.dos.writeByte(i);
byte[] data = seats[i].getAccount().
getBytes("UTF-8");
client.dos.writeInt(data.length);
client.dos.write(data);
}
}
}
client.dos.flush();
//读取客户端响应
byte resp = client.dis.readByte();
if (resp == MazeProtocol.RESP_OK) {
out("成功发送用户列表到 -" + client.getAccount());
} else {
out("不能发送用户列表到 -" + client.getAccount());
}
} catch (IOException e) {
//清除客户端
cleanupUser(client);
}
}
//--------------------------------------------------发送用户列表结束
//------------------------------------------------------登录处理开始
/**
* 进行登录验证
* <p>
* @param s 连接用Socket
* <p>
* @return 如果登录成功返回true,否则返回false。
*/
private boolean chekcLogin(Socket s) {
//读取用户登录信息
// 发送: LOGIN size1 UserName size2 Password
// 接收: OK | ERROR
try {
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
int cmd = dis.readByte();
out("Receive cmd: " + cmd);
//如果不是LOGIN命令,那么返回RESP_ERROR
if (cmd != MazeProtocol.CMD_LOGIN) {
//发送RESP_ERROR消息到客户端,通知登录失败
dos.writeByte(MazeProtocol.RESP_ERROR);
return false;
}
//读取登录信息
int size1 = dis.readInt();
byte[] un = new byte[size1];
dis.read(un);
String userName = new String(un, "UTF-8");
int size2 = dis.readInt();
byte[] ps = new byte[size2];
dis.read(ps);
String password = new String(ps);
out("user name" + userName);
//进行登录验证
Client client = verifyUser(userName, password);
if (client != null) {
//发送RESP_OK消息到客户端,通知登录正确
dos.writeByte(MazeProtocol.RESP_OK);
//更新服务器界面
out(userName + " 已经登录服务器");
//设置客户端连接
client.setSocket(s, dis, dos);
//把客户端连接到列表中
clients.put(userName, client);
//清除以前没有清除的记录
removeFromTables(userName);
}
} catch (Exception e) {
System.out.println("登录失败!");
e.printStackTrace();
return false;
}
return true;
}
private void removeFromTables(String username) {
Enumeration e = tables.elements();
while (e.hasMoreElements()) {
seats = (Client[])e.nextElement();
int num = 0;
for(byte i=0;i<seats.length;i++) {
if (seats[i] != null &&
seats[i].getAccount().equals(username)) {
num = seats[i].table_num;
seats[i].table_num = -1;
seats[i] = null;
}
}
//如果没有用户了,就删除桌子
if (seats[0]==null && seats[1]==null) {
tables.remove(new Integer(num));
}
}
}
/**
* 验证用户信息
* <p>
* @param username 要验证的用户名
* @param password 要验证的用户密码
* <p>
* @return 如果用户不存在,那么返回NULL,否则返回用户ClientConnection
*/
private Client verifyUser(String username, String password) {
Client client = null;
try {
//调用JDBC-ODBC 驱动程序
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
//与数据库连接,"MazeGameDB" 是Access数据库的ODB数据源名字,
//需要在控制面板中配置
//用户名和口令为空
Connection con = DriverManager.getConnection(
"jdbc:odbc:MazeGameDB");
//创建Statement
Statement s = con.createStatement();
String sql = "select * from Users where UserName='"
+ username + "'";
ResultSet rs = s.executeQuery(sql);
// 执行查询结果存放在ResultSet中, UserName是用户表
while(rs.next())
{
String ps = rs.getString("Password");
if (ps.equals(password)) {
//验证通过,读取积分
int score = rs.getInt("Score");
client = new Client(username);
client.score = score;
break;
}
}
//关闭数据库的连接
con.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return client;
}
//------------------------------------------------------登录处理结束
/**
* 把用户数据保存在数据库中
*/
private void save2DB(Client client) {
try {
//调用JDBC-ODBC 驱动程序
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
//与数据库连接,"MazeGameDB" 是Access数据库的ODB数据源名字,
//需要在控制面板中配置
//用户名和口令为空
Connection con = DriverManager.getConnection(
"jdbc:odbc:MazeGameDB");
//创建Statement
Statement s = con.createStatement();
String sql = "update Users set score=" +
String.valueOf(client.score) + " where UserName='"
+ client.getAccount() + "'";
s.executeUpdate(sql);
//关闭数据库的连接
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//---------------------------------------------打开和关闭服务器-开始
public void run() {
isRunning = true;
// 建立服务器
close();
out("打开服务器ServerSocket");
try {
server = new ServerSocket(9999);
} catch (IOException ioe) {
ioe.printStackTrace();
return;
}
Socket incoming;
while (isRunning) {
if (!isRunning) {
break;
}
try {
incoming = server.accept();
Thread.sleep(500);
} catch (Exception ex) {
continue;
}
out("有客户端连接服务器");
//进行登录验证
chekcLogin(incoming);
}
close();
}
private void close() {
//清除桌子
tables.clear();
//关闭客户端连接
Enumeration e = clients.elements();
while (e.hasMoreElements()) {
Client cc = (Client)e.nextElement();
cc.close();
}
clients.clear();
out("关闭所有的客户端连接");
// 关闭服务器
if (server != null) {
try {
server.close();
out("关闭服务器Socket");
} catch (IOException e1) {
}
server = null;
}
}
//---------------------------------------------打开和关闭服务器-结束
//---------------------------------------------随机产生迷宫地图-开始
/**
* 随机产生迷宫地图数据
* <p>
* @param row 行数
* @param col 列数
* @return 表示游戏地图的二维数组
*/
private int[][] generateMazeMap(int row, int col) {
int[][] cells = new int[row][col]; //行列需要为奇数
/*
* 初始化矩阵
*/
int rows = cells.length;
int cols = cells[0].length;
int counter = 0; // 墙的数量
int space_code = 0; // 空地编码
int[] wallrow = new int[(rows*cols)/2];
int[] wallcol = new int[(rows*cols)/2];
//全部用墙填充
for(int i=0;i<rows;i++) {
for (int j=0;j<cols;j++) {
cells[i][j] = 1;
}
}
//设置空格
for(int i=1;i<rows-1;i+=2) {
for (int j=1;j<cols-1;j+=2) {
cells[i][j] = --space_code;
if (i < rows-2) { // record info about wall below this room
wallrow[counter] = i+1;
wallcol[counter] = j;
counter++;
}
if (j < cols-2) { // record info about wall to right of this room
wallrow[counter] = i;
wallcol[counter] = j+1;
counter++;
}
}
}
//随机的去掉墙
Random ran = new Random();
for (int i=counter-1; i>0; i--) {
int r = ran.nextInt(i);
tearDown(cells, wallrow[r], wallcol[r]);
wallrow[r] = wallrow[i];
wallcol[r] = wallcol[i];
}
//把所有值为负的值,变为空地值0
for(int i=0;i<rows;i++) {
for (int j=0;j<cols;j++) {
if (cells[i][j]<0) {
cells[i][j]=0;
}
}
}
//添加出口
cells[cells.length-1][cells[0].length-2] = 0;
//打印输出
for(int i=0;i<cells.length;i++) {
System.out.print("{");
for (int j=0;j<cells[0].length-1;j++) {
System.out.print(String.valueOf(cells[i][j])+", ");
}
System.out.print(cells[i][cells[0].length-1]+"}, \n");
}
return cells;
}
/**
* 拆除指定位置的墙
* @param cells 包含地图信息的数组
* @param row 墙的row坐标
* @param col 墙的col坐标
*/
private void tearDown(int[][] cells, int row, int col) {
if (row % 2 == 1 && cells[row][col-1] != cells[row][col+1] &&
cells[row][col-1]<0 && cells[row][col+1]<0) {
cells[row][col] = cells[row][col+1];
replaceRoomCode(cells, row, col-1, cells[row][col-1], cells[row][col+1]);
} else if (row % 2 == 0 && cells[row-1][col] != cells[row+1][col] &&
cells[row-1][col]<0 && cells[row+1][col]<0) {
cells[row][col] = cells[row+1][col];
replaceRoomCode(cells, row-1, col, cells[row-1][col], cells[row+1][col]);
}
}
/**
* 把房间值替换为新值
* @param cells 包含地图信息的数组
* @param row 房间内某个方格的row坐标
* @param col 房间内某个方格的col坐标
* @param oldValue 房间旧值
* @param newValue 房间新值
*/
private void replaceRoomCode(int[][] cells,int row, int col,
int oldValue, int newValue) {
if (cells[row][col] == oldValue) {
cells[row][col] = newValue;
replaceRoomCode(cells, row-1, col, oldValue, newValue);
replaceRoomCode(cells, row+1, col, oldValue, newValue);
replaceRoomCode(cells, row, col-1, oldValue, newValue);
replaceRoomCode(cells, row, col+1, oldValue, newValue);
}
}
//---------------------------------------------随机产生迷宫地图-结束
//---------------------------------------------成员定义
/** 服务器运行标志 */
static boolean isRunning = false;
ServerSocket server = null;
private javax.swing.JButton jbRun;
private javax.swing.JButton jbStop;
private javax.swing.JButton jbExit;
static javax.swing.JTextArea jtaMsg;
/** 用来列表 */
Hashtable clients = new Hashtable();
/** 桌子列表 */
Hashtable tables = new Hashtable();
/** 桌子的座位 */
Client[] seats;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -