Skip to content

Commit

Permalink
feat: random multiple default model
Browse files Browse the repository at this point in the history
  • Loading branch information
samyycX committed Dec 28, 2024
1 parent 9b93526 commit a08d802
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 52 deletions.
1 change: 1 addition & 0 deletions Cache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public void SetPlayerModel(ulong steamid, string modelIndex, Side side, bool per
);

}

public ModelCache? GetPlayerModelCache(CCSPlayerController player)
{
return _Cache.Find(model => model.steamid == player!.AuthorizedSteamID!.SteamId64);
Expand Down
84 changes: 70 additions & 14 deletions DefaultModelManager.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Admin;
using Newtonsoft.Json;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace PlayerModelChanger;

Expand Down Expand Up @@ -93,22 +94,75 @@ public DefaultModelEntry(EntryKey key, DefaultModel item, Side side)
}
}

public class DefaultModelIndexConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(List<string>) || objectType == typeof(string);
}

public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.String)
{
return new List<string> { (string)reader.Value! };
}
else if (reader.TokenType == JsonToken.StartArray)
{
var list = new List<string>();
while (reader.Read())
{
if (reader.TokenType == JsonToken.EndArray)
break;
if (reader.TokenType == JsonToken.String)
list.Add((string)reader.Value!);
}
return list;
}

throw new JsonException("Expected string or array of strings");
}

public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
var list = (List<string>?)value;
if (list == null) return;

writer.WriteStartArray();
foreach (var item in list)
{
writer.WriteValue(item);
}
writer.WriteEndArray();
}
}

public class DefaultModel
{
public required string index;
public bool force;
[JsonProperty("index")]
[JsonConverter(typeof(DefaultModelIndexConverter))]
public required List<string> index;

[JsonProperty("force")]
public bool force = false;
}

class ConfigDefaultModelsTemplate
{
[JsonProperty("all")] public Dictionary<string, DefaultModel>? allModels = null;
[JsonProperty("t")] public Dictionary<string, DefaultModel>? tModels = null;
[JsonProperty("ct")] public Dictionary<string, DefaultModel>? ctModels = null;
[JsonProperty("all")]
public Dictionary<string, DefaultModel>? allModels = null;

[JsonProperty("t")]
public Dictionary<string, DefaultModel>? tModels = null;

[JsonProperty("ct")]
public Dictionary<string, DefaultModel>? ctModels = null;
}

class ConfigTemplate
{
[JsonProperty("DefaultModels")] public required ConfigDefaultModelsTemplate models { get; set; }
[JsonProperty("DefaultModels")]
public required ConfigDefaultModelsTemplate models { get; set; }
}

public class DefaultModelManager
Expand All @@ -122,8 +176,7 @@ public void ReloadConfig(string ModuleDirectory, ModelService service)
var filePath = Path.Join(ModuleDirectory, "../../configs/plugins/PlayerModelChanger/DefaultModels.json");
if (File.Exists(filePath))
{
StreamReader reader = File.OpenText(filePath);
string content = reader.ReadToEnd();
string content = File.ReadAllText(filePath);
ConfigTemplate config = JsonConvert.DeserializeObject<ConfigTemplate>(content)!;

DefaultModels = ParseModelConfig(config.models, service);
Expand Down Expand Up @@ -188,11 +241,14 @@ private static List<DefaultModelEntry> ParseModelConfig(ConfigDefaultModelsTempl
}
for (var i = 0; i < defaultModels.Count; i++)
{

if (service.GetModel(defaultModels[i].item.index) == null)
foreach (var index in defaultModels[i].item.index)
{
PlayerModelChanger.getInstance().Logger.LogInformation($"model '${defaultModels[i].item.index}' defined in DefaultModels.json does not exist. Skipped.");
defaultModels.RemoveAt(i);
if (index != "" || service.GetModel(index) == null)
{
PlayerModelChanger.getInstance().Logger.LogInformation($"model '${index}' defined in DefaultModels.json does not exist. Skipped.");
defaultModels.RemoveAt(i);
break;
}
}
}
return defaultModels;
Expand Down Expand Up @@ -226,7 +282,7 @@ private static List<DefaultModelEntry> ParseModelConfig(ConfigDefaultModelsTempl
{
return null;
}
if (result.item == null || result.item.index == "")
if (result.item == null || result.item.index.Count == 0)
{
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class Model
[JsonConverter(typeof(CaseInsensitiveJsonStringEnumConverter))]
public Side Side { get; set; } = Side.All;
[JsonPropertyName("disableleg")] public bool Disableleg { get; set; }
[JsonPropertyName("hideinmenu")] public bool Hideinmenu { get; set; }
[JsonPropertyName("hideinmenu")] public bool HideInMenu { get; set; }
[JsonPropertyName("fixedmeshgroups")] public Dictionary<int, int> FixedMeshgroups { get; set; } = [];
[JsonPropertyName("meshgroups")] public Dictionary<string, dynamic> Meshgroups { get; set; } = new();
}
Expand Down
33 changes: 18 additions & 15 deletions PlayerModelChanger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
using System.Drawing;
using CounterStrikeSharp.API.Modules.Config;
using Microsoft.Extensions.Logging;
using CounterStrikeSharp.API.Modules.Memory;
using System.Runtime.InteropServices;
namespace PlayerModelChanger;

public partial class PlayerModelChanger : BasePlugin, IPluginConfig<ModelConfig>
{
public override string ModuleName => "Player Model Changer";
public override string ModuleVersion => "1.8.2";
public override string ModuleVersion => "1.8.3";

public override string ModuleAuthor => "samyyc";
public required ModelConfig Config { get; set; }
Expand Down Expand Up @@ -100,8 +102,6 @@ public override void Unload(bool hotReload)
RemoveListener<Listeners.OnTick>(OnTick);
DeregisterEventHandler<EventPlayerSpawn>(OnPlayerSpawnEvent);
Logger.LogInformation("Unloaded successfully.");


}

public static PlayerModelChanger getInstance()
Expand Down Expand Up @@ -265,24 +265,27 @@ public HookResult OnPlayerSpawnEvent(EventPlayerSpawn @event, GameEventInfo info
}
}

Server.NextFrame(() =>
AddTimer(0.03f, () =>
{
if (!Service.MapDefaultModelInitialized(player))
{
Service.SetMapDefaultModel(player, player.PlayerPawn.Value.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.ModelName);
}
Server.NextFrame(() =>
{
var model = Service.GetPlayerNowTeamModel(player);
if (model != null)
if (!Service.MapDefaultModelInitialized(player))
{
SetModelNextServerFrame(player, model, model.Disableleg);
Service.SetMapDefaultModel(player, player.PlayerPawn.Value.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.ModelName);
}
else
Server.NextFrame(() =>
{
var originalRender = player.PlayerPawn.Value.Render;
player.PlayerPawn.Value.Render = Color.FromArgb(255, originalRender.R, originalRender.G, originalRender.B);
}
var model = Service.GetPlayerNowTeamModel(player);
if (model != null)
{
SetModelNextServerFrame(player, model, model.Disableleg);
}
else
{
var originalRender = player.PlayerPawn.Value.Render;
player.PlayerPawn.Value.Render = Color.FromArgb(255, originalRender.R, originalRender.G, originalRender.B);
}
});
});
});
}
Expand Down
58 changes: 38 additions & 20 deletions Service.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ public static void InitializeModel(string key, Model model)
model.Name = model.Index;
}
}

public void ReloadConfig(string ModuleDirectory, ModelConfig config)
{
this._Config = config;
Expand Down Expand Up @@ -125,6 +124,7 @@ public void SetPlayerAllModel(ulong steamid, string? tModel, string? ctModel, bo
}
}
}

public void SetPlayerModel(ulong steamid, string? modelIndex, CsTeam team, bool permissionBypass)
{
var side = team == CsTeam.Terrorist ? Side.T : Side.CT;
Expand Down Expand Up @@ -157,24 +157,24 @@ public Tuple<bool, bool> CheckAndReplaceModel(CCSPlayerController player)
var defaultCTModel = _DefaultModelManager.GetPlayerDefaultModel(player, Side.CT);
if (modelCache == null) // player first time join
{
SetPlayerAllModel(steamid, defaultTModel?.index, defaultCTModel?.index, false, false);
SetPlayerAllModel(steamid, "@default", "@default", false, false);
return new Tuple<bool, bool>(false, false);
}
var tValid = CheckModel(player, Side.T, modelCache, defaultTModel);
var ctValid = CheckModel(player, Side.CT, modelCache, defaultCTModel);
if (!tValid && !ctValid)
{
SetPlayerAllModel(steamid, defaultTModel?.index, defaultCTModel?.index, false);
SetPlayerAllModel(steamid, "@default", "@default", false);
return new Tuple<bool, bool>(true, true);
}
else if (!tValid)
{
SetPlayerModel(steamid, defaultTModel?.index, Side.T, false);
SetPlayerModel(steamid, "@default", Side.T, false);
return new Tuple<bool, bool>(true, false);
}
else if (!ctValid)
{
SetPlayerModel(steamid, defaultCTModel?.index, Side.CT, false);
SetPlayerModel(steamid, "@default", Side.CT, false);
return new Tuple<bool, bool>(false, true);
}
return new Tuple<bool, bool>(false, false);
Expand All @@ -192,18 +192,15 @@ public bool CheckModel(CCSPlayerController player, Side side, ModelCache? modelC
{
return true;
}
if (defaultModel != null && defaultModel.force)
if (defaultModel != null && defaultModel.force && modelIndex != "@default")
{
if (modelIndex != defaultModel.index)
{
return false;
}
return false;
}
if (modelIndex == "@random" && _Config.DisableRandomModel)
{
return false;
}
if (modelIndex == "" || modelIndex == "@random")
if (modelIndex == "" || modelIndex == "@random" || modelIndex == "@default")
{
return true;
}
Expand All @@ -216,28 +213,35 @@ public bool CheckModel(CCSPlayerController player, Side side, ModelCache? modelC
return CanPlayerApplyModel(player, side, model);
}

public bool SetPlayerModelWithCheck(CCSPlayerController player, string modelIndex, Side side)
private bool IsPlayerInCooldown(CCSPlayerController player)
{
if (_ModelChangeCooldown.ContainsKey(player.SteamID))
{
var lastTime = _ModelChangeCooldown[player.SteamID];
if (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - lastTime < (_Config.ModelChangeCooldownSecond * 1000))
{
player.PrintToChat(_Localizer["command.model.cooldown"]);
return false;
return true;
}
}
return false;
}

public bool SetPlayerModelWithCheck(CCSPlayerController player, string modelIndex, Side side)
{
if (IsPlayerInCooldown(player))
{
return false;
}

var isSpecial = modelIndex == "" || modelIndex == "@random";

if (modelIndex == "@default")
{
var tDefault = _DefaultModelManager.GetPlayerDefaultModel(player, Side.T);
var ctDefault = _DefaultModelManager.GetPlayerDefaultModel(player, Side.CT);
Utils.ExecuteSide(side,
() => SetPlayerAllModel(player!.AuthorizedSteamID!.SteamId64, tDefault == null ? "" : tDefault.index, ctDefault == null ? "" : ctDefault.index, false),
() => SetPlayerModel(player!.AuthorizedSteamID!.SteamId64, tDefault == null ? "" : tDefault.index, side, false),
() => SetPlayerModel(player!.AuthorizedSteamID!.SteamId64, ctDefault == null ? "" : ctDefault.index, side, false)
() => SetPlayerAllModel(player!.AuthorizedSteamID!.SteamId64, "@default", "@default", false),
() => SetPlayerModel(player!.AuthorizedSteamID!.SteamId64, "@default", side, false),
() => SetPlayerModel(player!.AuthorizedSteamID!.SteamId64, "@default", side, false)
);
if (_Config.DisableInstantChange || !Utils.CanPlayerSetModelInstantly(player, side))
{
Expand Down Expand Up @@ -277,8 +281,8 @@ public bool SetPlayerModelWithCheck(CCSPlayerController player, string modelInde
player.PrintToChat(_Localizer["command.model.success", _Localizer["side." + side.ToName()]]);
}
return true;

}

public Model? GetPlayerModel(CCSPlayerController player, Side side)
{
if (side == Side.All)
Expand All @@ -303,6 +307,20 @@ public bool SetPlayerModelWithCheck(CCSPlayerController player, string modelInde
var index = Random.Shared.Next(models.Count());
return models[index];
}
if (modelIndex == "@default")
{
var defaultModel = _DefaultModelManager.GetPlayerDefaultModel(player, side);
if (defaultModel == null || defaultModel.index.Count == 0)
{
return null;
}
var index = defaultModel.index[Random.Shared.Next(defaultModel.index.Count)];
if (index == "")
{
return null;
}
return GetModel(index);
}
return GetModel(modelIndex);
}

Expand All @@ -316,6 +334,7 @@ public bool SetPlayerModelWithCheck(CCSPlayerController player, string modelInde
var side = team == CsTeam.Terrorist ? Side.T : Side.CT;
return GetPlayerModel(player, side);
}

public string GetPlayerModelName(CCSPlayerController player, CsTeam team)
{
var modelCache = _CacheManager.GetPlayerModelCache(player);
Expand Down Expand Up @@ -457,5 +476,4 @@ public void ClearMapDefaultModel()
{
_MapDefaultModels.Clear();
}

}
1 change: 0 additions & 1 deletion Storage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ public interface IStorage
public void SetPlayerCTModel(ulong SteamID, string modelIndex, bool permissionBypass);
public void SetAllTModel(string tmodel, bool permissionBypass);
public void SetAllCTModel(string ctmodel, bool permissionBypass);

public List<int> GetMeshgroupPreference(ulong SteamID, string modelIndex);
public void AddMeshgroupPreference(ulong SteamID, string modelIndex, int meshgroup);
public void RemoveMeshgroupPreference(ulong SteamID, string modelIndex, int meshgroup);
Expand Down
Binary file modified build/Release/PlayerModelChanger/PlayerModelChanger.dll
Binary file not shown.
Binary file modified build/Release/PlayerModelChanger/PlayerModelChanger.pdb
Binary file not shown.
2 changes: 1 addition & 1 deletion commands/CommandModelMenu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public WasdModelMenu GetSelectModelMenu(CCSPlayerController player, Side side)

foreach (var model in models)
{
if (model.Hideinmenu)
if (model.HideInMenu)
{
continue;
}
Expand Down

0 comments on commit a08d802

Please sign in to comment.