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
|
*.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
|
#!/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 Hub Automator'
|
||||||
|
|
||||||
__project__ = 'SmileyFace UT4 Server Panel'
|
|
||||||
__version__ = '0.1.0'
|
__version__ = '0.1.0'
|
||||||
|
|
||||||
|
app_skellington_requirements = (
|
||||||
|
'appdirs',
|
||||||
|
'colorlog',
|
||||||
|
'configobj',
|
||||||
|
)
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name = __project__,
|
name = __project__,
|
||||||
version = __version__,
|
version = __version__,
|
||||||
@ -30,13 +21,12 @@ setup(
|
|||||||
|
|
||||||
# Third-party dependencies; will be automatically installed
|
# Third-party dependencies; will be automatically installed
|
||||||
install_requires = (
|
install_requires = (
|
||||||
'app_skellington'
|
'rdiff-backup',
|
||||||
),
|
) + app_skellington_requirements,
|
||||||
|
|
||||||
# Local packages to be installed (our packages)
|
|
||||||
packages = (
|
|
||||||
'smileyface',
|
|
||||||
),
|
|
||||||
|
|
||||||
|
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
|
import app_skellington
|
||||||
from app_skellington import _util
|
from app_skellington import _util
|
||||||
|
|
||||||
from . import model
|
|
||||||
|
|
||||||
class SmileyFace(app_skellington.ApplicationContainer):
|
class SmileyFace(app_skellington.ApplicationContainer):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
filename = 'config.spec'
|
filename = 'config.spec'
|
||||||
self.configspec_filepath = _util.get_asset(__name__, filename)
|
self.configspec_filepath = _util.get_asset(__name__, filename)
|
||||||
|
|
||||||
|
config_filepath = self._get_config_filepath(
|
||||||
|
'smileyface-ut4',
|
||||||
|
'app_author',
|
||||||
|
'hub-config.ini'
|
||||||
|
)
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
configspec_filepath=self.configspec_filepath,
|
configspec_filepath=self.configspec_filepath,
|
||||||
|
config_filepath=config_filepath,
|
||||||
app_name = 'SmileyFace UT4 Server Panel',
|
app_name = 'SmileyFace UT4 Server Panel',
|
||||||
app_author = 'Mathew Guest',
|
app_author = 'Mathew Guest',
|
||||||
app_version = '0.1',
|
app_version = '0.1',
|
||||||
*args,
|
*args,
|
||||||
**kwargs
|
**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):
|
def _cli_options(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _command_menu(self):
|
def _command_menu(self):
|
||||||
sm_root = self.cli.init_submenu('command')
|
sm_root = self.cli.init_submenu('command')
|
||||||
# sm_root.register_command(model.foo)
|
|
||||||
# sm_root.register_command(model.bar)
|
|
||||||
_util.register_class_as_commands(
|
_util.register_class_as_commands(
|
||||||
self, sm_root,
|
self, sm_root,
|
||||||
model.UT4ServerMachine
|
hub_machine.UT4ServerMachine
|
||||||
)
|
)
|
||||||
|
|
||||||
def _services(self):
|
def _services(self):
|
||||||
self['model'] = lambda: model.UTServerMachine(self.ctx)
|
self['model'] = lambda: hub_machine.UTServerMachine(self.ctx)
|
||||||
|
|
||||||
def interactive_shell(self):
|
def interactive_shell(self):
|
||||||
pass
|
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 app_skellington import _util
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import collections
|
import collections
|
||||||
@ -80,7 +84,6 @@ rsync -ravzp {remote_game_host}:{remote_game_dir}/LinuxServer/UnrealTournament/S
|
|||||||
})
|
})
|
||||||
self._invoke_command(cmd)
|
self._invoke_command(cmd)
|
||||||
|
|
||||||
|
|
||||||
# Delete logs on remote game server if successfully transferred to local:
|
# Delete logs on remote game server if successfully transferred to local:
|
||||||
self.ctx.log['ut4'].info('')
|
self.ctx.log['ut4'].info('')
|
||||||
cmd = '''
|
cmd = '''
|
||||||
@ -252,14 +255,26 @@ ssh {remote_game_host} chown ut4.ut4 {remote_game_dir} -R
|
|||||||
config_dir = self.ctx.config['app']['config_dir']
|
config_dir = self.ctx.config['app']['config_dir']
|
||||||
for fn in files:
|
for fn in files:
|
||||||
self.ctx.log['ut4'].info('Installing file: %s', fn)
|
self.ctx.log['ut4'].info('Installing file: %s', fn)
|
||||||
# src = '/'.join([config_dir, fn])
|
src = os.path.join(config_dir, fn)
|
||||||
# dst = '/'.join([project_dir, 'instance']) # needs corrected
|
dst = os.path.join(project_dir, 'instance/LinuxServer/UnrealTournament/Saved/Config/LinuxServer', fn)
|
||||||
cmd = 'cp {src} {dst}'.format(**{
|
cmd = 'cp {src} {dst}'.format(**{
|
||||||
'src': '/'.join([config_dir, fn]),
|
'src': src,
|
||||||
'dst': '/'.join([project_dir, 'instance']) # needs corrected
|
'dst': dst
|
||||||
})
|
})
|
||||||
self._invoke_command(cmd)
|
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):
|
def _install_paks(self):
|
||||||
project_dir = self.ctx.config['app']['project_dir']
|
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)
|
self._invoke_command(cmd)
|
||||||
|
|
||||||
def _install_redirect_lines(self):
|
def _install_redirect_lines(self):
|
||||||
return self.install_redirect_lines()
|
|
||||||
|
|
||||||
def install_redirect_lines(self):
|
|
||||||
self.ctx.log['ut4'].info('Generating redirect references...')
|
self.ctx.log['ut4'].info('Generating redirect references...')
|
||||||
|
|
||||||
redirect_protocol = self.ctx.config['app']['redirect_protocol']
|
redirect_protocol = self.ctx.config['app']['redirect_protocol']
|
||||||
redirect_url = self.ctx.config['app']['redirect_url']
|
redirect_url = self.ctx.config['app']['redirect_url']
|
||||||
project_dir = self.ctx.config['app']['project_dir']
|
project_dir = self.ctx.config['app']['project_dir']
|
||||||
mod_dir = '/'.join([project_dir, 'files'])
|
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 = []
|
redirect_lines = []
|
||||||
for idx, filename in enumerate(files):
|
for idx, filename in enumerate(files):
|
||||||
if idx > 5:
|
# if idx > 5:
|
||||||
break
|
# break
|
||||||
md5sum = self._md5sum_file(filename)
|
md5sum = _util.md5sum_file(filename)
|
||||||
p = pathlib.Path(filename)
|
p = pathlib.Path(filename)
|
||||||
relative_path = p.relative_to(mod_dir)
|
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)
|
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):
|
def _install_rulesets(self):
|
||||||
self.ctx.log['ut4'].info('Concatenating rulesets for game modes...')
|
self.ctx.log['ut4'].info('Concatenating rulesets for game modes...')
|
||||||
@ -378,14 +368,6 @@ PackageChecksum="{md5sum}")'\
|
|||||||
cwd = None # todo(mg) ?
|
cwd = None # todo(mg) ?
|
||||||
os.system(cmd)
|
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):
|
def _needs_first_run(self):
|
||||||
return False # TODO(MG): Hard-coded
|
return False # TODO(MG): Hard-coded
|
||||||
|
|
Loading…
Reference in New Issue
Block a user