Skip to content

Commit

Permalink
Merge pull request #94 from nwesterhausen/dev
Browse files Browse the repository at this point in the history
1.5.0 Switch to LiteDB
  • Loading branch information
nwesterhausen authored Oct 28, 2021
2 parents ea00036 + 4947e7c commit edda27b
Show file tree
Hide file tree
Showing 24 changed files with 874 additions and 482 deletions.
2 changes: 1 addition & 1 deletion DiscordConnector.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<!-- Include Newtonsoft.Json dependency -->
<BuiltLibraryAndDeps Include="$(ProjectDir)lib/Newtonsoft.Json/*.dll" />
<!-- Include LiteDB dependency -->
<!-- <BuiltLibraryAndDeps Include="$(ProjectDir)bin/Debug/net48/LiteDB.dll" /> -->
<BuiltLibraryAndDeps Include="$(ProjectDir)bin/Debug/net48/LiteDB.dll" />
<!-- Metadata files for Thunderstore -->
<ThunderstoreMetadata Include="$(ProjectDir)Metadata/manifest.json" />
<ThunderstoreMetadata Include="$(ProjectDir)Metadata/icon.png" />
Expand Down
47 changes: 47 additions & 0 deletions Metadata/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,53 @@

A full changelog for reference.

### Version 1.5.0

Features:

- Using LiteDB for record storage.

Because of how unreliable storing the records in a "roll-your-own"
database with a JSON file was, and because of the increased flexibility
in what could be stored, I've changed the storage system for the
recorded player stats to use LiteDB. Currently this means records for
join/leave/death/shout/ping will be timestamped, include the position of
the event, have the player name, and the player's steamid. Hopefully
adding this additional information will allow for more customization
options for the users of this mod.

It is set up to do a migration on first load of the updated plugin, the
steps it follows for that is:

1. check if records.json (or configured name) exists
2. read all records from the file
3. parse the records
4. loop through all the records and add them to the database

Records added this way will have position of zero and a
steamid of 1.

5. move the records.json file to records.json.migrated

If you don't want to have it auto-migrate the records, rename your
records.json or delete it. If the name does not match exactly it will
not migrate the data.

For the migration steps, it will be outputting log information (at INFO
level) with how many records were migrated and which steps completed.

- Ranked Lowest Player Leaderbaord

Added an inverse of the Top Player leaderboard.

- Custom leaderboard heading messages

Added configuration for the messages sent at the top of the leaderboard
messages.

- The variable `%PUBLICIP%` can be used in _any_ message configuration
now.

### Version 1.4.4

Fixes:
Expand Down
2 changes: 1 addition & 1 deletion Metadata/DiscordConnector-Nexus.readme
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
DISCORD CONNECTOR - 1.4.0
DISCORD CONNECTOR - 1.5.0
Connect your Valheim server to a Discord Webhook. Works for both dedicated and client-hosted servers. (Visit the github repo for a how-to guide.)

:: REQUIREMENTS ::
Expand Down
69 changes: 31 additions & 38 deletions Metadata/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,59 +52,52 @@ records.json 1.2.0+ (PlayerName changed to Key)
[{"Category":"death","Values":[{"Key":"Xithyr","Value":13} ...
```

### Version 1.4.4

Fixes:

- Position being sent with event messages even if event position was disabled in config

### Version 1.4.3

Fixes:

- Event messages were sending the wrong message (start instead of end and vice-versa)
- Event Stop messages were sending zero coordinates
- If you had enabled first death message and death message (this is default settings), you would
get two messages. This has been changed to merge the messages into one if both settings are on
and it's a player's first death.
### Version 1.5.0

Features:

- Added toggles to enable/disable some event debug messages (all disabled by default)
- Added a toggle to enable/disable a debug message with responses from the webhook (disabled by default)

### Version 1.4.2
- Using LiteDB for record storage.

Fixes:
Because of how unreliable storing the records in a "roll-your-own"
database with a JSON file was, and because of the increased flexibility
in what could be stored, I've changed the storage system for the
recorded player stats to use LiteDB. Currently this means records for
join/leave/death/shout/ping will be timestamped, include the position of
the event, have the player name, and the player's steamid. Hopefully
adding this additional information will allow for more customization
options for the users of this mod.

- Least deaths leaderboard wasn't respecting the correct config entry. (THanks @thedefside)
It is set up to do a migration on first load of the updated plugin, the
steps it follows for that is:

### Version 1.4.1
1. check if records.json (or configured name) exists
2. read all records from the file
3. parse the records
4. loop through all the records and add them to the database

Fixes:
Records added this way will have position of zero and a
steamid of 1.

- Removed the two debug logging calls for events -- sorry for the log spam!
5. move the records.json file to records.json.migrated

### Version 1.4.0
If you don't want to have it auto-migrate the records, rename your
records.json or delete it. If the name does not match exactly it will
not migrate the data.

Features:
For the migration steps, it will be outputting log information (at INFO
level) with how many records were migrated and which steps completed.

- 10 user defined variables that can be used an any messages (%VAR1% thru %VAR10%). These are set in their own configuration file,
`games.nwest.valheim.discordconnector-variables.cfg` which will get generated first time 1.4.0 is run.
- The position of where the player/ping/event coordinates are inserted into messages is configurable using the `%POS%` variable in
the messages config. It won't be replaced if the "send coordinates" toggle is off for that message. If you don't include a `%POS%`
variable, it will append the coordinates as happens with previous versions.
- Ranked Lowest Player Leaderbaord

Fixes:
Added an inverse of the Top Player leaderboard.

- Fixed an off-by-one error in the Top Players leaderboard (the default leaderboard) (Thanks @thedefside)
- Fixed configuration not referencing proper settings (Thanks @thedefside)
- Fixed event messages (now properly functioning on dedicated servers)
- Custom leaderboard heading messages

Breaking Changes:
Added configuration for the messages sent at the top of the leaderboard
messages.

- If you used `%PLAYERS%` in any of the event messages, you need to remove it. With the changes required for the event messages
functionality, it is not supportable at this time.
- The variable `%PUBLICIP%` can be used in _any_ message configuration
now.

Full changelog history available on the
[Github repository](https://github.com/nwesterhausen/valheim-discordconnector/blob/main/Metadata/CHANGELOG.md)
Expand Down
2 changes: 1 addition & 1 deletion Metadata/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "DiscordConnector",
"version_number": "1.4.4",
"version_number": "1.5.0",
"website_url": "https://discordconnector.valheim.nwest.games/",
"description": "Connects your Valheim server to a Discord webhook. Works for both dedicated and client-hosted servers.",
"dependencies": ["denikson-BepInExPack_Valheim-5.4.1600"]
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ The compiled plugin will be in a zip ready for upload at `bin/DiscordConnector.z

### Dependencies

For JSON serialization, I chose to use the System.Text.Json library which is part of
the most recent .NET but can be used with .NET 4.8 which is used in this project.
For JSON serialization, using Newtonsoft.Json

For data storage/retrieval using [LiteDB](https://www.litedb.org/)
(If you want to read the database file generated, you can use [LitDB Studio](https://github.com/mbdavid/LiteDB.Studio/releases/latest))

### Contributors

Expand Down
47 changes: 47 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,53 @@

A full changelog

### Version 1.5.0

Features:

- Using LiteDB for record storage.

Because of how unreliable storing the records in a "roll-your-own"
database with a JSON file was, and because of the increased flexibility
in what could be stored, I've changed the storage system for the
recorded player stats to use LiteDB. Currently this means records for
join/leave/death/shout/ping will be timestamped, include the position of
the event, have the player name, and the player's steamid. Hopefully
adding this additional information will allow for more customization
options for the users of this mod.

It is set up to do a migration on first load of the updated plugin, the
steps it follows for that is:

1. check if records.json (or configured name) exists
2. read all records from the file
3. parse the records
4. loop through all the records and add them to the database

Records added this way will have position of zero and a
steamid of 1.

5. move the records.json file to records.json.migrated

If you don't want to have it auto-migrate the records, rename your
records.json or delete it. If the name does not match exactly it will
not migrate the data.

For the migration steps, it will be outputting log information (at INFO
level) with how many records were migrated and which steps completed.

- Ranked Lowest Player Leaderbaord

Added an inverse of the Top Player leaderboard.

- Custom leaderboard heading messages

Added configuration for the messages sent at the top of the leaderboard
messages.

- The variable `%PUBLICIP%` can be used in _any_ message configuration
now.

### Version 1.4.4

Fixes:
Expand Down
41 changes: 41 additions & 0 deletions src/Config/MessagesConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ internal class MessagesConfig
private const string PLAYER_MESSAGES = "Messages.Player";
private const string PLAYER_FIRSTS_MESSAGES = "Messages.PlayerFirsts";
private const string EVENT_MESSAGES = "Messages.Events";
private const string BOARD_MESSAGES = "Messages.Leaderbaords";

// Server Messages
private ConfigEntry<string> serverLaunchMessage;
Expand Down Expand Up @@ -42,6 +43,12 @@ internal class MessagesConfig
private ConfigEntry<string> eventStopMessage;
private ConfigEntry<string> eventResumedMessage;

// Board Messages
private ConfigEntry<string> leaderboardTopPlayersMessage;
private ConfigEntry<string> leaderboardBottomPlayersMessage;
private ConfigEntry<string> leaderboardHighestPlayerMessage;
private ConfigEntry<string> leaderboardLowestPlayerMessage;

public MessagesConfig(ConfigFile configFile)
{
config = configFile;
Expand Down Expand Up @@ -173,6 +180,28 @@ private void LoadConfig()
"The special string %EVENT_END_MSG% will be replaced with the message that is displayed on the screen when the event ends."); // + Environment.NewLine +
// "The special string %PLAYERS% will be replaced with a list of players in the event area."); //! Removed due to unreliability

// Board Messages
leaderboardTopPlayersMessage = config.Bind<string>(BOARD_MESSAGES,
"Leaderboard Heading for Top N Players",
"Top %N% Player Leaderboards:",
"Set the message that is included as a heading when this leaderboard is sent." + Environment.NewLine +
"Include %N% to include the number of rankings returned (the configured number)");
leaderboardBottomPlayersMessage = config.Bind<string>(BOARD_MESSAGES,
"Leaderboard Heading for Bottom N Players",
"Bottom %N% Player Leaderboards:",
"Set the message that is included as a heading when this leaderboard is sent." + Environment.NewLine +
"Include %N% to include the number of rankings returned (the configured number)");
leaderboardHighestPlayerMessage = config.Bind<string>(BOARD_MESSAGES,
"Leaderboard Heading for Highest Player",
"Top Performer",
"Set the message that is included as a heading when this leaderboard is sent." + Environment.NewLine +
"Include %N% to include the number of rankings returned (the configured number)");
leaderboardLowestPlayerMessage = config.Bind<string>(BOARD_MESSAGES,
"Leaderboard Heading for Lowest Player",
"Bottom Performer",
"Set the message that is included as a heading when this leaderboard is sent." + Environment.NewLine +
"Include %N% to include the number of rankings returned (the configured number)");

config.Save();
}

Expand Down Expand Up @@ -209,6 +238,13 @@ public string ConfigAsJson()
jsonString += $"\"eventPausedMessage\":\"{eventPausedMessage.Value}\",";
jsonString += $"\"eventResumedMessage\":\"{eventResumedMessage.Value}\",";
jsonString += $"\"eventStopMessage\":\"{eventStopMessage.Value}\"";
jsonString += "},";

jsonString += $"\"{BOARD_MESSAGES}\":{{";
jsonString += $"\"leaderboardTopPlayersMessage\":\"{leaderboardTopPlayersMessage.Value}\",";
jsonString += $"\"leaderboardBottomPlayersMessage\":\"{leaderboardBottomPlayersMessage.Value}\",";
jsonString += $"\"leaderboardHighestPlayerMessage\":\"{leaderboardHighestPlayerMessage.Value}\",";
jsonString += $"\"leaderboardLowestPlayerMessage\":\"{leaderboardLowestPlayerMessage.Value}\"";
jsonString += "}";

jsonString += "}";
Expand Down Expand Up @@ -254,5 +290,10 @@ private static string GetRandomStringFromValue(ConfigEntry<string> configEntry)
public string EventStopMesssage => GetRandomStringFromValue(eventStopMessage);
public string EventResumedMesssage => GetRandomStringFromValue(eventResumedMessage);

// Messages.Leaderboards
public string LeaderboardTopPlayerHeading => GetRandomStringFromValue(leaderboardTopPlayersMessage);
public string LeaderboardBottomPlayersHeading => GetRandomStringFromValue(leaderboardBottomPlayersMessage);
public string LeaderboardHighestHeading => GetRandomStringFromValue(leaderboardHighestPlayerMessage);
public string LeaderboardLowestHeading => GetRandomStringFromValue(leaderboardLowestPlayerMessage);
}
}
8 changes: 7 additions & 1 deletion src/Config/PluginConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,19 @@ public void ReloadConfig()
public bool DebugEveryEventChange => togglesConfig.DebugEveryEventChange;
public bool DebugHttpRequestResponse => togglesConfig.DebugHttpRequestResponse;

// Leaderboard Messages
public string LeaderboardTopPlayerHeading => messagesConfig.LeaderboardTopPlayerHeading;
public string LeaderboardBottomPlayersHeading => messagesConfig.LeaderboardBottomPlayersHeading;
public string LeaderboardHighestHeading => messagesConfig.LeaderboardHighestHeading;
public string LeaderboardLowestHeading => messagesConfig.LeaderboardLowestHeading;

public string ConfigAsJson()
{
string jsonString = "{";

jsonString += $"\"Config.Main\":{mainConfig.ConfigAsJson()},";
jsonString += $"\"Config.Messages\":{messagesConfig.ConfigAsJson()},";
jsonString += $"\"Config.Toggles\":{togglesConfig.ConfigAsJson()}";
jsonString += $"\"Config.Toggles\":{togglesConfig.ConfigAsJson()},";
jsonString += $"\"Config.Variables\":{variableConfig.ConfigAsJson()}";

jsonString += "}";
Expand Down
46 changes: 46 additions & 0 deletions src/Leaderboard/BottomPlayer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;

namespace DiscordConnector.Leaderboards
{
internal class BottomPlayers : Base
{
public override void SendLeaderboard()
{
List<Tuple<string, string>> leaderFields = new List<Tuple<string, string>>();

var deaths = Records.Helper.BottomNResultForCategory(Records.Categories.Death, Plugin.StaticConfig.IncludedNumberOfRankings);
var sessions = Records.Helper.BottomNResultForCategory(Records.Categories.Join, Plugin.StaticConfig.IncludedNumberOfRankings);
var shouts = Records.Helper.BottomNResultForCategory(Records.Categories.Shout, Plugin.StaticConfig.IncludedNumberOfRankings);
var pings = Records.Helper.BottomNResultForCategory(Records.Categories.Ping, Plugin.StaticConfig.IncludedNumberOfRankings);



if (Plugin.StaticConfig.RankedDeathLeaderboardEnabled && deaths.Count > 0)
{
leaderFields.Add(Tuple.Create("Deaths", Leaderboard.RankedCountResultToString(deaths)));
}
if (Plugin.StaticConfig.RankedSessionLeaderboardEnabled && sessions.Count > 0)
{
leaderFields.Add(Tuple.Create("Sessions", Leaderboard.RankedCountResultToString(sessions)));
}
if (Plugin.StaticConfig.RankedShoutLeaderboardEnabled && shouts.Count > 0)
{
leaderFields.Add(Tuple.Create("Shouts", Leaderboard.RankedCountResultToString(shouts)));
}
if (Plugin.StaticConfig.RankedPingLeaderboardEnabled && pings.Count > 0)
{
leaderFields.Add(Tuple.Create("Pings", Leaderboard.RankedCountResultToString(pings)));
}
if (leaderFields.Count > 0)
{
string discordContent = MessageTransformer.FormatLeaderboardHeader(Plugin.StaticConfig.LeaderboardBottomPlayersHeading, Plugin.StaticConfig.IncludedNumberOfRankings);
DiscordApi.SendMessageWithFields(discordContent, leaderFields);
}
else
{
Plugin.StaticLogger.LogInfo("Not sending a leaderboard because theirs either no leaders, or nothing allowed.");
}
}
}
}
Loading

0 comments on commit edda27b

Please sign in to comment.