mirror of
https://github.com/shinyflvre/Mate-Engine.git
synced 2026-08-18 21:13:27 +00:00
**Changelog 1.4.0 – THE LOCAL AI Update** **Disclaimer:** The AI runs *entirely locally* and is designed to be environmentally and ethically responsible. - It does **not** harm nature or exploit any artists. - It has only **1.5 billion parameters**, making it a **very small model** by modern standards. - It consumes as much GPU energy as watching a **1440p 60fps YouTube video**. - It was **not trained on artist data**; it uses personal input and public Wikipedia datasets. - It has its own personality, and I ensured it adheres to **ethical standards**. --- ### New Features - Added **Qwen 2.5 1.5B LLM** to MateEngine! - Press **Middle Mouse Button** while hovering over the pet to open the chat window. - Runs fully locally on your GPU — no internet connection required. - Only uses GPU while processing prompts. - Note: This is a **lightweight model** and won’t handle complex tasks or coding. It’s just a small, fun feature! - Added **Resize Button** – Quickly adjust app size for 1080p, 1440p, and 4K monitors. - Added **VRM Information Panel** – Displays polygon count, VRM version, and bone status: - **Perfect** – Properly exported model. - **Failure** – Model has export issues; animations may break. - Added **Options Submenu**. - Added **Volume Sliders** – Independently control pet, effects, and menu volume. - Added **Graphics Settings**. - Added **Dance Trails** – Glowing effects on the pet’s hands during dance. Toggle on/off as desired. - Improved **Music Source Selector** – You can now whitelist or add custom audio sources for dancing. - Added **MateEngine Version Info** – View the current app version from the menu. - Menu can now be opened with **M** key or **Right-Click**. - Added full support for **VRM 1.x** and **VRM 0.x** models. - Introduced **VRM Validator Tool** in Unity Editor – Great for content creators. --- ### Improvements & Fixes - Major **Performance Optimizations**. - Fixed a **GC Error** that could appear after 6–12 hours of continuous use. - Improved **Hand Tracking** – Reduced stuttering in some animations. - Added **Discord Rich Presence** integration. - Added **Glowing Halo** for Steam users as exclusive DLC!
242 lines
No EOL
7.5 KiB
C#
242 lines
No EOL
7.5 KiB
C#
#if (UNITY_WSA || UNITY_WSA_10_0 || UNITY_STANDALONE) && !DISABLE_DISCORD
|
|
using DiscordRPC.IO;
|
|
using DiscordRPC.Logging;
|
|
using System;
|
|
using Lachee.IO;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
|
|
namespace Lachee.Discord.Control
|
|
{
|
|
/// <summary>
|
|
/// Pipe Client used to communicate with Discord.
|
|
/// </summary>
|
|
public class UnityNamedPipe : INamedPipeClient
|
|
{
|
|
const string PIPE_NAME = @"discord-ipc-{0}";
|
|
|
|
private NamedPipeClientStream _stream;
|
|
private byte[] _buffer = new byte[PipeFrame.MAX_SIZE];
|
|
|
|
public ILogger Logger { get; set; }
|
|
public bool IsConnected { get { return _stream != null && _stream.IsConnected; } }
|
|
public int ConnectedPipe { get; private set; }
|
|
|
|
private volatile bool _isDisposed = false;
|
|
|
|
public bool Connect(int pipe)
|
|
{
|
|
if (_isDisposed)
|
|
throw new ObjectDisposedException("NamedPipe");
|
|
|
|
if (pipe > 9)
|
|
throw new ArgumentOutOfRangeException("pipe", "Argument cannot be greater than 9");
|
|
|
|
if (pipe < 0)
|
|
{
|
|
//If we have -1, then we need to iterate over every single pipe until we get it
|
|
//Iterate until we connect to a pipe
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
if (AttemptConnection(i) || AttemptConnection(i, true))
|
|
return true;
|
|
}
|
|
|
|
//We failed everythign else
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
//We have a set one so we should just straight up try to connect to it
|
|
return AttemptConnection(pipe) || AttemptConnection(pipe, true);
|
|
}
|
|
}
|
|
|
|
private bool AttemptConnection(int pipe, bool doSandbox = false)
|
|
{
|
|
//Make sure the stream is null
|
|
if (_stream != null)
|
|
{
|
|
Logger.Error("Attempted to create a new stream while one already exists!");
|
|
return false;
|
|
}
|
|
|
|
//Make sure we are disconnected
|
|
if (IsConnected)
|
|
{
|
|
Logger.Error("Attempted to create a new connection while one already exists!");
|
|
return false;
|
|
}
|
|
|
|
try
|
|
{
|
|
//Prepare the sandbox
|
|
string sandbox = doSandbox ? GetPipeSandbox() : "";
|
|
if (doSandbox && sandbox == null)
|
|
{
|
|
Logger.Trace("Skipping sandbox because this platform does not support it.");
|
|
return false;
|
|
}
|
|
|
|
//Prepare the name
|
|
string pipename = GetPipeName(pipe);
|
|
|
|
//Attempt to connect
|
|
Logger.Info("Connecting to " + pipename + " (" + sandbox +")");
|
|
ConnectedPipe = pipe;
|
|
_stream = new NamedPipeClientStream(".", pipename);
|
|
_stream.Connect();
|
|
|
|
Logger.Info("Connected");
|
|
return true;
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
Logger.Error("Failed: " + e.GetType().FullName + ", " + e.Message);
|
|
ConnectedPipe = -1;
|
|
Close();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
if (_stream != null)
|
|
{
|
|
Logger.Trace("Closing stream");
|
|
_stream.Dispose();
|
|
_stream = null;
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_isDisposed) return;
|
|
Logger.Trace("Disposing Stream");
|
|
_isDisposed = true;
|
|
Close();
|
|
}
|
|
|
|
public bool ReadFrame(out PipeFrame frame)
|
|
{
|
|
if (_isDisposed)
|
|
throw new ObjectDisposedException("_stream");
|
|
|
|
//We are not connected so we cannot read!
|
|
if (!IsConnected)
|
|
{
|
|
frame = default(PipeFrame);
|
|
return false;
|
|
}
|
|
|
|
//Try and read a frame
|
|
int length = _stream.Read(_buffer, 0, _buffer.Length);
|
|
Logger.Trace("Read {0} bytes", length);
|
|
|
|
if (length == 0)
|
|
{
|
|
frame = default(PipeFrame);
|
|
return false;
|
|
}
|
|
|
|
//Read the stream now
|
|
using (MemoryStream memory = new MemoryStream(_buffer, 0, length))
|
|
{
|
|
frame = new PipeFrame();
|
|
if (!frame.ReadStream(memory))
|
|
{
|
|
Logger.Error("Failed to read a frame! {0}", frame.Opcode);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
Logger.Trace("Read pipe frame!");
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool WriteFrame(PipeFrame frame)
|
|
{
|
|
if (_isDisposed)
|
|
throw new ObjectDisposedException("_stream");
|
|
|
|
//Write the frame. We are assuming proper duplex connection here
|
|
if (!IsConnected)
|
|
{
|
|
Logger.Error("Failed to write frame because the stream is closed");
|
|
return false;
|
|
}
|
|
|
|
try
|
|
{
|
|
//Write the pipe
|
|
//This can only happen on the main thread so it should be fine.
|
|
Logger.Trace("Writing frame");
|
|
frame.WriteStream(_stream);
|
|
return true;
|
|
}
|
|
catch (IOException io)
|
|
{
|
|
Logger.Error("Failed to write frame because of a IO Exception: {0}", io.Message);
|
|
}
|
|
catch (ObjectDisposedException)
|
|
{
|
|
Logger.Warning("Failed to write frame as the stream was already disposed");
|
|
}
|
|
catch (InvalidOperationException)
|
|
{
|
|
Logger.Warning("Failed to write frame because of a invalid operation");
|
|
}
|
|
|
|
//We must have failed the try catch
|
|
return false;
|
|
}
|
|
|
|
private string GetPipeName(int pipe, string sandbox = "")
|
|
{
|
|
switch (Environment.OSVersion.Platform)
|
|
{
|
|
default:
|
|
|
|
#if !UNITY_EDITOR_OSX
|
|
case PlatformID.Win32NT:
|
|
case PlatformID.Win32S:
|
|
case PlatformID.Win32Windows:
|
|
case PlatformID.WinCE:
|
|
Logger.Trace("PIPE WIN");
|
|
return sandbox + string.Format(PIPE_NAME, pipe);
|
|
#endif
|
|
|
|
case PlatformID.Unix:
|
|
case PlatformID.MacOSX:
|
|
Logger.Trace("PIPE UNIX / MACOSX");
|
|
return Path.Combine(GetEnviromentTemp(), sandbox + string.Format(PIPE_NAME, pipe));
|
|
}
|
|
}
|
|
|
|
private string GetPipeSandbox()
|
|
{
|
|
switch (Environment.OSVersion.Platform)
|
|
{
|
|
default:
|
|
return null;
|
|
case PlatformID.Unix:
|
|
return "snap.discord/";
|
|
}
|
|
}
|
|
|
|
private string GetEnviromentTemp()
|
|
{
|
|
string temp = null;
|
|
temp = temp ?? Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR");
|
|
temp = temp ?? Environment.GetEnvironmentVariable("TMPDIR");
|
|
temp = temp ?? Environment.GetEnvironmentVariable("TMP");
|
|
temp = temp ?? Environment.GetEnvironmentVariable("TEMP");
|
|
temp = temp ?? "/tmp";
|
|
return temp;
|
|
}
|
|
}
|
|
}
|
|
#endif |