2025-09-23 21:46:12 +08:00
|
|
|
package uno.mloluyu.network;
|
|
|
|
|
|
|
|
|
|
import com.badlogic.gdx.Gdx;
|
|
|
|
|
|
2025-09-24 20:07:32 +08:00
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
2025-09-23 21:46:12 +08:00
|
|
|
public class NetworkManager {
|
|
|
|
|
private static NetworkManager instance;
|
|
|
|
|
private ConnectServer server;
|
|
|
|
|
private ConnectClient client;
|
|
|
|
|
private boolean isHost = false;
|
2025-09-24 20:07:32 +08:00
|
|
|
private String localPlayerId;
|
|
|
|
|
private String localCharacter;
|
|
|
|
|
private final Map<String, float[]> playerPositions = new HashMap<>();
|
|
|
|
|
private final Map<String, String> playerCharacters = new HashMap<>();
|
2025-09-23 21:46:12 +08:00
|
|
|
|
|
|
|
|
public static NetworkManager getInstance() {
|
|
|
|
|
if (instance == null) {
|
|
|
|
|
instance = new NetworkManager();
|
|
|
|
|
}
|
|
|
|
|
return instance;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-24 20:07:32 +08:00
|
|
|
public void setLocalPlayerId(String id) {
|
|
|
|
|
this.localPlayerId = id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getLocalPlayerId() {
|
|
|
|
|
return localPlayerId;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-25 14:57:01 +08:00
|
|
|
public void createRoom() {//创建房间
|
2025-09-23 21:46:12 +08:00
|
|
|
isHost = true;
|
|
|
|
|
server = new ConnectServer(11455);
|
|
|
|
|
new Thread(server).start();
|
2025-09-24 20:07:32 +08:00
|
|
|
Gdx.app.log("Network", "房主模式:服务器已启动");
|
2025-09-23 21:46:12 +08:00
|
|
|
}
|
|
|
|
|
|
2025-09-25 14:57:01 +08:00
|
|
|
public void joinRoom(String ip) {//加入房间
|
2025-09-23 21:46:12 +08:00
|
|
|
isHost = false;
|
|
|
|
|
client = new ConnectClient(ip, 11455);
|
2025-09-24 20:07:32 +08:00
|
|
|
Gdx.app.log("Network", "客户端模式:连接到房主 " + ip);
|
2025-09-23 21:46:12 +08:00
|
|
|
}
|
|
|
|
|
|
2025-09-25 14:57:01 +08:00
|
|
|
public void sendPosition(float x, float y) {//发送位置消息
|
2025-09-24 20:07:32 +08:00
|
|
|
String msg = "POS:" + localPlayerId + "," + x + "," + y;
|
|
|
|
|
Gdx.app.log("Network", "发送位置消息: " + msg);
|
2025-09-23 21:46:12 +08:00
|
|
|
if (isHost && server != null) {
|
2025-09-24 20:07:32 +08:00
|
|
|
server.broadcastToOthers(null, msg);
|
2025-09-25 14:57:01 +08:00
|
|
|
receiveMessage(msg);
|
2025-09-23 21:46:12 +08:00
|
|
|
} else if (client != null) {
|
2025-09-24 20:07:32 +08:00
|
|
|
client.sendMessage(msg);
|
2025-09-23 21:46:12 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-25 14:57:01 +08:00
|
|
|
public void sendCharacterSelection(String character) {//发送角色选择消息
|
2025-09-24 20:07:32 +08:00
|
|
|
this.localCharacter = character;
|
|
|
|
|
String msg = "SELECT:" + localPlayerId + "," + character;
|
|
|
|
|
Gdx.app.log("Network", "发送角色选择消息: " + msg);
|
|
|
|
|
if (isHost && server != null) {
|
|
|
|
|
server.broadcastToOthers(null, msg);
|
|
|
|
|
receiveMessage(msg);
|
|
|
|
|
} else if (client != null) {
|
|
|
|
|
client.sendMessage(msg);
|
|
|
|
|
}
|
2025-09-23 21:46:12 +08:00
|
|
|
}
|
|
|
|
|
|
2025-09-25 14:57:01 +08:00
|
|
|
public void receiveMessage(String message) {//解析消息
|
2025-09-24 20:07:32 +08:00
|
|
|
Gdx.app.log("Network", "收到消息: " + message);
|
|
|
|
|
|
|
|
|
|
if (message.startsWith("POS:")) {
|
|
|
|
|
String[] parts = message.substring(4).split(",");
|
|
|
|
|
if (parts.length == 3) {
|
|
|
|
|
String playerId = parts[0];
|
|
|
|
|
try {
|
|
|
|
|
float x = Float.parseFloat(parts[1]);
|
|
|
|
|
float y = Float.parseFloat(parts[2]);
|
|
|
|
|
playerPositions.put(playerId, new float[]{x, y});
|
|
|
|
|
Gdx.app.log("Network", "位置更新: " + playerId + " -> " + x + "," + y);
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
Gdx.app.error("Network", "位置解析失败: " + message);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
Gdx.app.error("Network", "位置消息格式错误: " + message);
|
|
|
|
|
}
|
|
|
|
|
} else if (message.startsWith("SELECT:")) {
|
|
|
|
|
String[] parts = message.substring(7).split(",");
|
|
|
|
|
if (parts.length == 2) {
|
|
|
|
|
String playerId = parts[0];
|
|
|
|
|
String character = parts[1];
|
|
|
|
|
playerCharacters.put(playerId, character);
|
|
|
|
|
Gdx.app.log("Network", "角色选择: " + playerId + " -> " + character);
|
|
|
|
|
} else {
|
|
|
|
|
Gdx.app.error("Network", "角色选择消息格式错误: " + message);
|
|
|
|
|
}
|
|
|
|
|
} else if (message.equals("READY")) {
|
|
|
|
|
Gdx.app.log("Network", "收到准备信号");
|
|
|
|
|
} else {
|
|
|
|
|
Gdx.app.log("Network", "未知消息类型: " + message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Map<String, float[]> getPlayerPositions() {
|
2025-09-23 21:46:12 +08:00
|
|
|
return playerPositions;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-24 20:07:32 +08:00
|
|
|
public Map<String, String> getPlayerCharacters() {
|
|
|
|
|
return playerCharacters;
|
2025-09-23 21:46:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean isHost() {
|
|
|
|
|
return isHost;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean isConnected() {
|
|
|
|
|
return server != null || client != null;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-24 20:07:32 +08:00
|
|
|
public void disconnect() {
|
|
|
|
|
if (server != null) {
|
|
|
|
|
server.dispose();
|
|
|
|
|
server = null;
|
2025-09-23 21:46:12 +08:00
|
|
|
}
|
2025-09-24 20:07:32 +08:00
|
|
|
if (client != null) {
|
|
|
|
|
client.disconnect();
|
|
|
|
|
client = null;
|
|
|
|
|
}
|
|
|
|
|
playerPositions.clear();
|
|
|
|
|
playerCharacters.clear();
|
|
|
|
|
Gdx.app.log("Network", "已断开连接");
|
2025-09-23 21:46:12 +08:00
|
|
|
}
|
|
|
|
|
}
|