diff --git a/Docs/AdminMapListsSettings.png b/Docs/AdminMapListsSettings.png new file mode 100644 index 0000000..1cc6e8d Binary files /dev/null and b/Docs/AdminMapListsSettings.png differ diff --git a/Docs/ui.md b/Docs/ui.md index 0c07ca3..67b179d 100644 --- a/Docs/ui.md +++ b/Docs/ui.md @@ -156,3 +156,9 @@ Admin settings are split into three parts: Voting, UI, and Setup. The tab-cards This tab-card is only visible when logged in as admin. It allows changing preset settings. ![Admin Presets Settings](AdminPresetsSettings.png) + +### Map Lists Settings + +This tab-card is only visible when logged in as admin. It allows editing map lists, including adding and removing them. + +![Admin Map Lists Settings](AdminMapListsSettings.png) diff --git a/README.md b/README.md index 8c04da4..878411d 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,12 @@ A new, independent implementation of map vote. * Automatic management of ServerPackages * Opt-in ([`bManageServerPackages`](#bmanageserverpackages)) * Before server version 469c [`DefaultPackages`](#defaultpackages) have to be configured correctly - * With 469c no further configuration is necessary + * With 469c or later no further configuration is necessary * Map repeat limits ([`MinimumMapRepeatDistance`](#minimummaprepeatdistance)) Servers must run at least UT v469. Clients must run at least UT v436. -Admin UI functionality also requires at least UT v469. +Admin UI functionality also requires at least UT v469 clients. ## [UI Documentation](Docs/ui.md) diff --git a/System/VoteSys.int b/System/VoteSys.int index fb659d5..90449bc 100644 --- a/System/VoteSys.int +++ b/System/VoteSys.int @@ -65,6 +65,15 @@ ErrMapLoadFailed="Loading map {1} failed, randomly selecting {2}" ErrNoConnection="VoteSys has no connection to server, check server firewall" ErrNotAllowed="Sorry, you are not allowed to vote" +[VS_UIS_PageAdminMapLists] +Text_MapListName="Map List Name" +Text_Map="Include Maps" +Text_IgnoreMap="Exclude Maps" +Text_IncludeMapsWithPrefix="Include Prefixes" +Text_IgnoreMapsWithPrefix="Exclude Prefixes" +Text_IncludeList="Include Lists" +Text_IgnoreList="Exclude Lists" + [VS_UIV_Window] WindowTitle="VoteSys Menu" @@ -111,6 +120,21 @@ Text_DefaultMap="Default Map" Text_AlwaysUseDefaultMap="Always Use Default Map" Text_IdleTimeout="Idle Timeout" +[VS_UI_PlayerMenu] +PlayerIdText="ID:" +PlayerKickText="&Kick" +PlayerBanText="&Ban" +PlayerBanTitle="Ban Player" +PlayerBanMessage="Do you want to permanently ban {1}?" + +[VS_UIS_ClientWindow] +PageClientSettingsName="Client" +PageAdminVotingName="[A] Voting" +PageAdminUIName="[A] UI" +PageAdminSetupName="[A] Setup" +PageAdminPresetsName="[A] Presets" +PageAdminMapListsName="[A] Map Lists" + [VS_UIS_PageClient] ThemeText="Theme" ThemeBright="Bright" @@ -123,13 +147,6 @@ MapListSortPlayCount="Play Count" FavoritesFirstText="Sort Favorites First" ShowPlayerListText="Show Player List" -[VS_UI_PlayerMenu] -PlayerIdText="ID:" -PlayerKickText="&Kick" -PlayerBanText="&Ban" -PlayerBanTitle="Ban Player" -PlayerBanMessage="Do you want to permanently ban {1}?" - [VS_UI_ScreenshotWindow] TextPlayerCount="Players:" diff --git a/USrc/MutVoteSys.uc b/USrc/MutVoteSys.uc index 81e8294..29e2583 100644 --- a/USrc/MutVoteSys.uc +++ b/USrc/MutVoteSys.uc @@ -20,6 +20,7 @@ var int PresetMaxIndex; var Object MapConfigDummy; var Object MapListDummy; var VS_MapList MapLists; +var array MapListArray; var Object HistoryDummy; var VS_HistoryConfig History; @@ -1390,6 +1391,8 @@ function VS_MapList LoadMapListByName(name ListName) { return ML; MC = new(MapConfigDummy, ListName) class'VS_MapListConfig'; + MapListArray.Insert(MapListArray.Length, 1); + MapListArray[MapListArray.Length - 1] = MC; MLIgnore = new(MapListDummy) class'VS_MapList'; @@ -1400,6 +1403,8 @@ function VS_MapList LoadMapListByName(name ListName) { ML = new(MapListDummy) class'VS_MapList'; ML.ListName = string(ListName); ML.Storage = MC; + ML.Next = MapLists; + MapLists = ML; AddAllMapsToMapList(MC.Map, ML); AddMapPrefixesToMapList(MC.IncludeMapsWithPrefix, ML); @@ -1423,9 +1428,9 @@ function VS_MapList LoadMapListByPrefix(string Prefix) { return ML; ML = new(MapListDummy) class'VS_MapList'; + ML.Prefix = Prefix; ML.Next = MapLists; MapLists = ML; - ML.Prefix = Prefix; FirstMap = GetMapName(Prefix, "", 0); if (FirstMap == "") @@ -1479,15 +1484,15 @@ function AddMapPrefixesToMapList(array MapPrefixArray, VS_MapList MapLis } } -function AddMapListsToMapList(array MapListArray, VS_MapList MapList) { +function AddMapListsToMapList(array MLArr, VS_MapList MapList) { local VS_MapList IncludeList; local int i; - for (i = 0; i < MapListArray.Length; i++) { - if (MapListArray[i] == '') + for (i = 0; i < MLArr.Length; i++) { + if (MLArr[i] == '') continue; - IncludeList = LoadMapListByName(MapListArray[i]); + IncludeList = LoadMapListByName(MLArr[i]); if (IncludeList != none) MapList.AddMapList(IncludeList); } diff --git a/USrc/VS_DataClient.uc b/USrc/VS_DataClient.uc index 2cf6ea7..658cfee 100644 --- a/USrc/VS_DataClient.uc +++ b/USrc/VS_DataClient.uc @@ -13,6 +13,7 @@ var VS_Preset Preset; var VS_Map LastMap; var VS_ServerSettings ServerSettings; var VS_ClientPresetList ServerPresets; +var VS_ClientMapListsContainer ServerMapLists; var float ResolveDelay; @@ -186,6 +187,19 @@ function ParseLine(string Line) { } else if (Line == "/ENDSERVERPRESETCONFIG/") { ServerPresets.TransmissionState = TS_Complete; Log("VS_DataClient GetServerPresets End", 'VoteSys'); + } else if (Left(Line, 21) == "/BEGINSERVERMAPLISTS/") { + ServerMapLists.TransmissionState = TS_New; + ServerMapLists.AllocateMapLists(int(Mid(Line, 21))); + Log("VS_DataClient GetServerMapLists Begin", 'VoteSys'); + } else if (Left(Line, 20) == "/BEGINSERVERMAPLIST/") { + ParseMapListName(Line); + } else if (Left(Line, 23) == "/SERVERMAPLISTPROPERTY/") { + ParseMapListProperty(Line); + } else if (Left(Line, 18) == "/ENDSERVERMAPLIST/") { + // + } else if (Line == "/ENDSERVERMAPLISTS/") { + ServerMapLists.TransmissionState = TS_Complete; + Log("VS_DataClient GetServerMapLists End", 'VoteSys'); } else if (Left(Line, 5) == "/PONG") { // nothing to do } else { @@ -310,7 +324,7 @@ function VS_ClientPresetList GetServerPresets() { Log("VS_DataClient GetServerPresets Version OK", 'VoteSys'); if (ServerPresets == none) { - ServerPresets = new(none) class'VS_ClientPresetList'; + ServerPresets = new(XLevel) class'VS_ClientPresetList'; SendLine("/SENDSERVERPRESETCONFIG/"); Log("VS_DataClient GetServerPresets Presets Requested", 'VoteSys'); } @@ -376,6 +390,80 @@ function SaveServerPresets(VS_ClientPresetList S) { Log("VS_DataClient SaveServerPresets Done", 'VoteSys'); } +function DiscardServerMapLists() { + ServerMapLists = none; +} + +function VS_ClientMapListsContainer GetServerMapLists() { + Log("DataClient GetServerMapLists", 'VoteSys'); + if (int(Level.EngineVersion) < 469) + return none; // not supported without 469 + + if (ServerMapLists == none) { + ServerMapLists = new(XLevel) class'VS_ClientMapListsContainer'; + SendLine("/SENDSERVERMAPLISTS/"); + Log("VS_DataClient GetServerMapLists Map Lists Requested", 'VoteSys'); + } + + return ServerMapLists; +} + +function ParseMapListName(string Line) { + local int Index; + + Line = Mid(Line, 20); + Index = int(Line); S11N.NextVariable(Line); + ServerMapLists.MapLists[Index].MapListName = S11N.DecodeString(Line); + + Log("VS_DataClient GetServerMapList"@ServerMapLists.MapLists[Index].MapListName, 'VoteSys'); +} + +function ParseMapListProperty(string Line) { + local int Index; + local string PropName, PropValue; + + Line = Mid(Line, 23); + + Index = int(Line); S11N.NextVariable(Line); + S11N.ParseProperty(Line, PropName, PropValue); + + ServerMapLists.MapLists[Index].SetPropertyText(PropName, PropValue); +} + +function SaveServerMapListProperty(VS_ClientMapList M, string Prefix, string Prop) { + SendLine(Prefix$S11N.SerializeProperty(Prop, M.GetPropertyText(Prop))); +} + +function SaveServerMapList(VS_ClientMapList M, int i) { + local string Prefix; + Prefix = "/SAVESERVERMAPLISTPROPERTY/"$i$"/"; + + SendLine("/SAVESERVERMAPLISTBEGIN/"$i$"/"$S11N.EncodeString(M.MapListName)); + + SaveServerMapListProperty(M, Prefix, "Map"); + SaveServerMapListProperty(M, Prefix, "IgnoreMap"); + SaveServerMapListProperty(M, Prefix, "IncludeMapsWithPrefix"); + SaveServerMapListProperty(M, Prefix, "IgnoreMapsWithPrefix"); + SaveServerMapListProperty(M, Prefix, "IncludeList"); + SaveServerMapListProperty(M, Prefix, "IgnoreList"); +} + +function SaveServerMapLists(VS_ClientMapListsContainer S) { + local int i; + if (S == none) + return; + + Log("VS_DataClient SaveServerMapLists", 'VoteSys'); + + for (i = 0; i < S.MapLists.Length; i++) + if (S.MapLists[i] != none && S.MapLists[i].MapListName != "") + SaveServerMapList(S.MapLists[i], i); + + SendLine("/SAVESERVERMAPLISTSFILE/"); + + Log("VS_DataClient SaveServerMapLists Done", 'VoteSys'); +} + defaultproperties { RemoteRole=ROLE_None } diff --git a/USrc/VS_DataLink.uc b/USrc/VS_DataLink.uc index 0e298b2..e4d68e1 100644 --- a/USrc/VS_DataLink.uc +++ b/USrc/VS_DataLink.uc @@ -8,6 +8,7 @@ var VS_ChannelContainer Channel; var string SendBuffer; var VS_Preset TempPreset; var VS_Map TempMap; +var array TempMapLists; var VS_Serialization S11N; var string CRLF; @@ -21,6 +22,8 @@ var array QueuedCommands; var name CurrentCommand; var string CommandParams; +var name TempName; + event PostBeginPlay() { LinkMode = MODE_Text; ReceiveMode = RMODE_Event; @@ -36,6 +39,9 @@ event Closed() { } final function bool SendLine(string Line) { + if (Len(Line) > 0xFFFE) + Channel.PlayerOwner.ClientMessage( + "Max line length exceeded in VoteSys. Please report this and include the following: "$Left(Line, 25)); // Len+2 to account for cr-lf at the end return SendText(Line$CRLF) == Len(Line) + 2; } @@ -89,6 +95,14 @@ function ParseLine(string Line) { ClearServerPreset(Line); } else if (Line == "/SAVESERVERPRESETSFILE/") { SaveServerPresetsFile(); + } else if (Line == "/SENDSERVERMAPLISTS/") { + QueueCommand('SendServerMapLists'); + } else if (Left(Line, 24) == "/SAVESERVERMAPLISTBEGIN/") { + SaveServerMapListBegin(Line); + } else if (Left(Line, 27) == "/SAVESERVERMAPLISTPROPERTY/") { + SaveServerMapListProperty(Line); + } else if (Line == "/SAVESERVERMAPLISTSFILE/") { + SaveServerMapListsFile(); } } @@ -349,6 +363,125 @@ function SaveServerPresetsFile() { VoteSys.PresetArray[i].SaveConfig(); } +state SendServerMapLists { + function SendServerMapList(VS_MapListConfig MC, int Index) { + local string Prefix; + if (MC == none) + return; + + SendLine("/BEGINSERVERMAPLIST/"$Index$"/"$S11N.EncodeString(string(MC.Name))); + + Prefix = "/SERVERMAPLISTPROPERTY/" $ Index $ "/"; + SendServerMapListProperty(Prefix, MC, "Map"); + SendServerMapListProperty(Prefix, MC, "IgnoreMap"); + SendServerMapListProperty(Prefix, MC, "IncludeMapsWithPrefix"); + SendServerMapListProperty(Prefix, MC, "IgnoreMapsWithPrefix"); + SendServerMapListProperty(Prefix, MC, "IncludeList"); + SendServerMapListProperty(Prefix, MC, "IgnoreList"); + + SendLine("/ENDSERVERMAPLIST/"$Index); + } + + function SendServerMapListProperty(string Prefix, VS_MapListConfig MC, string PropName) { + SendLine(Prefix $ S11N.SerializeProperty(PropName, MC.GetPropertyText(PropName))); + } + + function SendServerMapLists() { + local int i; + + SendLine("/BEGINSERVERMAPLISTS/"$VoteSys.MapListArray.Length); + + for (i = 0; i < VoteSys.MapListArray.Length; ++i) + SendServerMapList(VoteSys.MapListArray[i], i); + + SendLine("/ENDSERVERMAPLISTS/"); + } + +Begin: + if (Channel == none || + Channel.PlayerOwner == none || + Channel.PlayerOwner.bAdmin == false + ) { + SendLine("/NOTADMIN/"); + GoToState('Idle'); + } + + Log("VS_DataLink SendServerMapLists"@IpAddrToString(RemoteAddr), 'VoteSys'); + SendServerMapLists(); + + GoToState('Idle'); +} + +function SaveServerMapListBegin(string Line) { + local int Index; + local string MapListName; + + if (Channel == none || + Channel.PlayerOwner == none || + Channel.PlayerOwner.bAdmin == false + ) { + return; + } + + Line = Mid(Line, 24); + Index = int(Line); S11N.NextVariable(Line); + MapListName = S11N.DecodeString(Line); + + if (Index < 0) + return; + + if (Index >= TempMapLists.Length) + TempMapLists.Insert(TempMapLists.Length, Index - TempMapLists.Length + 1); + + if (TempMapLists[Index] != none) + return; + + SetPropertyText("TempName", MapListName); + TempMapLists[Index] = new(VoteSys.MapConfigDummy, TempName) class'VS_MapListConfig'; +} + +function SaveServerMapListProperty(string Line) { + local int Index; + local string PropName, PropValue; + + if (Channel == none || + Channel.PlayerOwner == none || + Channel.PlayerOwner.bAdmin == false + ) { + return; + } + + Line = Mid(Line, 27); + Index = int(Line); S11N.NextVariable(Line); + S11N.ParseProperty(Line, PropName, PropValue); + + if (Index < 0 || Index >= TempMapLists.Length || TempMapLists[Index] == none) + return; + + TempMapLists[Index].SetPropertyText(PropName, PropValue); +} + +function SaveServerMapListsFile() { + local int i; + + if (Channel == none || + Channel.PlayerOwner == none || + Channel.PlayerOwner.bAdmin == false + ) { + return; + } + + for (i = 0; i < VoteSys.MapListArray.Length; ++i) + VoteSys.MapListArray[i].ClearConfig(); + + VoteSys.MapListArray = TempMapLists; + TempMapLists.Remove(0, TempMapLists.Length); + + for (i = 0; i < VoteSys.MapListArray.Length; ++i) + if (VoteSys.MapListArray[i] != none) + VoteSys.MapListArray[i].SaveConfig(); +} + function HandleError() { SendLine("/RECONNECT"); Close(); diff --git a/USrc/VS_PlayerChannel.uc b/USrc/VS_PlayerChannel.uc index 3a3bb1e..2470518 100644 --- a/USrc/VS_PlayerChannel.uc +++ b/USrc/VS_PlayerChannel.uc @@ -10,6 +10,7 @@ var VS_DataClient DataClient; var VS_FavoritesProcessor FavoritesProcessor; var VS_ServerSettings ServerSettings; var VS_ClientPresetList ServerPresets; +var VS_ClientMapListsContainer ServerMapLists; var VS_Preset PresetList; var VS_UIV_Window VoteMenuDialog; @@ -602,6 +603,28 @@ simulated function SaveServerPresets() { DataClient.SaveServerPresets(ServerPresets); } +simulated function VS_ClientMapListsContainer ReloadServerMapLists() { + ServerMapLists = none; + DataClient.DiscardServerMapLists(); + return GetServerMapLists(); +} + +simulated function VS_ClientMapListsContainer GetServerMapLists() { + Log("PlayerChannel GetServerMapLists", 'VoteSys'); + if (ServerMapLists == none) { + ServerMapLists = DataClient.GetServerMapLists(); + } + return ServerMapLists; +} + +simulated function SaveServerMapLists() { + Log("PlayerChannel SaveServerMapLists", 'VoteSys'); + if (ServerMapLists == none) + return; + + DataClient.SaveServerMapLists(ServerMapLists); +} + simulated function LocalizeMessage( class MessageClass, optional int Switch, diff --git a/USrc/config/VS_ClientMapList.uc b/USrc/config/VS_ClientMapList.uc new file mode 100644 index 0000000..e1a0d15 --- /dev/null +++ b/USrc/config/VS_ClientMapList.uc @@ -0,0 +1,9 @@ +class VS_ClientMapList extends Object; + +var string MapListName; +var array Map; +var array IgnoreMap; +var array IncludeMapsWithPrefix; +var array IgnoreMapsWithPrefix; +var array IncludeList; +var array IgnoreList; diff --git a/USrc/config/VS_ClientMapListsContainer.uc b/USrc/config/VS_ClientMapListsContainer.uc new file mode 100644 index 0000000..f63cc94 --- /dev/null +++ b/USrc/config/VS_ClientMapListsContainer.uc @@ -0,0 +1,34 @@ +class VS_ClientMapListsContainer extends Object; + +var array MapLists; + +enum ETransmissionState { + TS_New, + TS_Complete, + TS_NotAdmin +}; +var ETransmissionState TransmissionState; + +function AllocateMapLists(int MaxIndex) { + local int i; + i = MapLists.Length; + if (i <= MaxIndex) { + MapLists.Insert(i, MaxIndex - i + 1); + while(i < MapLists.Length) { + MapLists[i] = new class'VS_ClientMapList'; + i += 1; + } + } +} + +function VS_ClientMapList AddMapList() { + local int i; + + if (TransmissionState != TS_Complete) + return none; + + i = MapLists.Length; + MapLists.Insert(i, 1); + MapLists[i] = new class'VS_ClientMapList'; + return MapLists[i]; +} diff --git a/USrc/ui/VS_UIS_ClientWindow.uc b/USrc/ui/VS_UIS_ClientWindow.uc index 22a3d6d..a6372b6 100644 --- a/USrc/ui/VS_UIS_ClientWindow.uc +++ b/USrc/ui/VS_UIS_ClientWindow.uc @@ -2,16 +2,23 @@ class VS_UIS_ClientWindow extends UWindowPageControl; var VS_PlayerChannel Channel; -var VS_UIS_PageClient ClientSettingsPage; +var localized string PageClientSettingsName; +var VS_UIS_PageClient PageClientSettings; +var localized string PageAdminVotingName; var VS_UIS_PageAdminVoting PageAdminVoting; +var localized string PageAdminUIName; var VS_UIS_PageAdminUI PageAdminUI; +var localized string PageAdminSetupName; var VS_UIS_PageAdminSetup PageAdminSetup; +var localized string PageAdminPresetsName; var VS_UIS_PageAdminPresets PageAdminPresets; +var localized string PageAdminMapListsName; +var VS_UIS_PageAdminMapLists PageAdminMapLists; function Created() { super.Created(); - ClientSettingsPage = VS_UIS_PageClient(AddPage("Client", class'VS_UIS_PageClient').Page); + PageClientSettings = VS_UIS_PageClient(AddPage(PageClientSettingsName, class'VS_UIS_PageClient').Page); } function BeforePaint(Canvas C, float X, float Y) { @@ -23,21 +30,25 @@ function BeforePaint(Canvas C, float X, float Y) { if (bIsAdmin) { if (PageAdminVoting == none) { - PageAdminVoting = VS_UIS_PageAdminVoting(AddPage("[A] Voting", class'VS_UIS_PageAdminVoting').Page); + PageAdminVoting = VS_UIS_PageAdminVoting(AddPage(PageAdminVotingName, class'VS_UIS_PageAdminVoting').Page); PageAdminVoting.LoadSettings(Channel); } if (PageAdminUI == none) { - PageAdminUI = VS_UIS_PageAdminUI(AddPage("[A] UI", class'VS_UIS_PageAdminUI').Page); + PageAdminUI = VS_UIS_PageAdminUI(AddPage(PageAdminUIName, class'VS_UIS_PageAdminUI').Page); PageAdminUI.LoadSettings(Channel); } if (PageAdminSetup == none) { - PageAdminSetup = VS_UIS_PageAdminSetup(AddPage("[A] Setup", class'VS_UIS_PageAdminSetup').Page); + PageAdminSetup = VS_UIS_PageAdminSetup(AddPage(PageAdminSetupName, class'VS_UIS_PageAdminSetup').Page); PageAdminSetup.LoadSettings(Channel); } if (PageAdminPresets == none) { - PageAdminPresets = VS_UIS_PageAdminPresets(AddPage("[A] Presets", class'VS_UIS_PageAdminPresets').Page); + PageAdminPresets = VS_UIS_PageAdminPresets(AddPage(PageAdminPresetsName, class'VS_UIS_PageAdminPresets').Page); PageAdminPresets.LoadSettings(Channel); } + if (PageAdminMapLists == none) { + PageAdminMapLists = VS_UIS_PageAdminMapLists(AddPage(PageAdminMapListsName, class'VS_UIS_PageAdminMapLists').Page); + PageAdminMapLists.LoadSettings(Channel); + } } else { if (PageAdminVoting != none) { DeletePage(PageAdminVoting.OwnerTab); @@ -55,6 +66,10 @@ function BeforePaint(Canvas C, float X, float Y) { DeletePage(PageAdminPresets.OwnerTab); PageAdminPresets = none; } + if (PageAdminMapLists != none) { + DeletePage(PageAdminMapLists.OwnerTab); + PageAdminMapLists = none; + } } super.BeforePaint(C, X, Y); @@ -63,7 +78,7 @@ function BeforePaint(Canvas C, float X, float Y) { function LoadSettings(VS_PlayerChannel C) { Channel = C; - ClientSettingsPage.LoadSettings(Channel); + PageClientSettings.LoadSettings(Channel); if (PageAdminVoting != none) PageAdminVoting.LoadSettings(Channel); @@ -73,4 +88,15 @@ function LoadSettings(VS_PlayerChannel C) { PageAdminSetup.LoadSettings(Channel); if (PageAdminPresets != none) PageAdminPresets.LoadSettings(Channel); + if (PageAdminMapLists != none) + PageAdminMapLists.LoadSettings(Channel); +} + +defaultproperties { + PageClientSettingsName="Client" + PageAdminVotingName="[A] Voting" + PageAdminUIName="[A] UI" + PageAdminSetupName="[A] Setup" + PageAdminPresetsName="[A] Presets" + PageAdminMapListsName="[A] Map Lists" } diff --git a/USrc/ui/VS_UIS_PageAdmin.uc b/USrc/ui/VS_UIS_PageAdmin.uc index 5d83c88..1b3eebf 100644 --- a/USrc/ui/VS_UIS_PageAdmin.uc +++ b/USrc/ui/VS_UIS_PageAdmin.uc @@ -2,6 +2,7 @@ class VS_UIS_PageAdmin extends VS_UIS_Page; var VS_ServerSettings Settings; var VS_ClientPresetList Presets; +var VS_ClientMapListsContainer MapLists; var bool bSettingsLoaded; var UWindowSmallButton Btn_RestartServer; @@ -36,6 +37,7 @@ function LoadSettings(VS_PlayerChannel C) { Settings = C.GetServerSettings(); Presets = C.GetServerPresets(); + MapLists = C.GetServerMapLists(); LoadServerSettings(); EnableInteraction(bSettingsLoaded); @@ -44,27 +46,30 @@ function LoadSettings(VS_PlayerChannel C) { function SaveSettings() { Channel.SaveServerSettings(); Channel.SaveServerPresets(); + Channel.SaveServerMapLists(); } function BeforePaint(Canvas C, float MouseX, float MouseY) { super.BeforePaint(C, MouseX, MouseY); - switch(Settings.SState) { - case S_NEW: - Lbl_SettingsState.SetText(Text_SettingsState_New); - break; - case S_COMPLETE: - Lbl_SettingsState.SetText(Text_SettingsState_Complete); - break; - case S_NOTADMIN: - Lbl_SettingsState.SetText(Text_SettingsState_NotAdmin); - break; - } - - if (bSettingsLoaded == false && Settings.SState == S_COMPLETE && Presets.TransmissionState == TS_Complete) { - LoadServerSettings(); - EnableInteraction(true); - bSettingsLoaded = true; + if (Settings.SState == S_COMPLETE && + Presets.TransmissionState == TS_Complete && + MapLists.TransmissionState == TS_Complete + ) { + Lbl_SettingsState.SetText(Text_SettingsState_Complete); + if (bSettingsLoaded == false) { + LoadServerSettings(); + EnableInteraction(true); + bSettingsLoaded = true; + } + } else if ( + Settings.SState == S_NOTADMIN || + Presets.TransmissionState == TS_NotAdmin || + MapLists.TransmissionState == TS_NotAdmin + ) { + Lbl_SettingsState.SetText(Text_SettingsState_NotAdmin); + } else { + Lbl_SettingsState.SetText(Text_SettingsState_New); } } @@ -78,6 +83,7 @@ function Notify(UWindowDialogControl C, byte E) { bSettingsLoaded = false; Settings = Channel.ReloadServerSettings(); Presets = Channel.ReloadServerPresets(); + MapLists = Channel.ReloadServerMapLists(); EnableInteraction(false); } } diff --git a/USrc/ui/VS_UIS_PageAdminMapLists.uc b/USrc/ui/VS_UIS_PageAdminMapLists.uc new file mode 100644 index 0000000..2d108e3 --- /dev/null +++ b/USrc/ui/VS_UIS_PageAdminMapLists.uc @@ -0,0 +1,208 @@ +class VS_UIS_PageAdminMapLists extends VS_UIS_PageAdmin; + +var VS_UI_MapListLB MapListLB; +var UWindowSmallButton AddMapList; +var UWindowSmallButton RemMapList; +var VS_UI_MapListLI SelectedMapList; +var VS_ClientMapList DefaultMapList; + +var VS_UI_EditControl Edt_MapListName; +var localized string Text_MapListName; + +var VS_UI_ArrayEditString Adt_Map; +var localized string Text_Map; + +var VS_UI_ArrayEditString Adt_IgnoreMap; +var localized string Text_IgnoreMap; + +var VS_UI_ArrayEditString Adt_IncludeMapsWithPrefix; +var localized string Text_IncludeMapsWithPrefix; + +var VS_UI_ArrayEditString Adt_IgnoreMapsWithPrefix; +var localized string Text_IgnoreMapsWithPrefix; + +var VS_UI_ArrayEditName Adt_IncludeList; +var localized string Text_IncludeList; + +var VS_UI_ArrayEditName Adt_IgnoreList; +var localized string Text_IgnoreList; + +function Created() { + super.Created(); + + DefaultMapList = new class'VS_ClientMapList'; + + MapListLB = VS_UI_MapListLB(CreateControl(class'VS_UI_MapListLB', 4, 28, 188, 302)); + + AddMapList = UWindowSmallButton(CreateControl(class'UWindowSmallButton', 4, 8, 16, 16)); + AddMapList.SetText("+"); + + RemMapList = UWindowSmallButton(CreateControl(class'UWindowSmallButton', 24, 8, 16, 16)); + RemMapList.SetText("-"); + + Edt_MapListName = VS_UI_EditControl(CreateControl(class'VS_UI_EditControl', 200, 8, 188, 16)); + Edt_MapListName.SetText(Text_MapListName); + Edt_MapListName.EditBoxWidth = 100; + Edt_MapListName.EditBox.MaxLength = 63; + + Adt_Map = VS_UI_ArrayEditString(CreateControl(class'VS_UI_ArrayEditString', 200, 28, 188, 16)); + Adt_Map.SetText(Text_Map); + Adt_Map.EditBoxWidth = 100; + Adt_Map.EditBox.MaxLength = 65000; + + Adt_IgnoreMap = VS_UI_ArrayEditString(CreateControl(class'VS_UI_ArrayEditString', 200, 48, 188, 16)); + Adt_IgnoreMap.SetText(Text_IgnoreMap); + Adt_IgnoreMap.EditBoxWidth = 100; + Adt_IgnoreMap.EditBox.MaxLength = 65000; + + Adt_IncludeMapsWithPrefix = VS_UI_ArrayEditString(CreateControl(class'VS_UI_ArrayEditString', 200, 68, 188, 16)); + Adt_IncludeMapsWithPrefix.SetText(Text_IncludeMapsWithPrefix); + Adt_IncludeMapsWithPrefix.EditBoxWidth = 100; + Adt_IncludeMapsWithPrefix.EditBox.MaxLength = 65000; + + Adt_IgnoreMapsWithPrefix = VS_UI_ArrayEditString(CreateControl(class'VS_UI_ArrayEditString', 200, 88, 188, 16)); + Adt_IgnoreMapsWithPrefix.SetText(Text_IgnoreMapsWithPrefix); + Adt_IgnoreMapsWithPrefix.EditBoxWidth = 100; + Adt_IgnoreMapsWithPrefix.EditBox.MaxLength = 65000; + + Adt_IncludeList = VS_UI_ArrayEditName(CreateControl(class'VS_UI_ArrayEditName', 200, 108, 188, 16)); + Adt_IncludeList.SetText(Text_IncludeList); + Adt_IncludeList.EditBoxWidth = 100; + Adt_IncludeList.EditBox.MaxLength = 65000; + + Adt_IgnoreList = VS_UI_ArrayEditName(CreateControl(class'VS_UI_ArrayEditName', 200, 128, 188, 16)); + Adt_IgnoreList.SetText(Text_IgnoreList); + Adt_IgnoreList.EditBoxWidth = 100; + Adt_IgnoreList.EditBox.MaxLength = 65000; +} + +function ApplyTheme() { + MapListLB.Theme = Theme; + Edt_MapListName.Theme = Theme; + Adt_Map.Theme = Theme; + Adt_IgnoreMap.Theme = Theme; + Adt_IncludeMapsWithPrefix.Theme = Theme; + Adt_IgnoreMapsWithPrefix.Theme = Theme; + Adt_IncludeList.Theme = Theme; + Adt_IgnoreList.Theme = Theme; +} + +function EnableInteraction(bool bEnable) { + AddMapList.bDisabled = !bEnable; + RemMapList.bDisabled = !bEnable; + Edt_MapListName.EditBox.SetEditable(false); + Adt_Map.EditBox.SetEditable(false); + Adt_IgnoreMap.EditBox.SetEditable(false); + Adt_IncludeMapsWithPrefix.EditBox.SetEditable(false); + Adt_IgnoreMapsWithPrefix.EditBox.SetEditable(false); + Adt_IncludeList.EditBox.SetEditable(false); + Adt_IgnoreList.EditBox.SetEditable(false); +} + +function SaveMapListSettings() { + if (SelectedMapList == none) + return; + + SelectedMapList.MapList.MapListName = Edt_MapListName.GetValue(); + SelectedMapList.MapList.SetPropertyText("Map", Adt_Map.GetValue()); + SelectedMapList.MapList.SetPropertyText("IgnoreMap", Adt_IgnoreMap.GetValue()); + SelectedMapList.MapList.SetPropertyText("IncludeMapsWithPrefix", Adt_IncludeMapsWithPrefix.GetValue()); + SelectedMapList.MapList.SetPropertyText("IgnoreMapsWithPrefix", Adt_IgnoreMapsWithPrefix.GetValue()); + SelectedMapList.MapList.SetPropertyText("IncludeList", Adt_IncludeList.GetValue()); + SelectedMapList.MapList.SetPropertyText("IgnoreList", Adt_IgnoreList.GetValue()); +} + +function LoadMapListSettings(VS_ClientMapList M) { + if (M == none) + M = DefaultMapList; + + Edt_MapListName.SetValue(M.MapListName); + Adt_Map.SetValue(M.GetPropertyText("Map")); + Adt_IgnoreMap.SetValue(M.GetPropertyText("IgnoreMap")); + Adt_IncludeMapsWithPrefix.SetValue(M.GetPropertyText("IncludeMapsWithPrefix")); + Adt_IgnoreMapsWithPrefix.SetValue(M.GetPropertyText("IgnoreMapsWithPrefix")); + Adt_IncludeList.SetValue(M.GetPropertyText("IncludeList")); + Adt_IgnoreList.SetValue(M.GetPropertyText("IgnoreList")); +} + +function BeforePaint(Canvas C, float MouseX, float MouseY) { + super.BeforePaint(C, MouseX, MouseY); + + if (SelectedMapList != MapListLB.SelectedItem) { + SaveMapListSettings(); + SelectedMapList = VS_UI_MapListLI(MapListLB.SelectedItem); + LoadMapListSettings(SelectedMapList.MapList); + + Edt_MapListName.EditBox.SetEditable(SelectedMapList != none); + Adt_Map.EditBox.SetEditable(SelectedMapList != none); + Adt_IgnoreMap.EditBox.SetEditable(SelectedMapList != none); + Adt_IncludeMapsWithPrefix.EditBox.SetEditable(SelectedMapList != none); + Adt_IgnoreMapsWithPrefix.EditBox.SetEditable(SelectedMapList != none); + Adt_IncludeList.EditBox.SetEditable(SelectedMapList != none); + Adt_IgnoreList.EditBox.SetEditable(SelectedMapList != none); + } +} + +function Notify(UWindowDialogControl C, byte E) { + if (E == DE_Click && C == AddMapList) { + MapListLB.SetSelectedItem(UWindowListBoxItem(MapListLB.Items.Append(class'VS_UI_MapListLI'))); + VS_UI_MapListLI(MapListLB.SelectedItem).MapList = new class'VS_ClientMapList'; + } else if (E == DE_Click && C == RemMapList) { + if (SelectedMapList != none) { + SelectedMapList.Remove(); + MapListLB.ClearSelection(); + } + } else if (E == DE_Change && C == Edt_MapListName) { + if (SelectedMapList != none) + SelectedMapList.MapList.MapListName = Edt_MapListName.GetValue(); + } else { + super.Notify(C, E); + } +} + +function LoadServerSettings() { + local int i; + local VS_UI_MapListLI M; + + MapListLB.Items.Clear(); + MapListLB.ClearSelection(); + + for (i = 0; i < MapLists.MapLists.Length; ++i) { + if (MapLists.MapLists[i].MapListName == "") + continue; + + M = VS_UI_MapListLI(MapListLB.Items.Append(class'VS_UI_MapListLI')); + M.MapList = MapLists.MapLists[i]; + } + + LoadMapListSettings(none); +} + +function SaveSettings() { + local int i; + local VS_UI_MapListLI M; + + SaveMapListSettings(); + + for (M = VS_UI_MapListLI(MapListLB.Items.Next); M != none; M = VS_UI_MapListLI(M.Next)) { + if (i >= MapLists.MapLists.Length) + MapLists.MapLists.Insert(i, 1); + MapLists.MapLists[i++] = M.MapList; + } + + while(i < MapLists.MapLists.Length) { + MapLists.MapLists[i++] = none; + } + + super.SaveSettings(); +} + +defaultproperties { + Text_MapListName="Map List Name" + Text_Map="Include Maps" + Text_IgnoreMap="Exclude Maps" + Text_IncludeMapsWithPrefix="Include Prefixes" + Text_IgnoreMapsWithPrefix="Exclude Prefixes" + Text_IncludeList="Include Lists" + Text_IgnoreList="Exclude Lists" +} diff --git a/USrc/ui/controls/VS_UI_MapListLB.uc b/USrc/ui/controls/VS_UI_MapListLB.uc new file mode 100644 index 0000000..ae58c2f --- /dev/null +++ b/USrc/ui/controls/VS_UI_MapListLB.uc @@ -0,0 +1,26 @@ +class VS_UI_MapListLB extends VS_UI_ListBox; + +function float ItemWidth(Canvas C, UWindowList Item, float VisibleWidth) { + local VS_UI_MapListLI I; + local float W, H; + + I = VS_UI_MapListLI(Item); + TextSize(C, I.MapList.MapListName, W, H); + + return FMax(W + 4.0, VisibleWidth); +} + +function DrawItem(Canvas C, UWindowList Item, float X, float Y, float W, float H) { + local VS_UI_MapListLI I; + + super.DrawItem(C, Item, X, Y, W, H); + + I = VS_UI_MapListLI(Item); + ClipText(C, X, Y, I.MapList.MapListName); +} + +defaultproperties { + HorizontalScrollbarMode=HSM_Show + ListClass=class'VS_UI_MapListLI' + bCanDrag=True +} diff --git a/USrc/ui/controls/VS_UI_MapListLI.uc b/USrc/ui/controls/VS_UI_MapListLI.uc new file mode 100644 index 0000000..c9a7c23 --- /dev/null +++ b/USrc/ui/controls/VS_UI_MapListLI.uc @@ -0,0 +1,3 @@ +class VS_UI_MapListLI extends VS_UI_ListItem; + +var VS_ClientMapList MapList;