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
|
extends Node
var world
var motd : String
var server_name : String
var player_limit : int
var connected_player_count : int = 0
var connected_players = {}
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, _ip: String, 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)
tree.get_root().add_child(world)
world.client_id = 1
print_line("Server started successfully.")
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] = ["", "SPEC"] #Placeholder for name
var server_info = {"player_count" : connected_player_count, "server_name" : server_name, "MOTD" : motd, "cam_pos" : world.get_node("DEFAULTCAM").transform}
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"], "SPEC"]
world.rpc("update_players_info", connected_players)
func _client_change_teams(arguments):
print_line(connected_players[arguments["id"]][0] + " ("+ str(arguments["id"]) +") changed to team " + arguments["team"])
connected_players[arguments["id"]][1] = 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"]][0] + " 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))
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"]][0]
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):
var victim_player = connected_players[arguments["victim_mp_id"]][0] if arguments["victim_mp_id"] != 1 else ""
print_line(arguments["victim"] + " ("+victim_player+") killed by " + arguments["killer"] + " " + arguments["extra"] + ".")
world.rpc("game_chat_msg", arguments["victim"] + " ("+victim_player+") killed by " + arguments["killer"] + " " + arguments["extra"] + ".")
world.get_node("PLAYERS/"+arguments["victim"]).rpc("remove_dead_character")
world.rpc("game_update_chars")
func _send_chat(arguments):
if !("name" in arguments):
arguments["name"]=connected_players[arguments["id"]][0]
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)
|