summaryrefslogtreecommitdiff
path: root/godot/scripts/Server.gd
blob: 498c5d80a408b9a6c5c4e05bc295ada03ecf8554 (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
extends Node

var world
var motd : String
var server_name : String
var player_limit : int
var connected_player_count : int = 0
var connected_players = {}
enum {PLAYER_NAME, PLAYER_TEAM}

var server_enet : NetworkedMultiplayerENet
var output 
var output_func : String

func print_line(line):
	if output == null:
		print("SERVER: " + line)
		return
	output.call(output_func, line)

func _ready():
	var signal_status = [ get_tree().connect("network_peer_connected", self, "_client_connect"), 
						  get_tree().connect("network_peer_disconnected", self, "_client_disconnect")]
	for sig in signal_status:
		if sig != OK:
			print("SERVER: Error connecting one or more signals. Error code: " + str(sig))

func start_server(_server_name: String, _motd: String, max_players: int, map_path: String, is_local: bool, port: int, tree, output_obj, output_f):
	output = output_obj
	output_func = output_f
	server_name = _server_name
	motd = _motd
	player_limit = max_players

	server_enet = NetworkedMultiplayerENet.new()
	var srv_stat = server_enet.create_server(port, max_players)
	if srv_stat != OK:
		print_line("Error creating server. Code: "+str(srv_stat))
		stop_server()
		return
	tree.set_network_peer(server_enet)

	world = load(map_path)
	if world:
		world = world.instance()
	else:
		print_line("Error loading map.")
		return

	world.add_child(self)
	world.client_id = 1
	world.is_host = true
	world.is_local = is_local
	if is_local:
		connected_players[1] = ["Player", -1]
	tree.get_root().add_child(world)

	world.client_id = 1
	
	print_line("Server started successfully.")
	NavigationServer.set_active(false)
	
func stop_server():
	print_line("Shutting down server...")
	server_enet.close_connection()
	print_line("Shut down successfully.")
	world.queue_free()

func _client_disconnect(id):
	print_line("Client (ID: "+str(id)+") has disconnected.")
	for character in world.get_node("PLAYERS").get_children():
		if character.get_network_master() == id:
			character.rpc("set_owner", 1)
	connected_players.erase(id)
	connected_player_count -= 1
	world.rpc("update_players_info", connected_players)

func _client_connect(id):
	print_line("Client (ID: "+str(id)+") connecting...")
	connected_player_count += 1
	connected_players[id] = ["", -1] #Placeholder for name
	
	var server_info = {"player_count" : connected_player_count, "server_name" : server_name, "MOTD" : motd, "cam_pos" : world.get_node("DEFAULTCAM").transform, "teams" : {0 : "RED", 1 : "BLUE"}}
	world.rpc_id(id, "set_up_server_info", server_info)
	
	var geo_info = []
	for world_geo in world.get_node("WORLDGEO").get_children():
		geo_info.append( { "filename" : world_geo.filename, "transform" : world_geo.transform })
	world.rpc_id(id, "load_map", geo_info)
	
	var ent_info = []
	for section in ["PLAYERS","MACHINES","BALLISTICS"]:
		for item in world.get_node(section).get_children():
			ent_info.append({"type" : section, "net_master" : item.get_network_master(), "name" : item.name, "filename" : item.filename, "transform" : item.transform, "init_info" : item.get_init_info() })
	world.rpc_id(id, "load_entities", ent_info)

func _client_connection_confirmed(arguments):
	print_line("Client (ID: "+str(arguments["id"])+") connected as " +arguments["username"] +".")
	connected_players[arguments["id"]] = [arguments["username"], -1]
	world.rpc("update_players_info", connected_players)

func _client_change_teams(arguments):
	print_line(connected_players[arguments["id"]][PLAYER_NAME] + " ("+ str(arguments["id"]) +") changed to team " + str(arguments["team"]))
	connected_players[arguments["id"]][PLAYER_TEAM] = arguments["team"]
	world.rpc("update_players_info", connected_players)

func _client_request_change_character(arguments):
	var dest = world.get_node("PLAYERS/"+arguments["char_name"])
	if dest != null and dest.get_network_master() == 1:
		print_line(connected_players[arguments["id"]][PLAYER_NAME] + " selected character " + arguments["char_name"])
		dest.rpc("set_net_owner", arguments["id"])
		if arguments["current_char_name"] != "NULL":
			var old = world.get_node("PLAYERS/"+arguments["current_char_name"])
			old.rpc("set_net_owner", int(1), true)

func _client_request_control_vehicle(arguments):
	var dest_machine = world.get_node(arguments["machine_path"])
	var name = "BOT" if arguments["id"] == 1 else connected_players[arguments["id"]][PLAYER_NAME]
	if dest_machine != null and dest_machine.get_network_master() == 1 and !dest_machine.in_use:
		print_line(arguments["char_name"] + "(" + name + ") is controlling " + dest_machine.name)
		dest_machine.rpc("set_net_owner", arguments["id"], arguments["char_name"])

func _character_death(arguments):
	if world.get_node("PLAYERS/"+arguments["victim_name"]) == null:
		return
	var victim_player: String = connected_players[arguments["victim_mp_id"]][PLAYER_NAME] if arguments["victim_mp_id"] != 1 else arguments["victim_name"]
	var killer_player: String = connected_players[arguments["killer_id"]][PLAYER_NAME] if arguments["killer_id"] != 1 else arguments["killer_name"]
	print_line(victim_player+" killed by " +killer_player+ " using " + arguments["extra"] + ".")
	world.rpc("game_chat_msg", victim_player+" killed by " +killer_player+ " using " + arguments["extra"] + ".")
	world.get_node("PLAYERS/"+arguments["victim_name"]).rpc("remove_dead_character")
	world.rpc("game_update_chars")

func _send_chat(arguments):
	if !("name" in arguments):
		arguments["name"]=connected_players[arguments["id"]][PLAYER_NAME]
	print_line(arguments["name"]+ ": " + arguments["msg"])
	world.rpc("game_chat_msg", arguments["name"]+ ": " + arguments["msg"])

func _set_ai_state(args):
	var charname: String = args[0]
	var state: String = args[1]
	print(args)
	var man: NetChar = world.get_node("PLAYERS/"+charname)
	if man:
		man.ai_set_state(state)