Skip to content

Commit

Permalink
Add project files.
Browse files Browse the repository at this point in the history
  • Loading branch information
SkyTech6 committed May 27, 2024
1 parent 67d0a78 commit 5e91f46
Show file tree
Hide file tree
Showing 10 changed files with 357 additions and 0 deletions.
52 changes: 52 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Build

on:
push:
branches: ["master"]
pull_request:
branches: ["master"]

jobs:
build:
permissions:
contents: write
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v2
with:
dotnet-version: 6.0.x

- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Restore dependencies
run: dotnet restore

- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v0.9.7
with:
versionSpec: "5.x"

- name: Determine Version
uses: gittools/actions/gitversion/execute@v0.9.7
with:
additionalArguments: '/updateprojectfiles /overrideconfig "mode=Mainline"'

- name: Build (Release)
run: dotnet build . --configuration Release -p:Version=$GitVersion_SemVer

- name: GH Release
uses: softprops/action-gh-release@v1
if: ${{ !env.ACT && github.event_name == 'push' }}
with:
body: Automatic pre-release of ${{ env.GitVersion_SemVer }} for ${{ env.GitVersion_ShortSha }}
name: v${{ env.GitVersion_SemVer }}
files: ./bin/Release/net6.0/CrimsonChatFilter.dll
fail_on_unmatched_files: true
prerelease: true
tag_name: v${{ env.GitVersion_SemVer }}
27 changes: 27 additions & 0 deletions CrimsonChatFilter.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AssemblyName>CrimsonChatFilter</AssemblyName>
<Description>Filter server chat!</Description>
<Version>1.0.0</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<RootNamespace>CrimsonChatFilter</RootNamespace>
<AssemblyVersion>0.1.8.0</AssemblyVersion>
<FileVersion>0.1.8.0</FileVersion>
<InformationalVersion>0.1.8+1.Branch.main.Sha.4435243bd013dc988e1f142db6f6cf5c889d1a5e</InformationalVersion>
</PropertyGroup>
<Target Name="Thunderstore Copy to Dist" AfterTargets="AfterBuild" Condition=" '$(Configuration' == 'Release'">
<Copy SourceFiles="$(OutDir)\CrimsonChatFilter.dll" DestinationFolder="$(SolutionDir)/dist" />
</Target>
<ItemGroup>
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.690" IncludeAssets="compile" />
<PackageReference Include="BepInEx.Core" Version="6.0.0-be.691" IncludeAssets="compile" />
<PackageReference Include="BepInEx.PluginInfoProps" Version="2.*" />
<PackageReference Include="VRising.Unhollowed.Client" Version="1.0.*" />
<PackageReference Include="VRising.Bloodstone" Version="0.2.1" />
</ItemGroup>
<ItemGroup>
<None Include=".github\workflows\build.yml" />
</ItemGroup>
</Project>
25 changes: 25 additions & 0 deletions CrimsonChatFilter.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34902.65
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CrimsonChatFilter", "CrimsonChatFilter.csproj", "{0F3CA94A-2A94-476E-9051-C036EB4AA6FB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0F3CA94A-2A94-476E-9051-C036EB4AA6FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0F3CA94A-2A94-476E-9051-C036EB4AA6FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F3CA94A-2A94-476E-9051-C036EB4AA6FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F3CA94A-2A94-476E-9051-C036EB4AA6FB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0049D2C2-4EC9-4BE6-BE61-4038C864C4BB}
EndGlobalSection
EndGlobal
40 changes: 40 additions & 0 deletions Hooks/ChatHook.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using CrimsonChatFilter.Utils;
using HarmonyLib;
using ProjectM;
using ProjectM.Network;
using Unity.Collections;
using Unity.Entities;

namespace CrimsonChatFilter.Hooks;

[HarmonyPatch]
public static class ChatMessageSystem_Patch
{
[HarmonyPatch(typeof(ChatMessageSystem), nameof(ChatMessageSystem.OnUpdate))]
[HarmonyPrefix]
public static bool OnUpdate(ChatMessageSystem __instance)
{
if (!Plugin.Settings.GetActiveOption(Structs.Settings.Options.Enable)) return true;
if (Plugin.Settings.GetActiveOption(Structs.Settings.Options.FullRemove)) return true;

if (__instance.__query_661171423_0 != null)

Check warning on line 20 in Hooks/ChatHook.cs

View workflow job for this annotation

GitHub Actions / build

The result of the expression is always 'true' since a value of type 'EntityQuery' is never equal to 'null' of type 'EntityQuery?'

Check warning on line 20 in Hooks/ChatHook.cs

View workflow job for this annotation

GitHub Actions / build

The result of the expression is always 'true' since a value of type 'EntityQuery' is never equal to 'null' of type 'EntityQuery?'
{
NativeArray<Entity> entities = __instance.__query_661171423_0.ToEntityArray(Allocator.Temp);
foreach (var entity in entities)
{
var fromData = __instance.EntityManager.GetComponentData<FromCharacter>(entity);
var userData = __instance.EntityManager.GetComponentData<User>(fromData.User);
var chatEventData = __instance.EntityManager.GetComponentData<ChatMessageEvent>(entity);

var messageText = chatEventData.MessageText.ToString();

messageText = messageText.Filter();

chatEventData.MessageText = messageText;
__instance.EntityManager.SetComponentData(entity, chatEventData);
}
}

return true;
}
}
51 changes: 51 additions & 0 deletions Plugin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using BepInEx;
using BepInEx.Unity.IL2CPP;
using CrimsonChatFilter.Structs;
using HarmonyLib;
using CrimsonChatFilter.Utils;
using BepInEx.Logging;

namespace CrimsonChatFilter;

[BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)]
[BepInDependency("gg.deca.Bloodstone")]
[Bloodstone.API.Reloadable]
public class Plugin : BasePlugin
{
Harmony _harmony;
public static Settings Settings { get; private set; }
public static ManualLogSource Logger { get; private set; }

public override void Load()
{
Logger = Log;
Settings = new(Config);
Settings.InitConfig();
Database.InitFiltered("filtered_words");

// Plugin startup logic
Log.LogInfo($"Plugin {MyPluginInfo.PLUGIN_GUID} version {MyPluginInfo.PLUGIN_VERSION} is loaded!");

// Harmony patching
_harmony = new Harmony(MyPluginInfo.PLUGIN_GUID);
_harmony.PatchAll(System.Reflection.Assembly.GetExecutingAssembly());

Bloodstone.Hooks.Chat.OnChatMessage += ((x) =>
{
if (!Settings.GetActiveOption(Settings.Options.Enable)) return;
if (!Settings.GetActiveOption(Settings.Options.FullRemove)) return;
if (x.Message.ContainsFiltered())
{
Logger.LogWarning($"FILTERED: {x.Message}");
x.Cancel();
}
});
}

public override bool Unload()
{
_harmony?.UnpatchSelf();
return true;
}

}
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# CrimsonDropRate
`Server side only` mod to filter unwanted words (or urls) from chat. The sending user will see their messages unfiltered, but all other clients will.

## Installation
* Install [BepInEx](https://v-rising.thunderstore.io/package/BepInEx/BepInExPack_V_Rising/)
* Install [Bloodstone](https://github.com/decaprime/Bloodstone/releases/tag/v0.2.1)
* Extract _CrimsonChatFilter.dll_ into _(VRising server folder)/BepInEx/plugins_

## Configurable Values
```ini
[CrimsonChatFilter]

## Enable or disable chat filtering
# Setting type: boolean
# Default value: true
EnableMode = true

## If enabled, others won't see the message, otherwise replaces filtered words with ****
# Setting type: boolean
# Default value: false
FullRemove = false
```
29 changes: 29 additions & 0 deletions Structs/Database.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using CrimsonChatFilter.Utils;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;

namespace CrimsonChatFilter.Structs;

public class Database
{
private static Database INSTANCE;
public string FilteredPath { get; set; }

public Database(string _path, string _db)
{
FilteredPath = Path.Combine(_path, $"{_db}.json");
}

public static void InitFiltered(string db)
{
var _path = Path.Combine(BepInEx.Paths.ConfigPath, "CrimsonChatFilter");
INSTANCE = new Database(_path, db);

if (File.Exists(INSTANCE.FilteredPath))
{
string _json = File.ReadAllText(INSTANCE.FilteredPath);
FilterString.FilteredWords = JsonSerializer.Deserialize<List<string>>(_json);
}
}
}
75 changes: 75 additions & 0 deletions Structs/Settings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using BepInEx.Configuration;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;

namespace CrimsonChatFilter.Structs;

public readonly struct Settings
{
private readonly ConfigFile CONFIG;
private readonly ConfigEntry<bool> ENABLE_MOD;
private readonly ConfigEntry<bool> FULL_REMOVE;

public static readonly string CONFIG_PATH = Path.Combine(BepInEx.Paths.ConfigPath, "CrimsonChatFilter");

public Settings(ConfigFile config)
{
CONFIG = config;
ENABLE_MOD = CONFIG.Bind("Config", "EnableMod", true, "Enable or disable chat filtering");
FULL_REMOVE = CONFIG.Bind("Config", "FullRemove", false, "If enabled, others won't see the message, otherwise replaces filtered words with ****");
}

public readonly void InitConfig()
{
WriteConfig();
}

public readonly void WriteConfig()
{
if(!Directory.Exists(CONFIG_PATH)) Directory.CreateDirectory(CONFIG_PATH);
if (!File.Exists(Path.Combine(CONFIG_PATH, "filtered_words.json")))
{
List<string> _filteredConfig = GenerateTemplate();
string _json = JsonSerializer.Serialize(_filteredConfig, new JsonSerializerOptions
{
WriteIndented = true
});

File.WriteAllText(Path.Combine(CONFIG_PATH, "filtered_words.json"), _json);
}
}

private List<string> GenerateTemplate()
{
List<string> _template = new List<string>
{
"coon",
"jim crow",
"nigger",
"gook",
"chink",
"towelhead",
"honky",
"beaner",
"spic"
};
return _template;
}

public readonly bool GetActiveOption(Options option)
{
return option switch
{
Options.Enable => ENABLE_MOD.Value,
Options.FullRemove => FULL_REMOVE.Value,
_ => false
};
}

public enum Options
{
Enable,
FullRemove
}
}
29 changes: 29 additions & 0 deletions Utils/FilterString.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace CrimsonChatFilter.Utils;

internal static class FilterString
{
public static List<string> FilteredWords;

public static string Filter(this string input)
{
foreach (var word in FilteredWords)
{
string pattern = $@"\b{Regex.Escape(word)}\b";
input = Regex.Replace(input, pattern, "****", RegexOptions.IgnoreCase);
}
return input;
}

public static bool ContainsFiltered(this string input)
{
foreach (var word in FilteredWords)
{
if(input.Contains(word)) return true;
}

return false;
}
}
7 changes: 7 additions & 0 deletions nuget.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="BepInEx" value="https://nuget.bepinex.dev/v3/index.json" />
<add key="Samboy Feed" value="https://nuget.samboy.dev/v3/index.json" />
</packageSources>
</configuration>

0 comments on commit 5e91f46

Please sign in to comment.