Compare commits

..

No commits in common. "master" and "v0.0.2" have entirely different histories.

5 changed files with 99 additions and 63 deletions

View file

@ -0,0 +1,43 @@
using System;
using System.Reflection;
using Gamecraft.Blocks.ConsoleBlock;
using HarmonyLib;
using RobocraftX;
using RobocraftX.GUI.CommandLine;
using RobocraftX.Multiplayer;
using RobocraftX.Services.MultiplayerNetworking;
using RobocraftX.StateSync;
using Svelto.ECS;
using Unity.Entities;
using UnityEngine;
namespace GCDC
{
[HarmonyPatch]
public class DiscordEngineInjectionPatch
{
static void Postfix(EnginesRoot enginesRoot, in StateSyncRegistrationHelper stateSyncReg, bool isAuthoritative)
{
if (isAuthoritative)
{
stateSyncReg.AddDeterministicEngine(new TextBlockUpdateEngine());
Debug.Log($"Added Discord text block update engine");
}
else
Debug.Log("Not authoritative, not adding Discord engine");
}
static MethodBase TargetMethod()
{
return _ComposeMethodInfo(ConsoleBlockCompositionRoot.Compose);
}
private delegate void ComposeAction(EnginesRoot er, in StateSyncRegistrationHelper ssrh,
NetworkReceivers networkReceivers, NetworkSender networkSende, bool isAuthoritative);
private static MethodInfo _ComposeMethodInfo(ComposeAction a)
{
return a.Method;
}
}
}

View file

@ -11,8 +11,8 @@
<AssemblyName>GCDC</AssemblyName>
<TargetFramework>net472</TargetFramework>
<FileAlignment>512</FileAlignment>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<AssemblyVersion>0.0.2.0</AssemblyVersion>
<FileVersion>0.0.2.0</FileVersion>
<ProductVersion>0.0.2.0</ProductVersion>
<Product>GCDC</Product>
<ProductName>GCDC</ProductName>
@ -52,7 +52,7 @@
<Reference Include="Gamecraft.Blocks.ConsoleBlock, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Gamecraft.Blocks.ConsoleBlock.dll</HintPath>
</Reference>
<Reference Include="GamecraftModdingAPI">
<Reference Include="GamecraftModdingAPI, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\GamecraftModdingAPI\GamecraftModdingAPI\bin\Debug\net472\GamecraftModdingAPI.dll</HintPath>
</Reference>
<Reference Include="IllusionPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
@ -61,7 +61,7 @@
<Reference Include="MultiplayerNetworking, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\ref\Gamecraft_Data\Managed\MultiplayerNetworking.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<Reference Include="Newtonsoft.Json, Version=12.0.1.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\ref\Gamecraft_Data\Managed\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="RobocraftX.AccountPreferences, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">

View file

@ -1,55 +1,31 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using GamecraftModdingAPI.App;
using GamecraftModdingAPI.Commands;
using System.Reflection;
using HarmonyLib;
using IllusionPlugin;
using RobocraftX.Schedulers;
using Svelto.Tasks.ExtraLean;
using UnityEngine;
using uREPL;
namespace GCDC
{
public class GCDCPlugin : IPlugin
{
public string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name;
public string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString();
public string Name { get; } = "GCDC";
public string Version { get; } = "v0.0.1";
public static Harmony harmony { get; protected set; }
public const string HarmonyID = "io.github.norbipeti.GCDC";
public void OnApplicationStart()
{
GamecraftModdingAPI.Main.Init();
var client = new DiscordClient(this);
CommandBuilder.Builder("dc", "Send messages to Discord.")
.Action<string>(client.SendMessage).Build();
CommandBuilder.Builder("dcsetup", "Initial setup for GCDC. The argument is the channel ID first. For example: dcsetup \"420159832423923714\"")
.Action<string>(client.Setup).Build();
Game.Enter += (sender, e) =>
client.Ready();
Game.Edit += (sender, e) =>
client.Update(); //Update text block
Game.Exit += (sender, e) =>
client.Stop();
if (harmony == null)
{
harmony = new Harmony(HarmonyID);
harmony.PatchAll(Assembly.GetExecutingAssembly());
}
Debug.Log("GCDC loaded");
}
public void Update(Queue<string> messages)
{
UpdateEnum(messages).RunOn(ExtraLean.EveryFrameStepRunner_RUNS_IN_TIME_STOPPED_AND_RUNNING);
}
private IEnumerator UpdateEnum(Queue<string> messages)
{
var txt = messages.Count > 0
? messages.Aggregate((current, msg) => current + "\n" + msg)
: "<No messages yet>";
RuntimeCommands.Call("ChangeTextBlockCommand", "Discord", txt);
yield break;
}
public void OnApplicationQuit()
{
harmony?.UnpatchAll(HarmonyID);
}
public void OnLevelWasLoaded(int level)

View file

@ -17,16 +17,18 @@ using uREPL;
namespace GCDC
{
public class DiscordClient
public class TextBlockUpdateEngine : IDeterministicTimeStopped, IDeterministicTimeRunning, IApiEngine, IUnorderedInitializeOnTimeStoppedModeEntered
{
private string _token;
private bool _running;
private Thread _rect;
private readonly Queue<string> messages = new Queue<string>();
private readonly GCDCPlugin plugin;
public DiscordClient(GCDCPlugin plugin) => this.plugin = plugin;
public void Ready()
{
if (!RuntimeCommands.HasRegistered("dc"))
RuntimeCommands.Register<string>("dc", SendMessage);
if (!RuntimeCommands.HasRegistered("dcsetup"))
RuntimeCommands.Register<string>("dcsetup", Setup,
"Initial setup for GCDC. The argument is the channel ID first.");
if (File.Exists("gcdc.json"))
{
var jo = JObject.Load(new JsonTextReader(File.OpenText("gcdc.json")));
@ -57,7 +59,7 @@ namespace GCDC
{
try
{
if (JObject.Parse(WebUtils.Request("users/get?token=" + tokenOrChannel))["response"]?.Value<string>() == "OK")
if (JObject.Parse(WebUtils.Request("users/get?token=" + tokenOrChannel))["response"].Value<string>() == "OK")
{
_token = tokenOrChannel;
var jo = new JObject {["token"] = tokenOrChannel};
@ -89,7 +91,8 @@ namespace GCDC
{
var parameters = "token=" + _token + "&message=" + message;
var resp = JObject.Parse(WebUtils.Request("messages/send?" + parameters, ""));
if (resp["response"]?.Value<string>() == "OK")
if (resp["response"]
.Value<string>() == "OK")
{
AddMessage("<nobr><" + resp["username"] + "> " + message);
Log.Output("Message sent");
@ -132,20 +135,46 @@ namespace GCDC
_rect.Start();
}
public EntitiesDB entitiesDB { get; set; }
public string name { get; } = "GCDC-TextUpdate";
private volatile Queue<string> messages = new Queue<string>();
private volatile bool updatedTextBlock;
public JobHandle SimulatePhysicsStep(
in float deltaTime,
in PhysicsUtility utility,
in PlayerInput[] playerInputs) //Gamecraft.Blocks.ConsoleBlock.dll
{
if (updatedTextBlock)
return new JobHandle();
var txt = messages.Count > 0 ? messages.Aggregate((current, msg) => current + "\n" + msg) : "<No messages yet>";
RuntimeCommands.Call("ChangeTextBlockCommand", "Discord", txt);
updatedTextBlock = true;
return new JobHandle();
}
public void AddMessage(string message)
{
messages.Enqueue(message);
if (messages.Count > 10)
messages.Dequeue();
plugin.Update(messages);
updatedTextBlock = false;
}
public void Stop()
public JobHandle OnInitializeTimeStoppedMode()
{
updatedTextBlock = false; //Update text block
return new JobHandle();
}
public void Dispose()
{
_running = false;
_rect.Interrupt();
}
public void Update() => plugin.Update(messages);
public string Name { get; } = "GCDCEngine";
public bool isRemovable { get; } = false;
}
}

View file

@ -1,12 +0,0 @@
# GCDC
A mod for Gamecraft-Discord chat connection using commands and text blocks.
## First-time setup
First invite the Discord bot to your server using [this link](https://discord.com/oauth2/authorize?client_id=680138144812892371&scope=bot) and make sure it has access to the channel you want to use. Then open the console in Gamecraft (`/` or the key near right shift by default) and do `dcsetup "channelid"` with the quotes. The channel ID can be obtained by enabling developer mode in Discord in User Settings -> Appearance and then right clicking the channel and clicking Copy ID.
When that is done, a browser window will open, asking you to give access to the Discord bot. This is only used to get basic info like your username to be displayed when you talk from the game and to avoid someone filling the database with junk. Also due to that, currently you can only have one channel linked at a time.
When you're logged in, the page will show a command to run in Gamecraft (it should be another `dcsetup` with a different argument). Then the initial setup is done.
## Usage
To send messages to Discord, use `dc "message"` with your message inside the quotes. To receive messages, place a text block named Discord. It will automatically update once messages are sent on Discord.