├── .editorconfig
├── .github
└── workflows
│ ├── milky-build.yaml
│ ├── native-api-build.yaml
│ ├── nuget-push-lagrange-core.yaml
│ ├── nuget-push-lagrange-proto-codegen.yaml
│ └── nuget-push-lagrange-proto.yaml
├── .gitignore
├── Lagrange.Codec
├── AssemblyInfo.cs
├── AudioCodec.cs
├── AudioHelper.cs
├── Entities
│ └── VideoInfo.cs
├── Exceptions
│ └── CodecException.cs
├── Interop
│ ├── AudioInterop.cs
│ └── VideoInterop.cs
├── Lagrange.Codec.csproj
├── Streams
│ ├── NativeCodecStream.cs
│ ├── PCMStream.cs
│ └── SilkStream.cs
└── VideoCodec.cs
├── Lagrange.Core.NativeAPI.Test
├── Lagrange.Core.NativeAPI.Test.csproj
├── NativeModel
│ ├── BotConfigStruct.cs
│ ├── BotLogEventStruct.cs
│ ├── BotQrCodeEventStruct.cs
│ ├── ByteArrayNative.cs
│ └── ReverseEventCountStruct.cs
├── Program.cs
└── Wrapper.cs
├── Lagrange.Core.NativeAPI
├── Context.cs
├── Lagrange.Core.NativeAPI.csproj
├── NativeModel
│ ├── Common
│ │ ├── BotConfigStruct.cs
│ │ ├── BotFriendCategoryStruct.cs
│ │ ├── BotKeystoreStruct.cs
│ │ ├── ByteArrayDictNative.cs
│ │ ├── ByteArrayKVPNative.cs
│ │ ├── ByteArrayNative.cs
│ │ └── KeyValuePairNative.cs
│ ├── Event
│ │ ├── BotCaptchaEventStruct.cs
│ │ ├── BotLogEventStruct.cs
│ │ ├── BotLoginEventStruct.cs
│ │ ├── BotMessageEventStruct.cs
│ │ ├── BotNewDeviceVerifyEventStruct.cs
│ │ ├── BotOnlineEventStruct.cs
│ │ ├── BotQrCodeEventStruct.cs
│ │ ├── BotQrCodeQueryEventStruct.cs
│ │ ├── BotRefreshKeystoreEventStruct.cs
│ │ ├── BotSMSEventStruct.cs
│ │ ├── IEventStruct.cs
│ │ └── ReverseEventCountStruct.cs
│ ├── Message
│ │ ├── BotFriendStruct.cs
│ │ ├── BotGroupMemberStruct.cs
│ │ ├── BotGroupStruct.cs
│ │ ├── BotMessageStruct.cs
│ │ ├── BotStrangerStruct.cs
│ │ ├── Entity
│ │ │ ├── EntityType.cs
│ │ │ ├── IEntityStruct.cs
│ │ │ ├── ImageEntityStruct.cs
│ │ │ ├── MentionEntityStruct.cs
│ │ │ ├── MultiMsgEntityStruct.cs
│ │ │ ├── RecordEntityStruct.cs
│ │ │ ├── ReplyEntityStruct.cs
│ │ │ ├── TextEntityStruct.cs
│ │ │ └── VideoEntityStruct.cs
│ │ └── TypedEntityStruct.cs
│ └── StructExtensions.cs
├── Program.cs
├── ReverseEvent
│ ├── Abstract
│ │ └── ReverseEventBase.cs
│ ├── BotCaptchaReverseEvent.cs
│ ├── BotLogReverseEvent.cs
│ ├── BotLoginReverseEvent.cs
│ ├── BotMessageReverseEvent.cs
│ ├── BotNewDeviceVerifyReverseEvent.cs
│ ├── BotOnlineReverseEvent.cs
│ ├── BotQrCodeQueryReverseEvent.cs
│ ├── BotQrCodeReverseEvent.cs
│ ├── BotRefreshKeystoreReverseEvent.cs
│ ├── BotSMSReverseEvent.cs
│ ├── EventEntryPoint.cs
│ └── ReverseEventInvoker.cs
├── SendMessageContext.cs
├── SendMessageEntryPoint.cs
└── StatusCode.cs
├── Lagrange.Core.Runner
├── InteropSignProvider.cs
├── Lagrange.Core.Runner.csproj
├── Program.cs
└── QrCodeHelper.cs
├── Lagrange.Core.Test
├── AssemblyInfo.cs
├── Binary
│ └── BinaryPacketTest.cs
├── Cryptography
│ ├── AesGcmTest.cs
│ ├── AesTest.cs
│ ├── EcdhTest.cs
│ ├── Sha1Test.cs
│ └── TeaTest.cs
└── Lagrange.Core.Test.csproj
├── Lagrange.Core.sln
├── Lagrange.Core
├── AssemblyInfo.cs
├── BotContext.cs
├── Common
│ ├── BotAppInfo.cs
│ ├── BotConfig.cs
│ ├── BotGender.cs
│ ├── BotInfo.cs
│ ├── BotKeystore.cs
│ ├── Entity
│ │ ├── BotContact.cs
│ │ ├── BotFriend.cs
│ │ ├── BotFriendCategory.cs
│ │ ├── BotGroup.cs
│ │ ├── BotGroupMember.cs
│ │ └── BotStranger.cs
│ ├── IAndroidBotSignProvider.cs
│ ├── IBotSignProvider.cs
│ ├── Interface
│ │ ├── BotExt.cs
│ │ ├── BotFactory.cs
│ │ ├── MessageExt.cs
│ │ └── OperationExt.cs
│ └── Response
│ │ └── BotQrCodeInfo.cs
├── Events
│ ├── EventArgs
│ │ ├── BotCaptchaEvent.cs
│ │ ├── BotLogEvent.cs
│ │ ├── BotLoginEvent.cs
│ │ ├── BotMessageEvent.cs
│ │ ├── BotNewDeviceVerifyEvent.cs
│ │ ├── BotOfflineEvent.cs
│ │ ├── BotOnlineEvent.cs
│ │ ├── BotQrCodeEvent.cs
│ │ ├── BotQrCodeQueryEvent.cs
│ │ ├── BotRefreshKeystoreEvent.cs
│ │ └── BotSMSEvent.cs
│ ├── EventBase.cs
│ └── EventInvoker.cs
├── Exceptions
│ ├── InvalidTargetException.cs
│ ├── LagrangeException.cs
│ ├── OperationException.cs
│ └── ServiceNotFoundException.cs
├── Internal
│ ├── Context
│ │ ├── CacheContext.cs
│ │ ├── EventContext.cs
│ │ ├── HighwayContext.cs
│ │ ├── PacketContext.cs
│ │ ├── ServiceContext.cs
│ │ └── SocketContext.cs
│ ├── Events
│ │ ├── EventSubscribeAttribute.cs
│ │ ├── Login
│ │ │ ├── CloseCodeEvent.cs
│ │ │ ├── ExchangeEmpEvent.cs
│ │ │ ├── KeyExchangeEvent.cs
│ │ │ ├── LoginEvent.cs
│ │ │ ├── NTLoginEvent.cs
│ │ │ ├── TransEmpEvent.cs
│ │ │ ├── UinResolveEvent.cs
│ │ │ └── VerifyCodeEvent.cs
│ │ ├── Message
│ │ │ ├── GroupFSEvent.cs
│ │ │ ├── GroupFileSendEvent.cs
│ │ │ ├── LongMsgRecvEvent.cs
│ │ │ ├── LongMsgSendEvent.cs
│ │ │ ├── NTV2RichMediaDownloadEvent.cs
│ │ │ ├── NTV2RichMediaUploadEvent.cs
│ │ │ ├── NudgeEvent.cs
│ │ │ ├── PushMessageEvent.cs
│ │ │ └── SendMessageEvent.cs
│ │ ├── ProtocolEvent.cs
│ │ └── System
│ │ │ ├── AliveEvent.cs
│ │ │ ├── FetchClientKeyEvent.cs
│ │ │ ├── FetchCookiesEvent.cs
│ │ │ ├── FetchFriendsEvent.cs
│ │ │ ├── FetchGroupMembersEvent.cs
│ │ │ ├── FetchGroupsEvent.cs
│ │ │ ├── FileUploadEvent.cs
│ │ │ ├── HighwaySessionEvent.cs
│ │ │ ├── InfoSyncEvent.cs
│ │ │ ├── InfoSyncPushEvent.cs
│ │ │ ├── KickEvent.cs
│ │ │ ├── PushParamsEvent.cs
│ │ │ ├── SsoHeartBeatEvent.cs
│ │ │ └── SsoUnregisterEvent.cs
│ ├── Logic
│ │ ├── ILogic.cs
│ │ ├── MessagingLogic.cs
│ │ ├── OperationLogic.cs
│ │ ├── PushLogic.cs
│ │ └── WtExchangeLogic.cs
│ ├── Network
│ │ ├── CallbackClientListener.cs
│ │ ├── ClientListener.SocketSession.cs
│ │ ├── ClientListener.cs
│ │ └── IClientListener.cs
│ ├── Packets
│ │ ├── Login
│ │ │ ├── NTEcdh.cs
│ │ │ ├── NTLogin.cs
│ │ │ ├── NTNewDevice.cs
│ │ │ ├── QrLogin.cs
│ │ │ ├── QrLoginExtInfo.cs
│ │ │ ├── Tlv.cs
│ │ │ ├── TlvQrCode.cs
│ │ │ └── WtLogin.cs
│ │ ├── Message
│ │ │ ├── Elem.cs
│ │ │ ├── Extra.cs
│ │ │ ├── GroupFileCommon.cs
│ │ │ ├── LongMsgInterface.cs
│ │ │ ├── NTMessageCommon.cs
│ │ │ ├── NTPushService.cs
│ │ │ └── NTSendMessage.cs
│ │ ├── Service
│ │ │ ├── FetchGroupMembers.cs
│ │ │ ├── FetchGroups.cs
│ │ │ ├── FileUploadExt.cs
│ │ │ ├── Highway.cs
│ │ │ ├── IncPull.cs
│ │ │ ├── KickNT.cs
│ │ │ ├── LightApp.cs
│ │ │ ├── NTV2RichMedia.cs
│ │ │ ├── NTV2RichMediaHighwayExt.cs
│ │ │ ├── NTV2RichMediaReq.cs
│ │ │ ├── NTV2RichMediaResp.cs
│ │ │ ├── OfflineFileUpload.cs
│ │ │ ├── Oidb.cs
│ │ │ ├── Oidb_0x102A.cs
│ │ │ ├── Oidb_0x6D6.cs
│ │ │ ├── Oidb_0x6D9.cs
│ │ │ ├── Oidb_0xED3.cs
│ │ │ └── SubCmd0x501.cs
│ │ ├── Struct
│ │ │ ├── ServicePacker.cs
│ │ │ ├── SsoPacker.cs
│ │ │ ├── SsoPacket.cs
│ │ │ ├── SsoReserveFields.cs
│ │ │ └── StructBase.cs
│ │ └── System
│ │ │ ├── InfoSyncPush.cs
│ │ │ ├── NTSsoHeartBeat.cs
│ │ │ ├── PushParams.cs
│ │ │ ├── SsoInfoSync.cs
│ │ │ ├── SsoUnregister.cs
│ │ │ └── ThirdPartyLoginResponse.cs
│ └── Services
│ │ ├── BaseService.cs
│ │ ├── IService.cs
│ │ ├── Login
│ │ ├── EasyLoginService.cs
│ │ ├── ExchangeEmpService.cs
│ │ ├── KeyExchangeService.cs
│ │ ├── LoginService.cs
│ │ ├── NTLoginCommon.cs
│ │ ├── NewDeviceLoginService.cs
│ │ ├── PasswordLoginService.cs
│ │ ├── QrLoginService.cs
│ │ ├── RefreshA2Service.cs
│ │ ├── RefreshTicketService.cs
│ │ ├── TransEmpService.cs
│ │ ├── UinResolveService.cs
│ │ └── UnusualEasyLoginService.cs
│ │ ├── Message
│ │ ├── GroupFSService.cs
│ │ ├── GroupFileSendService.cs
│ │ ├── LongMsgRecvService.cs
│ │ ├── LongMsgSendService.cs
│ │ ├── NTV2RichMediaDownloadService.cs
│ │ ├── NTV2RichMediaUploadService.cs
│ │ ├── NudgeService.cs
│ │ ├── PushMessageService.cs
│ │ └── SendMessageService.cs
│ │ ├── OidbService.cs
│ │ ├── ServiceAttribute.cs
│ │ └── System
│ │ ├── AliveService.cs
│ │ ├── FetchClientKeyService.cs
│ │ ├── FetchCookiesService.cs
│ │ ├── FetchFriendsService.cs
│ │ ├── FetchGroupMembersService.cs
│ │ ├── FetchGroupsService.cs
│ │ ├── FileUploadService.cs
│ │ ├── HighwaySessionService.cs
│ │ ├── InfoSyncPushService.cs
│ │ ├── InfoSyncService.cs
│ │ ├── KickService.cs
│ │ ├── PushParamsService.cs
│ │ ├── SsoHeartBeatService.cs
│ │ └── SsoUnregisterService.cs
├── Lagrange.Core.csproj
├── Message
│ ├── BotMessage.Create.cs
│ ├── BotMessage.cs
│ ├── Entities
│ │ ├── IMessageEntity.cs
│ │ ├── ImageEntity.cs
│ │ ├── MentionEntity.cs
│ │ ├── MultiMsgEntity.cs
│ │ ├── RecordEntity.cs
│ │ ├── ReplyEntity.cs
│ │ ├── RichMediaEntityBase.cs
│ │ ├── TextEntity.cs
│ │ └── VideoEntity.cs
│ ├── MessageBuilder.cs
│ ├── MessageChain.cs
│ ├── MessagePacker.cs
│ └── MessageType.cs
└── Utility
│ ├── AudioHelper.cs
│ ├── Binary
│ ├── BinaryPacket.cs
│ ├── Prefix.cs
│ └── SegmentBufferWriter.cs
│ ├── BinaryHelper.cs
│ ├── Compression
│ ├── Common.cs
│ └── ZCompression.cs
│ ├── Cryptography
│ ├── AesGcmProvider.cs
│ ├── EcdhProvider.cs
│ ├── PowProvider.cs
│ ├── Sha1Stream.cs
│ ├── TeaProvider.cs
│ └── TriSha1Provider.cs
│ ├── Extension
│ ├── CollectionExt.cs
│ ├── ProtocolExt.cs
│ ├── ReflectionExt.cs
│ ├── SocketExt.cs
│ ├── StreamExt.cs
│ └── TaskAwaitExt.cs
│ ├── ImageHelper.cs
│ ├── JsonHelper.cs
│ ├── ProtoHelper.cs
│ └── ProtocolHelper.cs
├── Lagrange.Milky.Implementation.Api.Generator
├── ApiHandlerInfo.cs
├── DiagnosticDescriptors.cs
├── Extension
│ ├── AttributeSyntaxExtension.cs
│ └── SymbolExtension.cs
├── Lagrange.Milky.Implementation.Api.Generator.csproj
└── MilkyApiHandlerGenerator.cs
├── Lagrange.Milky
├── Constants.cs
├── Core
│ ├── Configuration
│ │ ├── CoreConfiguration.cs
│ │ ├── LoginConfiguration.cs
│ │ ├── ServerConfiguration.cs
│ │ └── SignerConfiguration.cs
│ ├── Extension
│ │ ├── HostApplicationBuilderExtension.cs
│ │ └── LoggerFilterOptionsExtension.cs
│ ├── Service
│ │ ├── CoreLoggerService.cs
│ │ └── CoreLoginService.cs
│ └── Utility
│ │ ├── CaptchaResolver
│ │ ├── ICaptchaResolver.cs
│ │ ├── ManualCaptchaResolver.cs
│ │ └── OnlineCaptchaResolver.cs
│ │ ├── CoreJsonUtility.cs
│ │ ├── QrCodeUtility.cs
│ │ └── Signer.cs
├── Extension
│ ├── HostApplicationBuilderExtension.cs
│ └── ReaderWriterLockSlimExtension.cs
├── Implementation
│ ├── Api
│ │ ├── ApiAttribute.cs
│ │ ├── ApiFailedResult.cs
│ │ ├── ApiOkResult.cs
│ │ ├── Exception
│ │ │ └── ApiException.cs
│ │ ├── Handler
│ │ │ ├── File
│ │ │ │ ├── DeleteGroupFileHandler.cs
│ │ │ │ └── GetGroupFileDownloadUrlHandler.cs
│ │ │ ├── Friend
│ │ │ │ └── SendFriendNudgeHandler.cs
│ │ │ ├── Group
│ │ │ │ └── SendGroupNudgeHandler.cs
│ │ │ ├── Message
│ │ │ │ ├── SendGroupMessageHandler.cs
│ │ │ │ └── SendPrivateMessageHandler.cs
│ │ │ └── System
│ │ │ │ ├── GetFriendInfoHandler.cs
│ │ │ │ ├── GetFriendListHandler.cs
│ │ │ │ ├── GetGroupInfoHandler.cs
│ │ │ │ ├── GetGroupListHandler.cs
│ │ │ │ ├── GetGroupMemberInfoHandler.cs
│ │ │ │ ├── GetGroupMemberListHandler.cs
│ │ │ │ ├── GetImplInfoHandler.cs
│ │ │ │ └── GetLoginInfoHandler.cs
│ │ └── IApiHandler.cs
│ ├── Communication
│ │ ├── MilkyHttpApiService.cs
│ │ ├── MilkyWebHookEventService.cs
│ │ └── MilkyWebSocketEventService.cs
│ ├── Configuration
│ │ ├── MilkyConfiguration.cs
│ │ └── WebHookConfiguration.cs
│ ├── Entity
│ │ ├── Event
│ │ │ └── BotOfflineEvent.cs
│ │ ├── Friend.cs
│ │ ├── FriendCategory.cs
│ │ ├── Group.cs
│ │ ├── GroupMember.cs
│ │ ├── Message
│ │ │ └── Incoming
│ │ │ │ ├── FriendIncomingMessage.cs
│ │ │ │ ├── GroupIncomingMessage.cs
│ │ │ │ ├── IncomingMessageBase.cs
│ │ │ │ └── TempIncomingMessage.cs
│ │ └── Segment
│ │ │ ├── Common
│ │ │ └── Data
│ │ │ │ ├── FaceData.cs
│ │ │ │ ├── LightAppData.cs
│ │ │ │ ├── MarketFaceData.cs
│ │ │ │ ├── MentionAllData.cs
│ │ │ │ ├── MentionData.cs
│ │ │ │ ├── TextData.cs
│ │ │ │ └── XmlData.cs
│ │ │ ├── Incoming
│ │ │ ├── Data
│ │ │ │ ├── ForwardData.cs
│ │ │ │ ├── ImageData.cs
│ │ │ │ ├── RecordData.cs
│ │ │ │ ├── ReplyData.cs
│ │ │ │ └── VideoData.cs
│ │ │ ├── IIncomingSegment.cs
│ │ │ ├── IncomingFaceSegment.cs
│ │ │ ├── IncomingForwardSegment.cs
│ │ │ ├── IncomingImageSegment.cs
│ │ │ ├── IncomingLightAppSegment.cs
│ │ │ ├── IncomingMarketFaceSegment.cs
│ │ │ ├── IncomingMentionAllSegment.cs
│ │ │ ├── IncomingMentionSegment.cs
│ │ │ ├── IncomingRecordSegment.cs
│ │ │ ├── IncomingReplySegment.cs
│ │ │ ├── IncomingSegmentBase.cs
│ │ │ ├── IncomingTextSegment.cs
│ │ │ ├── IncomingVideoSegment.cs
│ │ │ └── IncomingXmlSegment.cs
│ │ │ └── Outgoing
│ │ │ ├── Data
│ │ │ ├── ImageData.cs
│ │ │ ├── RecordData.cs
│ │ │ ├── ReplyData.cs
│ │ │ └── VideoData.cs
│ │ │ ├── IOutgoingSegment.cs
│ │ │ ├── OutgoingFaceSegment.cs
│ │ │ ├── OutgoingForwardSegment.cs
│ │ │ ├── OutgoingImageSegment.cs
│ │ │ ├── OutgoingMentionAllSegment.cs
│ │ │ ├── OutgoingMentionSegment.cs
│ │ │ ├── OutgoingRecordSegment.cs
│ │ │ ├── OutgoingReplySegment.cs
│ │ │ ├── OutgoingSegmentBase.cs
│ │ │ ├── OutgoingTextSegment.cs
│ │ │ └── OutgoingVideoSegment.cs
│ ├── Event
│ │ ├── Event.cs
│ │ └── EventService.cs
│ ├── Extension
│ │ ├── HostApplicationBuilderExtension.cs
│ │ └── ServiceCollectionExtension.cs
│ └── Utility
│ │ ├── Converter.Entity.cs
│ │ ├── Converter.Event.cs
│ │ ├── Converter.Message.cs
│ │ ├── Converter.cs
│ │ ├── MilkyJsonUtility.cs
│ │ └── UriUtility.cs
├── Lagrange.Milky.csproj
├── Program.cs
├── README.md
└── Resources
│ ├── appsettings.jsonc
│ └── appsettings_schema.json
├── Lagrange.Proto.Benchmark
├── AssemblyInfo.cs
├── Lagrange.Proto.Benchmark.csproj
└── Program.cs
├── Lagrange.Proto.CodeGen
├── Commands
│ ├── DumpCommand.cs
│ └── GenerateCommand.cs
├── Format
│ ├── ProtoLexer.cs
│ ├── ProtoModel.cs
│ ├── ProtoParser.cs
│ ├── ProtoToken.cs
│ └── ProtoWriter.cs
├── Lagrange.Proto.CodeGen.csproj
├── Program.cs
└── Utility
│ ├── SourceWriter.cs
│ └── StringExt.cs
├── Lagrange.Proto.Generator
├── DiagnosticDescriptors.cs
├── Entity
│ ├── ProtoFieldInfo.cs
│ └── ProtoTypeInfo.cs
├── Lagrange.Proto.Generator.csproj
├── Properties
│ └── launchSettings.json
├── ProtoSourceGenerator.Emitter.Measure.cs
├── ProtoSourceGenerator.Emitter.Serialize.cs
├── ProtoSourceGenerator.Emitter.TypeInfo.cs
├── ProtoSourceGenerator.Emitter.cs
├── ProtoSourceGenerator.Parser.cs
├── ProtoSourceGenerator.cs
├── SymbolResolver.cs
└── Utility
│ ├── Extension
│ ├── RoslynExtension.cs
│ └── TypeExtension.cs
│ ├── ProtoHelper.cs
│ ├── Reference
│ └── NullableAttribute.cs
│ └── SourceWriter.cs
├── Lagrange.Proto.Runner
├── AssemblyInfo.cs
├── Lagrange.Proto.Runner.csproj
└── Program.cs
├── Lagrange.Proto.Test
├── CollectionTest.cs
├── EncoderTest.cs
├── Lagrange.Proto.Test.csproj
├── NodeTest.cs
├── ProtoTest.cs
├── ReflectionTest.cs
├── SegmentBufferTest.cs
└── UnknownTest.cs
├── Lagrange.Proto
├── AssemblyInfo.cs
├── IProtoSerializable.cs
├── Lagrange.Proto.csproj
├── Nodes
│ ├── ProtoArray.IList.cs
│ ├── ProtoArray.cs
│ ├── ProtoNode.Operators.cs
│ ├── ProtoNode.To.cs
│ ├── ProtoNode.cs
│ ├── ProtoObject.IDictionary.cs
│ ├── ProtoObject.cs
│ ├── ProtoRawValue.cs
│ ├── ProtoValue.CreateOverloads.cs
│ └── ProtoValue.cs
├── Primitives
│ ├── Lookup.cs
│ ├── ProtoReader.cs
│ ├── ProtoResolvable.cs
│ ├── ProtoWriteHelper.cs
│ ├── ProtoWriter.cs
│ └── ProtoWriterCache.cs
├── ProtoConstants.cs
├── ProtoMemberAttribute.cs
├── ProtoPackableAttribute.cs
├── ProtoValueMemberAttribute.cs
├── Serialization
│ ├── Converter
│ │ ├── Collection
│ │ │ ├── ProtoArrayConverter.cs
│ │ │ ├── ProtoListConverter.cs
│ │ │ └── ProtoRepeatedConverter.cs
│ │ ├── Generic
│ │ │ └── ProtoNullableConverter.cs
│ │ ├── Nodes
│ │ │ ├── ProtoArrayConverter.cs
│ │ │ ├── ProtoNodeConverter.cs
│ │ │ ├── ProtoObjectConverter.cs
│ │ │ ├── ProtoRawValueConverter.cs
│ │ │ └── ProtoValueConverter.cs
│ │ ├── Object
│ │ │ ├── ProtoErrorConverter.cs
│ │ │ ├── ProtoObjectConverter.cs
│ │ │ └── ProtoSerializableConverter.cs
│ │ └── Value
│ │ │ ├── ProtoBooleanConverter.cs
│ │ │ ├── ProtoBytesConverter.cs
│ │ │ ├── ProtoEnumConverter.cs
│ │ │ ├── ProtoMemoryByteConverter.cs
│ │ │ ├── ProtoMemoryCharConverter.cs
│ │ │ ├── ProtoNumberConverter.cs
│ │ │ ├── ProtoReadOnlyMemoryByteConverter.cs
│ │ │ ├── ProtoReadOnlyMemoryCharConverter.cs
│ │ │ └── ProtoStringConverter.cs
│ ├── Metadata
│ │ ├── MemberAccessor.cs
│ │ ├── ProtoFieldInfo.cs
│ │ ├── ProtoObjectInfo.cs
│ │ ├── ProtoTypeResolver.Dynamic.cs
│ │ ├── ProtoTypeResolver.WellKnownTypes.cs
│ │ ├── ProtoTypeResolver.WellKnownTypes.tt
│ │ ├── ProtoTypeResolver.cs
│ │ ├── ReflectionEmitCachingMemberAccessor.Cache.cs
│ │ ├── ReflectionEmitCachingMemberAccessor.cs
│ │ ├── ReflectionEmitMemberAccessor.cs
│ │ └── ReflectionMemberAccessor.cs
│ ├── ProtoConverter.cs
│ ├── ProtoNumberHandling.cs
│ ├── ProtoSerializer.Deserialize.cs
│ ├── ProtoSerializer.Helpers.cs
│ ├── ProtoSerializer.Serialize.cs
│ └── WireType.cs
├── ThrowHelper.cs
└── Utility
│ ├── ProtoHelper.cs
│ └── SegmentBufferWriter.cs
├── Proto.md
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # VSCode
2 | /.vscode
3 |
4 | # CSharp
5 | /*/bin
6 | /*/obj
7 |
8 | # VS
9 | /.vs
10 |
11 | # Rider (and other IDEs that use .idea)
12 | /.idea
13 | /global.json
--------------------------------------------------------------------------------
/Lagrange.Codec/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Lagrange.Core.Test")]
--------------------------------------------------------------------------------
/Lagrange.Codec/Entities/VideoInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Lagrange.Codec.Entities;
5 |
6 | [DebuggerVisualizer("{ToString(),nq}")]
7 | [StructLayout(LayoutKind.Sequential)]
8 | public struct VideoInfo
9 | {
10 | public int Width;
11 | public int Height;
12 | public long Duration;
13 |
14 | public override string ToString() => $"Width: {Width}, Height: {Height}, Duration: {Duration}";
15 | }
--------------------------------------------------------------------------------
/Lagrange.Codec/Exceptions/CodecException.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Codec.Exceptions;
2 |
3 | public class CodecException(string message, Exception? innerException = null) : Exception(message, innerException)
4 | {
5 | public CodecException(Exception innerException) : this(innerException.Message, innerException) { }
6 | }
--------------------------------------------------------------------------------
/Lagrange.Codec/Interop/AudioInterop.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace Lagrange.Codec.Interop;
4 |
5 | internal static partial class AudioInterop
6 | {
7 | public delegate void AudioCodecCallback(IntPtr userData, IntPtr p, int len);
8 |
9 | [LibraryImport("LagrangeCodec", EntryPoint = "audio_to_pcm")]
10 | public static partial int AudioToPCM(
11 | IntPtr audioData,
12 | int dataLen,
13 | AudioCodecCallback callback,
14 | IntPtr userdata);
15 |
16 | [LibraryImport("LagrangeCodec", EntryPoint = "silk_decode")]
17 | public static partial int SilkDecode(
18 | IntPtr silkData,
19 | int dataLen,
20 | AudioCodecCallback callback,
21 | IntPtr userdata);
22 |
23 | [LibraryImport("LagrangeCodec", EntryPoint = "silk_encode")]
24 | public static partial int SilkEncode(
25 | IntPtr pcmData,
26 | int dataLen,
27 | AudioCodecCallback callback,
28 | IntPtr userdata);
29 | }
--------------------------------------------------------------------------------
/Lagrange.Codec/Interop/VideoInterop.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using Lagrange.Codec.Entities;
3 |
4 | namespace Lagrange.Codec.Interop;
5 |
6 | internal static partial class VideoInterop
7 | {
8 | [LibraryImport("LagrangeCodec", EntryPoint = "video_first_frame")]
9 | public static partial int VideoFirstFrame(
10 | IntPtr videoData,
11 | int dataLen,
12 | ref IntPtr output,
13 | ref int outputLen);
14 |
15 | [LibraryImport("LagrangeCodec", EntryPoint = "video_get_size")]
16 | public static partial int VideoGetSize(
17 | IntPtr videoData,
18 | int dataLen,
19 | ref VideoInfo output);
20 | }
--------------------------------------------------------------------------------
/Lagrange.Codec/Lagrange.Codec.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 | enable
6 | enable
7 | true
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Lagrange.Codec/Streams/PCMStream.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Codec.Interop;
2 |
3 | namespace Lagrange.Codec.Streams;
4 |
5 | public class PCMStream() : NativeCodecStream(AudioInterop.AudioToPCM);
--------------------------------------------------------------------------------
/Lagrange.Codec/Streams/SilkStream.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Codec.Interop;
2 |
3 | namespace Lagrange.Codec.Streams;
4 |
5 | public class SilkEncodeStream() : NativeCodecStream(AudioInterop.SilkEncode);
6 |
7 | public class SilkDecodeStream() : NativeCodecStream(AudioInterop.SilkDecode);
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI.Test/Lagrange.Core.NativeAPI.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net9.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI.Test/NativeModel/BotConfigStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace Lagrange.Core.NativeAPI.Test.NativeModel
4 | {
5 | [StructLayout(LayoutKind.Sequential)]
6 | public struct BotConfigStruct
7 | {
8 | public BotConfigStruct()
9 | {
10 | }
11 |
12 | public byte Protocol { get; set; } = 0b00000100;
13 |
14 | public bool AutoReconnect { get; set; } = true;
15 |
16 | public bool UseIPv6Network { get; set; } = false;
17 |
18 | public bool GetOptimumServer { get; set; } = true;
19 |
20 | public uint HighwayChunkSize { get; set; } = 1024 * 1024;
21 |
22 | public uint HighwayConcurrent { get; set; } = 4;
23 |
24 | public bool AutoReLogin { get; set; } = true;
25 | }
26 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI.Test/NativeModel/BotLogEventStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace Lagrange.Core.NativeAPI.Test.NativeModel
4 | {
5 | [StructLayout(LayoutKind.Sequential)]
6 | public struct BotLogEventStruct
7 | {
8 | public BotLogEventStruct() { }
9 |
10 | public int Level = 0;
11 | public ByteArrayNative Tag = new();
12 | public ByteArrayNative Message = new();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI.Test/NativeModel/BotQrCodeEventStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace Lagrange.Core.NativeAPI.Test.NativeModel
4 | {
5 | [StructLayout(LayoutKind.Sequential)]
6 | public struct BotQrCodeEventStruct
7 | {
8 | public BotQrCodeEventStruct() { }
9 |
10 | public ByteArrayNative Url = new();
11 |
12 | public ByteArrayNative Image = new();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI.Test/NativeModel/ReverseEventCountStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace Lagrange.Core.NativeAPI.Test.NativeModel;
4 |
5 | [StructLayout(LayoutKind.Sequential)]
6 | public struct ReverseEventCountStruct
7 | {
8 | public ReverseEventCountStruct() { }
9 |
10 | public int BotCaptchaEventCount = 0;
11 | public int BotLoginEventCount = 0;
12 | public int BotLogEventCount = 0;
13 | public int BotMessageEventCount = 0;
14 | public int BotNewDeviceVerifyEventCount = 0;
15 | public int BotOnlineEventCount = 0;
16 | public int BotQrCodeEventCount = 0;
17 | public int BotQrCodeQueryEventCount = 0;
18 | public int BotRefreshKeystoreEventCount = 0;
19 | public int BotSMSEventCount = 0;
20 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI.Test/Wrapper.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace Lagrange.Core.NativeAPI.Test;
4 |
5 | public static class Wrapper
6 | {
7 | public const string DLL_NAME = "Lagrange.Core.NativeAPI.dll";
8 |
9 | [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
10 | public static extern int Initialize(IntPtr botConfigPtr, IntPtr keystorePtr);
11 |
12 | [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
13 | public static extern int Start(int index);
14 |
15 | [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
16 | public static extern int Stop(int index);
17 |
18 | [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
19 | public static extern int FreeMemory(IntPtr ptr);
20 |
21 | [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
22 | public static extern IntPtr GetQrCodeEvent(int index);
23 |
24 | [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
25 | public static extern IntPtr GetEventCount(int index);
26 |
27 | [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
28 | public static extern IntPtr GetBotLogEvent(int index);
29 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/Context.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.NativeAPI.ReverseEvent;
2 |
3 | namespace Lagrange.Core.NativeAPI
4 | {
5 | public class Context
6 | {
7 | public Context(BotContext botContext)
8 | {
9 | BotContext = botContext;
10 | EventInvoker = new ReverseEventInvoker(BotContext);
11 | SendMessageContext = new SendMessageContext(BotContext);
12 | }
13 | public BotContext BotContext { get; set; }
14 | public ReverseEventInvoker EventInvoker { get; set; }
15 | public SendMessageContext SendMessageContext { get; set; }
16 | }
17 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/Lagrange.Core.NativeAPI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 | enable
6 | enable
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Common/BotFriendCategoryStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Lagrange.Core.Common.Entity;
3 |
4 | namespace Lagrange.Core.NativeAPI.NativeModel.Common
5 | {
6 | public struct BotFriendCategoryStruct
7 | {
8 | public BotFriendCategoryStruct() { }
9 |
10 | public int Id = 0;
11 |
12 | public ByteArrayNative Name = new();
13 |
14 | public int Count = 0;
15 |
16 | public int SortId = 0;
17 |
18 | public static implicit operator BotFriendCategoryStruct(BotFriendCategory category)
19 | {
20 | return new BotFriendCategoryStruct()
21 | {
22 | Id = category.Id,
23 | Name = Encoding.UTF8.GetBytes(category.Name),
24 | Count = category.Count,
25 | SortId = category.SortId
26 | };
27 | }
28 |
29 | public static implicit operator BotFriendCategory(BotFriendCategoryStruct category)
30 | {
31 | return new BotFriendCategory(
32 | category.Id,
33 | Encoding.UTF8.GetString(category.Name),
34 | category.Count,
35 | category.SortId
36 | );
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Common/ByteArrayDictNative.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace Lagrange.Core.NativeAPI.NativeModel.Common;
4 |
5 | public struct ByteArrayDictNative
6 | {
7 | public int Length;
8 | public IntPtr Data;
9 |
10 | public static implicit operator ByteArrayDictNative(ByteArrayKVPNative[] dict)
11 | {
12 | int size = Marshal.SizeOf();
13 | IntPtr ptr = Marshal.AllocHGlobal(size * dict.Length);
14 | for (int i = 0; i < dict.Length; i++)
15 | {
16 | Marshal.StructureToPtr(dict[i], ptr + i * size, false);
17 | }
18 |
19 | return new ByteArrayDictNative { Length = dict.Length, Data = ptr };
20 | }
21 |
22 | public static implicit operator ByteArrayKVPNative[](ByteArrayDictNative dict)
23 | {
24 | if (dict.Data == IntPtr.Zero || dict.Length == 0)
25 | {
26 | return [];
27 | }
28 |
29 | ByteArrayKVPNative[] result = new ByteArrayKVPNative[dict.Length];
30 | int size = Marshal.SizeOf();
31 | for (int i = 0; i < dict.Length; i++)
32 | {
33 | result[i] = Marshal.PtrToStructure(dict.Data + i * size);
34 | }
35 |
36 | Marshal.FreeHGlobal(dict.Data);
37 |
38 | return result;
39 | }
40 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Common/ByteArrayKVPNative.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | // ReSharper disable InconsistentNaming
3 |
4 | namespace Lagrange.Core.NativeAPI.NativeModel.Common;
5 |
6 | [StructLayout(LayoutKind.Sequential)]
7 | public struct ByteArrayKVPNative
8 | {
9 | public ByteArrayNative Key;
10 | public ByteArrayNative Value;
11 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Common/KeyValuePairNative.cs:
--------------------------------------------------------------------------------
1 | // using System.Runtime.InteropServices;
2 | //
3 | // // 这东西疑似用不了,搁置
4 | // namespace Lagrange.Core.NativeAPI.NativeModel.Common
5 | // {
6 | // [StructLayout(LayoutKind.Sequential)]
7 | // public struct KeyValuePairNative
8 | // {
9 | // public T1 Key;
10 | // public T2 Value;
11 | // }
12 | // }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Event/BotCaptchaEventStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Lagrange.Core.Events.EventArgs;
3 | using Lagrange.Core.NativeAPI.NativeModel.Common;
4 |
5 | namespace Lagrange.Core.NativeAPI.NativeModel.Event
6 | {
7 | public struct BotCaptchaEventStruct : IEventStruct
8 | {
9 | public BotCaptchaEventStruct() { }
10 |
11 | public ByteArrayNative CaptchaUrl = new();
12 |
13 | public static implicit operator BotCaptchaEventStruct(BotCaptchaEvent e)
14 | {
15 | return new BotCaptchaEventStruct()
16 | {
17 | CaptchaUrl = Encoding.UTF8.GetBytes(e.CaptchaUrl)
18 | };
19 | }
20 |
21 | public static implicit operator BotCaptchaEvent(BotCaptchaEventStruct e)
22 | {
23 | return new BotCaptchaEvent(Encoding.UTF8.GetString(e.CaptchaUrl));
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Event/BotLogEventStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System.Text;
3 | using Lagrange.Core.Events.EventArgs;
4 | using Lagrange.Core.NativeAPI.NativeModel.Common;
5 |
6 | namespace Lagrange.Core.NativeAPI.NativeModel.Event
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct BotLogEventStruct : IEventStruct
10 | {
11 | public BotLogEventStruct() { }
12 |
13 | public int Level = 0;
14 | public ByteArrayNative Tag = new();
15 | public ByteArrayNative Message = new();
16 |
17 | public static implicit operator BotLogEventStruct(BotLogEvent e)
18 | {
19 | return new BotLogEventStruct()
20 | {
21 | Level = (int)e.Level,
22 | Tag = Encoding.UTF8.GetBytes(e.Tag),
23 | Message = Encoding.UTF8.GetBytes(e.Message)
24 | };
25 | }
26 |
27 | public static implicit operator BotLogEvent(BotLogEventStruct e)
28 | {
29 | return new BotLogEvent(
30 | Encoding.UTF8.GetString(e.Tag),
31 | (LogLevel)e.Level,
32 | Encoding.UTF8.GetString(e.Message),
33 | null // TODO: Handle exception if needed
34 | );
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Event/BotLoginEventStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System.Text;
3 | using Lagrange.Core.Events.EventArgs;
4 | using Lagrange.Core.NativeAPI.NativeModel.Common;
5 |
6 | namespace Lagrange.Core.NativeAPI.NativeModel.Event
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct BotLoginEventStruct : IEventStruct
10 | {
11 | public BotLoginEventStruct() { }
12 | public int State = 0;
13 | public ByteArrayNative Tag = new();
14 | public ByteArrayNative Message = new();
15 |
16 | public static implicit operator BotLoginEvent(BotLoginEventStruct e)
17 | {
18 | return new BotLoginEvent(
19 | e.State,
20 | (Encoding.UTF8.GetString(e.Tag), Encoding.UTF8.GetString(e.Message))
21 | );
22 | }
23 |
24 | public static implicit operator BotLoginEventStruct(BotLoginEvent e)
25 | {
26 | return new BotLoginEventStruct()
27 | {
28 | State = e.State,
29 | Tag = Encoding.UTF8.GetBytes(e.Error?.Tag ?? string.Empty),
30 | Message = Encoding.UTF8.GetBytes(e.Error?.Message ?? string.Empty)
31 | };
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Event/BotMessageEventStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using Lagrange.Core.Events.EventArgs;
3 | using Lagrange.Core.NativeAPI.NativeModel.Common;
4 | using Lagrange.Core.NativeAPI.NativeModel.Message;
5 |
6 | namespace Lagrange.Core.NativeAPI.NativeModel.Event
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct BotMessageEventStruct : IEventStruct
10 | {
11 | public BotMessageEventStruct() { }
12 |
13 | public BotMessageStruct Message = new();
14 |
15 | // 懒得写了,没意义
16 | // public static BotMessageEvent ToEvent(this BotMessageEventStruct e)
17 | // {
18 | // return new BotMessageEvent(
19 | // e.Message.ToMessage(),
20 | // Encoding.UTF8.GetString(e.RawMessage)
21 | // );
22 | // }
23 |
24 | public static implicit operator BotMessageEventStruct(BotMessageEvent e)
25 | {
26 | return new BotMessageEventStruct() { Message = e.Message };
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Event/BotNewDeviceVerifyEventStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System.Text;
3 | using Lagrange.Core.Events.EventArgs;
4 | using Lagrange.Core.NativeAPI.NativeModel.Common;
5 |
6 | namespace Lagrange.Core.NativeAPI.NativeModel.Event
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct BotNewDeviceVerifyEventStruct : IEventStruct
10 | {
11 | public BotNewDeviceVerifyEventStruct() { }
12 |
13 | public ByteArrayNative Url = new();
14 |
15 | public static implicit operator BotNewDeviceVerifyEvent(BotNewDeviceVerifyEventStruct e)
16 | {
17 | return new BotNewDeviceVerifyEvent(Encoding.UTF8.GetString(e.Url));
18 | }
19 |
20 | public static implicit operator BotNewDeviceVerifyEventStruct(BotNewDeviceVerifyEvent e)
21 | {
22 | return new BotNewDeviceVerifyEventStruct() { Url = Encoding.UTF8.GetBytes(e.Url) };
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Event/BotOnlineEventStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using Lagrange.Core.Events.EventArgs;
3 |
4 | namespace Lagrange.Core.NativeAPI.NativeModel.Event
5 | {
6 | [StructLayout(LayoutKind.Sequential)]
7 | public struct BotOnlineEventStruct : IEventStruct
8 | {
9 | public BotOnlineEventStruct() { }
10 |
11 | public int Reason = 0;
12 |
13 | public static implicit operator BotOnlineEvent(BotOnlineEventStruct e)
14 | {
15 | return new BotOnlineEvent((BotOnlineEvent.Reasons)e.Reason);
16 | }
17 |
18 | public static implicit operator BotOnlineEventStruct(BotOnlineEvent e)
19 | {
20 | return new BotOnlineEventStruct() { Reason = (int)e.Reason };
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Event/BotQrCodeEventStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System.Text;
3 | using Lagrange.Core.Events.EventArgs;
4 | using Lagrange.Core.NativeAPI.NativeModel.Common;
5 |
6 | namespace Lagrange.Core.NativeAPI.NativeModel.Event
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct BotQrCodeEventStruct : IEventStruct
10 | {
11 | public BotQrCodeEventStruct() { }
12 |
13 | public ByteArrayNative Url = new();
14 |
15 | public ByteArrayNative Image = new();
16 |
17 | public static implicit operator BotQrCodeEvent(BotQrCodeEventStruct e)
18 | {
19 | return new BotQrCodeEvent(Encoding.UTF8.GetString(e.Url), e.Image);
20 | }
21 |
22 | public static implicit operator BotQrCodeEventStruct(BotQrCodeEvent e)
23 | {
24 | return new BotQrCodeEventStruct()
25 | {
26 | Url = Encoding.UTF8.GetBytes(e.Url),
27 | Image = e.Image
28 | };
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Event/BotQrCodeQueryEventStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using Lagrange.Core.Events.EventArgs;
3 |
4 | namespace Lagrange.Core.NativeAPI.NativeModel.Event
5 | {
6 | [StructLayout(LayoutKind.Sequential)]
7 | public struct BotQrCodeQueryEventStruct : IEventStruct
8 | {
9 | public BotQrCodeQueryEventStruct() { }
10 |
11 | public byte State = 0;
12 |
13 | public static implicit operator BotQrCodeQueryEvent(BotQrCodeQueryEventStruct e)
14 | {
15 | return new BotQrCodeQueryEvent((BotQrCodeQueryEvent.TransEmpState)e.State);
16 | }
17 |
18 | public static implicit operator BotQrCodeQueryEventStruct(BotQrCodeQueryEvent e)
19 | {
20 | return new BotQrCodeQueryEventStruct { State = (byte)e.State };
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Event/BotRefreshKeystoreEventStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using Lagrange.Core.Events.EventArgs;
3 | using Lagrange.Core.NativeAPI.NativeModel.Common;
4 |
5 | namespace Lagrange.Core.NativeAPI.NativeModel.Event
6 | {
7 | [StructLayout(LayoutKind.Sequential)]
8 | public struct BotRefreshKeystoreEventStruct : IEventStruct
9 | {
10 | public BotRefreshKeystoreEventStruct() { }
11 |
12 | public BotKeystoreStruct Keystore = new();
13 |
14 | public static implicit operator BotRefreshKeystoreEvent(BotRefreshKeystoreEventStruct e)
15 | {
16 | return new BotRefreshKeystoreEvent(e.Keystore);
17 | }
18 |
19 | public static implicit operator BotRefreshKeystoreEventStruct(BotRefreshKeystoreEvent e)
20 | {
21 | return new BotRefreshKeystoreEventStruct() { Keystore = e.Keystore };
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Event/BotSMSEventStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System.Text;
3 | using Lagrange.Core.Events.EventArgs;
4 | using Lagrange.Core.NativeAPI.NativeModel.Common;
5 |
6 | namespace Lagrange.Core.NativeAPI.NativeModel.Event
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct BotSMSEventStruct : IEventStruct
10 | {
11 | public BotSMSEventStruct() { }
12 |
13 | public ByteArrayNative Url = new();
14 |
15 | public ByteArrayNative Phone = new();
16 |
17 | public static implicit operator BotSMSEvent(BotSMSEventStruct e)
18 | {
19 | return new BotSMSEvent(
20 | Encoding.UTF8.GetString(e.Url),
21 | Encoding.UTF8.GetString(e.Phone)
22 | );
23 | }
24 |
25 | public static implicit operator BotSMSEventStruct(BotSMSEvent e)
26 | {
27 | return new BotSMSEventStruct()
28 | {
29 | Url = Encoding.UTF8.GetBytes(e.Url ?? string.Empty),
30 | Phone = Encoding.UTF8.GetBytes(e.Phone)
31 | };
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Event/IEventStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace Lagrange.Core.NativeAPI.NativeModel.Event
4 | {
5 | public interface IEventStruct
6 | {
7 | }
8 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Event/ReverseEventCountStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace Lagrange.Core.NativeAPI.NativeModel.Event
4 | {
5 | [StructLayout(LayoutKind.Sequential)]
6 | public struct ReverseEventCountStruct
7 | {
8 | public ReverseEventCountStruct() { }
9 |
10 | public int BotCaptchaEventCount = 0;
11 | public int BotLoginEventCount = 0;
12 | public int BotLogEventCount = 0;
13 | public int BotMessageEventCount = 0;
14 | public int BotNewDeviceVerifyEventCount = 0;
15 | public int BotOnlineEventCount = 0;
16 | public int BotQrCodeEventCount = 0;
17 | public int BotQrCodeQueryEventCount = 0;
18 | public int BotRefreshKeystoreEventCount = 0;
19 | public int BotSMSEventCount = 0;
20 | }
21 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Message/BotStrangerStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System.Text;
3 | using Lagrange.Core.Common.Entity;
4 | using Lagrange.Core.NativeAPI.NativeModel.Common;
5 |
6 | namespace Lagrange.Core.NativeAPI.NativeModel.Message
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct BotStrangerStruct
10 | {
11 | public BotStrangerStruct() { }
12 | public long Uin = 0;
13 | public ByteArrayNative Nickname = new();
14 | public ByteArrayNative Uid = new();
15 | public long Source = 0;
16 |
17 | public static implicit operator BotStranger(BotStrangerStruct stranger)
18 | {
19 | return new BotStranger(
20 | stranger.Uin,
21 | Encoding.UTF8.GetString(stranger.Nickname),
22 | Encoding.UTF8.GetString(stranger.Uid)
23 | );
24 | }
25 |
26 | public static implicit operator BotStrangerStruct(BotStranger stranger)
27 | {
28 | return new BotStrangerStruct()
29 | {
30 | Uin = stranger.Uin,
31 | Nickname = Encoding.UTF8.GetBytes(stranger.Nickname),
32 | Uid = Encoding.UTF8.GetBytes(stranger.Uid),
33 | Source = stranger.Source
34 | };
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Message/Entity/EntityType.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.NativeAPI.NativeModel.Message.Entity
2 | {
3 | public enum EntityType
4 | {
5 | ImageEntity = 0,
6 | MentionEntity = 1,
7 | RecordEntity = 2,
8 | ReplyEntity = 3,
9 | VideoEntity = 4,
10 | TextEntity = 5,
11 | MultiMsgEntity = 6,
12 | }
13 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Message/Entity/IEntityStruct.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.NativeAPI.NativeModel.Message.Entity
2 | {
3 | public interface IEntityStruct;
4 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Message/Entity/MentionEntityStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System.Text;
3 | using Lagrange.Core.Message.Entities;
4 | using Lagrange.Core.NativeAPI.NativeModel.Common;
5 |
6 | namespace Lagrange.Core.NativeAPI.NativeModel.Message.Entity
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct MentionEntityStruct : IEntityStruct
10 | {
11 | public MentionEntityStruct() { }
12 |
13 | public long Uin = 0;
14 | public ByteArrayNative Display = new();
15 |
16 | public static implicit operator MentionEntityStruct(MentionEntity entity)
17 | {
18 | return new MentionEntityStruct()
19 | {
20 | Uin = entity.Uin,
21 | Display = Encoding.UTF8.GetBytes(entity.Display ?? string.Empty)
22 | };
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Message/Entity/RecordEntityStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System.Text;
3 | using Lagrange.Core.Message.Entities;
4 | using Lagrange.Core.NativeAPI.NativeModel.Common;
5 |
6 | namespace Lagrange.Core.NativeAPI.NativeModel.Message.Entity
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct RecordEntityStruct : IEntityStruct
10 | {
11 | public RecordEntityStruct() { }
12 | public ByteArrayNative FileUrl = new();
13 |
14 | public ByteArrayNative FileName = new();
15 |
16 | public ByteArrayNative FileSha1 = new();
17 |
18 | public uint FileSize = 0;
19 |
20 | public ByteArrayNative FileMd5 = new();
21 |
22 | public static implicit operator RecordEntityStruct(RecordEntity entity)
23 | {
24 | return new RecordEntityStruct()
25 | {
26 | FileUrl = Encoding.UTF8.GetBytes(entity.FileUrl),
27 | FileName = Encoding.UTF8.GetBytes(entity.FileName),
28 | FileSha1 = Encoding.UTF8.GetBytes(entity.FileSha1),
29 | FileSize = entity.FileSize,
30 | FileMd5 = Encoding.UTF8.GetBytes(entity.FileMd5)
31 | };
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Message/Entity/TextEntityStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System.Text;
3 | using Lagrange.Core.Message.Entities;
4 | using Lagrange.Core.NativeAPI.NativeModel.Common;
5 |
6 | namespace Lagrange.Core.NativeAPI.NativeModel.Message.Entity
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct TextEntityStruct : IEntityStruct
10 | {
11 | public TextEntityStruct() { }
12 |
13 | public ByteArrayNative Text = new();
14 |
15 | public static implicit operator TextEntityStruct(TextEntity entity)
16 | {
17 | return new TextEntityStruct() { Text = Encoding.UTF8.GetBytes(entity.Text) };
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Message/Entity/VideoEntityStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System.Text;
3 | using Lagrange.Core.Message.Entities;
4 | using Lagrange.Core.NativeAPI.NativeModel.Common;
5 |
6 | namespace Lagrange.Core.NativeAPI.NativeModel.Message.Entity
7 | {
8 | [StructLayout(LayoutKind.Sequential)]
9 | public struct VideoEntityStruct : IEntityStruct
10 | {
11 | public VideoEntityStruct() { }
12 |
13 | public ByteArrayNative FileUrl = new();
14 |
15 | public ByteArrayNative FileName = new();
16 |
17 | public ByteArrayNative FileSha1 = new();
18 |
19 | public uint FileSize = 0;
20 |
21 | public ByteArrayNative FileMd5 = new();
22 |
23 | public static implicit operator VideoEntityStruct(VideoEntity entity)
24 | {
25 | return new VideoEntityStruct()
26 | {
27 | FileUrl = Encoding.UTF8.GetBytes(entity.FileUrl),
28 | FileName = Encoding.UTF8.GetBytes(entity.FileName),
29 | FileSha1 = Encoding.UTF8.GetBytes(entity.FileSha1),
30 | FileSize = entity.FileSize,
31 | FileMd5 = Encoding.UTF8.GetBytes(entity.FileMd5)
32 | };
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/NativeModel/Message/TypedEntityStruct.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace Lagrange.Core.NativeAPI.NativeModel.Message
4 | {
5 | [StructLayout(LayoutKind.Sequential)]
6 | public class TypedEntityStruct
7 | {
8 | //需要手动释放
9 | public IntPtr Entity = IntPtr.Zero;
10 | public int Type = 0;
11 | }
12 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/ReverseEvent/Abstract/ReverseEventBase.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.NativeAPI.NativeModel.Event;
2 |
3 | namespace Lagrange.Core.NativeAPI.ReverseEvent.Abstract
4 | {
5 | public abstract class ReverseEventBase
6 | {
7 | public List Events = [];
8 | public virtual void RegisterEventHandler(BotContext context) { }
9 | }
10 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/ReverseEvent/BotCaptchaReverseEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Events.EventArgs;
2 | using Lagrange.Core.NativeAPI.NativeModel;
3 | using Lagrange.Core.NativeAPI.NativeModel.Event;
4 | using Lagrange.Core.NativeAPI.ReverseEvent.Abstract;
5 |
6 | namespace Lagrange.Core.NativeAPI.ReverseEvent
7 | {
8 | public class BotCaptchaReverseEvent : ReverseEventBase
9 | {
10 | public override void RegisterEventHandler(BotContext context)
11 | {
12 | context.EventInvoker.RegisterEvent((ctx, e) => Events.Add((BotCaptchaEventStruct)e)
13 | );
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/ReverseEvent/BotLogReverseEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Events.EventArgs;
2 | using Lagrange.Core.NativeAPI.NativeModel;
3 | using Lagrange.Core.NativeAPI.NativeModel.Event;
4 | using Lagrange.Core.NativeAPI.ReverseEvent.Abstract;
5 |
6 | namespace Lagrange.Core.NativeAPI.ReverseEvent
7 | {
8 | public class BotLogReverseEvent : ReverseEventBase
9 | {
10 | public override void RegisterEventHandler(BotContext context)
11 | {
12 | context.EventInvoker.RegisterEvent((ctx, e) =>
13 | {
14 | Events.Add((BotLogEventStruct)e);
15 | });
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/ReverseEvent/BotLoginReverseEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Events.EventArgs;
2 | using Lagrange.Core.NativeAPI.NativeModel;
3 | using Lagrange.Core.NativeAPI.NativeModel.Event;
4 | using Lagrange.Core.NativeAPI.ReverseEvent.Abstract;
5 |
6 | namespace Lagrange.Core.NativeAPI.ReverseEvent
7 | {
8 | public class BotLoginReverseEvent : ReverseEventBase
9 | {
10 | public override void RegisterEventHandler(BotContext context)
11 | {
12 | context.EventInvoker.RegisterEvent((ctx, e) =>
13 | {
14 | Events.Add((BotLoginEventStruct)e);
15 | });
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/ReverseEvent/BotMessageReverseEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Events.EventArgs;
2 | using Lagrange.Core.NativeAPI.NativeModel;
3 | using Lagrange.Core.NativeAPI.NativeModel.Event;
4 | using Lagrange.Core.NativeAPI.NativeModel.Message;
5 | using Lagrange.Core.NativeAPI.ReverseEvent.Abstract;
6 |
7 | namespace Lagrange.Core.NativeAPI.ReverseEvent
8 | {
9 | public class BotMessageReverseEvent : ReverseEventBase
10 | {
11 | public override void RegisterEventHandler(BotContext context)
12 | {
13 | context.EventInvoker.RegisterEvent(
14 | (ctx, e) => Events.Add((BotMessageEventStruct)e)
15 | );
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/ReverseEvent/BotNewDeviceVerifyReverseEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Events.EventArgs;
2 | using Lagrange.Core.NativeAPI.NativeModel;
3 | using Lagrange.Core.NativeAPI.NativeModel.Event;
4 | using Lagrange.Core.NativeAPI.ReverseEvent.Abstract;
5 |
6 | namespace Lagrange.Core.NativeAPI.ReverseEvent
7 | {
8 | public class BotNewDeviceVerifyReverseEvent : ReverseEventBase
9 | {
10 | public override void RegisterEventHandler(BotContext context)
11 | {
12 | context.EventInvoker.RegisterEvent((ctx, e) => Events.Add((BotNewDeviceVerifyEventStruct)e)
13 | );
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/ReverseEvent/BotOnlineReverseEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Events.EventArgs;
2 | using Lagrange.Core.NativeAPI.NativeModel;
3 | using Lagrange.Core.NativeAPI.NativeModel.Event;
4 | using Lagrange.Core.NativeAPI.ReverseEvent.Abstract;
5 |
6 | namespace Lagrange.Core.NativeAPI.ReverseEvent
7 | {
8 | public class BotOnlineReverseEvent : ReverseEventBase
9 | {
10 | public override void RegisterEventHandler(BotContext context)
11 | {
12 | context.EventInvoker.RegisterEvent((ctx, e) => Events.Add((BotOnlineEventStruct)e)
13 | );
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/ReverseEvent/BotQrCodeQueryReverseEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Events.EventArgs;
2 | using Lagrange.Core.NativeAPI.NativeModel;
3 | using Lagrange.Core.NativeAPI.NativeModel.Event;
4 | using Lagrange.Core.NativeAPI.ReverseEvent.Abstract;
5 |
6 | namespace Lagrange.Core.NativeAPI.ReverseEvent
7 | {
8 | public class BotQrCodeQueryReverseEvent : ReverseEventBase
9 | {
10 | public override void RegisterEventHandler(BotContext context)
11 | {
12 | context.EventInvoker.RegisterEvent((ctx, e) => Events.Add((BotQrCodeQueryEventStruct)e)
13 | );
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/ReverseEvent/BotQrCodeReverseEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Events.EventArgs;
2 | using Lagrange.Core.NativeAPI.NativeModel;
3 | using Lagrange.Core.NativeAPI.NativeModel.Event;
4 | using Lagrange.Core.NativeAPI.ReverseEvent.Abstract;
5 |
6 | namespace Lagrange.Core.NativeAPI.ReverseEvent
7 | {
8 | public class BotQrCodeReverseEvent : ReverseEventBase
9 | {
10 | public override void RegisterEventHandler(BotContext context)
11 | {
12 | context.EventInvoker.RegisterEvent((ctx, e) => Events.Add((BotQrCodeEventStruct)e)
13 | );
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/ReverseEvent/BotRefreshKeystoreReverseEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Events.EventArgs;
2 | using Lagrange.Core.NativeAPI.NativeModel;
3 | using Lagrange.Core.NativeAPI.NativeModel.Event;
4 | using Lagrange.Core.NativeAPI.ReverseEvent.Abstract;
5 |
6 | namespace Lagrange.Core.NativeAPI.ReverseEvent
7 | {
8 | public class BotRefreshKeystoreReverseEvent : ReverseEventBase
9 | {
10 | public override void RegisterEventHandler(BotContext context)
11 | {
12 | context.EventInvoker.RegisterEvent((ctx, e) => Events.Add((BotRefreshKeystoreEventStruct)e)
13 | );
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/ReverseEvent/BotSMSReverseEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Events.EventArgs;
2 | using Lagrange.Core.NativeAPI.NativeModel;
3 | using Lagrange.Core.NativeAPI.NativeModel.Event;
4 | using Lagrange.Core.NativeAPI.ReverseEvent.Abstract;
5 |
6 | namespace Lagrange.Core.NativeAPI.ReverseEvent
7 | {
8 | public class BotSMSReverseEvent : ReverseEventBase
9 | {
10 | public override void RegisterEventHandler(BotContext context)
11 | {
12 | context.EventInvoker.RegisterEvent((ctx, e) => Events.Add((BotSMSEventStruct)e)
13 | );
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/Lagrange.Core.NativeAPI/StatusCode.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.NativeAPI
2 | {
3 | public enum StatusCode
4 | {
5 | Success = 0,
6 | UnInitialized = 1,
7 | AlreadyInitialized = 2,
8 | AlreadyStarted = 3,
9 | InvalidIndex = 4,
10 | }
11 | }
--------------------------------------------------------------------------------
/Lagrange.Core.Runner/Lagrange.Core.Runner.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net9.0
6 | enable
7 | enable
8 | true
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Lagrange.Core.Test/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | [assembly: Parallelizable(ParallelScope.All)]
--------------------------------------------------------------------------------
/Lagrange.Core.Test/Cryptography/AesTest.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 | using Lagrange.Core.Utility.Cryptography;
3 |
4 | namespace Lagrange.Core.Test.Cryptography;
5 |
6 | public class AesTest
7 | {
8 | private byte[] _data;
9 |
10 | private byte[] _key;
11 |
12 | [SetUp]
13 | public void Setup()
14 | {
15 | _data = new byte[0x10000];
16 | _key = new byte[0x20];
17 |
18 | RandomNumberGenerator.Fill(_data);
19 | RandomNumberGenerator.Fill(_key);
20 | }
21 |
22 | [Test]
23 | public void TestEncrypt()
24 | {
25 | var cipher = AesGcmProvider.Encrypt(_data, _key);
26 | var plain = AesGcmProvider.Decrypt(cipher, _key);
27 |
28 | Assert.That(plain, Is.EqualTo(_data));
29 | }
30 | }
--------------------------------------------------------------------------------
/Lagrange.Core.Test/Cryptography/Sha1Test.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 | using Lagrange.Core.Utility.Cryptography;
3 |
4 | namespace Lagrange.Core.Test.Cryptography;
5 |
6 | public class Sha1Test
7 | {
8 | private byte[] _data;
9 |
10 | private Sha1Stream _sha1;
11 |
12 | [SetUp]
13 | public void Setup()
14 | {
15 | _data = new byte[1024 * 1024 * 10]; // 10MB
16 | _sha1 = new Sha1Stream();
17 |
18 | RandomNumberGenerator.Fill(_data.AsSpan());
19 | }
20 |
21 | [Test]
22 | public void Test()
23 | {
24 | var expected = SHA1.HashData(_data);
25 | var digest = new byte[Sha1Stream.Sha1DigestSize];
26 | var intermediate = new byte[Sha1Stream.Sha1BlockSize];
27 |
28 | for (int i = 0; i < _data.Length; i += Sha1Stream.Sha1BlockSize)
29 | {
30 | _sha1.Hash(intermediate.AsSpan(), false);
31 | _sha1.Hash(intermediate.AsSpan(), true);
32 | _sha1.Update(_data.AsSpan(i, Math.Min(Sha1Stream.Sha1BlockSize, _data.Length - i)));
33 | }
34 |
35 | _sha1.Final(digest);
36 |
37 | Assert.That(digest, Is.EqualTo(expected));
38 |
39 | Assert.Pass();
40 | }
41 | }
--------------------------------------------------------------------------------
/Lagrange.Core.Test/Cryptography/TeaTest.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 | using Lagrange.Core.Utility.Cryptography;
3 |
4 | namespace Lagrange.Core.Test.Cryptography;
5 |
6 | public class TeaTest
7 | {
8 | private byte[] _data;
9 |
10 | private byte[] _key;
11 |
12 | [SetUp]
13 | public void Setup()
14 | {
15 | _data = new byte[1024 * 1024 * 10]; // 10MB
16 | _key = new byte[16];
17 |
18 | RandomNumberGenerator.Fill(_key.AsSpan());
19 | }
20 |
21 | [Test]
22 | public void Test()
23 | {
24 | var encrypted = TeaProvider.Encrypt(_data, _key);
25 | var decrypted = TeaProvider.Decrypt(encrypted, _key);
26 | Assert.Multiple(() =>
27 | {
28 | Assert.That(encrypted, Is.Not.Null);
29 | Assert.That(decrypted, Is.Not.Null);
30 | });
31 | Assert.That(decrypted, Is.EqualTo(_data));
32 |
33 | Assert.Pass();
34 | }
35 | }
--------------------------------------------------------------------------------
/Lagrange.Core.Test/Lagrange.Core.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 | latest
6 | enable
7 | enable
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Lagrange.Core/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Lagrange.Core.Test")]
4 | [assembly: InternalsVisibleTo("Lagrange.Core.Runner")]
--------------------------------------------------------------------------------
/Lagrange.Core/Common/BotGender.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Common;
2 |
3 | public enum BotGender
4 | {
5 | Unset = 0,
6 | Male = 1,
7 | Female = 2,
8 | Unknown = 255
9 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Common/BotInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Lagrange.Core.Common;
4 |
5 | [Serializable]
6 | public class BotInfo(byte age, byte gender, string name)
7 | {
8 | public byte Age { get; set; } = age;
9 |
10 | public byte Gender { get; set; } = gender;
11 |
12 | public string Name { get; set; } = name;
13 |
14 | public override string ToString() => $"Bot name: {Name} | Gender: {Gender} | Age: {Age}";
15 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Common/Entity/BotContact.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Common.Entity;
2 |
3 | public abstract class BotContact
4 | {
5 | public abstract long Uin { get; }
6 |
7 | public abstract string Nickname { get; }
8 |
9 | public abstract string Uid { get; }
10 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Common/Entity/BotFriend.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Common.Entity;
2 |
3 | public class BotFriend(long uin, string nickname, string uid, string remarks, string personalSign, string qid, BotFriendCategory category) : BotContact
4 | {
5 | public override long Uin { get; } = uin;
6 |
7 | public override string Nickname { get; } = nickname;
8 |
9 | public override string Uid { get; } = uid;
10 |
11 | public int Age { get; init; }
12 |
13 | public BotGender Gender { get; init; }
14 |
15 | public string Remarks { get; } = remarks;
16 |
17 | public string PersonalSign { get; } = personalSign;
18 |
19 | public string Qid { get; } = qid;
20 |
21 | public BotFriendCategory Category { get; } = category;
22 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Common/Entity/BotFriendCategory.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Common.Entity;
2 |
3 | public class BotFriendCategory(int id, string name, int count, int sortId)
4 | {
5 | public int Id { get; } = id;
6 |
7 | public string Name { get; } = name;
8 |
9 | public int Count { get; } = count;
10 |
11 | public int SortId { get; } = sortId;
12 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Common/Entity/BotGroup.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Common.Entity;
2 |
3 | public class BotGroup(
4 | long groupUin,
5 | string groupName,
6 | int memberCount,
7 | int maxMember,
8 | long createTime,
9 | string? description,
10 | string? question,
11 | string? announcement) : BotContact
12 | {
13 | public long GroupUin { get; } = groupUin;
14 |
15 | public string GroupName { get; } = groupName;
16 |
17 | public int MemberCount { get; } = memberCount;
18 |
19 | public int MaxMember { get; } = maxMember;
20 |
21 | public long CreateTime { get; } = createTime;
22 |
23 | public string? Description { get; } = description;
24 |
25 | public string? Question { get; } = question;
26 |
27 | public string? Announcement { get; } = announcement;
28 |
29 | public override long Uin => GroupUin;
30 |
31 | public override string Nickname => GroupName;
32 |
33 | public override string Uid => GroupUin.ToString();
34 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Common/Entity/BotGroupMember.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Common.Entity;
2 |
3 | public class BotGroupMember(
4 | BotGroup group,
5 | long uin,
6 | string uid,
7 | string nickname,
8 | GroupMemberPermission permission,
9 | int groupLevel,
10 | string? memberCard,
11 | string? specialTitle,
12 | DateTime joinTime,
13 | DateTime lastMsgTime,
14 | DateTime shutUpTimestamp) : BotContact
15 | {
16 | public BotGroup Group { get; } = group;
17 |
18 | public override long Uin { get; } = uin;
19 |
20 | public override string Uid { get; } = uid;
21 |
22 | public override string Nickname { get; } = nickname;
23 |
24 | public int Age { get; init; }
25 |
26 | public BotGender Gender { get; init; }
27 |
28 | public GroupMemberPermission Permission { get; } = permission;
29 |
30 | public int GroupLevel { get; } = groupLevel;
31 |
32 | public string? MemberCard { get; } = memberCard;
33 |
34 | public string? SpecialTitle { get; } = specialTitle;
35 |
36 | public DateTime JoinTime { get; } = joinTime;
37 |
38 | public DateTime LastMsgTime { get; } = lastMsgTime;
39 |
40 | public DateTime ShutUpTimestamp { get; } = shutUpTimestamp;
41 | }
42 |
43 | public enum GroupMemberPermission
44 | {
45 | Member,
46 | Owner,
47 | Admin,
48 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Common/Entity/BotStranger.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Common.Entity;
2 |
3 | public class BotStranger(long uin, string nickname, string uid) : BotContact
4 | {
5 | public override long Uin { get; } = uin;
6 |
7 | public override string Nickname { get; } = nickname;
8 |
9 | public override string Uid { get; } = uid;
10 |
11 | public long Source { get; init; }
12 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Common/Interface/BotExt.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Internal.Logic;
2 |
3 | namespace Lagrange.Core.Common.Interface;
4 |
5 | public static class BotExt
6 | {
7 | public static Task Login(this BotContext context, long uin, string password, CancellationToken token = default) =>
8 | context.EventContext.GetLogic().Login(uin, password, token);
9 |
10 | public static Task Login(this BotContext context, CancellationToken token = default) =>
11 | context.EventContext.GetLogic().Login(0, null, token);
12 |
13 | public static Task Logout(this BotContext context) =>
14 | context.EventContext.GetLogic().Logout();
15 |
16 | public static Task ResolveUinByQid(this BotContext context, string qid) =>
17 | context.EventContext.GetLogic().ResolveUinByQid(qid);
18 |
19 | public static bool SubmitCaptcha(this BotContext context, string ticket, string randStr) =>
20 | context.EventContext.GetLogic().SubmitCaptcha(ticket, randStr);
21 |
22 | public static bool SubmitSMSCode(this BotContext context, string code) =>
23 | context.EventContext.GetLogic().SubmitSMSCode(code);
24 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Common/Interface/BotFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Common.Interface;
2 |
3 | public static class BotFactory
4 | {
5 | ///
6 | /// Create new Bot from existing
7 | ///
8 | /// The config for Bot
9 | /// Existing Keystore from deserialization
10 | /// The app info for Bot, if null, will use default app info from
11 | /// Created BotContext Instance
12 | public static BotContext Create(BotConfig config, BotKeystore keystore, BotAppInfo? appInfo = null) =>
13 | new(config, keystore, appInfo ?? BotAppInfo.ProtocolToAppInfo[config.Protocol]);
14 |
15 | ///
16 | /// Create new Bot from Empty
17 | ///
18 | /// The config for Bot
19 | /// The app info for Bot, if null, will use default app info from
20 | /// Created BotContext Instance
21 | public static BotContext Create(BotConfig config, BotAppInfo? appInfo = null) =>
22 | new(config, BotKeystore.CreateEmpty(), appInfo ?? BotAppInfo.ProtocolToAppInfo[config.Protocol]);
23 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Common/Response/BotQrCodeInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Lagrange.Core.Common.Response;
4 |
5 | [Serializable]
6 | public class BotQrCodeInfo(string message, string platform, string location, string? device)
7 | {
8 | [JsonPropertyName("message")] public string Message { get; } = message;
9 |
10 | [JsonPropertyName("platform")] public string Platform { get; } = platform;
11 |
12 | [JsonPropertyName("location")] public string Location { get; } = location;
13 |
14 | [JsonPropertyName("device")] public string? Device { get; } = device;
15 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Events/EventArgs/BotCaptchaEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Events.EventArgs;
2 |
3 | public class BotCaptchaEvent(string captchaUrl) : EventBase
4 | {
5 | public string CaptchaUrl { get; } = captchaUrl;
6 |
7 | public override string ToEventMessage() => $"{nameof(BotCaptchaEvent)}: Captcha required, URL: {CaptchaUrl}";
8 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Events/EventArgs/BotLogEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Events.EventArgs;
2 |
3 | public enum LogLevel
4 | {
5 | Trace = 0,
6 | Debug = 1,
7 | Information = 2,
8 | Warning = 3,
9 | Error = 4,
10 | Critical = 5
11 | }
12 |
13 | public class BotLogEvent(string tag, LogLevel level, string message, Exception? Exception) : EventBase
14 | {
15 | public string Tag { get; } = tag;
16 |
17 | public LogLevel Level { get; } = level;
18 |
19 | public string Message { get; } = message;
20 |
21 | public Exception? Exception { get; } = Exception;
22 |
23 | public override string ToEventMessage() => $"[{Tag}] [{Level.ToString().ToUpper()}]: {Message}";
24 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Events/EventArgs/BotLoginEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Events.EventArgs;
2 |
3 | public class BotLoginEvent(int state, (string, string)? error) : EventBase
4 | {
5 | public bool Success => State == 0;
6 |
7 | public int State { get; } = state;
8 |
9 | public (string Tag, string Message)? Error { get; } = error;
10 |
11 | public override string ToEventMessage() => Error == null
12 | ? $"[{nameof(BotLoginEvent)}] State: {State}"
13 | : $"[{nameof(BotLoginEvent)}] State: {State} | Error: {Error?.Tag} | Message: {Error?.Message}";
14 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Events/EventArgs/BotMessageEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Message;
2 |
3 | namespace Lagrange.Core.Events.EventArgs;
4 |
5 | public class BotMessageEvent(BotMessage message, ReadOnlyMemory rawMessage) : EventBase
6 | {
7 | public BotMessage Message { get; } = message;
8 |
9 | internal ReadOnlyMemory RawMessage { get; } = rawMessage;
10 |
11 | public override string ToEventMessage() => $"{nameof(EventBase)} {Message}";
12 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Events/EventArgs/BotNewDeviceVerifyEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Events.EventArgs;
2 |
3 | public class BotNewDeviceVerifyEvent(string url) : EventBase
4 | {
5 | public string Url { get; } = url;
6 |
7 | public override string ToEventMessage() => $"[{nameof(BotNewDeviceVerifyEvent)}] URL: {Url}";
8 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Events/EventArgs/BotOfflineEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Events.EventArgs;
2 |
3 | public class BotOfflineEvent(BotOfflineEvent.Reasons reason, (string, string)? tips) : EventBase
4 | {
5 | public Reasons Reason { get; } = reason;
6 |
7 | public (string Tag, string Message)? Tips { get; } = tips;
8 |
9 | public override string ToEventMessage() => $"{nameof(BotOfflineEvent)}: {Reason} ({Tips?.Tag}, {Tips?.Message})";
10 |
11 | public enum Reasons
12 | {
13 | Logout,
14 | Kicked,
15 | Disconnected,
16 | }
17 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Events/EventArgs/BotOnlineEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Events.EventArgs;
2 |
3 | public class BotOnlineEvent(BotOnlineEvent.Reasons reason) : EventBase
4 | {
5 | public enum Reasons
6 | {
7 | Login,
8 | Reconnect,
9 | }
10 |
11 | public Reasons Reason { get; } = reason;
12 |
13 | public override string ToEventMessage() => $"{nameof(BotOnlineEvent)}: {Reason}";
14 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Events/EventArgs/BotQrCodeEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Events.EventArgs;
2 |
3 | public class BotQrCodeEvent(string url, byte[] image) : EventBase
4 | {
5 | public string Url { get; } = url;
6 |
7 | public byte[] Image { get; } = image;
8 |
9 | public override string ToEventMessage() => $"[{nameof(BotQrCodeEvent)}] URL: {Url}";
10 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Events/EventArgs/BotQrCodeQueryEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Events.EventArgs;
2 |
3 | public class BotQrCodeQueryEvent(BotQrCodeQueryEvent.TransEmpState state) : EventBase
4 | {
5 | public TransEmpState State { get; } = state;
6 |
7 | public override string ToEventMessage() => $"[{nameof(BotQrCodeQueryEvent)}] State: {State}";
8 |
9 | public enum TransEmpState : byte
10 | {
11 | Confirmed = 0,
12 | CodeExpired = 17,
13 | WaitingForScan = 48,
14 | WaitingForConfirm = 53,
15 | Canceled = 54,
16 | Invalid = 144
17 | }
18 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Events/EventArgs/BotRefreshKeystoreEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Common;
2 |
3 | namespace Lagrange.Core.Events.EventArgs;
4 |
5 | public class BotRefreshKeystoreEvent(BotKeystore keystore) : EventBase
6 | {
7 | public BotKeystore Keystore { get; } = keystore;
8 |
9 | public override string ToEventMessage()
10 | {
11 | return $"{nameof(BotRefreshKeystoreEvent)}";
12 | }
13 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Events/EventArgs/BotSMSEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Events.EventArgs;
2 |
3 | public class BotSMSEvent(string? url, string phone) : EventBase
4 | {
5 | public string? Url { get; } = url;
6 |
7 | public string Phone { get; } = phone;
8 |
9 | public override string ToEventMessage() => $"{nameof(BotSMSEvent)} {Phone} | URL: {Url}";
10 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Events/EventBase.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Events;
2 |
3 | public abstract class EventBase : System.EventArgs
4 | {
5 | public DateTime EventTime { get; }
6 |
7 | internal EventBase() => EventTime = DateTime.Now;
8 |
9 | public abstract string ToEventMessage();
10 |
11 | public override string ToString() => $"[{EventTime:yyyy-MM-dd HH:mm:ss}] {ToEventMessage()}";
12 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Exceptions/InvalidTargetException.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Common.Entity;
2 |
3 | namespace Lagrange.Core.Exceptions;
4 |
5 | ///
6 | /// When specified target is not found or invalid, this exception will be thrown.
7 | ///
8 | public class InvalidTargetException : LagrangeException
9 | {
10 | public long? TargetUin { get; }
11 |
12 | public long? GroupUin { get; }
13 |
14 | public InvalidTargetException(long targetUin) :
15 | base($"Target {targetUin} is invalid or not found.")
16 | {
17 | TargetUin = targetUin;
18 | }
19 |
20 | public InvalidTargetException(long? targetUin, long groupUin) :
21 | base($"Target {targetUin} is invalid in group {groupUin} or not found.")
22 | {
23 | TargetUin = targetUin;
24 | GroupUin = groupUin;
25 | }
26 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Exceptions/LagrangeException.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Exceptions;
2 |
3 | ///
4 | /// The Exception class for Lagrange.Core, All exceptions should be derived from this class.
5 | ///
6 | public class LagrangeException : Exception
7 | {
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | public LagrangeException() { }
12 |
13 | ///
14 | /// Initializes a new instance of the class with a specified error message.
15 | ///
16 | /// The error message that explains the reason for the exception.
17 | public LagrangeException(string message) : base(message) { }
18 |
19 | ///
20 | /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception.
21 | ///
22 | /// The error message that explains the reason for the exception.
23 | /// The exception that is the cause of the current exception, or a null reference if no inner exception is specified.
24 | public LagrangeException(string? message, Exception innerException) : base(message, innerException) { }
25 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Exceptions/OperationException.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Exceptions;
2 |
3 | ///
4 | /// Exception thrown when an operation fails.
5 | ///
6 | public class OperationException(int result, string? errMsg = null) : LagrangeException($"Operation failed with code {result}: {errMsg}")
7 | {
8 | public int Result { get; } = result;
9 |
10 | public string? ErrMsg { get; } = errMsg;
11 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Exceptions/ServiceNotFoundException.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Exceptions;
2 |
3 | internal class ServiceNotFoundException(string command) : LagrangeException($"Service not found for command: {command}")
4 | {
5 | public string Command { get; } = command;
6 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/EventSubscribeAttribute.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Common;
2 |
3 | namespace Lagrange.Core.Internal.Events;
4 |
5 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
6 | internal class EventSubscribeAttribute(Protocols protocol) : EventSubscribeAttribute(typeof(T), protocol) where T : ProtocolEvent;
7 |
8 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
9 | internal class EventSubscribeAttribute(Type type, Protocols protocol) : Attribute
10 | {
11 | public Type EventType { get; } = type;
12 |
13 | public Protocols Protocol { get; set; } = protocol;
14 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/Login/CloseCodeEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.Login;
2 |
3 | internal class CloseCodeEventReq(byte[] k, bool isApproved) : ProtocolEvent
4 | {
5 | public byte[] K { get; } = k;
6 |
7 | public bool IsApproved { get; } = isApproved;
8 | }
9 |
10 | internal class CloseCodeEventResp(byte state, string message) : ProtocolEvent
11 | {
12 | public byte State { get; } = state;
13 |
14 | public string Message { get; } = message;
15 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/Login/ExchangeEmpEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.Login;
2 |
3 | internal class ExchangeEmpEventReq(ExchangeEmpEventReq.Command cmd) : ProtocolEvent
4 | {
5 | public enum Command
6 | {
7 | RefreshByA1 = 0xF
8 | }
9 |
10 | public Command Cmd { get; } = cmd;
11 | }
12 |
13 | internal class ExchangeEmpEventResp(byte retCode, Dictionary tlvs) : ProtocolEvent
14 | {
15 | public byte RetCode { get; } = retCode;
16 |
17 | public Dictionary Tlvs { get; set; } = tlvs;
18 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/Login/KeyExchangeEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.Login;
2 |
3 | internal class KeyExchangeEventReq : ProtocolEvent;
4 |
5 | internal class KeyExchangeEventResp(byte[] sessionTicket, byte[] sessionKey) : ProtocolEvent
6 | {
7 | public byte[] SessionTicket { get; } = sessionTicket;
8 |
9 | public byte[] SessionKey { get; } = sessionKey;
10 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/Login/TransEmpEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.Login;
2 |
3 | internal class TransEmp31EventReq(byte[]? unusualSig) : ProtocolEvent
4 | {
5 | public byte[]? UnusualSig { get; } = unusualSig;
6 | }
7 |
8 | internal class TransEmp31EventResp(string url, byte[] image, byte[] qrSig) : ProtocolEvent
9 | {
10 | public string Url { get; } = url;
11 |
12 | public byte[] Image { get; } = image;
13 |
14 | public byte[] QrSig { get; } = qrSig;
15 | }
16 |
17 | internal class TransEmp12EventReq : ProtocolEvent;
18 |
19 | internal class TransEmp12EventResp(byte state, long uin, (byte[], byte[], byte[])? data) : ProtocolEvent
20 | {
21 | public TransEmpState State { get; } = (TransEmpState)state;
22 |
23 | public long Uin { get; } = uin;
24 |
25 | public (byte[] TgtgtKey, byte[] NoPicSig, byte[] TempPassword)? Data { get; } = data;
26 |
27 | internal enum TransEmpState : byte
28 | {
29 | Confirmed = 0,
30 | CodeExpired = 17,
31 | WaitingForScan = 48,
32 | WaitingForConfirm = 53,
33 | Canceled = 54,
34 | Invalid = 144
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/Login/UinResolveEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.Login;
2 |
3 | internal class UinResolveEventReq(string qid) : ProtocolEvent
4 | {
5 | public string Qid { get; } = qid;
6 | }
7 |
8 | internal class UinResolveEventResp : ProtocolEvent
9 | {
10 | public byte State { get; }
11 |
12 | public (string, string)? Error { get; }
13 |
14 | public (long, string)? Info { get; }
15 |
16 | public byte[] Tlv104 { get; } = [];
17 |
18 | public UinResolveEventResp(byte retCode, (string, string)? error)
19 | {
20 | State = retCode;
21 | Error = error;
22 | }
23 |
24 | public UinResolveEventResp(byte retCode, (long, string) info, byte[] tlv104)
25 | {
26 | State = retCode;
27 | Info = info;
28 | Tlv104 = tlv104;
29 | }
30 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/Login/VerifyCodeEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.Login;
2 |
3 | internal class VerifyCodeEventReq(byte[] k) : ProtocolEvent
4 | {
5 | public byte[] K { get; } = k;
6 | }
7 |
8 | internal class VerifyCodeEventResp(byte state, string message, string platform, string location, string? device) : ProtocolEvent
9 | {
10 | public byte State { get; } = state;
11 |
12 | public string Message { get; } = message;
13 |
14 | public string Platform { get; } = platform;
15 |
16 | public string Location { get; } = location;
17 |
18 | public string? Device { get; } = device;
19 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/Message/GroupFileSendEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.Message;
2 |
3 | internal class GroupFileSendEventReq(long groupUin, string fileId, uint random) : ProtocolEvent
4 | {
5 | public long GroupUin { get; } = groupUin;
6 |
7 | public string FileId { get; } = fileId;
8 |
9 | public uint Random { get; set; } = random;
10 | }
11 |
12 | internal class GroupFileSendEventResp(int retCode, string? retMsg) : ProtocolEvent
13 | {
14 | public int RetCode { get; } = retCode;
15 |
16 | public string? RetMsg { get; } = retMsg;
17 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/Message/LongMsgRecvEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Message;
2 |
3 | namespace Lagrange.Core.Internal.Events.Message;
4 |
5 | internal class LongMsgRecvEventReq(bool isGroup, string resId) : ProtocolEvent
6 | {
7 | public bool IsGroup { get; } = isGroup;
8 |
9 | public string ResId { get; } = resId;
10 | }
11 |
12 | internal class LongMsgRecvEventResp(List messages) : ProtocolEvent
13 | {
14 | public List Messages { get; } = messages;
15 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/Message/LongMsgSendEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Common.Entity;
2 | using Lagrange.Core.Message;
3 |
4 | namespace Lagrange.Core.Internal.Events.Message;
5 |
6 | internal class LongMsgSendEventReq(BotContact receiver, List messages) : ProtocolEvent
7 | {
8 | public BotContact Receiver { get; } = receiver;
9 |
10 | public List Messages { get; } = messages;
11 | }
12 |
13 | internal class LongMsgSendEventResp(string resId) : ProtocolEvent
14 | {
15 | public string ResId { get; } = resId;
16 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/Message/NudgeEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.Message;
2 |
3 | internal class NudgeEventReq(bool isGroup, long peerUin, long targetUin) : ProtocolEvent
4 | {
5 | public bool IsGroup { get; } = isGroup;
6 |
7 | public long PeerUin { get; } = peerUin;
8 |
9 | public long TargetUin { get; } = targetUin;
10 | }
11 |
12 | internal class NudgeEventResp : ProtocolEvent;
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/Message/PushMessageEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Internal.Packets.Message;
2 |
3 | namespace Lagrange.Core.Internal.Events.Message;
4 |
5 | internal class PushMessageEvent(MsgPush msg, ReadOnlyMemory raw) : ProtocolEvent
6 | {
7 | public MsgPush MsgPush { get; } = msg;
8 |
9 | internal ReadOnlyMemory Raw { get; } = raw;
10 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/Message/SendMessageEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Common.Entity;
2 | using Lagrange.Core.Internal.Events.System;
3 | using Lagrange.Core.Message;
4 |
5 | namespace Lagrange.Core.Internal.Events.Message;
6 |
7 | internal class SendMessageEventReq(BotMessage message) : ProtocolEvent
8 | {
9 | public BotMessage Message { get; } = message;
10 | }
11 |
12 | internal class SendFriendFileEventReq(BotFriend friend, FileUploadEventReq request, FileUploadEventResp response, int clientSequence, uint sequence) : ProtocolEvent
13 | {
14 | public BotFriend Friend { get; } = friend;
15 |
16 | public FileUploadEventReq Request { get; } = request;
17 |
18 | public FileUploadEventResp Response { get; } = response;
19 |
20 | public int ClientSequence { get; } = clientSequence;
21 |
22 | public uint Sequence { get; } = sequence;
23 | }
24 |
25 | internal class SendMessageEventResp(int result, long sendTime, int sequence) : ProtocolEvent
26 | {
27 | public int Result { get; } = result;
28 |
29 | public long SendTime { get; } = sendTime;
30 |
31 | public int Sequence { get; } = sequence;
32 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/ProtocolEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events;
2 |
3 | internal class ProtocolEvent;
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/AliveEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.System;
2 |
3 | internal class AliveEvent : ProtocolEvent;
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/FetchClientKeyEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.System;
2 |
3 | internal class FetchClientKeyEventReq : ProtocolEvent;
4 |
5 | internal class FetchClientKeyEventResp(string clientKey, uint expiration) : ProtocolEvent
6 | {
7 | public string ClientKey { get; } = clientKey;
8 |
9 | public uint Expiration { get; } = expiration;
10 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/FetchCookiesEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.System;
2 |
3 | internal class FetchCookiesEventReq(List domain) : ProtocolEvent
4 | {
5 | public List Domain { get; } = domain;
6 | }
7 |
8 | internal class FetchCookiesEventResp(Dictionary cookies) : ProtocolEvent
9 | {
10 | public Dictionary Cookies { get; } = cookies;
11 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/FetchFriendsEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Common.Entity;
2 |
3 | namespace Lagrange.Core.Internal.Events.System;
4 |
5 | internal class FetchFriendsEventReq(byte[]? cookie) : ProtocolEvent
6 | {
7 | public byte[]? Cookie { get; set; } = cookie; // for the request of next page
8 | }
9 |
10 | internal class FetchFriendsEventResp(List friends, List category, byte[]? cookie) : ProtocolEvent
11 | {
12 | public List Friends { get; } = friends;
13 |
14 | public List Category { get; } = category;
15 |
16 | public byte[]? Cookie { get; } = cookie;
17 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/FetchGroupMembersEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Common.Entity;
2 |
3 | namespace Lagrange.Core.Internal.Events.System;
4 |
5 | internal class FetchGroupMembersEventReq(long groupUin, byte[]? cookie) : ProtocolEvent
6 | {
7 | public long GroupUin { get; } = groupUin;
8 |
9 | public byte[]? Cookie { get; } = cookie;
10 | }
11 |
12 | internal class FetchGroupMembersEventResp(List groupMembers, byte[]? cookie) : ProtocolEvent
13 | {
14 | public List GroupMembers { get; } = groupMembers;
15 |
16 | public byte[]? Cookie { get; } = cookie;
17 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/FetchGroupsEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Common.Entity;
2 |
3 | namespace Lagrange.Core.Internal.Events.System;
4 |
5 | internal class FetchGroupsEventReq : ProtocolEvent;
6 |
7 | internal class FetchGroupsEventResp(List groups) : ProtocolEvent
8 | {
9 | public List Groups { get; } = groups;
10 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/FileUploadEvent.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Utility.Extension;
2 |
3 | namespace Lagrange.Core.Internal.Events.System;
4 |
5 | internal class FileUploadEventReq(string targetUid, Stream fileStream, string fileName) : ProtocolEvent
6 | {
7 | public string TargetUid { get; } = targetUid;
8 |
9 | public Stream FileStream { get; } = fileStream;
10 |
11 | public string FileName { get; } = fileName;
12 |
13 | public byte[] FileMd5 { get; } = fileStream.Md5();
14 |
15 | public byte[] FileSha1 { get; } = fileStream.Sha1();
16 | }
17 |
18 | internal class FileUploadEventResp(bool isExist, string fileId, byte[] uploadKey, List<(string, uint)> rtpMediaPlatformUploadAddress, string crcMedia) : ProtocolEvent
19 | {
20 | public bool IsExist { get; } = isExist;
21 |
22 | public string FileId { get; } = fileId;
23 |
24 | public byte[] UploadKey { get; } = uploadKey;
25 |
26 | public List<(string, uint)> RtpMediaPlatformUploadAddress { get; } = rtpMediaPlatformUploadAddress;
27 |
28 | public string CrcMedia { get; } = crcMedia;
29 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/HighwaySessionEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.System;
2 |
3 | internal class HighwaySessionEventReq : ProtocolEvent;
4 |
5 | internal class HighwaySessionEventResp(Dictionary> highwayUrls, byte[] sigSession) : ProtocolEvent
6 | {
7 | public Dictionary> HighwayUrls { get; } = highwayUrls;
8 |
9 | public byte[] SigSession { get; } = sigSession;
10 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/InfoSyncEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.System;
2 |
3 | internal class InfoSyncEventReq : ProtocolEvent;
4 |
5 | internal class InfoSyncEventResp(string message) : ProtocolEvent
6 | {
7 | public string Message { get; } = message;
8 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/InfoSyncPushEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.System;
2 |
3 | internal class InfoSyncPushEvent : ProtocolEvent
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/KickEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.System;
2 |
3 | internal class KickEvent(string tipsTitle, string tipsInfo) : ProtocolEvent
4 | {
5 | public string TipsTitle { get; } = tipsTitle;
6 |
7 | public string TipsInfo { get; } = tipsInfo;
8 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/PushParamsEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.System;
2 |
3 | internal class PushParamsEvent : ProtocolEvent
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/SsoHeartBeatEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.System;
2 |
3 | internal class SsoHeartBeatEventReq : ProtocolEvent;
4 |
5 | internal class SsoHeartBeatEventResp(int interval) : ProtocolEvent
6 | {
7 | public int Interval { get; } = interval;
8 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Events/System/SsoUnregisterEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Events.System;
2 |
3 | internal class SsoUnregisterEventReq : ProtocolEvent;
4 |
5 | internal class SsoUnregisterEventResp(string message) : ProtocolEvent
6 | {
7 | public string Message { get; } = message;
8 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Logic/ILogic.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Events;
2 | using Lagrange.Core.Internal.Events;
3 |
4 | namespace Lagrange.Core.Internal.Logic;
5 |
6 | internal interface ILogic
7 | {
8 | public ValueTask Incoming(ProtocolEvent e) => ValueTask.CompletedTask;
9 |
10 | public ValueTask Outgoing(ProtocolEvent e) => ValueTask.CompletedTask;
11 |
12 | public ValueTask Outgoing(EventBase e) => ValueTask.CompletedTask;
13 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Logic/PushLogic.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Core.Common;
2 | using Lagrange.Core.Events.EventArgs;
3 | using Lagrange.Core.Internal.Events;
4 | using Lagrange.Core.Internal.Events.Message;
5 |
6 | namespace Lagrange.Core.Internal.Logic;
7 |
8 | [EventSubscribe(Protocols.All)]
9 | internal class PushLogic(BotContext context) : ILogic
10 | {
11 | public async ValueTask Incoming(ProtocolEvent e)
12 | {
13 | var messageEvent = (PushMessageEvent)e;
14 |
15 | switch ((Type)messageEvent.MsgPush.CommonMessage.ContentHead.Type)
16 | {
17 | case Type.GroupMessage:
18 | case Type.PrivateMessage:
19 | case Type.TempMessage:
20 | var message = await context.EventContext.GetLogic().Parse(messageEvent.MsgPush.CommonMessage);
21 | context.EventInvoker.PostEvent(new BotMessageEvent(message, messageEvent.Raw));
22 | break;
23 | }
24 | }
25 |
26 | private enum Type
27 | {
28 | PrivateMessage = 166,
29 | GroupMessage = 82,
30 | TempMessage = 141,
31 | }
32 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Network/CallbackClientListener.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Network;
2 |
3 | internal sealed class CallbackClientListener(IClientListener listener) : ClientListener
4 | {
5 | public override uint HeaderSize => listener.HeaderSize;
6 |
7 | public override uint GetPacketLength(ReadOnlySpan header) => listener.GetPacketLength(header);
8 |
9 | public override void OnDisconnect() => listener.OnDisconnect();
10 |
11 | public override void OnRecvPacket(ReadOnlySpan packet) => listener.OnRecvPacket(packet);
12 |
13 | public override void OnSocketError(Exception e, ReadOnlyMemory data = default) => listener.OnSocketError(e, data);
14 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Network/ClientListener.SocketSession.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Sockets;
2 |
3 | namespace Lagrange.Core.Internal.Network;
4 |
5 | internal abstract partial class ClientListener
6 | {
7 | protected sealed class SocketSession : IDisposable
8 | {
9 | public Socket Socket { get; }
10 |
11 | private CancellationTokenSource? _cts;
12 |
13 | public CancellationToken Token { get; }
14 |
15 | public SocketSession(bool useIPv6 = false)
16 | {
17 | Socket = new Socket(useIPv6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
18 | _cts = new CancellationTokenSource();
19 | Token = _cts.Token;
20 | }
21 |
22 | public void Dispose()
23 | {
24 | var cts = Interlocked.Exchange(ref _cts, null);
25 | if (cts == null) return;
26 |
27 | cts.Cancel();
28 | cts.Dispose();
29 | Socket.Dispose();
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Network/IClientListener.cs:
--------------------------------------------------------------------------------
1 | namespace Lagrange.Core.Internal.Network;
2 |
3 | internal interface IClientListener
4 | {
5 | uint HeaderSize { get; }
6 |
7 | ///
8 | /// Dissect a stream
9 | ///
10 | ///
11 | public uint GetPacketLength(ReadOnlySpan header);
12 |
13 | ///
14 | /// On handle a packet
15 | ///
16 | public void OnRecvPacket(ReadOnlySpan packet);
17 |
18 | ///
19 | /// On client disconnect
20 | ///
21 | public void OnDisconnect();
22 |
23 | ///
24 | /// On socket error
25 | ///
26 | public void OnSocketError(Exception e, ReadOnlyMemory data);
27 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Packets/Message/NTPushService.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Proto;
2 |
3 | namespace Lagrange.Core.Internal.Packets.Message;
4 |
5 | #pragma warning disable CS8618
6 |
7 | [ProtoPackable]
8 | internal partial class MsgPush
9 | {
10 | [ProtoMember(1)] public CommonMessage CommonMessage { get; set; }
11 |
12 | [ProtoMember(5)] public bool PushNotifyFlag { get; set; }
13 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Packets/Service/KickNT.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Proto;
2 |
3 | namespace Lagrange.Core.Internal.Packets.Service;
4 |
5 | #pragma warning disable CS8618
6 |
7 | [ProtoPackable]
8 | internal partial class KickNTReq
9 | {
10 | [ProtoMember(1)] public long Uin { get; set; }
11 |
12 | [ProtoMember(2)] public bool IsSameDevice { get; set; }
13 |
14 | [ProtoMember(3)] public string TipsInfo { get; set; }
15 |
16 | [ProtoMember(4)] public string TipsTitle { get; set; }
17 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Packets/Service/NTV2RichMediaHighwayExt.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Proto;
2 |
3 | #pragma warning disable CS8618
4 |
5 | namespace Lagrange.Core.Internal.Packets.Service;
6 |
7 | [ProtoPackable]
8 | internal partial class NTV2RichMediaHighwayExt
9 | {
10 | [ProtoMember(1)] public string FileUuid { get; set; }
11 |
12 | [ProtoMember(2)] public string UKey { get; set; }
13 |
14 | [ProtoMember(5)] public NTHighwayNetwork Network { get; set; }
15 |
16 | [ProtoMember(6)] public List MsgInfoBody { get; set; }
17 |
18 | [ProtoMember(10)] public uint BlockSize { get; set; }
19 |
20 | [ProtoMember(11)] public NTHighwayHash Hash { get; set; }
21 | }
22 |
23 | [ProtoPackable]
24 | internal partial class NTHighwayHash
25 | {
26 | [ProtoMember(1)] public List FileSha1 { get; set; }
27 | }
28 |
29 | [ProtoPackable]
30 | internal partial class NTHighwayNetwork
31 | {
32 | [ProtoMember(1)] public List IPv4s { get; set; }
33 | }
34 |
35 |
36 | [ProtoPackable]
37 | internal partial class NTHighwayIPv4
38 | {
39 | [ProtoMember(1)] public NTHighwayDomain Domain { get; set; }
40 |
41 | [ProtoMember(2)] public uint Port { get; set; }
42 | }
43 |
44 | [ProtoPackable]
45 | internal partial class NTHighwayDomain
46 | {
47 | [ProtoMember(1)] public bool IsEnable { get; set; } // true
48 |
49 | [ProtoMember(2)] public string IP { get; set; }
50 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Packets/Service/Oidb.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Proto;
2 |
3 | namespace Lagrange.Core.Internal.Packets.Service;
4 |
5 | [ProtoPackable]
6 | internal partial class Oidb
7 | {
8 | [ProtoMember(1)] public uint Command { get; set; }
9 |
10 | [ProtoMember(2)] public uint Service { get; set; }
11 |
12 | [ProtoMember(3)] public uint Result { get; set; }
13 |
14 | [ProtoMember(4)] public ReadOnlyMemory Body { get; set; }
15 |
16 | [ProtoMember(5)] public string Message { get; set; } = string.Empty;
17 |
18 | [ProtoMember(12)] public uint Reserved { get; set; }
19 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Packets/Service/Oidb_0x102A.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Proto;
2 |
3 | namespace Lagrange.Core.Internal.Packets.Service;
4 |
5 | #pragma warning disable CS8618
6 |
7 | [ProtoPackable]
8 | internal partial class D102AReqBody
9 | {
10 | [ProtoMember(1)] public List Domain { get; set; }
11 | }
12 |
13 | [ProtoPackable]
14 | internal partial class D102ARspBody
15 | {
16 | [ProtoMember(1)] public Dictionary PsKeys { get; set; }
17 |
18 | [ProtoMember(2)] public int KeyType { get; set; }
19 |
20 | [ProtoMember(3)] public string ClientKey { get; set; }
21 |
22 | [ProtoMember(4)] public uint Expiration { get; set; }
23 | }
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Packets/Service/Oidb_0xED3.cs:
--------------------------------------------------------------------------------
1 | using Lagrange.Proto;
2 |
3 | namespace Lagrange.Core.Internal.Packets.Service;
4 |
5 | [ProtoPackable]
6 | internal partial class DED3ReqBody
7 | {
8 | [ProtoMember(1)] public long ToUin { get; set; } // uint64_to_uin
9 |
10 | [ProtoMember(2)] public long GroupCode { get; set; } // uint64_group_code
11 |
12 | [ProtoMember(3)] public uint MsgSeq { get; set; } // uint32_msg_seq
13 |
14 | [ProtoMember(4)] public uint MsgRand { get; set; } // uint32_msg_rand
15 |
16 | [ProtoMember(5)] public long AioUin { get; set; } // uint64_aio_uin
17 |
18 | [ProtoMember(6)] public uint NudgeType { get; set; } // uint32_nudge_type
19 | }
20 |
21 | [ProtoPackable]
22 | internal partial class DED3RspBody;
--------------------------------------------------------------------------------
/Lagrange.Core/Internal/Packets/Struct/SsoPacket.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks.Sources;
2 |
3 | namespace Lagrange.Core.Internal.Packets.Struct;
4 |
5 | internal class SsoPacket(string command, int sequence, int retCode, string extra)
6 | {
7 | public ReadOnlyMemory Data { get; }
8 |
9 | public string Command { get; } = command;
10 |
11 | public string Extra { get; } = extra;
12 |
13 | public int RetCode { get; } = retCode;
14 |
15 | public int Sequence { get; } = sequence;
16 |
17 | public SsoPacket(string command, ReadOnlyMemory data, int sequence) : this(command, sequence, 0, string.Empty) => Data = data;
18 | }
19 |
20 | internal class SsoPacketValueTaskSource : IValueTaskSource
21 | {
22 | private ManualResetValueTaskSourceCore _core;
23 |
24 | public SsoPacket GetResult(short token) => _core.GetResult(token);
25 |
26 | public ValueTaskSourceStatus GetStatus(short token) => _core.GetStatus(token);
27 |
28 | public void OnCompleted(Action