init
This commit is contained in:
169
Scripts/AutoLoad/NetworkManager.gd
Normal file
169
Scripts/AutoLoad/NetworkManager.gd
Normal file
@@ -0,0 +1,169 @@
|
||||
extends Node
|
||||
|
||||
signal connected
|
||||
signal disconnected
|
||||
signal login_ok(my_id, players)
|
||||
signal player_joined(id, name, x, y, skin_id)
|
||||
signal player_left(id)
|
||||
signal player_moved(id, x, y, flip_h, frame)
|
||||
signal chat_message_received(sender_id, text)
|
||||
|
||||
signal private_chat_message_received(sender_id, text)
|
||||
signal notices_received(data)
|
||||
|
||||
const DEFAULT_SERVER_URL = "ws://127.0.0.1:8910"
|
||||
|
||||
var socket := WebSocketPeer.new()
|
||||
var my_id: int = -1
|
||||
var player_info := {"name": "Player", "skin_id": 0}
|
||||
var players := {} # id -> {name, x, y, skin_id}
|
||||
var _connected := false
|
||||
var next_spawn_position: Vector2 = Vector2.ZERO
|
||||
|
||||
func _ready():
|
||||
process_mode = Node.PROCESS_MODE_ALWAYS
|
||||
|
||||
func _process(_delta):
|
||||
socket.poll()
|
||||
var state = socket.get_ready_state()
|
||||
|
||||
if state == WebSocketPeer.STATE_OPEN:
|
||||
if not _connected:
|
||||
_connected = true
|
||||
_on_connected()
|
||||
|
||||
while socket.get_available_packet_count():
|
||||
var packet = socket.get_packet()
|
||||
_on_message(packet.get_string_from_utf8())
|
||||
|
||||
elif state == WebSocketPeer.STATE_CLOSED:
|
||||
if _connected:
|
||||
_connected = false
|
||||
_on_disconnected()
|
||||
|
||||
func connect_to_server(url: String = ""):
|
||||
if url.is_empty():
|
||||
url = DEFAULT_SERVER_URL
|
||||
var err = socket.connect_to_url(url)
|
||||
if err != OK:
|
||||
print("Failed to connect: ", err)
|
||||
return err
|
||||
|
||||
func _on_connected():
|
||||
print("Connected to server!")
|
||||
# Send login
|
||||
send_json({
|
||||
"type": "login",
|
||||
"name": player_info["name"],
|
||||
"skin_id": player_info["skin_id"]
|
||||
})
|
||||
connected.emit()
|
||||
|
||||
func _on_disconnected():
|
||||
print("Disconnected from server")
|
||||
my_id = -1
|
||||
players.clear()
|
||||
disconnected.emit()
|
||||
|
||||
func _on_message(data: String):
|
||||
var json = JSON.new()
|
||||
var err = json.parse(data)
|
||||
if err != OK:
|
||||
print("JSON parse error: ", data)
|
||||
return
|
||||
|
||||
var msg = json.data
|
||||
# if msg.get("type") == "player_move" and int(msg.get("id", -1)) != my_id:
|
||||
# print("RAW NET: ", data)
|
||||
var msg_type = msg.get("type", "")
|
||||
|
||||
match msg_type:
|
||||
"login_ok":
|
||||
my_id = int(msg["id"])
|
||||
for p in msg["players"]:
|
||||
players[int(p["id"])] = {
|
||||
"name": p["name"],
|
||||
"x": p["x"],
|
||||
"y": p["y"],
|
||||
"skin_id": p["skin_id"]
|
||||
}
|
||||
login_ok.emit(my_id, players)
|
||||
|
||||
"player_join":
|
||||
var id = int(msg["id"])
|
||||
players[id] = {
|
||||
"name": msg["name"],
|
||||
"x": msg["x"],
|
||||
"y": msg["y"],
|
||||
"skin_id": msg["skin_id"]
|
||||
}
|
||||
player_joined.emit(id, msg["name"], msg["x"], msg["y"], msg["skin_id"])
|
||||
|
||||
"player_leave":
|
||||
var id = int(msg["id"])
|
||||
players.erase(id)
|
||||
player_left.emit(id)
|
||||
|
||||
"player_move":
|
||||
var id = int(msg["id"])
|
||||
if id != my_id: # Only log others to reduce spam, or log all? Let's log all for now if issue is critical
|
||||
print("Net: Recv Move for ID: ", id, " Frame: ", msg.get("frame", 1))
|
||||
if players.has(id):
|
||||
players[id]["x"] = msg["x"]
|
||||
players[id]["y"] = msg["y"]
|
||||
player_moved.emit(id, msg["x"], msg["y"], msg.get("flip_h", false), int(msg.get("frame", 1)))
|
||||
|
||||
"chat":
|
||||
var id = int(msg["id"])
|
||||
chat_message_received.emit(id, msg["text"])
|
||||
|
||||
"private_chat":
|
||||
var id = int(msg["sender_id"])
|
||||
private_chat_message_received.emit(id, msg["text"])
|
||||
|
||||
"notices_list":
|
||||
notices_received.emit(msg.get("data", []))
|
||||
|
||||
|
||||
"scene_peers":
|
||||
# Refresh player list for new scene
|
||||
players.clear()
|
||||
for p in msg["players"]:
|
||||
players[int(p["id"])] = {
|
||||
"name": p["name"],
|
||||
"x": p["x"],
|
||||
"y": p["y"],
|
||||
"skin_id": p["skin_id"]
|
||||
}
|
||||
# Emit login_ok to trigger refresh (or we could add a scene_loaded signal)
|
||||
login_ok.emit(my_id, players)
|
||||
|
||||
func send_json(obj: Dictionary):
|
||||
if socket.get_ready_state() == WebSocketPeer.STATE_OPEN:
|
||||
socket.send_text(JSON.stringify(obj))
|
||||
|
||||
func send_move(x: float, y: float, flip_h: bool, frame: int):
|
||||
send_json({"type": "move", "x": x, "y": y, "flip_h": flip_h, "frame": frame})
|
||||
|
||||
func send_change_scene(scene_name: String, pos: Vector2 = Vector2(-20000, -20000)):
|
||||
var data = {"type": "change_scene", "scene": scene_name}
|
||||
if pos.x != -20000:
|
||||
data["x"] = pos.x
|
||||
data["y"] = pos.y
|
||||
send_json(data)
|
||||
|
||||
func send_message(text: String):
|
||||
send_json({"type": "chat", "text": text})
|
||||
|
||||
func send_private_message(target_id: int, text: String):
|
||||
send_json({"type": "private_chat", "target_id": target_id, "text": text})
|
||||
|
||||
func request_notices():
|
||||
send_json({"type": "get_notices"})
|
||||
|
||||
|
||||
func set_player_name(n: String):
|
||||
player_info["name"] = n
|
||||
|
||||
func set_skin_id(id: int):
|
||||
player_info["skin_id"] = id
|
||||
Reference in New Issue
Block a user