From 88abc095c279aac1438e8d4c934d215b5c698903 Mon Sep 17 00:00:00 2001 From: Eicy Date: Tue, 17 Dec 2024 00:23:59 +0800 Subject: [PATCH] init Signed-off-by: Eicy --- .gitignore | 3 + API/Api.cs | 594 ++++++++++++++++++++++++++++++++++++++++ API/api.proto | 21 ++ ApiS.cs | 2 + Command/Commands.cs | 156 +++++++++++ Login/QrCode.cs | 106 +++++++ Program.cs | 62 +++++ README.md | 12 + Shrink.csproj | 30 ++ Shrink.sln | 16 ++ Utility/Console.cs | 16 ++ Utility/Data.cs.disable | 43 +++ 12 files changed, 1061 insertions(+) create mode 100644 .gitignore create mode 100644 API/Api.cs create mode 100644 API/api.proto create mode 100644 ApiS.cs create mode 100644 Command/Commands.cs create mode 100644 Login/QrCode.cs create mode 100644 Program.cs create mode 100644 README.md create mode 100644 Shrink.csproj create mode 100644 Shrink.sln create mode 100644 Utility/Console.cs create mode 100644 Utility/Data.cs.disable diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c9704c2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.idea/ +/[Bb]in/ +/[Oo]bj/ \ No newline at end of file diff --git a/API/Api.cs b/API/Api.cs new file mode 100644 index 0000000..33ab674 --- /dev/null +++ b/API/Api.cs @@ -0,0 +1,594 @@ +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: api.proto +// +#pragma warning disable 1591, 0612, 3021, 8981 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Api { + + /// Holder for reflection information generated from api.proto + public static partial class ApiReflection { + + #region Descriptor + /// File descriptor for api.proto + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static ApiReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "CglhcGkucHJvdG8SA2FwaSJGCgdSZXF1ZXN0EgwKBGNvZGUYASABKAkSDAoE", + "c3RyMRgCIAEoCRIMCgRzdHIyGAMgASgJEhEKCWludF92YWx1ZRgEIAEoBSIs", + "CghSZXNwb25zZRIPCgdzdWNjZXNzGAEgASgIEg8KB21lc3NhZ2UYAiABKAky", + "NAoKQXBpU2VydmljZRImCgdDYWxsQXBpEgwuYXBpLlJlcXVlc3QaDS5hcGku", + "UmVzcG9uc2ViBnByb3RvMw==")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Api.Request), global::Api.Request.Parser, new[]{ "Code", "Str1", "Str2", "IntValue" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Api.Response), global::Api.Response.Parser, new[]{ "Success", "Message" }, null, null, null, null) + })); + } + #endregion + + } + #region Messages + /// + /// 定义消息结构 + /// + [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")] + public sealed partial class Request : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Request()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Api.ApiReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public Request() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public Request(Request other) : this() { + code_ = other.code_; + str1_ = other.str1_; + str2_ = other.str2_; + intValue_ = other.intValue_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public Request Clone() { + return new Request(this); + } + + /// Field number for the "code" field. + public const int CodeFieldNumber = 1; + private string code_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Code { + get { return code_; } + set { + code_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "str1" field. + public const int Str1FieldNumber = 2; + private string str1_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Str1 { + get { return str1_; } + set { + str1_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "str2" field. + public const int Str2FieldNumber = 3; + private string str2_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Str2 { + get { return str2_; } + set { + str2_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "int_value" field. + public const int IntValueFieldNumber = 4; + private int intValue_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int IntValue { + get { return intValue_; } + set { + intValue_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as Request); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(Request other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Code != other.Code) return false; + if (Str1 != other.Str1) return false; + if (Str2 != other.Str2) return false; + if (IntValue != other.IntValue) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Code.Length != 0) hash ^= Code.GetHashCode(); + if (Str1.Length != 0) hash ^= Str1.GetHashCode(); + if (Str2.Length != 0) hash ^= Str2.GetHashCode(); + if (IntValue != 0) hash ^= IntValue.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Code.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Code); + } + if (Str1.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Str1); + } + if (Str2.Length != 0) { + output.WriteRawTag(26); + output.WriteString(Str2); + } + if (IntValue != 0) { + output.WriteRawTag(32); + output.WriteInt32(IntValue); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Code.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Code); + } + if (Str1.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Str1); + } + if (Str2.Length != 0) { + output.WriteRawTag(26); + output.WriteString(Str2); + } + if (IntValue != 0) { + output.WriteRawTag(32); + output.WriteInt32(IntValue); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Code.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Code); + } + if (Str1.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Str1); + } + if (Str2.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Str2); + } + if (IntValue != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(IntValue); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(Request other) { + if (other == null) { + return; + } + if (other.Code.Length != 0) { + Code = other.Code; + } + if (other.Str1.Length != 0) { + Str1 = other.Str1; + } + if (other.Str2.Length != 0) { + Str2 = other.Str2; + } + if (other.IntValue != 0) { + IntValue = other.IntValue; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + Code = input.ReadString(); + break; + } + case 18: { + Str1 = input.ReadString(); + break; + } + case 26: { + Str2 = input.ReadString(); + break; + } + case 32: { + IntValue = input.ReadInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Code = input.ReadString(); + break; + } + case 18: { + Str1 = input.ReadString(); + break; + } + case 26: { + Str2 = input.ReadString(); + break; + } + case 32: { + IntValue = input.ReadInt32(); + break; + } + } + } + } + #endif + + } + + [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")] + public sealed partial class Response : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Response()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Api.ApiReflection.Descriptor.MessageTypes[1]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public Response() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public Response(Response other) : this() { + success_ = other.success_; + message_ = other.message_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public Response Clone() { + return new Response(this); + } + + /// Field number for the "success" field. + public const int SuccessFieldNumber = 1; + private bool success_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Success { + get { return success_; } + set { + success_ = value; + } + } + + /// Field number for the "message" field. + public const int MessageFieldNumber = 2; + private string message_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string Message { + get { return message_; } + set { + message_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as Response); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(Response other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Success != other.Success) return false; + if (Message != other.Message) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (Success != false) hash ^= Success.GetHashCode(); + if (Message.Length != 0) hash ^= Message.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Success != false) { + output.WriteRawTag(8); + output.WriteBool(Success); + } + if (Message.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Message); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Success != false) { + output.WriteRawTag(8); + output.WriteBool(Success); + } + if (Message.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Message); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (Success != false) { + size += 1 + 1; + } + if (Message.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(Response other) { + if (other == null) { + return; + } + if (other.Success != false) { + Success = other.Success; + } + if (other.Message.Length != 0) { + Message = other.Message; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Success = input.ReadBool(); + break; + } + case 18: { + Message = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Success = input.ReadBool(); + break; + } + case 18: { + Message = input.ReadString(); + break; + } + } + } + } + #endif + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/API/api.proto b/API/api.proto new file mode 100644 index 0000000..27b6a84 --- /dev/null +++ b/API/api.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package api; + +// 定义消息结构 +message Request { + string code = 1; + string str1 = 2; + string str2 = 3; + int32 int_value = 4; +} + +message Response { + bool success = 1; + string message = 2; +} + +// 定义服务 +service ApiService { + rpc CallApi (Request) returns (Response); +} diff --git a/ApiS.cs b/ApiS.cs new file mode 100644 index 0000000..e38a8b5 --- /dev/null +++ b/ApiS.cs @@ -0,0 +1,2 @@ +namespace Shrink; + diff --git a/Command/Commands.cs b/Command/Commands.cs new file mode 100644 index 0000000..0ea6d45 --- /dev/null +++ b/Command/Commands.cs @@ -0,0 +1,156 @@ +using System.Text.Json; +using System.Xml; +using Lagrange.Core; +using Lagrange.Core.Common.Interface.Api; +using Lagrange.Core.Message; +using Shrink.Login; + +namespace Shrink.Command; + +public class Commands +{ + private static Commands? _instance; + private static readonly object Lock = new(); + private Commands() { } + + public static Commands Instance + { + get + { + if (_instance != null) return _instance; + lock (Lock) + { + _instance ??= new Commands(); + } + return _instance; + } + } + + // 使用字典存储命令和群消息 + private Dictionary _commandDict = new(); + private List _corpus = new(); + private Dictionary _messageDict = new(); + private HashSet _adminSet = new(); + + // 文件初始化 + public async Task Init() + { + // 读取Admins.json + if (File.Exists("Admins.json")) + { + _adminSet = new HashSet(JsonSerializer.Deserialize>(await File.ReadAllTextAsync("Admins.json"))); + } + else + { + _adminSet.Add(3048536893); // 默认管理员 + await File.WriteAllTextAsync("Admins.json", JsonSerializer.Serialize(_adminSet.ToList())); + } + + // 读取JoinMessage.json + if (File.Exists("JoinMessage.json")) + { + _messageDict = JsonSerializer.Deserialize>>(await File.ReadAllTextAsync("JoinMessage.json")) + .ToDictionary(msg => msg.Key, msg => msg.Value); + } + else + { + _messageDict.Add(620902312, "欢迎"); + await File.WriteAllTextAsync("JoinMessage.json", JsonSerializer.Serialize(_messageDict.Select(kv => new KeyValuePair(kv.Key, kv.Value)).ToList())); + } + + // 读取Commands.json + if (File.Exists("Commands.json")) + { + _commandDict = JsonSerializer.Deserialize>>(await File.ReadAllTextAsync("Commands.json")) + .ToDictionary(cmd => cmd.Key, cmd => cmd.Value); + } + else + { + _commandDict.Add("/ping", "Pong!"); + await File.WriteAllTextAsync("Commands.json", JsonSerializer.Serialize(_commandDict.Select(kv => new KeyValuePair(kv.Key, kv.Value)).ToList())); + } + } + + private async Task SaveAdmin() + { + await File.WriteAllTextAsync("Admins.json", JsonSerializer.Serialize(_adminSet.ToList())); + await Init(); + } + + // bot管理员权限检查 + private void NoEnoughPermission(BotContext ctx, uint groupID) + { + var chain = MessageBuilder.Group(groupID).Text("权限不足"); + ctx.SendMessage(chain.Build()); + } + + // 先Init后再运行 + public Task Run() + { + QrCode.Instance.Client.Invoker.OnGroupMemberIncreaseEvent += (context, @event) => + { + var groupid = @event.GroupUin; + if (_messageDict.ContainsKey(groupid)) + { + var message = _messageDict[groupid]; + var chain = MessageBuilder.Group(groupid).Text(message); + context.SendMessage(chain.Build()); + } + }; + + QrCode.Instance.Client.Invoker.OnGroupMessageReceived += (content, @event) => + { + var groupId = @event.Chain.GroupUin.Value; + var senderId = @event.Chain.FriendUin; + var text = @event.Chain.ToPreviewText(); + + // 执行命令 + if (_commandDict.ContainsKey(text)) + { + var chain = MessageBuilder.Group(groupId).Text(_commandDict[text]); + content.SendMessage(chain.Build()); + } + + var today = DateTime.Today; + var seed = today.Year ^ today.Month ^ today.Day ^ senderId; + var random = new Random((int)seed); + + switch (text) + { + case "/reload": + _ = Init(); + var chain3 = MessageBuilder.Group(groupId).Text("重载完成!"); + content.SendMessage(chain3.Build()); + break; + } + + + if (text.Contains("/addadmin") && text.StartsWith("/addadmin")) + { + if (_adminSet.Contains(senderId)) + { + var temp = uint.Parse(text.Remove(0, 9)); + if (_adminSet.Contains(temp)) + { + var chain = MessageBuilder.Group(groupId).Text("已存在管理员: " + temp); + content.SendMessage(chain.Build()); + } + else + { + _adminSet.Add(temp); + var chain = MessageBuilder.Group(groupId).Text("已添加管理员: " + temp); + SaveAdmin(); + content.SendMessage(chain.Build()); + } + } + else + { + NoEnoughPermission(content, groupId); + } + } + + }; + + return Task.CompletedTask; + } +} diff --git a/Login/QrCode.cs b/Login/QrCode.cs new file mode 100644 index 0000000..17ba6aa --- /dev/null +++ b/Login/QrCode.cs @@ -0,0 +1,106 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using Lagrange.Core; +using Lagrange.Core.Common; +using Lagrange.Core.Common.Interface; +using Lagrange.Core.Common.Interface.Api; +using Shrink.Utility; +using Console = System.Console; + +namespace Shrink.Login; + +public class QrCode +{ + private static QrCode? _instance; + + private static readonly object Lock = new(); + + public static QrCode Instance + { + get + { + // 双重检查锁定 + if (_instance != null) return _instance; + lock (Lock) + { + _instance ??= new QrCode(); + } + return _instance; + } + } + + public BotContext? Client; + public static void SaveKeystore(BotKeystore keystore) => + File.WriteAllText("Keystore.json", JsonSerializer.Serialize(keystore)); + + public static BotDeviceInfo GetDeviceInfo() + { + if (File.Exists("DeviceInfo.json")) + { + var info = JsonSerializer.Deserialize(File.ReadAllText("DeviceInfo.json")); + if (info != null) return info; + + info = BotDeviceInfo.GenerateInfo(); + File.WriteAllText("DeviceInfo.json", JsonSerializer.Serialize(info)); + return info; + } + + var deviceInfo = BotDeviceInfo.GenerateInfo(); + File.WriteAllText("DeviceInfo.json", JsonSerializer.Serialize(deviceInfo)); + return deviceInfo; + } + public static BotKeystore? LoadKeystore() + { + try + { + var text = File.ReadAllText("Keystore.json"); + return JsonSerializer.Deserialize(text, new JsonSerializerOptions() + { + ReferenceHandler = ReferenceHandler.Preserve + }); + } + catch + { + return null; + } + } + // 登录方法 + public async Task Login() + { + #region bot实例化 + + var deviceInfo = GetDeviceInfo(); + var keyStore = LoadKeystore() ?? new BotKeystore(); + + Client = BotFactory.Create(new BotConfig + { + UseIPv6Network = false, + GetOptimumServer = true, + AutoReconnect = true, + Protocol = Protocols.Linux + }, deviceInfo, keyStore); + + #endregion + + // Log模式 + Client.Invoker.OnBotLogEvent += (_, @event) => + { + @event.Level.ChangeColorByTitle(); + Console.WriteLine(@event.ToString()); + }; + + // bot信息保存,但存在bug未修复 + Client.Invoker.OnBotOnlineEvent += (_, @event) => + { + Console.WriteLine(@event.ToString()); + SaveKeystore(Client.UpdateKeystore()); + }; + // 二维码生成,启动后在根目录下生成qr.png + var qrCode = await Client.FetchQrCode(); + if (qrCode != null) + { + await File.WriteAllBytesAsync("qr.png", qrCode.Value.QrCode); + await Client.LoginByQrCode(); + } + } +} \ No newline at end of file diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..7432cae --- /dev/null +++ b/Program.cs @@ -0,0 +1,62 @@ +using Grpc.Net.Client; +using Mono.Cecil; +using Mono.Cecil.Cil; +using Shrink.Command; +using Shrink.Login; + +namespace Shrink; + +public static class Program +{ + public static async Task Main() + { + /*var originalAssemblyPath = "Lagrange.Core.dll"; + var tempAssemblyPath = "ModifiedExternalAssembly.dll"; + var oldUrl = "自己找"; + var newUrl = "自己找"; + + ModifyAssembly(originalAssemblyPath, tempAssemblyPath, oldUrl, newUrl);*/ + + await QrCode.Instance.Login(); + await Commands.Instance.Init(); + await Commands.Instance.Run(); + + + } + /*private static void ModifyAssembly(string originalAssemblyPath, string tempAssemblyPath, string oldUrl, string newUrl) + { + var assembly = AssemblyDefinition.ReadAssembly(originalAssemblyPath); + var module = assembly.MainModule; + + // 查找LinuxSigner类型 + var linuxSignerType = module.Types.FirstOrDefault(t => t.Name == "LinuxSigner"); + if (linuxSignerType == null) + { + Console.WriteLine("无LinuxSigner类型"); + return; + } + + // 查找构造函数 + var constructor = linuxSignerType.Methods.FirstOrDefault(m => m.IsConstructor); + if (constructor == null) + { + Console.WriteLine("无构造函数"); + return; + } + + var ilProcessor = constructor.Body.GetILProcessor(); + foreach (var instruction in constructor.Body.Instructions) + { + // 检查是否是加载字符串操作 + if (instruction.OpCode == OpCodes.Ldstr && instruction.Operand is string str && str == oldUrl) + { + instruction.Operand = newUrl; // 替换为新URL + Console.WriteLine($"替换: {oldUrl}为{newUrl}"); + } + } + + assembly.Write(tempAssemblyPath); + Console.WriteLine($"已将修改后的程序集保存在{tempAssemblyPath}"); + }*/ + +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..a0bc81a --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# ShrinkSharp +.NET6 + +打包为Linux可执行文件请在项目文件夹下打开控制台输入dotnet publish -c Release -r linux-x64 + +一代: https://github.com/bingling-sama/BakaHDT + +二代: https://github.com/GBLodb/ChlorineSharp + +三代: https://github.com/cneicy/Shrink + +四代: https://github.com/cneicy/ShrinkSharp diff --git a/Shrink.csproj b/Shrink.csproj new file mode 100644 index 0000000..58f622f --- /dev/null +++ b/Shrink.csproj @@ -0,0 +1,30 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Shrink.sln b/Shrink.sln new file mode 100644 index 0000000..aedf9e8 --- /dev/null +++ b/Shrink.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shrink", "Shrink.csproj", "{7547D900-7445-4C83-ACAF-84C6E4B8F291}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7547D900-7445-4C83-ACAF-84C6E4B8F291}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7547D900-7445-4C83-ACAF-84C6E4B8F291}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7547D900-7445-4C83-ACAF-84C6E4B8F291}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7547D900-7445-4C83-ACAF-84C6E4B8F291}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Utility/Console.cs b/Utility/Console.cs new file mode 100644 index 0000000..0a8194b --- /dev/null +++ b/Utility/Console.cs @@ -0,0 +1,16 @@ +using Lagrange.Core.Event.EventArg; + +namespace Shrink.Utility; + +public static class Console +{ + public static void ChangeColorByTitle(this LogLevel level) => System.Console.ForegroundColor = level switch + { + LogLevel.Debug => ConsoleColor.White, + LogLevel.Verbose => ConsoleColor.DarkGray, + LogLevel.Information => ConsoleColor.Blue, + LogLevel.Warning => ConsoleColor.Yellow, + LogLevel.Fatal => ConsoleColor.Red, + _ => System.Console.ForegroundColor + }; +} \ No newline at end of file diff --git a/Utility/Data.cs.disable b/Utility/Data.cs.disable new file mode 100644 index 0000000..e8ed830 --- /dev/null +++ b/Utility/Data.cs.disable @@ -0,0 +1,43 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using Lagrange.Core.Common; + +namespace Shrink.Utility; + +public static class Data +{ + public static void SaveKeystore(BotKeystore keystore) => + File.WriteAllText("Keystore.json", JsonSerializer.Serialize(keystore)); + + public static BotDeviceInfo GetDeviceInfo() + { + if (File.Exists("DeviceInfo.json")) + { + var info = JsonSerializer.Deserialize(File.ReadAllText("DeviceInfo.json")); + if (info != null) return info; + + info = BotDeviceInfo.GenerateInfo(); + File.WriteAllText("DeviceInfo.json", JsonSerializer.Serialize(info)); + return info; + } + + var deviceInfo = BotDeviceInfo.GenerateInfo(); + File.WriteAllText("DeviceInfo.json", JsonSerializer.Serialize(deviceInfo)); + return deviceInfo; + } + public static BotKeystore? LoadKeystore() + { + try + { + var text = File.ReadAllText("Keystore.json"); + return JsonSerializer.Deserialize(text, new JsonSerializerOptions() + { + ReferenceHandler = ReferenceHandler.Preserve + }); + } + catch + { + return null; + } + } +} \ No newline at end of file