Compare commits

...

2 commits

Author SHA1 Message Date
Norbi Peti 3b5888fbf7 Add 'README.md' 2020-07-04 22:42:49 +00:00
Norbi Peti 8d2d11b736 Reorganize project and use latest API features 2020-06-18 16:59:24 +02:00
5 changed files with 63 additions and 99 deletions

View file

@ -17,18 +17,16 @@ using uREPL;
namespace GCDC
{
public class TextBlockUpdateEngine : IDeterministicTimeStopped, IDeterministicTimeRunning, IApiEngine, IUnorderedInitializeOnTimeStoppedModeEntered
public class DiscordClient
{
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")));
@ -59,7 +57,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};
@ -91,8 +89,7 @@ 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");
@ -135,46 +132,20 @@ 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();
updatedTextBlock = false;
plugin.Update(messages);
}
public JobHandle OnInitializeTimeStoppedMode()
{
updatedTextBlock = false; //Update text block
return new JobHandle();
}
public void Dispose()
public void Stop()
{
_running = false;
_rect.Interrupt();
}
public string Name { get; } = "GCDCEngine";
public bool isRemovable { get; } = false;
public void Update() => plugin.Update(messages);
}
}

View file

@ -1,43 +0,0 @@
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>0.0.2.0</AssemblyVersion>
<FileVersion>0.0.2.0</FileVersion>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.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, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null">
<Reference Include="GamecraftModdingAPI">
<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, Version=12.0.1.0, Culture=neutral, PublicKeyToken=null">
<Reference Include="Newtonsoft.Json">
<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,31 +1,55 @@
using System.Reflection;
using HarmonyLib;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using GamecraftModdingAPI.App;
using GamecraftModdingAPI.Commands;
using IllusionPlugin;
using RobocraftX.Schedulers;
using Svelto.Tasks.ExtraLean;
using UnityEngine;
using uREPL;
namespace GCDC
{
public class GCDCPlugin : IPlugin
{
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 string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name;
public string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString();
public void OnApplicationStart()
{
if (harmony == null)
{
harmony = new Harmony(HarmonyID);
harmony.PatchAll(Assembly.GetExecutingAssembly());
}
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();
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)

12
README.md Normal file
View file

@ -0,0 +1,12 @@
# 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.