Files
UT99-Official/DoConfig.py
2022-07-05 06:31:24 +00:00

371 lines
13 KiB
Python
Executable File

#!/usr/bin/env python3
"""
ChaCha DoConfig script
"""
import argparse
from enum import Enum
from dataclasses import dataclass
from collections import OrderedDict
from os.path import join
from pprint import pprint
from ChaChaSimpleINI import ChaChaSimpleINI
from abc import ABCMeta,abstractmethod
class OptionType(Enum):
OT_INVALID = 0
OT_STRING = 1
OT_INTEGER = 2
OT_BOOLEAN = 3
OT_FLOAT = 4
class GameOption(metaclass=ABCMeta):
szGameType:str = ""
szOptionName:str = ""
TValueType:OptionType = OptionType.OT_INVALID
szDefaultValue:str = ""
szHelp:str = ""
@abstractmethod
def __init__(self,GameRootDir:str,ConfigFileRelPath:str=None):
self.GameRootDir = GameRootDir
self.ConfigFileRelPath = ConfigFileRelPath
def set(self,value:str):
print("set option <{0}> to: {1}".format(self.szOptionName,value))
if self.TValueType == OptionType.OT_STRING:
value = str(value)
elif self.TValueType == OptionType.OT_INTEGER:
value = int(value)
elif self.TValueType == OptionType.OT_BOOLEAN:
value = bool(value)
elif self.TValueType == OptionType.OT_FLOAT:
value = float(value)
else:
raise RuntimeError("Invalid Option TValueType")
self.setAddKeyValue(value)
@abstractmethod
def set(self,value):
raise NotImplementedError("method not implemented")
@abstractmethod
def rem(self,value):
raise NotImplementedError("method not implemented")
@abstractmethod
def get(self,inifile:ChaChaSimpleINI):
raise NotImplementedError("method not implemented")
class GameOptions_Factory:
ar_Options_cls = []
def __init__(self,szGameType:str,GameRootDir:str,ConfigFileRelPath:str=None):
self.szGameType = szGameType
self.ar_Options = []
for Options_cls in self.ar_Options_cls:
if Options_cls.szGameType == szGameType:
self.ar_Options.append(Options_cls(GameRootDir,ConfigFileRelPath))
@classmethod
def GameOptionRegister(cls,Option:GameOption):
cls.ar_Options_cls.append(Option)
def set(cls,OptionName:str,value:str):
for _option in cls.ar_Options:
if _option.szOptionName==OptionName:
_option.set(value)
return
raise RuntimeError("Option not found")
def rem(cls,OptionName:str,value:str):
for _option in cls.ar_Options:
if _option.szOptionName==OptionName:
_option.rem(value)
return
raise RuntimeError("Option not found")
def get(cls,OptionName:str) -> str:
for _option in cls.ar_Options:
if _option.szOptionName==OptionName:
return _option.get()
raise RuntimeError("Option not found")
def GameOptions_Factory_Register(cls):
GameOptions_Factory.GameOptionRegister(cls)
return cls
class GameOption_UT99(GameOption):
szGameType = "ut99"
TValueType = OptionType.OT_INVALID
szOptionName = ""
szSectionName = ""
szKeyName = ""
bForceAdd:bool = False
bRemovable:bool = False
def __init__(self,GameRootDir:str,ConfigFileRelPath:str):
super().__init__(GameRootDir,ConfigFileRelPath)
self. mainConfigFilePath = join(GameRootDir,ConfigFileRelPath)
def set(self,value:str):
if not self.szOptionName:
raise RuntimeError("szOptionName is not set")
inifile = ChaChaSimpleINI(self. mainConfigFilePath)
inifile.setAddKeyValue(self.szSectionName,self.szKeyName,value,self.bForceAdd)
inifile.writeFile()
def rem(self,value:str):
if not self.szOptionName:
raise RuntimeError("szOptionName is not set")
if not self.bRemovable:
raise RuntimeError("this options is not removable")
inifile = ChaChaSimpleINI(self. mainConfigFilePath)
inifile.delKeyEx(self.szSectionName,self.szKeyName,None,value)
inifile.writeFile()
def get(self):
if not self.szOptionName:
raise RuntimeError("szOptionName not set")
print("get option <{0}>".format(self.szOptionName))
inifile = ChaChaSimpleINI(self. mainConfigFilePath)
res = inifile.getKeyValue(self.szSectionName,self.szKeyName)
return res
class GameOption_UT99_GenAdd(GameOption_UT99):
bForceAdd = True
@GameOptions_Factory_Register
class GameOption_UT99_ServerPackages(GameOption_UT99_GenAdd):
szOptionName = "ServerPackages"
szSectionName = "Engine.GameEngine"
szKeyName = "ServerPackages"
TValueType = OptionType.OT_STRING
szHelp = "Add a ServerPackages record"
bRemovable = True
@GameOptions_Factory_Register
class GameOption_UT99_ServerActors(GameOption_UT99_GenAdd):
szOptionName = "ServerActors"
szSectionName = "Engine.GameEngine"
szKeyName = "ServerActors"
TValueType = OptionType.OT_STRING
szHelp = "Add a ServerActors record"
bRemovable = True
@GameOptions_Factory_Register
class GameOption_UT99_Port(GameOption_UT99):
szOptionName = "Port"
szSectionName = "URL"
szKeyName = "Port"
TValueType = OptionType.OT_INTEGER
szDefaultValue = "7777"
szHelp = "Server Listening port"
@GameOptions_Factory_Register
class GameOption_UT99_Map(GameOption_UT99):
szOptionName = "Map"
szSectionName = "URL"
szKeyName = "Map"
TValueType = OptionType.OT_STRING
szDefaultValue = "dm-deck16]["
szHelp = "Server Map"
@GameOptions_Factory_Register
class GameOption_UT99_GameType(GameOption_UT99):
szOptionName = "GameType"
szSectionName = "Engine.Engine"
szKeyName = "DefaultServerGame"
TValueType = OptionType.OT_STRING
szDefaultValue = "Botpack.DeathMatchPlus"
szHelp = "Server Gametype"
@GameOptions_Factory_Register
class GameOption_UT99_HostName(GameOption_UT99):
szOptionName = "HostName"
szSectionName = "Engine.GameReplicationInfo"
szKeyName = "ServerName"
TValueType = OptionType.OT_STRING
szDefaultValue = "ChaCha Test Server"
szHelp = "Server's HostName"
def set(self,value:str):
super().set(value)
self.inifile.setAddKeyValue("Engine.GameReplicationInfo","ShortName",value)
@GameOptions_Factory_Register
class GameOption_UT99_MOTD(GameOption_UT99):
szOptionName = "MOTD"
szSectionName = "Engine.GameReplicationInfo"
szKeyName = "MOTDLine1"
TValueType = OptionType.OT_STRING
szDefaultValue = "Welcome to ChaCha's server"
szHelp = "Message of the day"
@GameOptions_Factory_Register
class GameOption_UT99_MOTD2(GameOption_UT99):
szOptionName = "MOTD2"
szSectionName = "Engine.GameReplicationInfo"
szKeyName = "MOTDLine2"
TValueType = OptionType.OT_STRING
szDefaultValue = "Enjoy your stay and have fun"
szHelp = "Message of the day (2)"
@GameOptions_Factory_Register
class GameOption_UT99_AdminEmail(GameOption_UT99):
szOptionName = "AdminEmail"
szSectionName = "Engine.GameReplicationInfo"
szKeyName = "AdminEmail"
TValueType = OptionType.OT_STRING
szDefaultValue = "chachacorp@protonmail.com"
szHelp = "Admin mail"
@GameOptions_Factory_Register
class GameOption_UT99_AdminName(GameOption_UT99):
szOptionName = "AdminName"
szSectionName = "Engine.GameReplicationInfo"
szKeyName = "AdminName"
TValueType = OptionType.OT_STRING
szDefaultValue = "chacha"
szHelp = "Admin name"
def set(self,value:str):
super().set(value)
self.inifile.setAddKeyValue("UTServerAdmin.UTServerAdmin","AdminUsername",value)
@GameOptions_Factory_Register
class GameOption_UT99_HTTPDownloadServer(GameOption_UT99):
szOptionName = "HTTPDownloadServer"
szSectionName = "IpDrv.HTTPDownload"
szKeyName = "RedirectToURL"
TValueType = OptionType.OT_STRING
szDefaultValue = "http://chacha.ddns.net/games/ut99"
szHelp = "FastDL url"
def set(self,value:str):
super().set(value)
self.inifile.setAddKeyValue("IpDrv.HTTPDownload","UseCompression","True")
self.inifile.delKey("IpDrv.HTTPDownload","ProxyServerHost")
self.inifile.delKey("IpDrv.HTTPDownload","ProxyServerPort")
@GameOptions_Factory_Register
class GameOption_UT99_MaxClientRate(GameOption_UT99):
szOptionName = "MaxClientRate"
szSectionName = "IpDrv.TcpNetDriver"
szKeyName = "MaxClientRate"
TValueType = OptionType.OT_INTEGER
szDefaultValue = "20000"
szHelp = "Max Client Rate"
@GameOptions_Factory_Register
class GameOption_UT99_NetServerMaxTickRate(GameOption_UT99):
szOptionName = "NetServerMaxTickRate"
szSectionName = "IpDrv.TcpNetDriver"
szKeyName = "NetServerMaxTickRate"
TValueType = OptionType.OT_INTEGER
szDefaultValue = "60"
szHelp = "Server Max TickRate"
@GameOptions_Factory_Register
class GameOption_UT99_LanServerMaxTickRate(GameOption_UT99):
szOptionName = "LanServerMaxTickRate"
szSectionName = "IpDrv.TcpNetDriver"
szKeyName = "LanServerMaxTickRate"
TValueType = OptionType.OT_INTEGER
szDefaultValue = "60"
szHelp = "Lan Server Max TickRate"
@GameOptions_Factory_Register
class GameOption_UT99_AdminPassword(GameOption_UT99):
szOptionName = "AdminPassword"
szSectionName = "Engine.GameInfo"
szKeyName = "AdminPassword"
TValueType = OptionType.OT_STRING
szDefaultValue = "cfographut"
szHelp = "Admin password"
def set(self,value:str):
super().set(value)
self.inifile.setAddKeyValue("UTServerAdmin.UTServerAdmin","AdminPassword",value)
@GameOptions_Factory_Register
class GameOption_UT99_GamePassword(GameOption_UT99):
szOptionName = "GamePassword"
szSectionName = "Engine.GameInfo"
szKeyName = "GamePassword"
TValueType = OptionType.OT_STRING
szDefaultValue = ""
szHelp = "Game password"
@GameOptions_Factory_Register
class GameOption_UT99_MaxPlayers(GameOption_UT99):
szOptionName = "MaxPlayers"
szSectionName = "Engine.GameInfo"
szKeyName = "MaxPlayers"
TValueType = OptionType.OT_INTEGER
szDefaultValue = "20"
szHelp = "Max Players"
@GameOptions_Factory_Register
class GameOption_UT99_ServerLogName(GameOption_UT99):
szOptionName = "ServerLogName"
szSectionName = "Engine.GameInfo"
szKeyName = "ServerLogName"
TValueType = OptionType.OT_STRING
szDefaultValue = "server.log"
szHelp = "Server Log Name"
@GameOptions_Factory_Register
class GameOption_UT99_WebServer(GameOption_UT99):
szOptionName = "WebServer"
szSectionName = "UWeb.WebServer"
szKeyName = "ListenPort"
TValueType = OptionType.OT_INTEGER
szDefaultValue = "8076"
szHelp = "enable Web Server"
def set(self,value:str):
super().set(value)
if int(value) > 0:
self.inifile.setAddKeyValue("UWeb.WebServer","bEnabled","True")
else:
self.inifile.setAddKeyValue("UWeb.WebServer","bEnabled","False")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("-v", "--verbosity", action="count", default=0,
help="increase output verbosity")
parser.add_argument("-b", "--basegamedir", help="set the game base dir", default="./")
parser.add_argument("-c", "--configfile", help="set the default config file",default="./System/UnrealTournament.ini")
subparsers = parser.add_subparsers(dest='command',help='command type',required=True)
SetOption_subparser = subparsers.add_parser("SetOption",help="Set/Add a game config file option value (may need reboot)")
SetOption_subparser.add_argument('option')
SetOption_subparser.add_argument('value')
RemOption_subparser = subparsers.add_parser("RemOption",help="Remove a game config file option, w or w/o value (may need reboot)")
RemOption_subparser.add_argument('option')
RemOption_subparser.add_argument('value')
GetOption_subparser = subparsers.add_parser("GetOption",help="Get a game config file option value")
GetOption_subparser.add_argument('option')
args=parser.parse_args()
if args.verbosity :
print("Using base game dir: {0}".format(args.basegamedir))
print("Using config file: {0}".format(args.configfile))
_GameOptions = GameOptions_Factory("ut99",args.basegamedir,args.configfile)
if args.command == "SetOption":
_GameOptions.set(args.option,args.value)
elif args.command == "RemOption":
_GameOptions.rem(args.option,args.value)
elif args.command == "GetOption":
res=_GameOptions.get(args.option)
print(res)
else:
raise RuntimeError("Invalid argument")