diff --git a/EvoSC.sln b/EvoSC.sln index 2ec61fa13..5ed2b9e99 100644 --- a/EvoSC.sln +++ b/EvoSC.sln @@ -84,7 +84,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatchTrackerModule", "src\M EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatchReadyModule", "src\Modules\MatchReadyModule\MatchReadyModule.csproj", "{0538B9AB-B556-45BF-8230-53087BA9D353}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scoreboard", "src\Modules\Scoreboard\Scoreboard.csproj", "{CD032D37-3BC8-4DE8-8C5B-45A0DE36932E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScoreboardModule", "src\Modules\ScoreboardModule\ScoreboardModule.csproj", "{CD032D37-3BC8-4DE8-8C5B-45A0DE36932E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NextMapModule", "src\Modules\NextMapModule\NextMapModule.csproj", "{64688FA7-136C-4BB9-B716-4E96DD0AA82F}" EndProject @@ -148,6 +148,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpectatorCamModeModule", "s EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpectatorCamModeModule.Tests", "tests\Modules\SpectatorCamModeModule.Tests\SpectatorCamModeModule.Tests.csproj", "{09A88256-8008-4085-A8E6-CA6DEFAC63E3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerSyncModule", "src\Modules\ServerSyncModule\ServerSyncModule.csproj", "{AB39B49E-729D-42EF-93DE-98AD6329AAEC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ToornamentModule", "src\Modules\ToornamentModule\ToornamentModule.csproj", "{6F12A74A-BC4B-426D-B094-638FCB266FC6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ContactAdminModule", "src\Modules\ContactAdminModule\ContactAdminModule.csproj", "{056D6390-6A39-4A5B-BFCE-7694CDD4EA62}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RoundRankingModule", "src\Modules\RoundRankingModule\RoundRankingModule.csproj", "{41FD20E7-5064-425F-B110-CEBD53F80ECA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RoundRankingModule.Tests", "tests\Modules\RoundRankingModule.Tests\RoundRankingModule.Tests.csproj", "{2623A6E2-125F-49B5-B8E1-5883B6E36C1A}" +EndProject @@ -447,6 +457,26 @@ Global {09A88256-8008-4085-A8E6-CA6DEFAC63E3}.Debug|Any CPU.Build.0 = Debug|Any CPU {09A88256-8008-4085-A8E6-CA6DEFAC63E3}.Release|Any CPU.ActiveCfg = Release|Any CPU {09A88256-8008-4085-A8E6-CA6DEFAC63E3}.Release|Any CPU.Build.0 = Release|Any CPU + {AB39B49E-729D-42EF-93DE-98AD6329AAEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AB39B49E-729D-42EF-93DE-98AD6329AAEC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AB39B49E-729D-42EF-93DE-98AD6329AAEC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AB39B49E-729D-42EF-93DE-98AD6329AAEC}.Release|Any CPU.Build.0 = Release|Any CPU + {6F12A74A-BC4B-426D-B094-638FCB266FC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6F12A74A-BC4B-426D-B094-638FCB266FC6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6F12A74A-BC4B-426D-B094-638FCB266FC6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6F12A74A-BC4B-426D-B094-638FCB266FC6}.Release|Any CPU.Build.0 = Release|Any CPU + {056D6390-6A39-4A5B-BFCE-7694CDD4EA62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {056D6390-6A39-4A5B-BFCE-7694CDD4EA62}.Debug|Any CPU.Build.0 = Debug|Any CPU + {056D6390-6A39-4A5B-BFCE-7694CDD4EA62}.Release|Any CPU.ActiveCfg = Release|Any CPU + {056D6390-6A39-4A5B-BFCE-7694CDD4EA62}.Release|Any CPU.Build.0 = Release|Any CPU + {41FD20E7-5064-425F-B110-CEBD53F80ECA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {41FD20E7-5064-425F-B110-CEBD53F80ECA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {41FD20E7-5064-425F-B110-CEBD53F80ECA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {41FD20E7-5064-425F-B110-CEBD53F80ECA}.Release|Any CPU.Build.0 = Release|Any CPU + {2623A6E2-125F-49B5-B8E1-5883B6E36C1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2623A6E2-125F-49B5-B8E1-5883B6E36C1A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2623A6E2-125F-49B5-B8E1-5883B6E36C1A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2623A6E2-125F-49B5-B8E1-5883B6E36C1A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -517,5 +547,10 @@ Global {E4BF17BE-A517-4D3C-8DCA-DA99A100EBFE} = {6D75D6A2-6ECD-4DE4-96C5-CAD7D134407A} {E9806703-6E24-4F05-A728-A04F7EB31749} = {DC47658A-F421-4BA4-B617-090A7DFB3900} {09A88256-8008-4085-A8E6-CA6DEFAC63E3} = {6D75D6A2-6ECD-4DE4-96C5-CAD7D134407A} + {41FD20E7-5064-425F-B110-CEBD53F80ECA} = {DC47658A-F421-4BA4-B617-090A7DFB3900} + {2623A6E2-125F-49B5-B8E1-5883B6E36C1A} = {6D75D6A2-6ECD-4DE4-96C5-CAD7D134407A} + {AB39B49E-729D-42EF-93DE-98AD6329AAEC} = {DC47658A-F421-4BA4-B617-090A7DFB3900} + {6F12A74A-BC4B-426D-B094-638FCB266FC6} = {DC47658A-F421-4BA4-B617-090A7DFB3900} + {056D6390-6A39-4A5B-BFCE-7694CDD4EA62} = {DC47658A-F421-4BA4-B617-090A7DFB3900} EndGlobalSection EndGlobal diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 46640ee76..f242f71e4 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -3,8 +3,9 @@ services: image: evoesports/trackmania restart: always ports: - - 2350:2350/udp - - 2350:2350/tcp + - "2350:2350/udp" + - "2350:2350/tcp" + - "5001:5000" environment: - MASTER_LOGIN= - MASTER_PASSWORD= @@ -19,21 +20,8 @@ services: - POSTGRES_PASSWORD=evosc_sharp - POSTGRES_USER=evosc_sharp - POSTGRES_DB=evosc_sharp - - evosc_sharp: - image: evoscsharp:latest - restart: always - depends_on: - - trackmania - - postgres - environment: - - EVOSC_DATABASE_HOST=postgres - - EVOSC_DATABASE_NAME=evosc_sharp - - EVOSC_DATABASE_USERNAME=evosc_sharp - - EVOSC_DATABASE_PASSWORD=evosc_sharp - - EVOSC_SERVER_HOST=trackmania - volumes: - - UserData:/server/UserData + ports: + - "5432:5432" volumes: PostgresData: null diff --git a/src/EvoSC/EvoSC.csproj b/src/EvoSC/EvoSC.csproj index 844ecefc8..69a102d20 100644 --- a/src/EvoSC/EvoSC.csproj +++ b/src/EvoSC/EvoSC.csproj @@ -12,18 +12,22 @@ + + all runtime; build; native; contentfiles; analyzers; buildtransitive + + @@ -34,6 +38,8 @@ + + @@ -49,12 +55,21 @@ + + + + + + + + + diff --git a/src/EvoSC/InternalModules.cs b/src/EvoSC/InternalModules.cs index a7fa2c43b..bc9b5b91d 100644 --- a/src/EvoSC/InternalModules.cs +++ b/src/EvoSC/InternalModules.cs @@ -1,5 +1,8 @@ using EvoSC.Common.Interfaces; +using EvoSC.Modules.EvoEsports.ServerSyncModule; +using EvoSC.Modules.EvoEsports.ToornamentModule; using EvoSC.Modules.Interfaces; +using EvoSC.Modules.Nsgr.ContactAdminModule; using EvoSC.Modules.Official.ASayModule; using EvoSC.Modules.Official.CurrentMapModule; using EvoSC.Modules.Official.ExampleModule; @@ -20,7 +23,8 @@ using EvoSC.Modules.Official.OpenPlanetModule; using EvoSC.Modules.Official.Player; using EvoSC.Modules.Official.PlayerRecords; -using EvoSC.Modules.Official.Scoreboard; +using EvoSC.Modules.Official.RoundRankingModule; +using EvoSC.Modules.Official.ScoreboardModule; using EvoSC.Modules.Official.ServerManagementModule; using EvoSC.Modules.Official.SetName; using EvoSC.Modules.Official.SpectatorCamModeModule; @@ -65,7 +69,11 @@ public static class InternalModules typeof(TeamSettingsModule), typeof(ServerManagementModule), typeof(TeamInfoModule), - typeof(TeamChatModule) + typeof(TeamChatModule), + typeof(ServerSyncModule), + typeof(ToornamentModule), + typeof(ContactAdminModule), + typeof(RoundRankingModule) ]; /// diff --git a/src/EvoSC/Properties/launchSettings.json b/src/EvoSC/Properties/launchSettings.json index e3a1b92e6..e489a043f 100644 --- a/src/EvoSC/Properties/launchSettings.json +++ b/src/EvoSC/Properties/launchSettings.json @@ -2,7 +2,24 @@ "profiles": { "EvoSC": { "commandName": "Project", - "commandLineArgs": "run" + "commandLineArgs": "run", + "environmentVariables": { + "EVOSC_SERVERSYNCMODULE_NATSSETTINGS_HOST": "116.202.26.112", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_APIKEY": "", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_CLIENTID": "", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_CLIENTSECRET": "", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_WHITELIST": "8ecce824-8ada-4fbf-9af1-64b2d8dd42a4", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_TOORNAMENTID": "7930620280195727360", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_USETOORNAMENTDISCIPLINE": "false", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_AUTOMATICMATCHSTART": "true", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_MAPTMXIDS": "186972,186973,186974,186870,186980", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_MAPIDS": "b0c2e735-15a9-43df-a772-f5f1f692fa29,e8233617-a929-4891-924d-6ba72fd546c7,c7ffcdfe-fd98-417b-80d9-b464927f76a1,ae1eb6cb-76ef-45ab-8149-07377e3e45bd,b653936e-1316-461a-b4cf-befa6630e839", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_MAPUIDS": "zS5d30EU7x6meq2eIM5Uhu4UbTg,VbW1c9rTPSwtZNHrlDE8FVPqIca,lKJQ8YrXza3XiEN1a1fPK3fl4wf,W6GjI5Nsr9MYdBBOBXIOd8JhZwj,YUTy7o9O0hDmWFNVQ4QuxaXzXD4", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_MAPMACHINENAMES": "blueprint,domino,fe4turing,karotte,schwaadlappe", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_DEFAULTGROUPID": "2", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_USEEXPERIMENTALFEATURES": "true", + "EVOSC_TOORNAMENTMODULE_TOORNAMENTSETTINGS_DISCIPLINES": "[{\"game_mode\":\"rounds\",\"group_number\":1,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":1,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":30,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":1,\"S_PointsLimit\":-1,\"S_PointsRepartition\":\"n-1\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":1,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":1,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":1,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":1,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":2,\"S_PointsLimit\":120,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":2,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":1,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":1,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":2,\"S_PointsLimit\":120,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":3,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":1,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":2,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":2,\"S_PointsLimit\":120,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":3,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":2,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":1,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":2,\"S_PointsLimit\":120,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":3,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":1,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":3,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":2,\"S_PointsLimit\":120,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":3,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":2,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":2,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":2,\"S_PointsLimit\":120,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":3,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":1,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":4,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":2,\"S_PointsLimit\":120,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":3,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":2,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":3,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":2,\"S_PointsLimit\":120,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":3,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":1,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":5,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":2,\"S_PointsLimit\":140,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":3,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":2,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":2,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":2,\"S_PointsLimit\":120,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":3,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":2,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":5,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":2,\"S_PointsLimit\":140,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":3,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":2,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":6,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":2,\"S_PointsLimit\":140,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":3,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":2,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":7,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":2,\"S_PointsLimit\":140,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":3,\"tracks_shuffle\":true},{\"game_mode\":\"cup\",\"group_number\":3,\"plugins\":{\"S_UseAutoReady\":false},\"round_number\":1,\"scripts\":{\"S_DelayBeforeNextMap\":2000,\"S_FinishTimeout\":10,\"S_MapsPerMatch\":5,\"S_NbOfWinners\":3,\"S_PointsLimit\":140,\"S_PointsRepartition\":\"10,6,4,3\",\"S_RespawnBehaviour\":0,\"S_RoundsPerMap\":4,\"S_UseTieBreak\":false,\"S_WarmUpDuration\":60,\"S_WarmUpNb\":1},\"stage_number\":3,\"tracks_shuffle\":true}]" + } } } } \ No newline at end of file diff --git a/src/Modules/ContactAdminModule/Config/IContactAdminSettings.cs b/src/Modules/ContactAdminModule/Config/IContactAdminSettings.cs new file mode 100644 index 000000000..ebdc562f7 --- /dev/null +++ b/src/Modules/ContactAdminModule/Config/IContactAdminSettings.cs @@ -0,0 +1,15 @@ +using System.ComponentModel; +using Config.Net; +using EvoSC.Modules.Attributes; + +namespace EvoSC.Modules.Nsgr.ContactAdminModule.Config; + +[Settings] +public interface IContactAdminSettings +{ + [Option(DefaultValue = ""), Description("Specifies the Discord Webhook endpoint to POST to.")] + public string WebhookUrl { get; set; } + + [Option(DefaultValue = ""), Description("A suffix that will be added to each message. Can be used for Discord pings")] + public string MessageSuffix { get; set; } +} diff --git a/src/Modules/ContactAdminModule/ContactAdminModule.cs b/src/Modules/ContactAdminModule/ContactAdminModule.cs new file mode 100644 index 000000000..7f3b4b4a0 --- /dev/null +++ b/src/Modules/ContactAdminModule/ContactAdminModule.cs @@ -0,0 +1,12 @@ +using EvoSC.Modules.Attributes; +using EvoSC.Modules.Interfaces; +using EvoSC.Modules.Nsgr.ContactAdminModule.Interfaces; + +namespace EvoSC.Modules.Nsgr.ContactAdminModule; + +[Module] +public class ContactAdminModule(IContactAdminService service) : EvoScModule, IToggleable +{ + public Task EnableAsync() => service.ShowWidgetAsync(); + public Task DisableAsync() => service.HideWidgetAsync(); +} diff --git a/src/Modules/ContactAdminModule/ContactAdminModule.csproj b/src/Modules/ContactAdminModule/ContactAdminModule.csproj new file mode 100644 index 000000000..00e521166 --- /dev/null +++ b/src/Modules/ContactAdminModule/ContactAdminModule.csproj @@ -0,0 +1,29 @@ + + + + net8.0 + enable + enable + EvoSC.Modules.Nsgr.ContactAdminModule + false + ContactAdminModule + Contact Admin Module + Creates a button for players that when clicked, notifies a Discord webhook. + 1.0.0 + Nsgr + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Modules/ContactAdminModule/Controllers/ContactAdminManialinkController.cs b/src/Modules/ContactAdminModule/Controllers/ContactAdminManialinkController.cs new file mode 100644 index 000000000..605999205 --- /dev/null +++ b/src/Modules/ContactAdminModule/Controllers/ContactAdminManialinkController.cs @@ -0,0 +1,11 @@ +using EvoSC.Common.Controllers.Attributes; +using EvoSC.Manialinks; +using EvoSC.Modules.Nsgr.ContactAdminModule.Interfaces; + +namespace EvoSC.Modules.Nsgr.ContactAdminModule.Controllers; + +[Controller] +public class ContactAdminManialinkController(IContactAdminService service) : ManialinkController +{ + public Task ContactAdminButtonAsync() => service.ContactAdminAsync(Context.Player); +} diff --git a/src/Modules/ContactAdminModule/Interfaces/IContactAdminService.cs b/src/Modules/ContactAdminModule/Interfaces/IContactAdminService.cs new file mode 100644 index 000000000..7226bee54 --- /dev/null +++ b/src/Modules/ContactAdminModule/Interfaces/IContactAdminService.cs @@ -0,0 +1,26 @@ +using EvoSC.Common.Interfaces.Models; + +namespace EvoSC.Modules.Nsgr.ContactAdminModule.Interfaces; + +public interface IContactAdminService +{ + /// + /// Shows the widget + /// + /// + Task ShowWidgetAsync(); + + /// + /// Hides the Widget + /// + /// + Task HideWidgetAsync(); + + /// + /// Posts a help message containing the Trackmania server name to the specified Webhook + /// If contextPlayer is specified, the chat message will mention who requested the contact. + /// + /// + /// + Task ContactAdminAsync(IOnlinePlayer? contextPlayer); +} diff --git a/src/Modules/ContactAdminModule/Localization.resx b/src/Modules/ContactAdminModule/Localization.resx new file mode 100644 index 000000000..f2bbd290f --- /dev/null +++ b/src/Modules/ContactAdminModule/Localization.resx @@ -0,0 +1,24 @@ + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Hello {0} + + \ No newline at end of file diff --git a/src/Modules/ContactAdminModule/Services/ContactAdminService.cs b/src/Modules/ContactAdminModule/Services/ContactAdminService.cs new file mode 100644 index 000000000..69c514fa9 --- /dev/null +++ b/src/Modules/ContactAdminModule/Services/ContactAdminService.cs @@ -0,0 +1,89 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text; +using EvoSC.Common.Interfaces; +using EvoSC.Common.Interfaces.Database.Repository; +using EvoSC.Common.Interfaces.Models; +using EvoSC.Common.Interfaces.Services; +using EvoSC.Common.Services.Attributes; +using EvoSC.Common.Services.Models; +using EvoSC.Manialinks.Interfaces; +using EvoSC.Modules.Nsgr.ContactAdminModule.Config; +using EvoSC.Modules.Nsgr.ContactAdminModule.Interfaces; +using GbxRemoteNet.Events; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; + +namespace EvoSC.Modules.Nsgr.ContactAdminModule.Services; + +[Service(LifeStyle = ServiceLifeStyle.Transient)] +public class ContactAdminService( + IManialinkManager manialinkManager, + ILogger logger, + IServerClient client, + IChatService chat, + IContactAdminSettings settings +) + : IContactAdminService +{ + private readonly HttpClient _http = new(); + + public async Task ShowWidgetAsync() + { + await manialinkManager.SendPersistentManialinkAsync("ContactAdminModule.ContactAdminWidget"); + logger.LogDebug("Showing 'Contact Admin' widget"); + } + + public async Task HideWidgetAsync() + { + await manialinkManager.HideManialinkAsync("ContactAdminModule.ContactAdminWidget"); + logger.LogDebug("Hiding 'Contact Admin' widget"); + } + + public async Task ContactAdminAsync(IOnlinePlayer? contextPlayer) + { + var serverName = await client.Remote.GetServerNameAsync(); + + var discordMessage = contextPlayer is null + ? $"Help requested on server {serverName}" + : $"{contextPlayer.NickName} requested help on server {serverName}"; + + // Check for suffix so we can ping people on Discord + if (settings.MessageSuffix.Length > 0) + { + discordMessage += $" {settings.MessageSuffix}"; + } + + var messageObject = new { content = discordMessage }; + var json = JsonConvert.SerializeObject(messageObject); + var data = new StringContent(json, Encoding.UTF8, "application/json"); + + logger.LogTrace($"Requesting {settings.WebhookUrl}"); + + try + { + var response = await _http.PostAsync(settings.WebhookUrl, data); + if (!response.IsSuccessStatusCode) throw new Exception("The request status code was not successful."); + + logger.LogDebug("Successfully executed webhook."); + + var chatMessage = contextPlayer is null + ? "The admins were contacted." + : $"$<{contextPlayer.NickName}$> requested to contact the admins."; + + await chat.InfoMessageAsync(chatMessage); + } + catch (Exception ex) + { + logger.LogError($"Failed to execute Discord webhook: {ex.ToString()}"); + + if (contextPlayer is null) + { + await chat.ErrorMessageAsync("Could not notify admins. Please reach out manually."); + } + else + { + await chat.ErrorMessageAsync("Could not notify admins. Please reach out manually.", contextPlayer); + } + } + } +} diff --git a/src/Modules/ContactAdminModule/Templates/ContactAdminWidget.mt b/src/Modules/ContactAdminModule/Templates/ContactAdminWidget.mt new file mode 100644 index 000000000..2eb6eb0cc --- /dev/null +++ b/src/Modules/ContactAdminModule/Templates/ContactAdminWidget.mt @@ -0,0 +1,22 @@ + + + + + + + + + - diff --git a/src/Modules/Scoreboard/Templates/Components/PlayerRow/PlayerRowBackground.mt b/src/Modules/Scoreboard/Templates/Components/PlayerRow/PlayerRowBackground.mt deleted file mode 100644 index ad4154156..000000000 --- a/src/Modules/Scoreboard/Templates/Components/PlayerRow/PlayerRowBackground.mt +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/src/Modules/Scoreboard/Templates/Components/PlayerRow/PointsBox.mt b/src/Modules/Scoreboard/Templates/Components/PlayerRow/PointsBox.mt deleted file mode 100644 index fcabef295..000000000 --- a/src/Modules/Scoreboard/Templates/Components/PlayerRow/PointsBox.mt +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Modules/Scoreboard/Templates/Components/PlayerRow/PositionBox.mt b/src/Modules/Scoreboard/Templates/Components/PlayerRow/PositionBox.mt deleted file mode 100644 index 9af6a75eb..000000000 --- a/src/Modules/Scoreboard/Templates/Components/PlayerRow/PositionBox.mt +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Modules/Scoreboard/Templates/Components/ScoreboardHeader.mt b/src/Modules/Scoreboard/Templates/Components/ScoreboardHeader.mt deleted file mode 100644 index 3ddbd19e8..000000000 --- a/src/Modules/Scoreboard/Templates/Components/ScoreboardHeader.mt +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/Modules/Scoreboard/Templates/Components/Scrollbar.mt b/src/Modules/Scoreboard/Templates/Components/Scrollbar.mt deleted file mode 100644 index 61d55dddb..000000000 --- a/src/Modules/Scoreboard/Templates/Components/Scrollbar.mt +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Modules/Scoreboard/Themes/DefaultScoreboardTheme.cs b/src/Modules/Scoreboard/Themes/DefaultScoreboardTheme.cs deleted file mode 100644 index e9a88b652..000000000 --- a/src/Modules/Scoreboard/Themes/DefaultScoreboardTheme.cs +++ /dev/null @@ -1,49 +0,0 @@ -using EvoSC.Common.Interfaces.Themes; -using EvoSC.Common.Themes; -using EvoSC.Common.Themes.Attributes; -using EvoSC.Common.Util; - -namespace EvoSC.Modules.Official.Scoreboard.Themes; - -[Theme(Name = "Scoreboard", Description = "Default theme for the scoreboard.")] -public class DefaultScoreboardTheme(IThemeManager theme) : Theme -{ - private readonly dynamic _theme = theme.Theme; - - public override Task ConfigureAsync() - { - Set("ScoreboardModule.BackgroundBox.BgHeader").To(_theme.UI_BgPrimary); - Set("ScoreboardModule.BackgroundBox.BgHeaderGrad").To(ColorUtils.Darken(_theme.UI_BgPrimary)); - Set("ScoreboardModule.BackgroundBox.BgList").To(_theme.UI_BgHighlight); - - Set("ScoreboardModule.ScoreboardHeader.Text").To(_theme.UI_TextPrimary); - Set("ScoreboardModule.ScoreboardHeader.Logo").To(_theme.UI_LogoLight); - - Set("ScoreboardModule.ClubTag.Bg").To(_theme.UI_BgHighlight); - - Set("ScoreboardModule.PlayerRow.Text").To(_theme.UI_TextPrimary); - Set("ScoreboardModule.PlayerRow.CustomLabelBackground.Bg").To(_theme.Black); - - Set("ScoreboardModule.PlayerRow.PlayerActions.BgHighlight").To(_theme.UI_BgHighlight); - - Set("ScoreboardModule.PlayerRow.PlayerRowBackground.Bg").To(ColorUtils.Lighten(_theme.UI_BgHighlight)); - Set("ScoreboardModule.PlayerRow.PlayerRowBackground.BgHighlight").To(ColorUtils.SetLightness(_theme.UI_BgHighlight, 70)); - - Set("ScoreboardModule.PlayerRow.PointsBox.Bg").To(ColorUtils.SetLightness(_theme.UI_BgHighlight, 70)); - Set("ScoreboardModule.PlayerRow.PointsBox.Text").To(ColorUtils.SetLightness(_theme.UI_BgHighlight, 20)); - - Set("ScoreboardModule.PlayerRow.PositionBox.Bg").To(_theme.UI_BgHighlight); - - Set("ScoreboardModule.PlayerRow.FrameModel.Bg").To(_theme.UI_BgHighlight); - - Set("ScoreboardModule.PlayerRow.FrameModel.Text").To(_theme.UI_TextPrimary); - Set("ScoreboardModule.PlayerRow.FrameModel.BgRow").To(_theme.UI_BgHighlight); - Set("ScoreboardModule.PlayerRow.FrameModel.TextRoundPoints").To(_theme.UI_TextSecondary); - - Set("ScoreboardModule.Scoreboard.BgPosition").To(_theme.UI_BgHighlight); - - Set("ScoreboardModule.Settings.Text").To(_theme.UI_TextPrimary); - - return Task.CompletedTask; - } -} diff --git a/src/Modules/ScoreboardModule/Config/IScoreboardSettings.cs b/src/Modules/ScoreboardModule/Config/IScoreboardSettings.cs new file mode 100644 index 000000000..60b50627b --- /dev/null +++ b/src/Modules/ScoreboardModule/Config/IScoreboardSettings.cs @@ -0,0 +1,15 @@ +using System.ComponentModel; +using Config.Net; +using EvoSC.Modules.Attributes; + +namespace EvoSC.Modules.Official.ScoreboardModule.Config; + +[Settings] +public interface IScoreboardSettings +{ + [Option(DefaultValue = 160.0), Description("Sets the width of the scoreboard.")] + public double Width { get; } + + [Option(DefaultValue = 80.0), Description("Sets the height of the scoreboard.")] + public double Height { get; } +} diff --git a/src/Modules/ScoreboardModule/Controllers/ScoreboardEventController.cs b/src/Modules/ScoreboardModule/Controllers/ScoreboardEventController.cs new file mode 100644 index 000000000..9943a7af6 --- /dev/null +++ b/src/Modules/ScoreboardModule/Controllers/ScoreboardEventController.cs @@ -0,0 +1,28 @@ +using EvoSC.Common.Controllers; +using EvoSC.Common.Controllers.Attributes; +using EvoSC.Common.Events.Attributes; +using EvoSC.Common.Interfaces.Controllers; +using EvoSC.Common.Remote; +using EvoSC.Modules.Official.ScoreboardModule.Interfaces; +using GbxRemoteNet.Events; + +namespace EvoSC.Modules.Official.ScoreboardModule.Controllers; + +[Controller] +public class ScoreboardEventController( + IScoreboardService scoreboardService, + IScoreboardNicknamesService nicknamesService +) + : EvoScController +{ + [Subscribe(GbxRemoteEvent.PlayerConnect)] + public Task OnPlayerConnectAsync(object sender, PlayerGbxEventArgs args) => + nicknamesService.AddNicknameByLoginAsync(args.Login); + + [Subscribe(GbxRemoteEvent.BeginMap)] + public async Task OnBeginMapAsync(object sender, MapGbxEventArgs args) + { + await nicknamesService.LoadNicknamesAsync(); + await scoreboardService.SendScoreboardAsync(); + } +} diff --git a/src/Modules/ScoreboardModule/Interfaces/IScoreboardNicknamesService.cs b/src/Modules/ScoreboardModule/Interfaces/IScoreboardNicknamesService.cs new file mode 100644 index 000000000..a3023558b --- /dev/null +++ b/src/Modules/ScoreboardModule/Interfaces/IScoreboardNicknamesService.cs @@ -0,0 +1,50 @@ +namespace EvoSC.Modules.Official.ScoreboardModule.Interfaces; + +public interface IScoreboardNicknamesService +{ + /// + /// Gets the online player by login and then sets their custom nickname in the repo. + /// + /// + /// + public Task AddNicknameByLoginAsync(string login); + + /// + /// Clears the nicknames repo. + /// + /// + public Task ClearNicknamesAsync(); + + /// + /// Gets all online players and sets their custom nicknames in the repo. + /// + /// + public Task LoadNicknamesAsync(); + + /// + /// Sends the manialink containing the nicknames in the repo. + /// + /// + public Task SendNicknamesManialinkAsync(); + + /// + /// Converts the nickname repo to a ManiaScript array. + /// + /// + /// + public string ToManiaScriptArray(Dictionary nicknameMap); + + /// + /// Converts an entry of the nickname repo to a ManiaScript array entry. + /// + /// + /// + public string ToManiaScriptArrayEntry(KeyValuePair loginNickname); + + /// + /// Escapes a nickname to be safely inserted into a XMl comment. + /// + /// + /// + public string EscapeNickname(string nickname); +} diff --git a/src/Modules/ScoreboardModule/Interfaces/IScoreboardService.cs b/src/Modules/ScoreboardModule/Interfaces/IScoreboardService.cs new file mode 100644 index 000000000..9dc5c0624 --- /dev/null +++ b/src/Modules/ScoreboardModule/Interfaces/IScoreboardService.cs @@ -0,0 +1,19 @@ +namespace EvoSC.Modules.Official.ScoreboardModule.Interfaces; + +public interface IScoreboardService +{ + /// + /// Sends the scoreboard manialink to all players. + /// + public Task SendScoreboardAsync(); + + /// + /// Hide the default game scoreboard. + /// + public Task HideNadeoScoreboardAsync(); + + /// + /// Shows the default game scoreboard. + /// + public Task ShowNadeoScoreboardAsync(); +} diff --git a/src/Modules/ScoreboardModule/Localization.resx b/src/Modules/ScoreboardModule/Localization.resx new file mode 100644 index 000000000..02cf34b4b --- /dev/null +++ b/src/Modules/ScoreboardModule/Localization.resx @@ -0,0 +1,19 @@ + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Modules/ScoreboardModule/ScoreboardModule.cs b/src/Modules/ScoreboardModule/ScoreboardModule.cs new file mode 100644 index 000000000..6d8235ca3 --- /dev/null +++ b/src/Modules/ScoreboardModule/ScoreboardModule.cs @@ -0,0 +1,20 @@ +using EvoSC.Modules.Attributes; +using EvoSC.Modules.Interfaces; +using EvoSC.Modules.Official.ScoreboardModule.Interfaces; + +namespace EvoSC.Modules.Official.ScoreboardModule; + +[Module(IsInternal = true)] +public class ScoreboardModule(IScoreboardService scoreboardService, IScoreboardNicknamesService nicknamesService) + : EvoScModule, IToggleable +{ + public async Task EnableAsync() + { + await nicknamesService.LoadNicknamesAsync(); + await scoreboardService.HideNadeoScoreboardAsync(); + await scoreboardService.SendScoreboardAsync(); + } + + public Task DisableAsync() => + scoreboardService.ShowNadeoScoreboardAsync(); +} diff --git a/src/Modules/Scoreboard/Scoreboard.csproj b/src/Modules/ScoreboardModule/ScoreboardModule.csproj similarity index 93% rename from src/Modules/Scoreboard/Scoreboard.csproj rename to src/Modules/ScoreboardModule/ScoreboardModule.csproj index b1ff40dea..456dbbf3f 100644 --- a/src/Modules/Scoreboard/Scoreboard.csproj +++ b/src/Modules/ScoreboardModule/ScoreboardModule.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - EvoSC.Modules.Official.Scoreboard + EvoSC.Modules.Official.ScoreboardModule diff --git a/src/Modules/ScoreboardModule/Services/ScoreboardNicknamesService.cs b/src/Modules/ScoreboardModule/Services/ScoreboardNicknamesService.cs new file mode 100644 index 000000000..7619688c8 --- /dev/null +++ b/src/Modules/ScoreboardModule/Services/ScoreboardNicknamesService.cs @@ -0,0 +1,68 @@ +using EvoSC.Common.Interfaces.Services; +using EvoSC.Common.Services.Attributes; +using EvoSC.Common.Services.Models; +using EvoSC.Common.Util; +using EvoSC.Manialinks.Interfaces; +using EvoSC.Modules.Official.ScoreboardModule.Interfaces; + +namespace EvoSC.Modules.Official.ScoreboardModule.Services; + +[Service(LifeStyle = ServiceLifeStyle.Singleton)] +public class ScoreboardNicknamesService( + IPlayerManagerService playerManagerService, + IManialinkManager manialinkManager +) : IScoreboardNicknamesService +{ + private readonly Dictionary _nicknames = new(); + + public async Task AddNicknameByLoginAsync(string login) + { + var player = await playerManagerService.GetOnlinePlayerAsync(PlayerUtils.ConvertLoginToAccountId(login)); + + if (player.NickName == player.UbisoftName) + { + return; + } + + _nicknames[login] = player.NickName; + } + + public Task ClearNicknamesAsync() + { + _nicknames.Clear(); + + return Task.CompletedTask; + } + + public async Task LoadNicknamesAsync() + { + var onlinePlayers = await playerManagerService.GetOnlinePlayersAsync(); + foreach (var player in onlinePlayers.Where(player => player.NickName != player.UbisoftName)) + { + _nicknames[player.GetLogin()] = player.NickName; + } + } + + public Task SendNicknamesManialinkAsync() => + manialinkManager.SendPersistentManialinkAsync("ScoreboardModule.PlayerNicknames", + new { nicknames = ToManiaScriptArray(_nicknames) }); + + public string ToManiaScriptArray(Dictionary nicknameMap) + { + var entriesList = nicknameMap.Select(ToManiaScriptArrayEntry).ToList(); + var joinedEntries = string.Join(",\n", entriesList); + + return $"[{joinedEntries}]"; + } + + public string ToManiaScriptArrayEntry(KeyValuePair loginNickname) + { + return $"\"{loginNickname.Key}\" => \"{EscapeNickname(loginNickname.Value)}\""; + } + + public string EscapeNickname(string nickname) + { + return nickname.Replace("-->", "-\u2192", StringComparison.OrdinalIgnoreCase) + .Replace("\"", "\\\"", StringComparison.OrdinalIgnoreCase); + } +} diff --git a/src/Modules/ScoreboardModule/Services/ScoreboardService.cs b/src/Modules/ScoreboardModule/Services/ScoreboardService.cs new file mode 100644 index 000000000..f66570308 --- /dev/null +++ b/src/Modules/ScoreboardModule/Services/ScoreboardService.cs @@ -0,0 +1,64 @@ +using EvoSC.Common.Interfaces; +using EvoSC.Common.Interfaces.Services; +using EvoSC.Common.Services.Attributes; +using EvoSC.Common.Services.Models; +using EvoSC.Manialinks.Interfaces; +using EvoSC.Modules.Official.GameModeUiModule.Enums; +using EvoSC.Modules.Official.GameModeUiModule.Interfaces; +using EvoSC.Modules.Official.ScoreboardModule.Config; +using EvoSC.Modules.Official.ScoreboardModule.Interfaces; + +namespace EvoSC.Modules.Official.ScoreboardModule.Services; + +[Service(LifeStyle = ServiceLifeStyle.Transient)] +public class ScoreboardService( + IManialinkManager manialinks, + IServerClient server, + IScoreboardNicknamesService nicknamesService, + IScoreboardSettings settings, + IGameModeUiModuleService gameModeUiModuleService, + IMatchSettingsService matchSettingsService +) + : IScoreboardService +{ + private const string ScoreboardTemplate = "ScoreboardModule.Scoreboard"; + + public async Task SendScoreboardAsync() + { + await manialinks.SendPersistentManialinkAsync(ScoreboardTemplate, await GetDataAsync()); + await nicknamesService.SendNicknamesManialinkAsync(); + } + + private async Task GetDataAsync() + { + var currentNextMaxPlayers = await server.Remote.GetMaxPlayersAsync(); + var currentNextMaxSpectators = await server.Remote.GetMaxSpectatorsAsync(); + var modeScriptSettings = await matchSettingsService.GetCurrentScriptSettingsAsync(); + + return new + { + settings, + MaxPlayers = currentNextMaxPlayers.CurrentValue + currentNextMaxSpectators.CurrentValue, + PointsLimit = (int)(modeScriptSettings?["S_PointsLimit"] ?? 0), + RoundsPerMap = (int)(modeScriptSettings?["S_RoundsPerMap"] ?? 0), + }; + } + + public Task HideNadeoScoreboardAsync() => + gameModeUiModuleService.ApplyComponentSettingsAsync( + GameModeUiComponents.ScoresTable, + false, + 0.0, + 0.0, + 1.0 + ); + + public Task ShowNadeoScoreboardAsync() => + gameModeUiModuleService.ApplyComponentSettingsAsync( + GameModeUiComponents.ScoresTable, + true, + 0.0, + 0.0, + 1.0 + ); +} diff --git a/src/Modules/ScoreboardModule/Templates/Components/Body/Legend.mt b/src/Modules/ScoreboardModule/Templates/Components/Body/Legend.mt new file mode 100644 index 000000000..b0ad6e0a8 --- /dev/null +++ b/src/Modules/ScoreboardModule/Templates/Components/Body/Legend.mt @@ -0,0 +1,86 @@ + + + + + + + + + + + + diff --git a/src/Modules/ScoreboardModule/Templates/Components/Header/HeaderBackground.mt b/src/Modules/ScoreboardModule/Templates/Components/Header/HeaderBackground.mt new file mode 100644 index 000000000..78adc18e1 --- /dev/null +++ b/src/Modules/ScoreboardModule/Templates/Components/Header/HeaderBackground.mt @@ -0,0 +1,11 @@ + + + + + + diff --git a/src/Modules/ScoreboardModule/Templates/Components/Header/HeaderContent.mt b/src/Modules/ScoreboardModule/Templates/Components/Header/HeaderContent.mt new file mode 100644 index 000000000..4415f8cc2 --- /dev/null +++ b/src/Modules/ScoreboardModule/Templates/Components/Header/HeaderContent.mt @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/Modules/ScoreboardModule/Templates/Components/Header/Logo.mt b/src/Modules/ScoreboardModule/Templates/Components/Header/Logo.mt new file mode 100644 index 000000000..c1a8ad19a --- /dev/null +++ b/src/Modules/ScoreboardModule/Templates/Components/Header/Logo.mt @@ -0,0 +1,14 @@ + + + + + + diff --git a/src/Modules/ScoreboardModule/Templates/Components/Row/CustomLabelBackground.mt b/src/Modules/ScoreboardModule/Templates/Components/Row/CustomLabelBackground.mt new file mode 100644 index 000000000..74cf71d74 --- /dev/null +++ b/src/Modules/ScoreboardModule/Templates/Components/Row/CustomLabelBackground.mt @@ -0,0 +1,20 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/Modules/ScoreboardModule/Templates/Components/Row/Flag.mt b/src/Modules/ScoreboardModule/Templates/Components/Row/Flag.mt new file mode 100644 index 000000000..a53876481 --- /dev/null +++ b/src/Modules/ScoreboardModule/Templates/Components/Row/Flag.mt @@ -0,0 +1,11 @@ + + + + + diff --git a/src/Modules/ScoreboardModule/Templates/Components/Row/Framemodel.mt b/src/Modules/ScoreboardModule/Templates/Components/Row/Framemodel.mt new file mode 100644 index 000000000..e38ae2fbe --- /dev/null +++ b/src/Modules/ScoreboardModule/Templates/Components/Row/Framemodel.mt @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Modules/Scoreboard/Templates/Components/PlayerRow/PlayerActions.mt b/src/Modules/ScoreboardModule/Templates/Components/Row/PlayerActions.mt similarity index 59% rename from src/Modules/Scoreboard/Templates/Components/PlayerRow/PlayerActions.mt rename to src/Modules/ScoreboardModule/Templates/Components/Row/PlayerActions.mt index 58ad3f4de..45d13b8a1 100644 --- a/src/Modules/Scoreboard/Templates/Components/PlayerRow/PlayerActions.mt +++ b/src/Modules/ScoreboardModule/Templates/Components/Row/PlayerActions.mt @@ -2,36 +2,36 @@ - - + diff --git a/src/Modules/ScoreboardModule/Templates/Components/Row/PlayerRowBackground.mt b/src/Modules/ScoreboardModule/Templates/Components/Row/PlayerRowBackground.mt new file mode 100644 index 000000000..8499ed831 --- /dev/null +++ b/src/Modules/ScoreboardModule/Templates/Components/Row/PlayerRowBackground.mt @@ -0,0 +1,57 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Modules/ScoreboardModule/Templates/Components/Row/PositionBox.mt b/src/Modules/ScoreboardModule/Templates/Components/Row/PositionBox.mt new file mode 100644 index 000000000..9286387b3 --- /dev/null +++ b/src/Modules/ScoreboardModule/Templates/Components/Row/PositionBox.mt @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + diff --git a/src/Modules/ScoreboardModule/Templates/Components/ScoreboardBg.mt b/src/Modules/ScoreboardModule/Templates/Components/ScoreboardBg.mt new file mode 100644 index 000000000..edf86e156 --- /dev/null +++ b/src/Modules/ScoreboardModule/Templates/Components/ScoreboardBg.mt @@ -0,0 +1,13 @@ + + + + + + diff --git a/src/Modules/ScoreboardModule/Templates/Components/ScoreboardBody.mt b/src/Modules/ScoreboardModule/Templates/Components/ScoreboardBody.mt new file mode 100644 index 000000000..403d4b037 --- /dev/null +++ b/src/Modules/ScoreboardModule/Templates/Components/ScoreboardBody.mt @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + diff --git a/src/Modules/ScoreboardModule/Templates/Components/ScoreboardHeader.mt b/src/Modules/ScoreboardModule/Templates/Components/ScoreboardHeader.mt new file mode 100644 index 000000000..9f7d22109 --- /dev/null +++ b/src/Modules/ScoreboardModule/Templates/Components/ScoreboardHeader.mt @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/src/Modules/Scoreboard/Templates/Components/Settings/Form.mt b/src/Modules/ScoreboardModule/Templates/Components/Settings/Form.mt similarity index 100% rename from src/Modules/Scoreboard/Templates/Components/Settings/Form.mt rename to src/Modules/ScoreboardModule/Templates/Components/Settings/Form.mt diff --git a/src/Modules/Scoreboard/Templates/Components/Settings/Wrapper.mt b/src/Modules/ScoreboardModule/Templates/Components/Settings/Wrapper.mt similarity index 100% rename from src/Modules/Scoreboard/Templates/Components/Settings/Wrapper.mt rename to src/Modules/ScoreboardModule/Templates/Components/Settings/Wrapper.mt diff --git a/src/Modules/ScoreboardModule/Templates/PlayerNicknames.mt b/src/Modules/ScoreboardModule/Templates/PlayerNicknames.mt new file mode 100644 index 000000000..5a252187d --- /dev/null +++ b/src/Modules/ScoreboardModule/Templates/PlayerNicknames.mt @@ -0,0 +1,10 @@ + + +