Skip to content

Commit

Permalink
Merge pull request #259 from MrDave1999/dev
Browse files Browse the repository at this point in the history
9.2.0 Release
  • Loading branch information
MrDave1999 authored Dec 21, 2024
2 parents 226202c + 6c62129 commit d56d080
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 56 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ServerInfo__HostName=[CTF] Capture The Flag | Team Deathmatch | [TDM]
ServerInfo__LanguageText=English
ServerInfo__GameModeText=CTF/Team Deathmatch [v9.1]
ServerInfo__GameModeText=CTF/Team Deathmatch [v9]
ServerInfo__MapName=RC_Battlefield
ServerInfo__WebUrl=https://github.com/MrDave1999/Capture-The-Flag
ServerInfo__IntroAudioUrl=https://od.lk/s/Nl8yMDg4MTc0NDBf/intro-cs.mp3
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/deploy-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ jobs:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.PRIVATE_KEY }}
port: 22
port: ${{ secrets.PORT }}
script: |
cd ctf-prod
git pull origin main
git status
sudo docker compose up --build -d
sudo docker builder prune -f
sudo docker builder prune -f -a
sudo docker image prune -f -a
5 changes: 3 additions & 2 deletions .github/workflows/deploy-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ jobs:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.PRIVATE_KEY }}
port: 22
port: ${{ secrets.PORT }}
script: |
cd ctf-test
git pull origin dev
git status
sudo docker compose up --build -d
sudo docker builder prune -f
sudo docker builder prune -f -a
sudo docker image prune -f -a
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
namespace CTF.Application;

public class CommandLockMiddleware(
public class PlayerCommandLockMiddleware(
IEntityManager entityManager,
EventDelegate next,
MapRotationService mapRotationService)
{
/// <summary>
/// Invokes the middleware logic to lock player commands if certain conditions are met.
/// </summary>
/// <param name="context">Contains context information about the fired event.</param>
/// <returns>
/// <see langword="null"/> if any condition is met to block the command.
/// Otherwise, it proceeds to the next middleware or action.
/// </returns>
public object Invoke(EventContext context)
{
int playerId = (int)context.Arguments[0];
Expand Down
9 changes: 9 additions & 0 deletions src/Application/Players/Combos/ComboSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ public ComboSystem(
_tablistDialog.Add(combo.Name, combo.RequiredCoins.ToString());
}

[Event]
public void OnPlayerKeyStateChange(Player player, Keys newKeys, Keys oldKeys)
{
if (KeyUtils.HasPressed(newKeys, oldKeys, Keys.AnalogLeft))
{
ShowCombos(player);
}
}

[PlayerCommand("combos")]
public async void ShowCombos(Player player)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
namespace CTF.Application.Players.GeneralCommands;
namespace CTF.Application.Players.GeneralCommands.Public;

public class PublicCommands(
IEntityManager entityManager,
IDialogService dialogService) : ISystem
{
[PlayerCommand("cmds")]
public void ShowCommands(Player player)
{
var content = Smart.Format(DetailedCommandInfo.Public, new
{
Color1 = Color.Yellow,
Color2 = Color.White
});
var dialog = new MessageDialog(caption: "Commands", content, "Close");
dialogService.ShowAsync(player, dialog);
}

[PlayerCommand("help")]
public void ShowHelp(Player player)
{
Expand Down
41 changes: 41 additions & 0 deletions src/Application/Players/GeneralCommands/Public/ShowCommands.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace CTF.Application.Players.GeneralCommands.Public;

public class ShowCommands(IDialogService dialogService) : ISystem
{
[PlayerCommand("cmds")]
public async void ShowFirstDialog(Player player)
{
var content = Smart.Format(DetailedCommandInfo.Public1, new
{
Color1 = Color.Yellow,
Color2 = Color.White
});
var firstDialog = new MessageDialog(
caption: "Commands [1/2]",
content,
button1: "Next",
button2: "Close"
);
var response = await dialogService.ShowAsync(player, firstDialog);
if (response.Response == DialogResponse.LeftButton)
ShowNextDialog(player);
}

private async void ShowNextDialog(Player player)
{
var content = Smart.Format(DetailedCommandInfo.Public2, new
{
Color1 = Color.Yellow,
Color2 = Color.White
});
var nextDialog = new MessageDialog(
caption: "Commands [2/2]",
content,
button1: "Previous",
button2: "Close"
);
var response = await dialogService.ShowAsync(player, nextDialog);
if (response.Response == DialogResponse.LeftButton)
ShowFirstDialog(player);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -177,23 +177,32 @@ Beware! Enemies will see flag carriers on their radar as well!</value>

{Color1}Use the '&amp;' symbol at the start of your message to access the private moderator chat.</value>
</data>
<data name="Public" xml:space="preserve">
<data name="Public1" xml:space="preserve">
<value>{Color1}/help: {Color2}Display an introduction to the Capture The Flag game mode.
{Color1}/credits: {Color2}Show credits for the game and contributors.
{Color1}/ranks: {Color2}List the different player ranks and their requirements.
{Color1}/mystats: {Color2}Display the statistics of the current player.
{Color1}/stats: {Color2}Show the statistics of a specified player.
{Color1}/tstats: {Color2}Display the statistics of the teams (Alpha and Beta).
{Color1}/topkills: {Color2}Display the list of top players based on their total number of kills.
{Color1}/topspree: {Color2}Display the list of top players based on their maximum killing spree.
{Color1}/changepass: {Color2}Change your account password.
{Color1}/changename: {Color2}Change your account name.
{Color1}/skin: {Color2}Change your character's skin.
{Color1}/weapons: {Color2}Display a list of available weapons
{Color1}/pack: {Color2}Display your current weapons package.
{Color1}/combos: {Color2}Display a list of available combos and their benefits.
{Color1}/team: {Color2}Switch to a different team.
{Color1}/scoreboard: {Color2}Show the current scoreboard with player scores.

{Color1}Shortcuts:
{Color2}Use the '!' symbol at the start of your message to access the private team chat.
{Color2}Use the 'N' key to show the scoreboard with the players of both teams.
{Color2}Use the 'Y' key to show the weapons menu.
{Color2}Use the 'H' key to show your current weapons package.
{Color2}Use the 'NUM 4' key to show a list of available combos and their benefits.</value>
</data>
<data name="Public2" xml:space="preserve">
<value>{Color1}/topkills: {Color2}Display the list of top players based on their total number of kills.
{Color1}/topspree: {Color2}Display the list of top players based on their maximum killing spree.
{Color1}/team: {Color2}Switch to a different team.
{Color1}/kill: {Color2}Eliminate your character for respawn purposes.
{Color1}/re: {Color2}Reset the statistics of the current player.
{Color1}/admins: {Color2}List the current server administrators.
Expand All @@ -203,10 +212,7 @@ Beware! Enemies will see flag carriers on their radar as well!</value>
{Color1}/class: {Color2}Redirect to the class selection menu and enter AFK mode.
{Color1}/cmdsvip: {Color2}Display a list of commands available to VIP players.
{Color1}/cmdsadmin: {Color2}Show the commands accessible to server administrators.
{Color1}/cmdsmoderator: {Color2}Show the commands accessible to server moderators.

{Color1}Use the '!' symbol at the start of your message to access the private team chat.
{Color1}Use the 'N' key to show the scoreboard with the players of both teams.</value>
{Color1}/cmdsmoderator: {Color2}Show the commands accessible to server moderators.</value>
</data>
<data name="VIP" xml:space="preserve">
<value>{Color1}/armour: {Color2}Grants you temporary armour, reducing damage taken from attacks.
Expand Down
37 changes: 29 additions & 8 deletions src/Application/Players/Weapons/WeaponSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

public class WeaponSystem : ISystem
{
private readonly IDialogService _dialogService;
private readonly ListDialog _weaponsDialog;
public WeaponSystem()
public WeaponSystem(IDialogService dialogService)
{
_dialogService = dialogService;
_weaponsDialog = new ListDialog("Weapons", "Select", "Close");
var weapons = GtaWeapons.GetAll();
foreach (IWeapon weapon in weapons)
Expand All @@ -17,6 +19,25 @@ public void OnPlayerConnect(Player player)
player.AddComponent<WeaponSelectionComponent>();
}

[Event]
public void OnPlayerRequestSpawn(Player player)
{
ShowWeapons(player);
}

[Event]
public void OnPlayerKeyStateChange(Player player, Keys newKeys, Keys oldKeys)
{
if (KeyUtils.HasPressed(newKeys, oldKeys, Keys.Yes))
{
ShowWeapons(player);
}
else if (KeyUtils.HasPressed(newKeys,oldKeys, Keys.CtrlBack))
{
ShowWeaponPackage(player);
}
}

[Event]
public void OnPlayerSpawn(Player player)
{
Expand All @@ -32,11 +53,11 @@ public void OnPlayerSpawn(Player player)
}

[PlayerCommand("weapons")]
public async void ShowWeapons(Player player, IDialogService dialogService)
public async void ShowWeapons(Player player)
{
var weaponSelection = player.GetComponent<WeaponSelectionComponent>();
WeaponPack selectedWeapons = weaponSelection.SelectedWeapons;
ListDialogResponse response = await dialogService.ShowAsync(player, _weaponsDialog);
ListDialogResponse response = await _dialogService.ShowAsync(player, _weaponsDialog);
if (response.IsRightButtonOrDisconnected())
return;

Expand All @@ -45,7 +66,7 @@ public async void ShowWeapons(Player player, IDialogService dialogService)
{
var message = Smart.Format(Messages.WeaponAlreadyExists, weaponSelectedFromDialog);
player.SendClientMessage(Color.Red, message);
ShowWeapons(player, dialogService);
ShowWeapons(player);
return;
}

Expand All @@ -55,11 +76,11 @@ public async void ShowWeapons(Player player, IDialogService dialogService)
var message = Smart.Format(Messages.WeaponSuccessfullyAdded, weaponSelectedFromDialog);
player.SendClientMessage(Color.Yellow, message);
}
ShowWeapons(player, dialogService);
ShowWeapons(player);
}

[PlayerCommand("pack")]
public async void ShowWeaponPackage(Player player, IDialogService dialogService)
public async void ShowWeaponPackage(Player player)
{
var weaponSelection = player.GetComponent<WeaponSelectionComponent>();
WeaponPack selectedWeapons = weaponSelection.SelectedWeapons;
Expand All @@ -72,7 +93,7 @@ public async void ShowWeaponPackage(Player player, IDialogService dialogService)
foreach (IWeapon weapon in selectedWeapons)
dialog.Add(weapon.Name);

ListDialogResponse response = await dialogService.ShowAsync(player, dialog);
ListDialogResponse response = await _dialogService.ShowAsync(player, dialog);
if (response.IsRightButtonOrDisconnected())
return;

Expand All @@ -83,6 +104,6 @@ public async void ShowWeaponPackage(Player player, IDialogService dialogService)
player.ResetWeapons();
foreach (IWeapon weapon in selectedWeapons)
player.GiveWeapon(weapon.Id, IWeapon.UnlimitedAmmo);
ShowWeaponPackage(player, dialogService);
ShowWeaponPackage(player);
}
}
3 changes: 2 additions & 1 deletion src/Application/SampEcsBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ public static class ApplicationEcsBuilderExtensions
public static IEcsBuilder RegisterMiddlewares(this IEcsBuilder builder)
{
builder
.UseMiddleware<CommandLockMiddleware>(name: "OnPlayerCommandText");
.UseMiddleware<PlayerCommandLockMiddleware>(name: "OnPlayerCommandText")
.UseMiddleware<PlayerRequestSpawnMiddleware>(name: "OnPlayerRequestSpawn");

return builder;
}
Expand Down
17 changes: 0 additions & 17 deletions src/Application/Teams/ClassSelection/ClassSelectionSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ public class ClassSelectionSystem(
IWorldService worldService,
ClassSelectionTextDrawRenderer classSelectionTextDrawRenderer,
TeamTextDrawRenderer teamTextDrawRenderer,
MapRotationService mapRotationService,
ServerSettings serverSettings) : ISystem
{
[Event]
Expand Down Expand Up @@ -57,23 +56,7 @@ public void OnPlayerRequestClass(Player player, int classId)
[Event]
public bool OnPlayerRequestSpawn(Player player)
{
if (player.IsUnauthenticated())
{
player.SendClientMessage(Color.Red, Messages.LoginOrRegisterToContinue);
return false;
}
if (mapRotationService.IsMapLoading())
{
player.SendClientMessage(Color.Red, Messages.MapIsLoading);
return false;
}
Team selectedTeam = player.Team == (int)TeamId.Alpha ? Team.Alpha : Team.Beta;
if (selectedTeam.IsFull())
{
string gameText = selectedTeam.GetAvailabilityMessage();
player.GameText(gameText, 999999999, 3);
return false;
}
player.DisableClassSelection();
player.HideGameText(style: 3);
player.GetInfo().SetTeam(selectedTeam.Id);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
namespace CTF.Application.Teams.ClassSelection;

public class PlayerRequestSpawnMiddleware(
IEntityManager entityManager,
EventDelegate next,
MapRotationService mapRotationService)
{
/// <summary>
/// Invokes the middleware logic to handle player spawn requests.
/// </summary>
/// <param name="context">Contains context information about the fired event.</param>
/// <returns>
/// <see langword="false"/> if any condition is met to prevent the player from spawning.
/// Otherwise, it proceeds to the next middleware or action.
/// </returns>
public object Invoke(EventContext context)
{
int playerId = (int)context.Arguments[0];
EntityId entity = SampEntities.GetPlayerId(playerId);
Player player = entityManager.GetComponent<Player>(entity);
if (player.IsUnauthenticated())
{
player.SendClientMessage(Color.Red, Messages.LoginOrRegisterToContinue);
return false;
}

if (mapRotationService.IsMapLoading())
{
player.SendClientMessage(Color.Red, Messages.MapIsLoading);
return false;
}

Team selectedTeam = player.Team == (int)TeamId.Alpha ? Team.Alpha : Team.Beta;
if (selectedTeam.IsFull())
{
string gameText = selectedTeam.GetAvailabilityMessage();
player.GameText(gameText, 999999999, 3);
return false;
}

return next(context);
}
}

0 comments on commit d56d080

Please sign in to comment.