cs-os/scripts/utils/ServerUtils.gd

224 lines
7.4 KiB
GDScript

extends Node
var team_CS = {
"spawnpoints": [],
"members": [],
"round_score": 0,
"game_score": 0
}
var team_OS = {
"spawnpoints": [],
"members": [],
"round_score": 0,
"game_score": 0
}
var round_number = 0
var gamemode
var map_path
var map_root_name
var server_map
func find_class_type_by_number(number):
var found_class
var classtypes = GameData.server_settings["game"]["classTypes"]
for classtype in classtypes:
if classtypes[classtype]["number"] == number:
found_class = classtypes[classtype].duplicate()
break
return found_class
func check_map_availability(path):
var maps = DirAccess.open("res://scenes/maps").get_files()
var map_name = (path.split("/")[-1]).split(".")[0]
for map in maps:
var checking_map_name = str(map.split(".")[0])
if(checking_map_name == map_name):
return true
return false
func check_gamemode_availability(gm):
var gamemodes = GameData.server_settings["game"]["gamemodes"].keys()
for g in gamemodes:
if gm == g:
return true
return false
func find_weapon_name_by_number(number):
var name = ""
for weapon in GameData.server_settings["game"]["weapons"].keys():
if (GameData.server_settings["game"]["weapons"][weapon].number == number):
name = weapon
return name
func find_weapon_by_number(number):
var found_weapon
for weapon in GameData.server_settings["game"]["weapons"].keys():
if (GameData.server_settings["game"]["weapons"][weapon]["number"] == number):
found_weapon = GameData.server_settings["game"]["weapons"][weapon].duplicate()
break
return found_weapon
func find_playermodel_by_internal_id(internal_id):
return server_map.get_node("player" + str(internal_id))
func reloading_complete(client_id, reloading_time):
await get_tree().create_timer(reloading_time).timeout
var client = Networking.clients[client_id]
if (!client["reloading"]): # if a client has interrupted the reloading
return
var weapons_list = GameData.server_settings["game"]["weapons"]
var current_client_weapon = client["current_weapon"]
var current_weapon_example = weapons_list.find_key(ServerUtils.find_weapon_by_number(current_client_weapon["number"]))
var current_weapon_settings = weapons_list[current_weapon_example]
var to_reload = current_weapon_settings["magazine"] - current_client_weapon["magazine"]
if (to_reload <= current_client_weapon["ammo"]):
current_client_weapon["magazine"] += to_reload
current_client_weapon["ammo"] -= to_reload
else:
current_client_weapon["magazine"] += current_client_weapon["ammo"]
current_client_weapon["ammo"] = 0
func choose_collision_shape(target, shape_num):
var collision_shapes:Array = []
for s in target.get_children():
if s is CollisionShape3D:
collision_shapes.push_back(s)
var shape
for i in range(0, collision_shapes.size()):
if i == shape_num:
shape = collision_shapes[i]
break
return shape
func new_round():
round_number += 1
team_OS["round_score"] = 0
team_CS["round_score"] = 0
print("CS members " + str(team_CS["members"]))
print("OS members " + str(team_OS["members"]))
for member in team_CS["members"]:
member["position"] = team_CS["spawnpoints"].pick_random().get_class_spawnpoint(abs(member["class_type"]))
ServerUtils.find_playermodel_by_internal_id(member["internal_id"]).teleport.rpc_id(Networking.clients.find_key(member), member["position"])
for member in team_OS["members"]:
member["position"] = team_OS["spawnpoints"].pick_random().get_class_spawnpoint(abs(member["class_type"]))
ServerUtils.find_playermodel_by_internal_id(member["internal_id"]).teleport.rpc_id(Networking.clients.find_key(member), member["position"])
send_scores()
func new_game(new_map_path, new_gamemode):
team_OS["game_score"] = 0
team_OS["round_score"] = 0
team_CS["game_score"] = 0
team_CS["round_score"] = 0
round_number = 0
send_scores()
new_map_path = map_path if (new_map_path == null) else new_map_path
new_gamemode = gamemode if (new_gamemode == null) else new_gamemode
await switch_map(new_map_path)
await switch_gamemode(new_gamemode)
func check_gamemode_end_conditions():
match gamemode:
"TDM":
var kills_amount_to_win = GameData.server_settings["game"]["gamemodes"]["TDM"]["kills"]
if team_OS["round_score"] >= kills_amount_to_win:
team_OS["game_score"] += 1
print("OS won")
NetUtils.send_everyone(["end_round", 1]) # 1 = os is win
new_round()
elif team_CS["round_score"] >= kills_amount_to_win:
team_CS["game_score"] += 1
NetUtils.send_everyone(["end_round", -1]) # -1 = cs is win
print("CS won")
new_round()
send_scores()
func switch_map(new_map_path):
print("Switching map to %s" % new_map_path)
if (not ServerUtils.check_map_availability(new_map_path)):
var default_map = GameData.server_settings["defaults"]["map"]
print("Error. No map found. Loading default map %s" % default_map)
new_map_path = "res://scenes/maps/%s.tscn" % default_map
if (not ServerUtils.check_map_availability(new_map_path)):
print("Error. Default map is not valid. Please, specify a valid map in a config file.")
return
map_path = new_map_path
get_tree().change_scene_to_file(map_path)
await get_tree().create_timer(0.1).timeout #I know that this isn't a good practice, but I didn't find anything better
map_root_name = (map_path.split("/")[-1]).split(".")[0]
server_map = get_tree().root.get_node(map_root_name)
var spawnpoints = server_map.find_children("spawnpoint*", "" ,true)
team_OS["spawnpoints"] = []
team_CS["spawnpoints"] = []
for spawnpoint in spawnpoints:
if spawnpoint.team == 0: # cs
team_CS["spawnpoints"].push_back(spawnpoint)
elif spawnpoint.team > 0: # os
team_OS["spawnpoints"].push_back(spawnpoint)
var spectator = preload("res://scenes/models/spectator.tscn").instantiate()
server_map.add_child(spectator)
func send_scores():
NetUtils.send_everyone(["update_round_status", {
"cs_round_score" = team_CS["round_score"],
"os_round_score" = team_OS["round_score"],
"os_game_score" = team_OS["game_score"],
"cs_game_score" = team_CS["game_score"],
"round_number" = round_number,
}])
func switch_gamemode(new_gamemode):
if not ServerUtils.check_gamemode_availability(new_gamemode):
print("No gamemode found")
return
gamemode = new_gamemode
func parse_arguments():
var arguments = {}
for argument in OS.get_cmdline_args():
if argument.find("=") > -1:
var key_value = argument.split("=")
arguments[key_value[0].lstrip("--")] = key_value[1]
else:
# Options without an argument will be present in the dictionary,
# with the value set to an empty string.
arguments[argument.lstrip("--")] = ""
return arguments
func setup_server():
var arguments = parse_arguments()
GameData.read_settings()
################ parsing map
var path = "res://scenes/maps/%s.tscn" % arguments["map"] if arguments.has("map") else "res://scenes/maps/%s.tscn" % GameData.server_settings["defaults"]["map"]
if (ServerUtils.check_map_availability(path)):
map_path = path
else:
print("Unknown map %s Available maps:" % path)
for map in DirAccess.open("res://scenes/maps").get_files():
print(str(map.split(".")[0]))
get_tree().quit()
return
################ parsing gamemode
var gm = str(arguments["gamemode"]) if (arguments.has("gamemode")) else "TDM"
if (ServerUtils.check_gamemode_availability(gm)):
print("Gamemode exists")
else:
print("No")
await new_game(map_path, gm)
var spectator = preload("res://scenes/models/spectator.tscn").instantiate()
server_map.add_child(spectator)
Networking.StartServer()
func _ready():
if "--server" in OS.get_cmdline_args():
setup_server()