mirror of
https://git.zavage.net/Zavage-Software/smileyface.git
synced 2024-12-22 04:39:21 -07:00
first py impl of redirect lines, misc improvements
This commit is contained in:
parent
7b2643cf45
commit
a81e2d4c46
5
.gitignore
vendored
5
.gitignore
vendored
@ -1 +1,6 @@
|
||||
*.pak
|
||||
build/
|
||||
dist/
|
||||
__pycache__
|
||||
*.egg-info
|
||||
|
||||
|
0
edit-config.sh
Normal file → Executable file
0
edit-config.sh
Normal file → Executable file
51
files/rulesets/3-Duel-Beginner.json
Normal file
51
files/rulesets/3-Duel-Beginner.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"uniqueTag": "UTPlusDUELBeginner",
|
||||
"categories": [
|
||||
"Duel"
|
||||
],
|
||||
"title": "Duel (Beginners)",
|
||||
"toolTip": "Ultimate 1v1 test of deathmatch skill",
|
||||
"description": "1v1 Duel with shield timers\n\n<UT.Hub.RulesText_Small>Mutators: UT+, TeamSkins, WeaponSkins, HitSounds, CustomHUD</>\n<UT.Hub.RulesText_Small>Options: MaxPlayers=2, TimeLimit=10, WeaponStay=OFF, Amp=OFF, PickupTimers=ON</>",
|
||||
"mapPrefixes": [],
|
||||
"maxMapsInList": 0,
|
||||
"epicMaps": "/Game/RestrictedAssets/Maps/DM-Chill,/Game/RestrictedAssets/Maps/WIP/DM-ASDF,/Game/EpicInternal/Lea/DM-Lea,/Game/RestrictedAssets/Maps/WIP/DM-Solo,/Game/RestrictedAssets/Maps/WIP/DM-Decktest",
|
||||
"defaultMap": "/Game/RestrictedAssets/Maps/WIP/DM-ASDF",
|
||||
"customMapList": [
|
||||
"/Game/DM-BoneBone_Textured",
|
||||
"/Game/DM-Campgrounds-G1E/DM-Campgrounds-G1E",
|
||||
"/Game/DM-Coma/Maps/DM-Coma_A015",
|
||||
"/Game/Maps/DM-1/DM-Pure_vrc_3",
|
||||
"/Game/Maps/DM-Deep-03g",
|
||||
"/Game/Maps/DM-Erase/DM-EraseV2_a04",
|
||||
"/Game/Maps/DM-Fervor/DM-Fervor_V8",
|
||||
"/Game/Rankin/DM-Rankin-LE",
|
||||
"/Game/RestrictedAssets/Maps/DM-1on1-Roughinery",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-BoneCrusher_MC2",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Echo_b7",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Focus-LE",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-HyperBlast-UT99/DM-HyperBlast-UT99_metal-1",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Idoma-UT3/DM-Idoma",
|
||||
"/Game/_Ransom/Maps/DM-ChillShell-Abs-A/DM-ChillShell-Abs-A",
|
||||
"/Game/dc/Ironic/DM-Alanis"
|
||||
],
|
||||
"maxPlayers": 2,
|
||||
"maxTeamCount": 2,
|
||||
"maxTeamSize": 1,
|
||||
"maxPartySize": 1,
|
||||
"displayTexture": "Texture2D'/Game/RestrictedAssets/UI/GameModeBadges/GB_Duel.GB_Duel'",
|
||||
"gameMode" : "/Script/UnrealTournament.UTDuelGame",
|
||||
"gameOptions" : "?MaxPlayers=2?TimeLimit=10?ignoreidle=1?GoalScore=0?ForceNoBots=1?ForceRespawn=1?mutator=UTPlus,UTPlusMovement,MutHitsounds,MutTeamskins,WeaponSkins,CustomHUD,WeaponReplacement?WTR=/Game/UT+/UTPlus/UT+GrenadeLauncher.UT+GrenadeLauncher_C:/Game/UT+/UTPlus/UT+BioRifle.UT+BioRifle_C?",
|
||||
"requiredPackages" : [
|
||||
"CustomHUD",
|
||||
"MutHitSounds",
|
||||
"MutTeamSkins",
|
||||
"WeaponSkins",
|
||||
"UTPlus",
|
||||
"UTPlusMovement"
|
||||
],
|
||||
"bTeamGame": true,
|
||||
"bCompetitiveMatch": false,
|
||||
"optionFlags": 65535,
|
||||
"bHideFromUI": false,
|
||||
"epicForceUIVisibility": 0
|
||||
},
|
52
files/rulesets/3-Duel-ProMode-noGL.json
Normal file
52
files/rulesets/3-Duel-ProMode-noGL.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"uniqueTag": "MYDUELnogl",
|
||||
"categories": [
|
||||
"Duel"
|
||||
],
|
||||
"title": "ProMode Duel noGL",
|
||||
"toolTip": "Ultimate 1v1 test of deathmatch skill",
|
||||
"description": "1v1 Duel (with ProMode Movement and Weapon Stats)\n\n<UT.Hub.RulesText_Small>Mutators: ProMode, TeamSkins, WeaponSkins, HitSounds, CustomHUD</>\n<UT.Hub.RulesText_Small>Options: MaxPlayers=2, TimeLimit=10, WeaponStay=OFF, Amp=OFF*, PickupTimers=OFF</>",
|
||||
"mapPrefixes": [],
|
||||
"maxMapsInList": 0,
|
||||
"epicMaps": "/Game/RestrictedAssets/Maps/DM-Chill,/Game/RestrictedAssets/Maps/WIP/DM-ASDF,/Game/EpicInternal/Lea/DM-Lea,/Game/RestrictedAssets/Maps/WIP/DM-Solo,/Game/RestrictedAssets/Maps/WIP/DM-Decktest",
|
||||
"defaultMap": "/Game/RestrictedAssets/Maps/WIP/DM-ASDF",
|
||||
"customMapList": [
|
||||
"/Game/DM-BoneBone_Textured",
|
||||
"/Game/DM-Campgrounds-G1E/DM-Campgrounds-G1E",
|
||||
"/Game/DM-Coma/Maps/DM-Coma_A015",
|
||||
"/Game/Maps/DM-1/DM-Pure_vrc_3",
|
||||
"/Game/Maps/DM-Deep-03g",
|
||||
"/Game/Maps/DM-Erase/DM-EraseV2_a04",
|
||||
"/Game/Maps/DM-Fervor/DM-Fervor_V8",
|
||||
"/Game/Rankin/DM-Rankin-LE",
|
||||
"/Game/RestrictedAssets/Maps/DM-1on1-Roughinery",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-BoneCrusher_MC2",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Echo_b7",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Focus-LE",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-HyperBlast-UT99/DM-HyperBlast-UT99_metal-1",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Idoma-UT3/DM-Idoma",
|
||||
"/Game/_Ransom/Maps/DM-ChillShell-Abs-A/DM-ChillShell-Abs-A",
|
||||
"/Game/dc/Ironic/DM-Alanis"
|
||||
],
|
||||
"maxPlayers": 2,
|
||||
"maxTeamCount": 2,
|
||||
"maxTeamSize": 1,
|
||||
"maxPartySize": 1,
|
||||
"displayTexture": "Texture2D'/Game/RestrictedAssets/UI/GameModeBadges/GB_Duel.GB_Duel'",
|
||||
"gameMode" : "/Script/UnrealTournament.UTDuelGame",
|
||||
"gameOptions" : "?MaxPlayers=2?TimeLimit=10?ignoreidle=1?GoalScore=0?ForceNoBots=1?ForceRespawn=1?WTR=/Game/ProMode/Weapons/Pro_GrenadeLauncher.Pro_GrenadeLauncher_C:/Game/Proctf/Weapons/Proctf/Weapons/bp2_Orig_BioRifle.bp2_Orig_BioRifle_C?mutator=ProMode,MutHitsounds,MutTeamSkins,WeaponSkins,CustomHUD,NoPickupTimerMutator,WeaponReplacement",
|
||||
"requiredPackages" : [
|
||||
"CustomHUD",
|
||||
"MutHitSounds",
|
||||
"MutTeamSkins",
|
||||
"ProMovement",
|
||||
"ProWeapons",
|
||||
"WeaponSkins",
|
||||
"NoPickupTimerMutator"
|
||||
],
|
||||
"bTeamGame": true,
|
||||
"bCompetitiveMatch": false,
|
||||
"optionFlags": 65535,
|
||||
"bHideFromUI": false,
|
||||
"epicForceUIVisibility": 0
|
||||
},
|
52
files/rulesets/3-Duel-ProMode.json
Normal file
52
files/rulesets/3-Duel-ProMode.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"uniqueTag": "MYDUEL",
|
||||
"categories": [
|
||||
"Duel"
|
||||
],
|
||||
"title": "ProMode Duel",
|
||||
"toolTip": "Ultimate 1v1 test of deathmatch skill",
|
||||
"description": "1v1 Duel (with ProMode Movement and Weapon Stats)\n\n<UT.Hub.RulesText_Small>Mutators: ProMode, TeamSkins, WeaponSkins, HitSounds, CustomHUD</>\n<UT.Hub.RulesText_Small>Options: MaxPlayers=2, TimeLimit=10, WeaponStay=OFF, Amp=OFF*, PickupTimers=OFF</>",
|
||||
"mapPrefixes": [],
|
||||
"maxMapsInList": 0,
|
||||
"epicMaps": "/Game/RestrictedAssets/Maps/DM-Chill,/Game/RestrictedAssets/Maps/WIP/DM-ASDF,/Game/EpicInternal/Lea/DM-Lea,/Game/RestrictedAssets/Maps/WIP/DM-Solo,/Game/RestrictedAssets/Maps/WIP/DM-Decktest",
|
||||
"defaultMap": "/Game/RestrictedAssets/Maps/WIP/DM-ASDF",
|
||||
"customMapList": [
|
||||
"/Game/DM-BoneBone_Textured",
|
||||
"/Game/DM-Campgrounds-G1E/DM-Campgrounds-G1E",
|
||||
"/Game/DM-Coma/Maps/DM-Coma_A015",
|
||||
"/Game/Maps/DM-1/DM-Pure_vrc_3",
|
||||
"/Game/Maps/DM-Deep-03g",
|
||||
"/Game/Maps/DM-Erase/DM-EraseV2_a04",
|
||||
"/Game/Maps/DM-Fervor/DM-Fervor_V8",
|
||||
"/Game/Rankin/DM-Rankin-LE",
|
||||
"/Game/RestrictedAssets/Maps/DM-1on1-Roughinery",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-BoneCrusher_MC2",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Echo_b7",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Focus-LE",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-HyperBlast-UT99/DM-HyperBlast-UT99_metal-1",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Idoma-UT3/DM-Idoma",
|
||||
"/Game/_Ransom/Maps/DM-ChillShell-Abs-A/DM-ChillShell-Abs-A",
|
||||
"/Game/dc/Ironic/DM-Alanis"
|
||||
],
|
||||
"maxPlayers": 2,
|
||||
"maxTeamCount": 2,
|
||||
"maxTeamSize": 1,
|
||||
"maxPartySize": 1,
|
||||
"displayTexture": "Texture2D'/Game/RestrictedAssets/UI/GameModeBadges/GB_Duel.GB_Duel'",
|
||||
"gameMode" : "/Script/UnrealTournament.UTDuelGame",
|
||||
"gameOptions" : "?MaxPlayers=2?TimeLimit=10?ignoreidle=1?GoalScore=0?ForceNoBots=1?ForceRespawn=1?mutator=ProMovement,ProWeapons,MutHitsounds,MutTeamSkins,WeaponSkins,CustomHUD,NoPickupTimerMutator",
|
||||
"requiredPackages" : [
|
||||
"CustomHUD",
|
||||
"MutHitSounds",
|
||||
"MutTeamSkins",
|
||||
"ProMovement",
|
||||
"ProWeapons",
|
||||
"WeaponSkins",
|
||||
"NoPickupTimerMutator"
|
||||
],
|
||||
"bTeamGame": true,
|
||||
"bCompetitiveMatch": false,
|
||||
"optionFlags": 65535,
|
||||
"bHideFromUI": false,
|
||||
"epicForceUIVisibility": 0
|
||||
},
|
53
files/rulesets/3-Duel-UTplus-noGL.json
Normal file
53
files/rulesets/3-Duel-UTplus-noGL.json
Normal file
@ -0,0 +1,53 @@
|
||||
{
|
||||
"uniqueTag": "UTPlusDUELnogl",
|
||||
"categories": [
|
||||
"Duel"
|
||||
],
|
||||
"title": "UT+ Duel noGL",
|
||||
"toolTip": "Ultimate 1v1 test of deathmatch skill",
|
||||
"description": "1v1 Duel (with UT+ Movement and Weapon Stats)\n\n<UT.Hub.RulesText_Small>Mutators: UT+, TeamSkins, WeaponSkins, HitSounds, CustomHUD</>\n<UT.Hub.RulesText_Small>Options: MaxPlayers=2, TimeLimit=10, WeaponStay=OFF, Amp=OFF, PickupTimers=OFF</>",
|
||||
"mapPrefixes": [],
|
||||
"maxMapsInList": 0,
|
||||
"epicMaps": "/Game/RestrictedAssets/Maps/DM-Chill,/Game/RestrictedAssets/Maps/WIP/DM-ASDF,/Game/EpicInternal/Lea/DM-Lea,/Game/RestrictedAssets/Maps/WIP/DM-Solo,/Game/RestrictedAssets/Maps/WIP/DM-Decktest",
|
||||
"defaultMap": "/Game/RestrictedAssets/Maps/WIP/DM-ASDF",
|
||||
"customMapList": [
|
||||
"/Game/DM-BoneBone_Textured",
|
||||
"/Game/DM-Campgrounds-G1E/DM-Campgrounds-G1E",
|
||||
"/Game/DM-Coma/Maps/DM-Coma_A015",
|
||||
"/Game/Maps/DM-1/DM-Pure_vrc_3",
|
||||
"/Game/Maps/DM-Deep-03g",
|
||||
"/Game/Maps/DM-Erase/DM-EraseV2_a04",
|
||||
"/Game/Maps/DM-Fervor/DM-Fervor_V8",
|
||||
"/Game/Rankin/DM-Rankin-LE",
|
||||
"/Game/RestrictedAssets/Maps/DM-1on1-Roughinery",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-BoneCrusher_MC2",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Echo_b7",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Focus-LE",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-HyperBlast-UT99/DM-HyperBlast-UT99_metal-1",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Idoma-UT3/DM-Idoma",
|
||||
"/Game/_Ransom/Maps/DM-ChillShell-Abs-A/DM-ChillShell-Abs-A",
|
||||
"/Game/dc/Ironic/DM-Alanis"
|
||||
],
|
||||
"maxPlayers": 2,
|
||||
"maxTeamCount": 2,
|
||||
"maxTeamSize": 1,
|
||||
"maxPartySize": 1,
|
||||
"displayTexture": "Texture2D'/Game/RestrictedAssets/UI/GameModeBadges/GB_Duel.GB_Duel'",
|
||||
"gameMode" : "/Script/UnrealTournament.UTDuelGame",
|
||||
"gameOptions" : "?MaxPlayers=2?TimeLimit=10?ignoreidle=1?GoalScore=0?MaxSpecators=10?ForceNoBots=1?ForceRespawn=1?mutator=UTPlus,UTPlusMovement,MutHitsounds,MutTeamskins,WeaponSkins,CustomHUD,NoPickupTimerMutator,WeaponReplacement?WTR=/Game/UT+/UTPlus/UT+GrenadeLauncher.UT+GrenadeLauncher_C:/Game/UT+/UTPlus/UT+BioRifle.UT+BioRifle_C?",
|
||||
"requiredPackages" : [
|
||||
"CustomHUD",
|
||||
"MutHitSounds",
|
||||
"MutTeamskins",
|
||||
"WeaponSkins",
|
||||
"UTPlus",
|
||||
"UTPlusMovement",
|
||||
"NoPickupTimerMutator"
|
||||
],
|
||||
"bTeamGame": true,
|
||||
"bCompetitiveMatch": false,
|
||||
"optionFlags": 65535,
|
||||
"bHideFromUI": false,
|
||||
"minPlayersToStart": 2,
|
||||
"epicForceUIVisibility": 0
|
||||
},
|
52
files/rulesets/3-Duel-UTplus.json
Normal file
52
files/rulesets/3-Duel-UTplus.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"uniqueTag": "UTPlusDUEL",
|
||||
"categories": [
|
||||
"Duel"
|
||||
],
|
||||
"title": "UT+ Duel",
|
||||
"toolTip": "Ultimate 1v1 test of deathmatch skill",
|
||||
"description": "1v1 Duel (with UT+ Movement and Weapon Stats)\n\n<UT.Hub.RulesText_Small>Mutators: UT+, TeamSkins, WeaponSkins, HitSounds, CustomHUD</>\n<UT.Hub.RulesText_Small>Options: MaxPlayers=2, TimeLimit=10, WeaponStay=OFF, Amp=OFF, PickupTimers=OFF</>",
|
||||
"mapPrefixes": [],
|
||||
"maxMapsInList": 0,
|
||||
"epicMaps": "/Game/RestrictedAssets/Maps/DM-Chill,/Game/RestrictedAssets/Maps/WIP/DM-ASDF,/Game/EpicInternal/Lea/DM-Lea,/Game/RestrictedAssets/Maps/WIP/DM-Solo,/Game/RestrictedAssets/Maps/WIP/DM-Decktest",
|
||||
"defaultMap": "/Game/RestrictedAssets/Maps/WIP/DM-ASDF",
|
||||
"customMapList": [
|
||||
"/Game/DM-BoneBone_Textured",
|
||||
"/Game/DM-Campgrounds-G1E/DM-Campgrounds-G1E",
|
||||
"/Game/DM-Coma/Maps/DM-Coma_A015",
|
||||
"/Game/Maps/DM-1/DM-Pure_vrc_3",
|
||||
"/Game/Maps/DM-Deep-03g",
|
||||
"/Game/Maps/DM-Erase/DM-EraseV2_a04",
|
||||
"/Game/Maps/DM-Fervor/DM-Fervor_V8",
|
||||
"/Game/Rankin/DM-Rankin-LE",
|
||||
"/Game/RestrictedAssets/Maps/DM-1on1-Roughinery",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-BoneCrusher_MC2",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Echo_b7",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Focus-LE",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-HyperBlast-UT99/DM-HyperBlast-UT99_metal-1",
|
||||
"/Game/RestrictedAssets/Maps/WIP/DM-Idoma-UT3/DM-Idoma",
|
||||
"/Game/_Ransom/Maps/DM-ChillShell-Abs-A/DM-ChillShell-Abs-A",
|
||||
"/Game/dc/Ironic/DM-Alanis"
|
||||
],
|
||||
"maxPlayers": 2,
|
||||
"maxTeamCount": 2,
|
||||
"maxTeamSize": 1,
|
||||
"maxPartySize": 1,
|
||||
"displayTexture": "Texture2D'/Game/RestrictedAssets/UI/GameModeBadges/GB_Duel.GB_Duel'",
|
||||
"gameMode" : "/Script/UnrealTournament.UTDuelGame",
|
||||
"gameOptions" : "?MaxPlayers=2?TimeLimit=10?ignoreidle=1?GoalScore=0?ForceNoBots=1?ForceRespawn=1?mutator=UTPlus,UTPlusMovement,MutHitsounds,MutTeamskins,WeaponSkins,CustomHUD,NoPickupTimerMutator",
|
||||
"requiredPackages" : [
|
||||
"CustomHUD",
|
||||
"MutHitSounds",
|
||||
"MutTeamSkins",
|
||||
"WeaponSkins",
|
||||
"UTPlus",
|
||||
"UTPlusMovement",
|
||||
"NoPickupTimerMutator"
|
||||
],
|
||||
"bTeamGame": true,
|
||||
"bCompetitiveMatch": false,
|
||||
"optionFlags": 65535,
|
||||
"bHideFromUI": false,
|
||||
"epicForceUIVisibility": 0
|
||||
},
|
38
setup.py
38
setup.py
@ -1,25 +1,16 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# First, enable the python environment you want to install to, or if installing
|
||||
# system-wide then ensure you're logged in with sufficient permissions
|
||||
# (admin or root to install to system directories)
|
||||
#
|
||||
# installation:
|
||||
#
|
||||
# $ ./setup.py install
|
||||
#
|
||||
# de-installation:
|
||||
#
|
||||
# $ pip uninstall <app>
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
__project__ = 'SmileyFace UT4 Server Panel'
|
||||
__project__ = 'SmileyFace UT4 Hub Automator'
|
||||
__version__ = '0.1.0'
|
||||
|
||||
app_skellington_requirements = (
|
||||
'appdirs',
|
||||
'colorlog',
|
||||
'configobj',
|
||||
)
|
||||
|
||||
setup(
|
||||
name = __project__,
|
||||
version = __version__,
|
||||
@ -30,13 +21,12 @@ setup(
|
||||
|
||||
# Third-party dependencies; will be automatically installed
|
||||
install_requires = (
|
||||
'app_skellington'
|
||||
),
|
||||
|
||||
# Local packages to be installed (our packages)
|
||||
packages = (
|
||||
'smileyface',
|
||||
),
|
||||
'rdiff-backup',
|
||||
) + app_skellington_requirements,
|
||||
|
||||
packages = find_packages(),
|
||||
package_dir = {
|
||||
'app_skellington': 'lib/app_skellington'
|
||||
},
|
||||
)
|
||||
|
||||
|
10
smileyface/_util.py
Normal file
10
smileyface/_util.py
Normal file
@ -0,0 +1,10 @@
|
||||
import hashlib
|
||||
|
||||
def md5sum_file(filename):
|
||||
with open(filename, mode='rb') as f:
|
||||
d = hashlib.md5()
|
||||
for buf in iter(partial(f.read, 128), b''):
|
||||
d.update(buf)
|
||||
h = d.hexdigest()
|
||||
return h
|
||||
|
@ -1,56 +1,41 @@
|
||||
from . import hub_machine
|
||||
|
||||
import app_skellington
|
||||
from app_skellington import _util
|
||||
|
||||
from . import model
|
||||
|
||||
class SmileyFace(app_skellington.ApplicationContainer):
|
||||
def __init__(self, *args, **kwargs):
|
||||
filename = 'config.spec'
|
||||
self.configspec_filepath = _util.get_asset(__name__, filename)
|
||||
|
||||
config_filepath = self._get_config_filepath(
|
||||
'smileyface-ut4',
|
||||
'app_author',
|
||||
'hub-config.ini'
|
||||
)
|
||||
|
||||
super().__init__(
|
||||
configspec_filepath=self.configspec_filepath,
|
||||
config_filepath=config_filepath,
|
||||
app_name = 'SmileyFace UT4 Server Panel',
|
||||
app_author = 'Mathew Guest',
|
||||
app_version = '0.1',
|
||||
*args,
|
||||
**kwargs
|
||||
)
|
||||
# super().__init__(
|
||||
# app_name = 'SmileyFace UT4 Server Panel',
|
||||
# app_author = 'Mathew Guest',
|
||||
# app_version = '0.1'
|
||||
# )
|
||||
self._load_config()
|
||||
|
||||
def _load_config(self, config_file=None):
|
||||
"""
|
||||
Parse the config file, (todo) environment variables, and command-line
|
||||
arguments to determine runtime configuration.
|
||||
"""
|
||||
if config_file is None:
|
||||
config_file = self._get_config_filepath(
|
||||
'smileyface-ut4',
|
||||
'app_author',
|
||||
'hub-config.ini'
|
||||
)
|
||||
|
||||
rc = self.ctx.config.load_config_from_file(config_file)
|
||||
|
||||
def _cli_options(self):
|
||||
pass
|
||||
|
||||
def _command_menu(self):
|
||||
sm_root = self.cli.init_submenu('command')
|
||||
# sm_root.register_command(model.foo)
|
||||
# sm_root.register_command(model.bar)
|
||||
_util.register_class_as_commands(
|
||||
self, sm_root,
|
||||
model.UT4ServerMachine
|
||||
hub_machine.UT4ServerMachine
|
||||
)
|
||||
|
||||
def _services(self):
|
||||
self['model'] = lambda: model.UTServerMachine(self.ctx)
|
||||
self['model'] = lambda: hub_machine.UTServerMachine(self.ctx)
|
||||
|
||||
def interactive_shell(self):
|
||||
pass
|
||||
|
82
smileyface/config_editor.py
Normal file
82
smileyface/config_editor.py
Normal file
@ -0,0 +1,82 @@
|
||||
import configparser
|
||||
import re
|
||||
|
||||
class UnrealIniFile:
|
||||
def __init__(self, filename=None):
|
||||
self._config = None
|
||||
self.filename = filename
|
||||
|
||||
@property
|
||||
def filename(self):
|
||||
return self._filename
|
||||
|
||||
@filename.setter
|
||||
def filename(self, val):
|
||||
self._filename = val
|
||||
if val is not None:
|
||||
self._config = configparser.RawConfigParser(
|
||||
strict=False
|
||||
)
|
||||
self._config.optionxform = str # Trick to preserve case in key names
|
||||
self._config.read(self._filename)
|
||||
|
||||
class GameIniSpecial:
|
||||
def __init__(self, filename):
|
||||
self._redirect_lines = []
|
||||
self._filename = None
|
||||
self.filename = filename
|
||||
|
||||
@property
|
||||
def filename(self):
|
||||
return self._filename
|
||||
|
||||
@filename.setter
|
||||
def filename(self, val):
|
||||
self._filename = val
|
||||
|
||||
def clear_redirect_references(self):
|
||||
self._redirect_lines = []
|
||||
|
||||
def add_redirect_reference(
|
||||
self, pkg_basename, redirect_url, redirect_protocol,
|
||||
relative_path, md5sum
|
||||
):
|
||||
args = {
|
||||
'pkg_basename': pkg_basename,
|
||||
'redirect_protocol': redirect_protocol,
|
||||
'redirect_url': redirect_url,
|
||||
'relative_path': relative_path,
|
||||
'md5sum': md5sum
|
||||
}
|
||||
########### START multi-line awkward indent
|
||||
line = '\
|
||||
RedirectReferences=(PackageName="{pkg_basename}",\
|
||||
PackageURLProtocol="{redirect_protocol}",\
|
||||
PackageURL="{redirect_url}/{relative_path}",\
|
||||
PackageChecksum="{md5sum}")'.format(**args)
|
||||
########### END multi-line awkward indent
|
||||
|
||||
return self.add_redirect_reference_line(line)
|
||||
|
||||
def add_redirect_reference_line(self, line):
|
||||
self._redirect_lines.append(line)
|
||||
return line
|
||||
|
||||
def write(self, fp):
|
||||
newcontents = None
|
||||
|
||||
with open(self.filename, 'r') as inifile:
|
||||
curcontents = inifile.read()
|
||||
lines_str = '\n'.join(self._redirect_lines)
|
||||
|
||||
newcontents = re.sub(
|
||||
'RedirectReferences = :PARAM:',
|
||||
lines_str,
|
||||
curcontents
|
||||
)
|
||||
has_data = True
|
||||
|
||||
if has_data:
|
||||
with open(self.filename, 'w') as fp:
|
||||
fp.write(newcontents)
|
||||
|
@ -1,3 +1,7 @@
|
||||
from .config_editor import UnrealIniFile, GameIniSpecial
|
||||
from . import config_editor
|
||||
from . import _util
|
||||
|
||||
from app_skellington import _util
|
||||
from functools import partial
|
||||
import collections
|
||||
@ -80,7 +84,6 @@ rsync -ravzp {remote_game_host}:{remote_game_dir}/LinuxServer/UnrealTournament/S
|
||||
})
|
||||
self._invoke_command(cmd)
|
||||
|
||||
|
||||
# Delete logs on remote game server if successfully transferred to local:
|
||||
self.ctx.log['ut4'].info('')
|
||||
cmd = '''
|
||||
@ -252,14 +255,26 @@ ssh {remote_game_host} chown ut4.ut4 {remote_game_dir} -R
|
||||
config_dir = self.ctx.config['app']['config_dir']
|
||||
for fn in files:
|
||||
self.ctx.log['ut4'].info('Installing file: %s', fn)
|
||||
# src = '/'.join([config_dir, fn])
|
||||
# dst = '/'.join([project_dir, 'instance']) # needs corrected
|
||||
src = os.path.join(config_dir, fn)
|
||||
dst = os.path.join(project_dir, 'instance/LinuxServer/UnrealTournament/Saved/Config/LinuxServer', fn)
|
||||
cmd = 'cp {src} {dst}'.format(**{
|
||||
'src': '/'.join([config_dir, fn]),
|
||||
'dst': '/'.join([project_dir, 'instance']) # needs corrected
|
||||
'src': src,
|
||||
'dst': dst
|
||||
})
|
||||
self._invoke_command(cmd)
|
||||
|
||||
# Monkey-patch Game.ini to ensure it has a place for RedirectReferences
|
||||
if fn == 'Game.ini':
|
||||
ini = UnrealIniFile(dst)
|
||||
sect_name = '/Script/UnrealTournament.UTBaseGameMode'
|
||||
opt_name = 'RedirectReferences'
|
||||
if not ini._config.has_section(sect_name):
|
||||
ini._config.add_section(sect_name)
|
||||
if not ini._config.has_option(sect_name, opt_name):
|
||||
ini._config.set(sect_name, opt_name, ':PARAM:')
|
||||
with open(dst, 'w') as fp:
|
||||
ini._config.write(fp)
|
||||
|
||||
def _install_paks(self):
|
||||
project_dir = self.ctx.config['app']['project_dir']
|
||||
|
||||
@ -278,63 +293,38 @@ ssh {remote_game_host} chown ut4.ut4 {remote_game_dir} -R
|
||||
self._invoke_command(cmd)
|
||||
|
||||
def _install_redirect_lines(self):
|
||||
return self.install_redirect_lines()
|
||||
|
||||
def install_redirect_lines(self):
|
||||
self.ctx.log['ut4'].info('Generating redirect references...')
|
||||
|
||||
redirect_protocol = self.ctx.config['app']['redirect_protocol']
|
||||
redirect_url = self.ctx.config['app']['redirect_url']
|
||||
project_dir = self.ctx.config['app']['project_dir']
|
||||
mod_dir = '/'.join([project_dir, 'files'])
|
||||
files = glob.iglob('{}/**/*.pak'.format(mod_dir))
|
||||
|
||||
game_ini_filepath = '/'.join([project_dir, 'instance/LinuxServer/UnrealTournament/Saved/Config/LinuxServer/Game.ini'])
|
||||
game_ini = GameIniSpecial(game_ini_filepath)
|
||||
game_ini.clear_redirect_references()
|
||||
|
||||
files = glob.glob('{}/**/*.pak'.format(mod_dir))
|
||||
redirect_lines = []
|
||||
for idx, filename in enumerate(files):
|
||||
if idx > 5:
|
||||
break
|
||||
md5sum = self._md5sum_file(filename)
|
||||
# if idx > 5:
|
||||
# break
|
||||
md5sum = _util.md5sum_file(filename)
|
||||
p = pathlib.Path(filename)
|
||||
relative_path = p.relative_to(mod_dir)
|
||||
basename = p.name
|
||||
pkg_basename = p.name
|
||||
|
||||
line = game_ini.add_redirect_reference(**{
|
||||
'pkg_basename': pkg_basename,
|
||||
'redirect_protocol': redirect_protocol,
|
||||
'redirect_url': redirect_url,
|
||||
'relative_path': relative_path,
|
||||
'md5sum': md5sum
|
||||
})
|
||||
|
||||
line = '\
|
||||
RedirectReferences=(PackageName="{basename}",\
|
||||
PackageURLProtocol="{redirect_protocol}",\
|
||||
PackageURL="{redirect_url}/{relative_path}",\
|
||||
PackageChecksum="{md5sum}")'\
|
||||
.format(**{
|
||||
'basename': basename,
|
||||
'redirect_protocol': redirect_protocol,
|
||||
'redirect_url': redirect_url,
|
||||
'relative_path': relative_path,
|
||||
'md5sum': md5sum
|
||||
})
|
||||
self.ctx.log['ut4'].debug("redirect line = '%s'", line)
|
||||
redirect_lines.append(line)
|
||||
# end loop - for filename in files:
|
||||
|
||||
# START HERE --trying to dynamically add redirect references and
|
||||
# gonna need to be able to work with the ini file, including support
|
||||
# for duplicate keys. Alternatively, maybe do the redirect lines through
|
||||
# a patch
|
||||
|
||||
# I found out the hard way, configobj doesn't seem the best suited for
|
||||
# duplicate keys...
|
||||
|
||||
# install into Game.ini
|
||||
game_ini_filepath = '/'.join([project_dir, 'files/config/Game.ini'])
|
||||
# game_ini_data = configobj.ConfigObj(game_ini_filepath)
|
||||
config = configparser.ConfigParser(
|
||||
# game_ini_filepath,
|
||||
# dict_type=MultiOrderedDict,
|
||||
strict=False
|
||||
)
|
||||
s = config.sections()
|
||||
print(s)
|
||||
# config.set('/Script/UnrealTournament.UTBaseGameMode', 'RedirectReferences', line)
|
||||
config.read(game_ini_filepath)
|
||||
l = config.write(sys.stdout)
|
||||
print('l', l)
|
||||
|
||||
data = game_ini.write(sys.stdout)
|
||||
|
||||
def _install_rulesets(self):
|
||||
self.ctx.log['ut4'].info('Concatenating rulesets for game modes...')
|
||||
@ -378,14 +368,6 @@ PackageChecksum="{md5sum}")'\
|
||||
cwd = None # todo(mg) ?
|
||||
os.system(cmd)
|
||||
|
||||
def _md5sum_file(self, filename):
|
||||
with open(filename, mode='rb') as f:
|
||||
d = hashlib.md5()
|
||||
for buf in iter(partial(f.read, 128), b''):
|
||||
d.update(buf)
|
||||
h = d.hexdigest()
|
||||
return h
|
||||
|
||||
def _needs_first_run(self):
|
||||
return False # TODO(MG): Hard-coded
|
||||
|
Loading…
Reference in New Issue
Block a user