aboutsummaryrefslogtreecommitdiff
path: root/client/scripts/multiplayer.gd
blob: d7dd9d1bf524f1f7cc4e6f163cae600d822e0206 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
extends Node

signal update_map(tile: int, pos: Array, neighbors: Array)
signal clear_message(player: int)
signal text_message(player: int, text: String)
signal item_message(player: int, item: int)

var connected := false
var socket := WebSocketPeer.new()

var item_names = []
var tile_names = []
var player_id = -1

var other_players = {}

func connectClient(url: String):
	socket.connect_to_url(url)
	connected = true

func _process(_delta):
	if connected:
		socket.poll()
		var state = socket.get_ready_state()
		if state == WebSocketPeer.STATE_OPEN:
			while socket.get_available_packet_count():
				handle_packet(socket.get_packet())
		elif state == WebSocketPeer.STATE_CONNECTING:
			print("connecting")
		elif state == WebSocketPeer.STATE_CLOSING:
			# Keep polling to achieve proper close.
			print("closing")
			pass
		elif state == WebSocketPeer.STATE_CLOSED:
			var code = socket.get_close_code()
			var reason = socket.get_close_reason()
			print("WebSocket closed with code: %d, reason %s. Clean: %s" % [code, reason, code != - 1])

func handle_packet(bytes: PackedByteArray):
	var decoded = decode_packet(bytes)

	if decoded == null:
		return

	var packet_type: String = decoded["type"]
	match packet_type:
		"init":
			player_id = decoded["id"]
			item_names = decoded["data"]["item_names"]
			tile_names = decoded["data"]["tile_names"]
		"add_player":
			var id = decoded["id"]
			var player_name = decoded["name"]
			#var item = decoded["item"]
			var pos = decoded["position"]
			var char = decoded["character"]
			other_players[id] = [player_name, char]
		"remove_player":
			var id = decoded["id"]
			other_players.erase(id)
		"position":
			var id = decoded["player"]
			var pos = decoded["pos"]
			var rot = decoded["rot"]
		"take_item":
			var tile = decoded["tile"]
			var player_id = decoded["player"]
		"put_item":
			var tile = decoded["tile"]
			var player_id = decoded["player"]
		"produce_item":
			var tile = decoded["tile"]
			var item = decoded["item"]
		"consume_item":
			var tile = decoded["tile"]
		"set_active":
			var tile = decoded["tile"]
			var progress = decoded["progress"]
		"update_map":
			var tile: int = decoded["tile"]
			var pos: Array = decoded["pos"]
			var neighbors: Array = decoded["neighbors"]
			emit_signal("update_map", pos, tile_names[tile], neighbors)
		"communicate":
			var player = decoded["player"]
			if decoded.has("message"):
				var message: Dictionary = decoded["message"]
				if message.has("item"):
					emit_signal("item_message", player, message["item"])
				else:
					emit_signal("text_message", player, message["text"])
			else:
				emit_signal("clear_message", player)
		_:
			push_error("Unrecognized packet type: %s" % packet_type)

func send_join(player_name: String):
	send_packet({
		"type": "join",
		"name": player_name
	})

func send_position(pos: Vector2, rotation: float):
	send_packet({
		"type": "position",
		"pos": [pos.x, pos.y],
		"rot": rotation
	})

func send_interact(pos: Vector2, edge: bool):
	send_packet({
		"type": "interact",
		"pos": [pos.x, pos.y],
		"edge": edge
	})

func send_packet(packet):
	var json = JSON.stringify(packet)
	socket.send_text(json)

func decode_packet(bytes: PackedByteArray):
	var json = JSON.new()
	var in_str = bytes.get_string_from_utf8()
	var error = json.parse(in_str)
	if error == OK:
		return json.data
	else:
		print("Decode of packet failed: %s in %s" % [json.get_error_message(), in_str])
		return null