I am new to C# development, having recently completing a 2 year software development course covering a variety of languages, i have chosen to carry on with C# as it has multiple games i can build mods for. My friend who is a developer and have been coding a lot longer then i have put together a twitch bot and mod for the popular city building game Cities Skylines.
Since finishing my course i have started to develop and make my own WPF application to give this console bot my friend made me more functionality whilst exploring what can be done in C#. In the chatbot console app he made me there is a set of cooldowns in a dictionary and a checking statemenet to stop twitch users from being able to spam the same chat command over and over which trigger in game events like disasters.
Since pulling all the code into my new project i have been able to work out and sort most of the errors that popped up but this single last one.
So here is some code, this is the dictionary which is in a file called commands.cs-
public CommandHandler()
{
// TODO: Fill the final times
cooldownManager.SetCooldown("Meteor", 60.0f);
cooldownManager.SetCooldown("Armageddon", 200.0f);
cooldownManager.SetCooldown("Tsunami", 120.0f);
cooldownManager.SetCooldown("Twister", 60.00f);
cooldownManager.SetCooldown("SuperCell", 120.00f);
cooldownManager.SetCooldown("Sinkhole", 20.00f);
cooldownManager.SetCooldown("Thunderstorm", 5.00f);
cooldownManager.SetCooldown("Earthquake", 60.0f);
cooldownManager.SetCooldown("Fire", 5.0f);
cooldownManager.SetCooldown("DestroyRoad", 5.0f);
}
and here is the function which checks if the user is not found in this other created dictionary upon commands being sent to the chat. This code is in a file called Cooldown.cs
public CooldownManager()
{
lastUsed = new Dictionary<string, Dictionary<string, DateTime>>();
cooldownTimes = new Dictionary<string, int>();
}
public bool OnCooldown(string username, string command)
{
string key = CleanKey(command);
if (!lastUsed.ContainsKey(username)) lastUsed.Add(username, new Dictionary<string, DateTime>());
if (lastUsed[username].ContainsKey(key))
{
TimeSpan timeSpan = DateTime.UtcNow - lastUsed[username][key];
if (timeSpan.Seconds <= cooldownTimes.GetValueOrDefault(key, 0)) return true;
}
if (lastUsed[username].ContainsKey(key)) lastUsed[username].Remove(key);
lastUsed[username].Add(key, DateTime.UtcNow);
return false;
}
Both are of the same namespace Kigbot.ChatCommands. The problem i am facing is that the "GetValueOrDefault" for some reason cant seem to see or read the float values for the disasters in the dictionary which are the cool down timers. I am getting a "does not contain a definition for 'GetValueOrDefault' and no accessible extension method 'GetValueOrDefault' accepting the first argument of type 'Dictionary<string, int>' could be found. I have been looking around and trying to solve it but i am at a loss. Any help would be much appreciated.
CodePudding user response:
SO in looking at the original files from my friends built console app and what i was building in WPF, the big difference was the targetted framework. I have since changed these from .NET Framework 4.8 to just .NET 5.0 and everything is fine and dandy no errors.
CodePudding user response:
GetValueOrDefault is an extension method that isn't available in some versions of .net - you can swap your code out for a ContainsKey based version:
if (timeSpan.Seconds <= (cooldownTimes.ContainsKey(key) ? cooldownTimes[key] : 0)) return true;
Or TryGetValue
if (timeSpan.Seconds <= (cooldownTimes.TryGetValue(key, out var v) ? v : 0)) return true;
The containskey approach will do two lookups, but it doesn't strike me as a scenario where this will matter much
