From 2204bf42feededce10fe2a890b1b3be09bc4980f Mon Sep 17 00:00:00 2001 From: thexeondev <149735250+thexeondev@users.noreply.github.com> Date: Thu, 4 Jan 2024 16:48:39 +0300 Subject: [PATCH] Initial commit --- .gitignore | 398 + LICENSE | 661 ++ .../Constants/AvatarConstants.cs | 25 + NahidaImpact.Common/Constants/FightProp.cs | 100 + NahidaImpact.Common/Constants/PlayerProp.cs | 49 + .../Data/Binout/Ability/AbilityData.cs | 17 + .../Data/Binout/AvatarConfig.cs | 14 + .../Data/Binout/BinDataCollection.cs | 50 + NahidaImpact.Common/Data/DataHelper.cs | 34 + .../Data/Excel/Attributes/ExcelAttribute.cs | 16 + NahidaImpact.Common/Data/Excel/AvatarExcel.cs | 136 + NahidaImpact.Common/Data/Excel/ExcelItem.cs | 5 + NahidaImpact.Common/Data/Excel/ExcelTable.cs | 46 + .../Data/Excel/ExcelTableCollection.cs | 41 + NahidaImpact.Common/Data/Excel/ExcelType.cs | 5 + .../Data/Provider/IAssetProvider.cs | 9 + .../Data/Provider/LocalAssetProvider.cs | 27 + .../Provider/ServiceCollectionExtensions.cs | 10 + .../Extensions/StringExtensions.cs | 14 + .../NahidaImpact.Common.csproj | 270 + NahidaImpact.Common/Security/MhySecurity.cs | 79 + NahidaImpact.Common/Security/Util/MT19937.cs | 68 + .../binout/avatar/ConfigAvatar_Albedo.json | 114 + .../binout/avatar/ConfigAvatar_Alhatham.json | 154 + .../binout/avatar/ConfigAvatar_Aloy.json | 214 + .../binout/avatar/ConfigAvatar_Ambor.json | 314 + .../binout/avatar/ConfigAvatar_Ayaka.json | 254 + .../binout/avatar/ConfigAvatar_Ayato.json | 249 + .../binout/avatar/ConfigAvatar_Baizhuer.json | 204 + .../binout/avatar/ConfigAvatar_Barbara.json | 144 + .../binout/avatar/ConfigAvatar_Beidou.json | 109 + .../binout/avatar/ConfigAvatar_Bennett.json | 134 + .../binout/avatar/ConfigAvatar_Candace.json | 174 + .../binout/avatar/ConfigAvatar_Charlotte.json | 429 + .../binout/avatar/ConfigAvatar_Chevreuse.json | 174 + .../binout/avatar/ConfigAvatar_Chongyun.json | 124 + .../binout/avatar/ConfigAvatar_Collei.json | 144 + .../binout/avatar/ConfigAvatar_Cyno.json | 319 + .../binout/avatar/ConfigAvatar_Dehya.json | 489 ++ .../binout/avatar/ConfigAvatar_Diluc.json | 174 + .../binout/avatar/ConfigAvatar_Diona.json | 224 + .../binout/avatar/ConfigAvatar_Dori.json | 119 + .../binout/avatar/ConfigAvatar_Eula.json | 174 + .../binout/avatar/ConfigAvatar_Faruzan.json | 264 + .../binout/avatar/ConfigAvatar_Feiyan.json | 154 + .../binout/avatar/ConfigAvatar_Fischl.json | 259 + .../binout/avatar/ConfigAvatar_Freminet.json | 154 + .../binout/avatar/ConfigAvatar_Furina.json | 144 + .../binout/avatar/ConfigAvatar_Gaming.json | 5 + .../binout/avatar/ConfigAvatar_Ganyu.json | 189 + .../binout/avatar/ConfigAvatar_Gorou.json | 234 + .../binout/avatar/ConfigAvatar_Heizo.json | 119 + .../binout/avatar/ConfigAvatar_Hutao.json | 179 + .../binout/avatar/ConfigAvatar_Itto.json | 364 + .../binout/avatar/ConfigAvatar_Kaeya.json | 94 + .../binout/avatar/ConfigAvatar_Kaveh.json | 224 + .../binout/avatar/ConfigAvatar_Kazuha.json | 634 ++ .../binout/avatar/ConfigAvatar_Keqing.json | 314 + .../binout/avatar/ConfigAvatar_Klee.json | 209 + .../binout/avatar/ConfigAvatar_Kokomi.json | 374 + .../binout/avatar/ConfigAvatar_Layla.json | 109 + .../binout/avatar/ConfigAvatar_Linette.json | 169 + .../binout/avatar/ConfigAvatar_Liney.json | 129 + .../binout/avatar/ConfigAvatar_Lisa.json | 189 + .../binout/avatar/ConfigAvatar_Liuyun.json | 129 + .../binout/avatar/ConfigAvatar_Mika.json | 254 + .../binout/avatar/ConfigAvatar_Momoka.json | 134 + .../binout/avatar/ConfigAvatar_Mona.json | 169 + .../binout/avatar/ConfigAvatar_Nahida.json | 454 ++ .../binout/avatar/ConfigAvatar_Navia.json | 144 + .../avatar/ConfigAvatar_Neuvillette.json | 504 ++ .../binout/avatar/ConfigAvatar_Nilou.json | 264 + .../binout/avatar/ConfigAvatar_Ningguang.json | 289 + .../binout/avatar/ConfigAvatar_Noel.json | 119 + .../binout/avatar/ConfigAvatar_PlayerBoy.json | 5 + .../binout/avatar/ConfigAvatar_Qin.json | 304 + .../binout/avatar/ConfigAvatar_Qiqi.json | 139 + .../binout/avatar/ConfigAvatar_Razor.json | 139 + .../binout/avatar/ConfigAvatar_Rosaria.json | 114 + .../binout/avatar/ConfigAvatar_Sara.json | 179 + .../binout/avatar/ConfigAvatar_Sayu.json | 239 + .../binout/avatar/ConfigAvatar_Shenhe.json | 134 + .../binout/avatar/ConfigAvatar_Shinobu.json | 139 + .../binout/avatar/ConfigAvatar_Shougun.json | 124 + .../binout/avatar/ConfigAvatar_Sucrose.json | 244 + .../binout/avatar/ConfigAvatar_Tartaglia.json | 239 + .../binout/avatar/ConfigAvatar_Tighnari.json | 194 + .../binout/avatar/ConfigAvatar_Tohma.json | 114 + .../binout/avatar/ConfigAvatar_Venti.json | 194 + .../binout/avatar/ConfigAvatar_Wanderer.json | 569 ++ .../avatar/ConfigAvatar_Wriothesley.json | 264 + .../binout/avatar/ConfigAvatar_Xiangling.json | 169 + .../binout/avatar/ConfigAvatar_Xiao.json | 134 + .../binout/avatar/ConfigAvatar_Xingqiu.json | 189 + .../binout/avatar/ConfigAvatar_Xinyan.json | 99 + .../binout/avatar/ConfigAvatar_Yae.json | 224 + .../binout/avatar/ConfigAvatar_Yaoyao.json | 209 + .../binout/avatar/ConfigAvatar_Yelan.json | 474 ++ .../binout/avatar/ConfigAvatar_Yoimiya.json | 239 + .../binout/avatar/ConfigAvatar_Yunjin.json | 119 + .../binout/avatar/ConfigAvatar_Zhongli.json | 94 + .../assets/excel/AvatarExcelConfigData.json | 6978 +++++++++++++++++ .../assets/security/client_public_key.der | Bin 0 -> 294 bytes .../assets/security/initial_key.bin | Bin 0 -> 4096 bytes .../assets/security/initial_key.ec2b | Bin 0 -> 2076 bytes .../Controllers/AccountController.cs | 152 + .../Attributes/NetCommandAttribute.cs | 9 + .../Attributes/NetControllerAttribute.cs | 6 + .../Controllers/AvatarController.cs | 35 + .../Controllers/ControllerBase.cs | 25 + .../Dispatching/NetCommandDispatcher.cs | 99 + .../Controllers/Result/IResult.cs | 8 + .../Controllers/Result/SinglePacketResult.cs | 16 + .../Controllers/SceneController.cs | 57 + .../Game/Avatar/GameAvatar.cs | 135 + .../Game/Avatar/GameAvatarTeam.cs | 11 + .../Game/Entity/AvatarEntity.cs | 99 + .../Game/Entity/EntityManager.cs | 20 + .../Game/Entity/Factory/EntityFactory.cs | 12 + .../Entity/Listener/IEntityEventListener.cs | 7 + .../Game/Entity/SceneEntity.cs | 69 + NahidaImpact.Gameserver/Game/Player.cs | 72 + .../Game/Scene/SceneEnterState.cs | 12 + .../Game/Scene/SceneManager.cs | 209 + NahidaImpact.Gameserver/GameServer.cs | 28 + .../NahidaImpact.Gameserver.csproj | 26 + NahidaImpact.Gameserver/Network/IGateway.cs | 6 + .../Network/INetworkUnit.cs | 10 + .../Network/Kcp/KcpGateway.cs | 85 + .../Network/Kcp/KcpHandshake.cs | 39 + .../Network/Kcp/KcpNetworkUnit.cs | 29 + .../Network/Kcp/KcpSession.cs | 41 + NahidaImpact.Gameserver/Network/NetPacket.cs | 67 + .../Network/NetSessionManager.cs | 49 + .../Network/Session/NetSession.cs | 100 + .../Session/SessionEntityEventListener.cs | 18 + .../Options/GatewayOptions.cs | 12 + NahidaImpact.Gameserver/Program.cs | 54 + NahidaImpact.Gameserver/appsettings.json | 6 + NahidaImpact.Kcp/ArrayMemoryOwner.cs | 22 + NahidaImpact.Kcp/AsyncAutoResetEvent.cs | 117 + .../DefaultArrayPoolBufferAllocator.cs | 13 + NahidaImpact.Kcp/IKcpBufferPool.cs | 15 + NahidaImpact.Kcp/IKcpConversation.cs | 23 + ...KcpConversationUpdateNotificationSource.cs | 8 + NahidaImpact.Kcp/IKcpExceptionProducer.cs | 16 + NahidaImpact.Kcp/IKcpMultiplexConnection.cs | 57 + .../IKcpMultiplexConnectionOfT.cs | 53 + NahidaImpact.Kcp/IKcpTransport.cs | 22 + NahidaImpact.Kcp/IKcpTransportOfT.cs | 22 + NahidaImpact.Kcp/KcpAcknowledgeList.cs | 104 + NahidaImpact.Kcp/KcpBuffer.cs | 59 + NahidaImpact.Kcp/KcpBufferPoolRentOptions.cs | 41 + NahidaImpact.Kcp/KcpCommand.cs | 10 + ...KcpConversation.FlushAsyncMethodBuilder.cs | 275 + NahidaImpact.Kcp/KcpConversation.cs | 1395 ++++ NahidaImpact.Kcp/KcpConversationOptions.cs | 97 + .../KcpConversationReceiveResult.cs | 61 + .../KcpConversationUpdateActivation.cs | 490 ++ .../KcpConversationUpdateNotification.cs | 30 + .../KcpExceptionProducerExtensions.cs | 134 + NahidaImpact.Kcp/KcpGlobalVars.cs | 14 + NahidaImpact.Kcp/KcpKeepAliveOptions.cs | 30 + NahidaImpact.Kcp/KcpMultiplexConnection.cs | 339 + NahidaImpact.Kcp/KcpPacketHeader.cs | 75 + NahidaImpact.Kcp/KcpProbeType.cs | 10 + NahidaImpact.Kcp/KcpRawChannel.cs | 371 + NahidaImpact.Kcp/KcpRawChannelOptions.cs | 33 + NahidaImpact.Kcp/KcpRawReceiveQueue.cs | 356 + NahidaImpact.Kcp/KcpRawSendOperation.cs | 182 + NahidaImpact.Kcp/KcpReceiveQueue.cs | 693 ++ .../KcpReceiveWindowNotificationOptions.cs | 37 + NahidaImpact.Kcp/KcpRentedBuffer.cs | 222 + NahidaImpact.Kcp/KcpSendQueue.cs | 715 ++ NahidaImpact.Kcp/KcpSendReceiveBufferItem.cs | 9 + .../KcpSendReceiveBufferItemCache.cs | 73 + .../KcpSendReceiveQueueItemCache.cs | 84 + NahidaImpact.Kcp/KcpSendSegmentStats.cs | 20 + NahidaImpact.Kcp/KcpSocketTransport.cs | 158 + .../KcpSocketTransportForConversation.cs | 45 + ...cpSocketTransportForMultiplexConnection.cs | 40 + .../KcpSocketTransportForRawChannel.cs | 41 + NahidaImpact.Kcp/KcpSocketTransportOfT.cs | 224 + NahidaImpact.Kcp/KcpStream.cs | 166 + NahidaImpact.Kcp/NahidaImpact.Kcp.csproj | 9 + NahidaImpact.Kcp/ThrowHelper.cs | 66 + .../AbilityActionCreateGadget.proto | 9 + .../AbilityActionGenerateElemBall.proto | 7 + ...ilityActionSetRandomOverrideMapValue.proto | 5 + .../AbilityAppliedAbility.proto | 12 + .../AbilityAppliedModifier.proto | 22 + .../AbilityAttachedModifier.proto | 9 + NahidaImpact.Protocol/AbilityBornType.proto | 9 + .../AbilityControlBlock.proto | 8 + NahidaImpact.Protocol/AbilityEmbryo.proto | 7 + NahidaImpact.Protocol/AbilityGadgetInfo.proto | 7 + .../AbilityInvocationsNotify.proto | 6 + .../AbilityInvokeArgument.proto | 71 + .../AbilityInvokeEntry.proto | 12 + .../AbilityInvokeEntryHead.proto | 7 + .../AbilityMetaModifierChange.proto | 11 + .../AbilityMetaModifierDurabilityChange.proto | 6 + .../AbilityMetaSetKilledState.proto | 5 + .../AbilityMetaSetModifierApplyEntityId.proto | 5 + .../AbilityMetaTriggerElementReaction.proto | 7 + .../AbilityMetaUpdateBaseReactionDamage.proto | 11 + .../AbilityMixinAvatarSteerByCamera.proto | 7 + .../AbilityMixinFieldEntityCountChange.proto | 5 + .../AbilityMixinRecoverInfo.proto | 17 + NahidaImpact.Protocol/AbilityScalarType.proto | 12 + .../AbilityScalarValueEntry.proto | 16 + NahidaImpact.Protocol/AbilityString.proto | 8 + .../AbilitySyncStateInfo.proto | 16 + .../ActivityDungeonAvatar.proto | 8 + NahidaImpact.Protocol/ActivityInfo.proto | 10 + .../ActivityInfoNotify.proto | 7 + .../ActivityPushTipsState.proto | 8 + .../AddBackupAvatarTeamReq.proto | 6 + .../AdjustTrackingInfo.proto | 4 + ...AllWidgetBackgroundActiveStateNotify.proto | 5 + .../AnimatorParameterValueInfo.proto | 10 + .../AnimatorParameterValueInfoPair.proto | 9 + .../AranaraCollectionState.proto | 9 + NahidaImpact.Protocol/AreaPlayType.proto | 8 + .../AsterLittleStageState.proto | 9 + NahidaImpact.Protocol/AttackResult.proto | 13 + NahidaImpact.Protocol/AuditState.proto | 8 + NahidaImpact.Protocol/AvatarAddNotify.proto | 9 + .../AvatarBuffAddNotify.proto | 8 + .../AvatarBuffDelNotify.proto | 8 + .../AvatarChangeAnimHashReq.proto | 7 + .../AvatarChangeAnimHashRsp.proto | 8 + NahidaImpact.Protocol/AvatarDataNotify.proto | 19 + .../AvatarDieAnimationEndReq.proto | 10 + .../AvatarDieAnimationEndRsp.proto | 9 + .../AvatarEnterSceneInfo.proto | 20 + .../AvatarEquipAffixInfo.proto | 6 + .../AvatarEquipChangeNotify.proto | 14 + NahidaImpact.Protocol/AvatarExcelInfo.proto | 9 + .../AvatarExpeditionAllDataReq.proto | 6 + .../AvatarExpeditionInfo.proto | 11 + .../AvatarExpeditionState.proto | 10 + NahidaImpact.Protocol/AvatarFetterInfo.proto | 13 + .../AvatarFightPropNotify.proto | 7 + .../AvatarFightPropUpdateNotify.proto | 7 + .../AvatarFlycloakChangeNotify.proto | 7 + NahidaImpact.Protocol/AvatarInfo.proto | 39 + .../AvatarLifeStateChangeNotify.proto | 15 + NahidaImpact.Protocol/AvatarRenameInfo.proto | 6 + NahidaImpact.Protocol/AvatarSkillInfo.proto | 7 + NahidaImpact.Protocol/AvatarTeam.proto | 6 + .../AvatarTeamUpdateNotify.proto | 8 + NahidaImpact.Protocol/AvatarType.proto | 9 + .../AvatarWearFlycloakReq.proto | 8 + .../AvatarWearFlycloakRsp.proto | 8 + NahidaImpact.Protocol/BackMyWorldReq.proto | 6 + NahidaImpact.Protocol/BargainResultType.proto | 8 + .../BattlePassUnlockStatus.proto | 8 + NahidaImpact.Protocol/Birthday.proto | 9 + .../BlessingAcceptAllGivePicReq.proto | 6 + .../BlessingGetAllRecvPicRecordListReq.proto | 6 + .../BlessingGetFriendPicListReq.proto | 6 + .../BlessingRedeemRewardReq.proto | 6 + NahidaImpact.Protocol/BlockInfo.proto | 8 + NahidaImpact.Protocol/BlossomChestInfo.proto | 10 + .../BonusActivityInfoReq.proto | 6 + NahidaImpact.Protocol/BossChestInfo.proto | 12 + NahidaImpact.Protocol/BreakoutAction.proto | 31 + NahidaImpact.Protocol/BreakoutBrickInfo.proto | 6 + .../BreakoutElementReactionCounter.proto | 6 + .../BreakoutPhysicalObject.proto | 25 + .../BreakoutPhysicalObjectModifier.proto | 20 + NahidaImpact.Protocol/BreakoutSnapShot.proto | 31 + .../BreakoutSpawnPoint.proto | 10 + .../BreakoutSyncConnectUidInfo.proto | 7 + NahidaImpact.Protocol/BreakoutVector2.proto | 6 + .../BrickBreakerQuitReq.proto | 6 + .../BrickBreakerSetReadyReq.proto | 6 + .../BrickBreakerStageType.proto | 10 + .../BrickBreakerTwiceStartReq.proto | 6 + NahidaImpact.Protocol/BuyResinReq.proto | 6 + .../ChallengeFinishType.proto | 9 + NahidaImpact.Protocol/ChangeAvatarReq.proto | 11 + NahidaImpact.Protocol/ChangeAvatarRsp.proto | 8 + .../ChangeEnergyReason.proto | 8 + NahidaImpact.Protocol/ChangeHpDebts.proto | 9 + NahidaImpact.Protocol/ChangeHpReason.proto | 37 + .../ChangeServerGlobalValueNotify.proto | 7 + ...ChangeWidgetBackgroundActiveStateReq.proto | 9 + ...ChangeWidgetBackgroundActiveStateRsp.proto | 8 + .../ChangeWorldToSingleModeNotify.proto | 6 + .../ChangeWorldToSingleModeReq.proto | 6 + ...annellerSlabCheckEnterLoopDungeonReq.proto | 6 + .../ChannellerSlabOneOffDungeonInfoReq.proto | 6 + NahidaImpact.Protocol/ChapterState.proto | 9 + NahidaImpact.Protocol/ChatChannelInfo.proto | 7 + NahidaImpact.Protocol/ChatInfo.proto | 21 + NahidaImpact.Protocol/CheckUgcStateReq.proto | 6 + .../ChessManualRefreshCardsReq.proto | 6 + NahidaImpact.Protocol/CityInfo.proto | 8 + .../ClientBulletCreateNotify.proto | 7 + NahidaImpact.Protocol/ClientGadgetInfo.proto | 13 + NahidaImpact.Protocol/ClientInputType.proto | 9 + .../ClientMassiveEntity.proto | 16 + .../ClientReconnectReason.proto | 7 + .../CloseCommonTipsNotify.proto | 6 + NahidaImpact.Protocol/CmdType.cs | 2601 ++++++ NahidaImpact.Protocol/CodexType.proto | 14 + .../CoinCollectOperatorInfo.proto | 5 + .../CoinCollectPrepareReq.proto | 6 + .../CombatInvocationsNotify.proto | 7 + NahidaImpact.Protocol/CombatInvokeEntry.proto | 9 + .../CombatTypeArgument.proto | 24 + .../CompoundBoostTakeStatusType.proto | 9 + NahidaImpact.Protocol/ContentAuditInfo.proto | 11 + NahidaImpact.Protocol/CreateReason.proto | 8 + .../CrystalLinkRestartDungeonReq.proto | 6 + NahidaImpact.Protocol/CurVehicleInfo.proto | 7 + .../CustomCommonNodeInfo.proto | 7 + .../CustomDungeonBanType.proto | 7 + .../CustomDungeonFinishType.proto | 9 + .../CustomDungeonState.proto | 8 + .../CustomGadgetTreeInfo.proto | 8 + .../DealAddFriendResultType.proto | 7 + .../DeshretObeliskGadgetInfo.proto | 5 + .../DoSetPlayerBornDataNotify.proto | 6 + .../DraftInviteFailReason.proto | 12 + .../DuelHeartCgEndNotify.proto | 6 + .../DuelHeartRestartDungeonReq.proto | 6 + .../DungeonCandidateTeamDismissReason.proto | 8 + .../DungeonCandidateTeamLeaveReq.proto | 6 + ...ungeonCandidateTeamPlayerLeaveReason.proto | 9 + .../DungeonCandidateTeamPlayerState.proto | 8 + .../DungeonEntryBlockReason.proto | 9 + .../DungeonGetStatueDropReq.proto | 6 + .../DungeonPlayerDieReq.proto | 9 + .../DungeonPlayerDieRsp.proto | 7 + NahidaImpact.Protocol/DungeonRestartReq.proto | 6 + NahidaImpact.Protocol/EchoShellInfo.proto | 5 + .../EffigyChallengeV2RestartDungeonReq.proto | 6 + .../EndCameraSceneLookNotify.proto | 6 + .../EnterCustomDungeonType.proto | 9 + NahidaImpact.Protocol/EnterSceneDoneReq.proto | 6 + NahidaImpact.Protocol/EnterSceneDoneRsp.proto | 7 + .../EnterScenePeerNotify.proto | 9 + .../EnterSceneReadyReq.proto | 6 + .../EnterSceneReadyRsp.proto | 7 + .../EnterTransPointRegionNotify.proto | 8 + NahidaImpact.Protocol/EnterType.proto | 17 + .../EntityAiKillSelfNotify.proto | 7 + .../EntityAuthorityInfo.proto | 18 + NahidaImpact.Protocol/EntityClientData.proto | 7 + .../EntityClientExtraInfo.proto | 8 + .../EntityEnvironmentInfo.proto | 6 + .../EntityFightPropChangeReasonNotify.proto | 20 + .../EntityFightPropNotify.proto | 6 + .../EntityFightPropUpdateNotify.proto | 7 + NahidaImpact.Protocol/EntityJumpNotify.proto | 18 + NahidaImpact.Protocol/EntityMoveInfo.proto | 11 + .../EntityRendererChangedInfo.proto | 7 + NahidaImpact.Protocol/Equip.proto | 13 + NahidaImpact.Protocol/EquipParam.proto | 9 + NahidaImpact.Protocol/EventTriggerType.proto | 7 + .../EvtAnimatorParameterInfo.proto | 9 + .../EvtAvatarLockChairReq.proto | 10 + .../EvtAvatarLockChairRsp.proto | 12 + NahidaImpact.Protocol/EvtBeingHitInfo.proto | 8 + .../EvtCostStaminaNotify.proto | 7 + .../EvtCreateGadgetNotify.proto | 17 + .../EvtDestroyGadgetNotify.proto | 7 + .../EvtDestroyServerGadgetNotify.proto | 7 + .../EvtDoSkillSuccNotify.proto | 10 + .../EvtEntityStartDieEndNotify.proto | 11 + NahidaImpact.Protocol/EvtFaceToDirInfo.proto | 7 + NahidaImpact.Protocol/EvtFixedRushMove.proto | 9 + .../EvtSetAttackTargetInfo.proto | 7 + .../ExhibitionDisplayInfo.proto | 8 + .../ExitCustomDungeonTryReq.proto | 6 + NahidaImpact.Protocol/ExitFishingReq.proto | 6 + .../ExitTransPointRegionNotify.proto | 8 + NahidaImpact.Protocol/ExpeditionState.proto | 10 + NahidaImpact.Protocol/FeatureBlockInfo.proto | 6 + NahidaImpact.Protocol/FetterData.proto | 7 + NahidaImpact.Protocol/FightPropPair.proto | 6 + .../FindHilichurlAcceptQuestNotify.proto | 6 + .../FireworksLaunchParamType.proto | 11 + .../FireworksReformParamType.proto | 11 + .../FishBattleBeginReq.proto | 6 + NahidaImpact.Protocol/FishBattleResult.proto | 11 + NahidaImpact.Protocol/FishBiteReq.proto | 6 + NahidaImpact.Protocol/FishEscapeReason.proto | 8 + NahidaImpact.Protocol/FishPoolInfo.proto | 7 + NahidaImpact.Protocol/FishtankFishInfo.proto | 7 + .../FleurFairFinishGalleryStageNotify.proto | 6 + .../ForceDragBackTransferNotify.proto | 6 + NahidaImpact.Protocol/ForceUpdateInfo.proto | 5 + .../ForgeGetQueueDataReq.proto | 6 + .../ForgeQueueManipulateType.proto | 7 + NahidaImpact.Protocol/ForwardType.proto | 14 + NahidaImpact.Protocol/FoundationInfo.proto | 11 + NahidaImpact.Protocol/FoundationOpType.proto | 12 + NahidaImpact.Protocol/FoundationStatus.proto | 9 + NahidaImpact.Protocol/FriendBrief.proto | 34 + .../FriendEnterHomeOption.proto | 10 + NahidaImpact.Protocol/FriendOnlineState.proto | 9 + ...ungusFighterRestartTraningDungeonReq.proto | 6 + NahidaImpact.Protocol/Furniture.proto | 5 + .../FurnitureMakeFinishNotify.proto | 6 + .../FurnitureMakeHelpReq.proto | 6 + NahidaImpact.Protocol/FurnitureMakeReq.proto | 6 + NahidaImpact.Protocol/GCGAskDuelReq.proto | 6 + .../GCGClientSettleReq.proto | 6 + NahidaImpact.Protocol/GCGDiceSideType.proto | 14 + NahidaImpact.Protocol/GCGEndReason.proto | 16 + NahidaImpact.Protocol/GCGGameMaxNotify.proto | 6 + NahidaImpact.Protocol/GCGInitFinishReq.proto | 6 + .../GCGIntentionChangeType.proto | 7 + .../GCGMsgPhaseContinue.proto | 5 + NahidaImpact.Protocol/GCGOperationPass.proto | 5 + .../GCGOperationSurrender.proto | 5 + NahidaImpact.Protocol/GCGPhaseType.proto | 17 + NahidaImpact.Protocol/GCGReason.proto | 25 + NahidaImpact.Protocol/GCGSettleOption.proto | 9 + .../GCGSkillHpChangeType.proto | 8 + .../GCGSkillPreviewAskReq.proto | 6 + .../GCGWorldPlayerGCGStateReq.proto | 6 + NahidaImpact.Protocol/GCGZoneType.proto | 14 + .../GachaActivityCreateRobotReq.proto | 6 + .../GachaActivityNextStageReq.proto | 6 + NahidaImpact.Protocol/GadgetBornType.proto | 12 + .../GadgetCrucibleInfo.proto | 6 + .../GadgetGeneralRewardInfo.proto | 12 + NahidaImpact.Protocol/GadgetPlayInfo.proto | 16 + NahidaImpact.Protocol/GalleryStageType.proto | 8 + .../GalleryStartSource.proto | 8 + NahidaImpact.Protocol/GatherGadgetInfo.proto | 6 + .../GearActivityStartPlayPictureReq.proto | 6 + .../GetActivityScheduleReq.proto | 6 + .../GetAllActivatedBargainDataReq.proto | 6 + .../GetAllH5ActivityInfoReq.proto | 6 + .../GetAllSceneGalleryInfoReq.proto | 6 + .../GetAllUnlockNameCardReq.proto | 4 + .../GetAllUnlockNameCardRsp.proto | 6 + .../GetChatEmojiCollectionReq.proto | 6 + .../GetCityReputationMapInfoReq.proto | 6 + .../GetCompoundDataReq.proto | 6 + .../GetCustomDungeonReq.proto | 6 + .../GetExpeditionAssistInfoListReq.proto | 6 + ...GetFurnitureCurModuleArrangeCountReq.proto | 6 + NahidaImpact.Protocol/GetGachaInfoReq.proto | 6 + .../GetHomeExchangeWoodInfoReq.proto | 6 + NahidaImpact.Protocol/GetMapAreaReq.proto | 6 + NahidaImpact.Protocol/GetMapMarkTipsReq.proto | 6 + .../GetMechanicusInfoReq.proto | 6 + .../GetNextResourceInfoReq.proto | 6 + .../GetOnlinePlayerListReq.proto | 6 + .../GetOpActivityInfoReq.proto | 6 + .../GetPlayerAskFriendListReq.proto | 5 + .../GetPlayerAskFriendListRsp.proto | 8 + .../GetPlayerBlacklistReq.proto | 5 + .../GetPlayerBlacklistRsp.proto | 8 + .../GetPlayerFriendListReq.proto | 5 + .../GetPlayerFriendListRsp.proto | 9 + .../GetPlayerHomeCompInfoReq.proto | 6 + .../GetPlayerMpModeAvailabilityReq.proto | 6 + .../GetPlayerSocialDetailReq.proto | 7 + .../GetPlayerSocialDetailRsp.proto | 9 + NahidaImpact.Protocol/GetPlayerTokenReq.proto | 26 + NahidaImpact.Protocol/GetPlayerTokenRsp.proto | 40 + .../GetRecentMpPlayerListReq.proto | 6 + .../GetRegionSearchReq.proto | 6 + .../GetRogueDairyRepairInfoReq.proto | 6 + NahidaImpact.Protocol/GetSceneAreaReq.proto | 8 + NahidaImpact.Protocol/GetSceneAreaRsp.proto | 8 + .../GetScenePerformanceReq.proto | 6 + NahidaImpact.Protocol/GetScenePointReq.proto | 9 + NahidaImpact.Protocol/GetScenePointRsp.proto | 10 + .../GetShopmallDataReq.proto | 6 + .../GetStoreCustomDungeonReq.proto | 6 + NahidaImpact.Protocol/GetUgcType.proto | 8 + NahidaImpact.Protocol/GetWidgetSlotReq.proto | 6 + NahidaImpact.Protocol/GetWorldMpInfoReq.proto | 6 + .../GiveUpRoguelikeDungeonCardReq.proto | 6 + .../HideAndSeekSetReadyReq.proto | 6 + .../HideAndSeekStageType.proto | 11 + NahidaImpact.Protocol/HitColliderType.proto | 8 + NahidaImpact.Protocol/HitCollision.proto | 12 + .../HomeEnterEditModeFinishReq.proto | 6 + .../HomeGetBasicInfoReq.proto | 6 + .../HomeGetBlueprintSlotInfoReq.proto | 6 + .../HomeGetFishFarmingInfoReq.proto | 6 + .../HomeGetOnlineStatusReq.proto | 6 + .../HomeLimitedShopGoodsListReq.proto | 6 + .../HomeLimitedShopInfoReq.proto | 6 + .../HomeMarkPointFurnitureData.proto | 16 + .../HomeMarkPointNPCData.proto | 7 + .../HomeMarkPointSuiteData.proto | 6 + .../HomePlantFieldStatus.proto | 9 + NahidaImpact.Protocol/HomePlantInfoReq.proto | 6 + .../HomeResourceTakeFetterExpReq.proto | 6 + .../HomeResourceTakeHomeCoinReq.proto | 6 + .../HomeSceneInitFinishReq.proto | 6 + NahidaImpact.Protocol/HostPlayerNotify.proto | 8 + NahidaImpact.Protocol/HuntingOfferState.proto | 9 + ...InBattleMechanicusCardChallengeState.proto | 9 + .../InBattleMechanicusStageType.proto | 9 + NahidaImpact.Protocol/InterOpType.proto | 7 + .../InteractDailyDungeonInfoNotify.proto | 6 + NahidaImpact.Protocol/InteractType.proto | 22 + .../InvestigationQuestDailyNotify.proto | 6 + .../InvestigationReadQuestDailyNotify.proto | 6 + .../IslandPartySailStage.proto | 8 + NahidaImpact.Protocol/Item.proto | 16 + NahidaImpact.Protocol/ItemHint.proto | 9 + NahidaImpact.Protocol/ItemParam.proto | 6 + NahidaImpact.Protocol/KeepAliveNotify.proto | 6 + .../LanV3BoatGameStartSingleReq.proto | 6 + .../LanV3BoatInterruptSettleStageReq.proto | 6 + .../LanternRiteTakeSkinRewardReq.proto | 6 + .../LastPacketPrintNotify.proto | 6 + NahidaImpact.Protocol/LeaveSceneReq.proto | 6 + NahidaImpact.Protocol/LeaveWorldNotify.proto | 6 + .../LifeStateChangeNotify.proto | 14 + NahidaImpact.Protocol/LuaShellType.proto | 9 + .../LunaRiteHintPointType.proto | 8 + .../LunaRiteHintStatusType.proto | 8 + NahidaImpact.Protocol/MPLevelEntityInfo.proto | 10 + NahidaImpact.Protocol/MailCollectState.proto | 9 + NahidaImpact.Protocol/MailData.proto | 19 + NahidaImpact.Protocol/MailItem.proto | 9 + NahidaImpact.Protocol/MailTextContent.proto | 8 + NahidaImpact.Protocol/MapAreaInfo.proto | 7 + NahidaImpact.Protocol/MapMarkFromType.proto | 8 + NahidaImpact.Protocol/MapMarkPoint.proto | 14 + NahidaImpact.Protocol/MapMarkPointType.proto | 11 + NahidaImpact.Protocol/MapMarkTipsInfo.proto | 8 + NahidaImpact.Protocol/MapMarkTipsType.proto | 6 + NahidaImpact.Protocol/MarkMapReq.proto | 17 + NahidaImpact.Protocol/MassiveBoxInfo.proto | 13 + .../MassiveEntityState.proto | 8 + NahidaImpact.Protocol/MassiveGrassInfo.proto | 9 + NahidaImpact.Protocol/MassivePropParam.proto | 8 + .../MassivePropSyncInfo.proto | 9 + NahidaImpact.Protocol/MassiveWaterInfo.proto | 6 + NahidaImpact.Protocol/MatchReason.proto | 15 + NahidaImpact.Protocol/MatchType.proto | 11 + NahidaImpact.Protocol/Material.proto | 9 + .../MaterialDeleteInfo.proto | 22 + .../MaterialDeleteReturnType.proto | 7 + .../MaterialDeleteUpdateNotify.proto | 6 + NahidaImpact.Protocol/MathQuaternion.proto | 8 + NahidaImpact.Protocol/ModifierAction.proto | 7 + .../ModifierDurability.proto | 6 + NahidaImpact.Protocol/ModifierProperty.proto | 7 + NahidaImpact.Protocol/MonsterBornType.proto | 8 + NahidaImpact.Protocol/MonsterRoute.proto | 11 + NahidaImpact.Protocol/MotionInfo.proto | 17 + NahidaImpact.Protocol/MotionState.proto | 64 + .../MovingPlatformType.proto | 9 + NahidaImpact.Protocol/MpPlayRewardInfo.proto | 7 + NahidaImpact.Protocol/MpSettingType.proto | 8 + .../MuqadasPotionRestartDungeonReq.proto | 6 + .../NahidaImpact.Protocol.csproj | 161 + .../NightCrowGadgetInfo.proto | 5 + NahidaImpact.Protocol/NpcPositionInfo.proto | 8 + NahidaImpact.Protocol/NpcTalkReq.proto | 6 + NahidaImpact.Protocol/NpcTalkRsp.proto | 10 + NahidaImpact.Protocol/OfferingInfo.proto | 5 + NahidaImpact.Protocol/OnlinePlayerInfo.proto | 22 + .../OpenStateChangeNotify.proto | 7 + .../OpenStateUpdateNotify.proto | 6 + .../OutStuckCustomDungeonReq.proto | 6 + NahidaImpact.Protocol/PacketHead.proto | 22 + NahidaImpact.Protocol/ParamList.proto | 6 + .../PathfindingPingNotify.proto | 6 + .../PerformOperationNotify.proto | 18 + .../PersonalLineAllDataReq.proto | 6 + .../PersonalSceneJumpReq.proto | 6 + .../PersonalSceneJumpRsp.proto | 9 + NahidaImpact.Protocol/PingReq.proto | 8 + NahidaImpact.Protocol/PingRsp.proto | 6 + NahidaImpact.Protocol/PlaceInfo.proto | 8 + NahidaImpact.Protocol/PlatformInfo.proto | 24 + NahidaImpact.Protocol/PlatformType.proto | 26 + NahidaImpact.Protocol/PlayProduct.proto | 8 + .../PlayTeamEntityInfo.proto | 11 + .../PlayerChatCDNotify.proto | 7 + NahidaImpact.Protocol/PlayerChatNotify.proto | 9 + NahidaImpact.Protocol/PlayerDataNotify.proto | 12 + NahidaImpact.Protocol/PlayerDieOption.proto | 9 + NahidaImpact.Protocol/PlayerDieType.proto | 14 + .../PlayerEnterSceneInfoNotify.proto | 15 + .../PlayerEnterSceneNotify.proto | 20 + .../PlayerForceExitReq.proto | 6 + .../PlayerGameTimeNotify.proto | 8 + .../PlayerGetForceQuitBanInfoReq.proto | 6 + NahidaImpact.Protocol/PlayerLoginReq.proto | 53 + NahidaImpact.Protocol/PlayerLoginRsp.proto | 49 + .../PlayerLogoutNotify.proto | 6 + NahidaImpact.Protocol/PlayerLogoutReq.proto | 18 + NahidaImpact.Protocol/PlayerLogoutRsp.proto | 6 + .../PlayerPropChangeNotify.proto | 7 + NahidaImpact.Protocol/PlayerPropNotify.proto | 8 + NahidaImpact.Protocol/PlayerRTTInfo.proto | 7 + NahidaImpact.Protocol/PlayerStoreNotify.proto | 11 + NahidaImpact.Protocol/PlayerWidgetInfo.proto | 10 + NahidaImpact.Protocol/PostEnterSceneReq.proto | 6 + NahidaImpact.Protocol/PostEnterSceneRsp.proto | 7 + .../PotionRestartDungeonReq.proto | 6 + NahidaImpact.Protocol/PrivateChatNotify.proto | 10 + NahidaImpact.Protocol/PrivateChatReq.proto | 10 + NahidaImpact.Protocol/PrivateChatRsp.proto | 7 + NahidaImpact.Protocol/ProfilePicture.proto | 9 + NahidaImpact.Protocol/PropChangeReason.proto | 19 + NahidaImpact.Protocol/PropPair.proto | 9 + NahidaImpact.Protocol/PropValue.proto | 11 + NahidaImpact.Protocol/ProtEntityType.proto | 20 + .../PullPrivateChatReq.proto | 9 + NahidaImpact.Protocol/PullRecentChatReq.proto | 8 + .../QueryCurrRegionHttpRsp.proto | 19 + .../QueryRegionListHttpRsp.proto | 12 + NahidaImpact.Protocol/Quest.proto | 19 + .../ReadNicknameAuditReq.proto | 6 + .../ReadPrivateChatReq.proto | 7 + .../ReadPrivateChatRsp.proto | 7 + .../ReadSignatureAuditReq.proto | 6 + NahidaImpact.Protocol/RecordUsage.proto | 10 + NahidaImpact.Protocol/RedPointData.proto | 8 + .../RedeemLegendaryKeyReq.proto | 6 + .../RefreshBackgroundAvatarReq.proto | 6 + .../RefreshRoguelikeDungeonCardReq.proto | 6 + NahidaImpact.Protocol/RegionInfo.proto | 36 + NahidaImpact.Protocol/RegionSearchState.proto | 10 + NahidaImpact.Protocol/RegionSimpleInfo.proto | 8 + NahidaImpact.Protocol/Reliquary.proto | 9 + .../ReplayCustomDungeonReq.proto | 6 + NahidaImpact.Protocol/ReportReasonType.proto | 12 + NahidaImpact.Protocol/ResVersionConfig.proto | 11 + NahidaImpact.Protocol/ResinCostType.proto | 11 + .../RestartEffigyChallengeReq.proto | 6 + NahidaImpact.Protocol/Retcode.cs | 1377 ++++ NahidaImpact.Protocol/Retcode.proto | 1209 +++ .../RetryCurRogueDiaryDungeonReq.proto | 6 + .../ReunionBriefInfoReq.proto | 6 + .../ReunionSettleNotify.proto | 6 + NahidaImpact.Protocol/Reward.proto | 8 + NahidaImpact.Protocol/RogueCellState.proto | 10 + .../RogueDiaryAvatarDisableStatus.proto | 9 + .../RogueEliteCellDifficultyType.proto | 7 + .../RoguelikeGadgetInfo.proto | 8 + .../RoguelikeMistClearNotify.proto | 6 + NahidaImpact.Protocol/Route.proto | 9 + NahidaImpact.Protocol/RoutePoint.proto | 20 + .../SalesmanStatusType.proto | 9 + .../SalvageEscortStopReason.proto | 12 + .../SalvagePreventStopReason.proto | 12 + NahidaImpact.Protocol/SceneAvatarInfo.proto | 32 + NahidaImpact.Protocol/SceneDataNotify.proto | 8 + NahidaImpact.Protocol/SceneEntityAiInfo.proto | 15 + .../SceneEntityAppearNotify.proto | 12 + .../SceneEntityDisappearNotify.proto | 10 + .../SceneEntityDrownReq.proto | 5 + NahidaImpact.Protocol/SceneEntityInfo.proto | 40 + NahidaImpact.Protocol/SceneFishInfo.proto | 12 + NahidaImpact.Protocol/SceneGadgetInfo.proto | 73 + .../SceneInitFinishReq.proto | 6 + .../SceneInitFinishRsp.proto | 7 + NahidaImpact.Protocol/SceneMonsterInfo.proto | 38 + NahidaImpact.Protocol/SceneNpcInfo.proto | 8 + .../ScenePointUnlockNotify.proto | 11 + .../SceneReliquaryInfo.proto | 8 + NahidaImpact.Protocol/SceneTeamAvatar.proto | 23 + .../SceneTeamUpdateNotify.proto | 10 + NahidaImpact.Protocol/SceneTimeNotify.proto | 6 + .../SceneTransToPointReq.proto | 8 + .../SceneTransToPointRsp.proto | 9 + NahidaImpact.Protocol/SceneWeaponInfo.proto | 17 + NahidaImpact.Protocol/ScreenInfo.proto | 6 + NahidaImpact.Protocol/SealBattleType.proto | 8 + NahidaImpact.Protocol/ServantInfo.proto | 6 + NahidaImpact.Protocol/ServerBuff.proto | 9 + .../ServerGlobalValueChangeNotify.proto | 9 + NahidaImpact.Protocol/ServerLogLevel.proto | 10 + NahidaImpact.Protocol/ServerLogType.proto | 10 + .../ServerMassiveEntity.proto | 18 + NahidaImpact.Protocol/SetNameCardReq.proto | 6 + NahidaImpact.Protocol/SetNameCardRsp.proto | 7 + NahidaImpact.Protocol/SetOpenStateReq.proto | 6 + NahidaImpact.Protocol/SetOpenStateRsp.proto | 8 + .../SetPlayerBornDataReq.proto | 6 + .../SetPlayerBornDataRsp.proto | 7 + NahidaImpact.Protocol/SetPlayerNameReq.proto | 5 + NahidaImpact.Protocol/SetPlayerPropRsp.proto | 6 + .../SetUpAvatarTeamReq.proto | 8 + .../SetUpAvatarTeamRsp.proto | 10 + NahidaImpact.Protocol/SetWidgetSlotReq.proto | 9 + NahidaImpact.Protocol/SetWidgetSlotRsp.proto | 11 + NahidaImpact.Protocol/ShapeBox.proto | 11 + NahidaImpact.Protocol/ShapeSphere.proto | 8 + NahidaImpact.Protocol/ShopCardProduct.proto | 20 + .../ShopConcertProduct.proto | 12 + NahidaImpact.Protocol/ShopMcoinProduct.proto | 12 + .../ShortAbilityHashPair.proto | 6 + NahidaImpact.Protocol/ShowAvatarInfo.proto | 22 + NahidaImpact.Protocol/ShowEquip.proto | 12 + NahidaImpact.Protocol/SignInInfoReq.proto | 6 + NahidaImpact.Protocol/SocialDetail.proto | 38 + .../SocialShowAvatarInfo.proto | 10 + NahidaImpact.Protocol/StatueGadgetInfo.proto | 5 + NahidaImpact.Protocol/StopServerInfo.proto | 8 + NahidaImpact.Protocol/StoreType.proto | 10 + .../StoreWeightLimitNotify.proto | 13 + .../SummerTimeV2RestartDungeonReq.proto | 6 + .../SumoLeaveDungeonNotify.proto | 6 + .../SumoRestartDungeonReq.proto | 6 + NahidaImpact.Protocol/SvrMsgId.proto | 12 + .../TakeFirstShareRewardReq.proto | 6 + .../TakeReunionFirstGiftRewardReq.proto | 6 + .../TeamChainTakeCostumeRewardReq.proto | 6 + .../TeamEnterSceneInfo.proto | 11 + .../ToTheMoonPingNotify.proto | 6 + .../TowerMiddleLevelChangeTeamNotify.proto | 6 + .../TowerRecordHandbookReq.proto | 6 + NahidaImpact.Protocol/TowerSurrenderReq.proto | 6 + NahidaImpact.Protocol/TrackingIOInfo.proto | 4 + NahidaImpact.Protocol/TransmitReason.proto | 7 + .../TreasureMapGuideTaskDoneNotify.proto | 6 + .../TreasureMapMpChallengeNotify.proto | 6 + .../TreasureMapPreTaskDoneNotify.proto | 6 + .../TrialAvatarActivityRewardDetailInfo.proto | 9 + .../TrialAvatarGrantRecord.proto | 6 + NahidaImpact.Protocol/TrialAvatarInfo.proto | 11 + NahidaImpact.Protocol/TrifleGadget.proto | 8 + .../TryCustomDungeonType.proto | 9 + .../TryEnterNextRogueDiaryDungeonReq.proto | 6 + .../TryInterruptRogueDiaryDungeonReq.proto | 6 + NahidaImpact.Protocol/UgcType.proto | 7 + NahidaImpact.Protocol/Uint32Pair.proto | 7 + NahidaImpact.Protocol/UnionCmd.proto | 6 + NahidaImpact.Protocol/UnionCmdNotify.proto | 6 + .../UnlockTransPointReq.proto | 6 + .../UnlockTransPointRsp.proto | 6 + NahidaImpact.Protocol/Vector.proto | 7 + NahidaImpact.Protocol/Vector3Int.proto | 8 + NahidaImpact.Protocol/VectorPlane.proto | 7 + NahidaImpact.Protocol/VehicleInfo.proto | 10 + .../VehicleInteractType.proto | 8 + NahidaImpact.Protocol/VehicleMember.proto | 7 + .../VintageHuntingThirdStageInfo.proto | 5 + NahidaImpact.Protocol/VisionType.proto | 25 + .../WaterSpritePhaseFinishNotify.proto | 6 + NahidaImpact.Protocol/Weapon.proto | 8 + NahidaImpact.Protocol/WearEquipReq.proto | 6 + NahidaImpact.Protocol/WearEquipRsp.proto | 9 + NahidaImpact.Protocol/WeatherInfo.proto | 5 + .../WeeklyBossResinDiscountInfo.proto | 8 + .../WidgetCreatorOpType.proto | 8 + NahidaImpact.Protocol/WidgetDoBagReq.proto | 5 + NahidaImpact.Protocol/WidgetDoBagRsp.proto | 6 + NahidaImpact.Protocol/WidgetExtraCdType.proto | 7 + .../WidgetSlotChangeNotify.proto | 9 + NahidaImpact.Protocol/WidgetSlotData.proto | 11 + NahidaImpact.Protocol/WidgetSlotOp.proto | 6 + NahidaImpact.Protocol/WidgetSlotTag.proto | 9 + .../WindFieldDungeonFailReason.proto | 10 + .../WindFieldRestartDungeonReq.proto | 6 + .../WindSeedType1Notify.proto | 7 + .../WinterCampAcceptAllGiveItemReq.proto | 6 + .../WinterCampGetCanGiveFriendItemReq.proto | 6 + .../WinterCampGetFriendWishListReq.proto | 6 + .../WinterCampGetRecvItemListReq.proto | 6 + NahidaImpact.Protocol/WorktopInfo.proto | 6 + NahidaImpact.Protocol/WorldDataNotify.proto | 8 + .../WorldPlayerInfoNotify.proto | 11 + .../WorldPlayerReviveReq.proto | 6 + NahidaImpact.Protocol/proto_4.2.5.zip | Bin 0 -> 253831 bytes NahidaImpact.Proxy/NahidaImpact.Proxy.csproj | 14 + NahidaImpact.Proxy/Program.cs | 18 + NahidaImpact.Proxy/ProxyService.cs | 94 + NahidaImpact.SDK/Handlers/AuthHandler.cs | 50 + NahidaImpact.SDK/Handlers/RegionHandler.cs | 49 + NahidaImpact.SDK/Models/AuthAccountData.cs | 24 + NahidaImpact.SDK/Models/AuthSuccessData.cs | 21 + .../Models/GranterLoginRequest.cs | 18 + .../Models/ShieldApiAuthResponse.cs | 15 + NahidaImpact.SDK/NahidaImpact.SDK.csproj | 18 + NahidaImpact.SDK/Program.cs | 25 + .../Properties/launchSettings.json | 28 + NahidaImpact.SDK/appsettings.Development.json | 8 + NahidaImpact.SDK/appsettings.json | 9 + NahidaImpact.sln | 69 + README.md | 31 + 792 files changed, 45934 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 NahidaImpact.Common/Constants/AvatarConstants.cs create mode 100644 NahidaImpact.Common/Constants/FightProp.cs create mode 100644 NahidaImpact.Common/Constants/PlayerProp.cs create mode 100644 NahidaImpact.Common/Data/Binout/Ability/AbilityData.cs create mode 100644 NahidaImpact.Common/Data/Binout/AvatarConfig.cs create mode 100644 NahidaImpact.Common/Data/Binout/BinDataCollection.cs create mode 100644 NahidaImpact.Common/Data/DataHelper.cs create mode 100644 NahidaImpact.Common/Data/Excel/Attributes/ExcelAttribute.cs create mode 100644 NahidaImpact.Common/Data/Excel/AvatarExcel.cs create mode 100644 NahidaImpact.Common/Data/Excel/ExcelItem.cs create mode 100644 NahidaImpact.Common/Data/Excel/ExcelTable.cs create mode 100644 NahidaImpact.Common/Data/Excel/ExcelTableCollection.cs create mode 100644 NahidaImpact.Common/Data/Excel/ExcelType.cs create mode 100644 NahidaImpact.Common/Data/Provider/IAssetProvider.cs create mode 100644 NahidaImpact.Common/Data/Provider/LocalAssetProvider.cs create mode 100644 NahidaImpact.Common/Data/Provider/ServiceCollectionExtensions.cs create mode 100644 NahidaImpact.Common/Extensions/StringExtensions.cs create mode 100644 NahidaImpact.Common/NahidaImpact.Common.csproj create mode 100644 NahidaImpact.Common/Security/MhySecurity.cs create mode 100644 NahidaImpact.Common/Security/Util/MT19937.cs create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Albedo.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Alhatham.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Aloy.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ambor.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ayaka.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ayato.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Baizhuer.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Barbara.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Beidou.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Bennett.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Candace.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Charlotte.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Chevreuse.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Chongyun.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Collei.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Cyno.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Dehya.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Diluc.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Diona.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Dori.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Eula.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Faruzan.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Feiyan.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Fischl.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Freminet.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Furina.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Gaming.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ganyu.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Gorou.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Heizo.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Hutao.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Itto.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kaeya.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kaveh.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kazuha.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Keqing.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Klee.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kokomi.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Layla.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Linette.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Liney.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Lisa.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Liuyun.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Mika.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Momoka.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Mona.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Nahida.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Navia.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Neuvillette.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Nilou.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ningguang.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Noel.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_PlayerBoy.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Qin.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Qiqi.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Razor.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Rosaria.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Sara.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Sayu.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Shenhe.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Shinobu.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Shougun.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Sucrose.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Tartaglia.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Tighnari.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Tohma.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Venti.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Wanderer.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Wriothesley.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xiangling.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xiao.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xingqiu.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xinyan.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yae.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yaoyao.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yelan.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yoimiya.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yunjin.json create mode 100644 NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Zhongli.json create mode 100644 NahidaImpact.Common/assets/excel/AvatarExcelConfigData.json create mode 100644 NahidaImpact.Common/assets/security/client_public_key.der create mode 100644 NahidaImpact.Common/assets/security/initial_key.bin create mode 100644 NahidaImpact.Common/assets/security/initial_key.ec2b create mode 100644 NahidaImpact.Gameserver/Controllers/AccountController.cs create mode 100644 NahidaImpact.Gameserver/Controllers/Attributes/NetCommandAttribute.cs create mode 100644 NahidaImpact.Gameserver/Controllers/Attributes/NetControllerAttribute.cs create mode 100644 NahidaImpact.Gameserver/Controllers/AvatarController.cs create mode 100644 NahidaImpact.Gameserver/Controllers/ControllerBase.cs create mode 100644 NahidaImpact.Gameserver/Controllers/Dispatching/NetCommandDispatcher.cs create mode 100644 NahidaImpact.Gameserver/Controllers/Result/IResult.cs create mode 100644 NahidaImpact.Gameserver/Controllers/Result/SinglePacketResult.cs create mode 100644 NahidaImpact.Gameserver/Controllers/SceneController.cs create mode 100644 NahidaImpact.Gameserver/Game/Avatar/GameAvatar.cs create mode 100644 NahidaImpact.Gameserver/Game/Avatar/GameAvatarTeam.cs create mode 100644 NahidaImpact.Gameserver/Game/Entity/AvatarEntity.cs create mode 100644 NahidaImpact.Gameserver/Game/Entity/EntityManager.cs create mode 100644 NahidaImpact.Gameserver/Game/Entity/Factory/EntityFactory.cs create mode 100644 NahidaImpact.Gameserver/Game/Entity/Listener/IEntityEventListener.cs create mode 100644 NahidaImpact.Gameserver/Game/Entity/SceneEntity.cs create mode 100644 NahidaImpact.Gameserver/Game/Player.cs create mode 100644 NahidaImpact.Gameserver/Game/Scene/SceneEnterState.cs create mode 100644 NahidaImpact.Gameserver/Game/Scene/SceneManager.cs create mode 100644 NahidaImpact.Gameserver/GameServer.cs create mode 100644 NahidaImpact.Gameserver/NahidaImpact.Gameserver.csproj create mode 100644 NahidaImpact.Gameserver/Network/IGateway.cs create mode 100644 NahidaImpact.Gameserver/Network/INetworkUnit.cs create mode 100644 NahidaImpact.Gameserver/Network/Kcp/KcpGateway.cs create mode 100644 NahidaImpact.Gameserver/Network/Kcp/KcpHandshake.cs create mode 100644 NahidaImpact.Gameserver/Network/Kcp/KcpNetworkUnit.cs create mode 100644 NahidaImpact.Gameserver/Network/Kcp/KcpSession.cs create mode 100644 NahidaImpact.Gameserver/Network/NetPacket.cs create mode 100644 NahidaImpact.Gameserver/Network/NetSessionManager.cs create mode 100644 NahidaImpact.Gameserver/Network/Session/NetSession.cs create mode 100644 NahidaImpact.Gameserver/Network/Session/SessionEntityEventListener.cs create mode 100644 NahidaImpact.Gameserver/Options/GatewayOptions.cs create mode 100644 NahidaImpact.Gameserver/Program.cs create mode 100644 NahidaImpact.Gameserver/appsettings.json create mode 100644 NahidaImpact.Kcp/ArrayMemoryOwner.cs create mode 100644 NahidaImpact.Kcp/AsyncAutoResetEvent.cs create mode 100644 NahidaImpact.Kcp/DefaultArrayPoolBufferAllocator.cs create mode 100644 NahidaImpact.Kcp/IKcpBufferPool.cs create mode 100644 NahidaImpact.Kcp/IKcpConversation.cs create mode 100644 NahidaImpact.Kcp/IKcpConversationUpdateNotificationSource.cs create mode 100644 NahidaImpact.Kcp/IKcpExceptionProducer.cs create mode 100644 NahidaImpact.Kcp/IKcpMultiplexConnection.cs create mode 100644 NahidaImpact.Kcp/IKcpMultiplexConnectionOfT.cs create mode 100644 NahidaImpact.Kcp/IKcpTransport.cs create mode 100644 NahidaImpact.Kcp/IKcpTransportOfT.cs create mode 100644 NahidaImpact.Kcp/KcpAcknowledgeList.cs create mode 100644 NahidaImpact.Kcp/KcpBuffer.cs create mode 100644 NahidaImpact.Kcp/KcpBufferPoolRentOptions.cs create mode 100644 NahidaImpact.Kcp/KcpCommand.cs create mode 100644 NahidaImpact.Kcp/KcpConversation.FlushAsyncMethodBuilder.cs create mode 100644 NahidaImpact.Kcp/KcpConversation.cs create mode 100644 NahidaImpact.Kcp/KcpConversationOptions.cs create mode 100644 NahidaImpact.Kcp/KcpConversationReceiveResult.cs create mode 100644 NahidaImpact.Kcp/KcpConversationUpdateActivation.cs create mode 100644 NahidaImpact.Kcp/KcpConversationUpdateNotification.cs create mode 100644 NahidaImpact.Kcp/KcpExceptionProducerExtensions.cs create mode 100644 NahidaImpact.Kcp/KcpGlobalVars.cs create mode 100644 NahidaImpact.Kcp/KcpKeepAliveOptions.cs create mode 100644 NahidaImpact.Kcp/KcpMultiplexConnection.cs create mode 100644 NahidaImpact.Kcp/KcpPacketHeader.cs create mode 100644 NahidaImpact.Kcp/KcpProbeType.cs create mode 100644 NahidaImpact.Kcp/KcpRawChannel.cs create mode 100644 NahidaImpact.Kcp/KcpRawChannelOptions.cs create mode 100644 NahidaImpact.Kcp/KcpRawReceiveQueue.cs create mode 100644 NahidaImpact.Kcp/KcpRawSendOperation.cs create mode 100644 NahidaImpact.Kcp/KcpReceiveQueue.cs create mode 100644 NahidaImpact.Kcp/KcpReceiveWindowNotificationOptions.cs create mode 100644 NahidaImpact.Kcp/KcpRentedBuffer.cs create mode 100644 NahidaImpact.Kcp/KcpSendQueue.cs create mode 100644 NahidaImpact.Kcp/KcpSendReceiveBufferItem.cs create mode 100644 NahidaImpact.Kcp/KcpSendReceiveBufferItemCache.cs create mode 100644 NahidaImpact.Kcp/KcpSendReceiveQueueItemCache.cs create mode 100644 NahidaImpact.Kcp/KcpSendSegmentStats.cs create mode 100644 NahidaImpact.Kcp/KcpSocketTransport.cs create mode 100644 NahidaImpact.Kcp/KcpSocketTransportForConversation.cs create mode 100644 NahidaImpact.Kcp/KcpSocketTransportForMultiplexConnection.cs create mode 100644 NahidaImpact.Kcp/KcpSocketTransportForRawChannel.cs create mode 100644 NahidaImpact.Kcp/KcpSocketTransportOfT.cs create mode 100644 NahidaImpact.Kcp/KcpStream.cs create mode 100644 NahidaImpact.Kcp/NahidaImpact.Kcp.csproj create mode 100644 NahidaImpact.Kcp/ThrowHelper.cs create mode 100644 NahidaImpact.Protocol/AbilityActionCreateGadget.proto create mode 100644 NahidaImpact.Protocol/AbilityActionGenerateElemBall.proto create mode 100644 NahidaImpact.Protocol/AbilityActionSetRandomOverrideMapValue.proto create mode 100644 NahidaImpact.Protocol/AbilityAppliedAbility.proto create mode 100644 NahidaImpact.Protocol/AbilityAppliedModifier.proto create mode 100644 NahidaImpact.Protocol/AbilityAttachedModifier.proto create mode 100644 NahidaImpact.Protocol/AbilityBornType.proto create mode 100644 NahidaImpact.Protocol/AbilityControlBlock.proto create mode 100644 NahidaImpact.Protocol/AbilityEmbryo.proto create mode 100644 NahidaImpact.Protocol/AbilityGadgetInfo.proto create mode 100644 NahidaImpact.Protocol/AbilityInvocationsNotify.proto create mode 100644 NahidaImpact.Protocol/AbilityInvokeArgument.proto create mode 100644 NahidaImpact.Protocol/AbilityInvokeEntry.proto create mode 100644 NahidaImpact.Protocol/AbilityInvokeEntryHead.proto create mode 100644 NahidaImpact.Protocol/AbilityMetaModifierChange.proto create mode 100644 NahidaImpact.Protocol/AbilityMetaModifierDurabilityChange.proto create mode 100644 NahidaImpact.Protocol/AbilityMetaSetKilledState.proto create mode 100644 NahidaImpact.Protocol/AbilityMetaSetModifierApplyEntityId.proto create mode 100644 NahidaImpact.Protocol/AbilityMetaTriggerElementReaction.proto create mode 100644 NahidaImpact.Protocol/AbilityMetaUpdateBaseReactionDamage.proto create mode 100644 NahidaImpact.Protocol/AbilityMixinAvatarSteerByCamera.proto create mode 100644 NahidaImpact.Protocol/AbilityMixinFieldEntityCountChange.proto create mode 100644 NahidaImpact.Protocol/AbilityMixinRecoverInfo.proto create mode 100644 NahidaImpact.Protocol/AbilityScalarType.proto create mode 100644 NahidaImpact.Protocol/AbilityScalarValueEntry.proto create mode 100644 NahidaImpact.Protocol/AbilityString.proto create mode 100644 NahidaImpact.Protocol/AbilitySyncStateInfo.proto create mode 100644 NahidaImpact.Protocol/ActivityDungeonAvatar.proto create mode 100644 NahidaImpact.Protocol/ActivityInfo.proto create mode 100644 NahidaImpact.Protocol/ActivityInfoNotify.proto create mode 100644 NahidaImpact.Protocol/ActivityPushTipsState.proto create mode 100644 NahidaImpact.Protocol/AddBackupAvatarTeamReq.proto create mode 100644 NahidaImpact.Protocol/AdjustTrackingInfo.proto create mode 100644 NahidaImpact.Protocol/AllWidgetBackgroundActiveStateNotify.proto create mode 100644 NahidaImpact.Protocol/AnimatorParameterValueInfo.proto create mode 100644 NahidaImpact.Protocol/AnimatorParameterValueInfoPair.proto create mode 100644 NahidaImpact.Protocol/AranaraCollectionState.proto create mode 100644 NahidaImpact.Protocol/AreaPlayType.proto create mode 100644 NahidaImpact.Protocol/AsterLittleStageState.proto create mode 100644 NahidaImpact.Protocol/AttackResult.proto create mode 100644 NahidaImpact.Protocol/AuditState.proto create mode 100644 NahidaImpact.Protocol/AvatarAddNotify.proto create mode 100644 NahidaImpact.Protocol/AvatarBuffAddNotify.proto create mode 100644 NahidaImpact.Protocol/AvatarBuffDelNotify.proto create mode 100644 NahidaImpact.Protocol/AvatarChangeAnimHashReq.proto create mode 100644 NahidaImpact.Protocol/AvatarChangeAnimHashRsp.proto create mode 100644 NahidaImpact.Protocol/AvatarDataNotify.proto create mode 100644 NahidaImpact.Protocol/AvatarDieAnimationEndReq.proto create mode 100644 NahidaImpact.Protocol/AvatarDieAnimationEndRsp.proto create mode 100644 NahidaImpact.Protocol/AvatarEnterSceneInfo.proto create mode 100644 NahidaImpact.Protocol/AvatarEquipAffixInfo.proto create mode 100644 NahidaImpact.Protocol/AvatarEquipChangeNotify.proto create mode 100644 NahidaImpact.Protocol/AvatarExcelInfo.proto create mode 100644 NahidaImpact.Protocol/AvatarExpeditionAllDataReq.proto create mode 100644 NahidaImpact.Protocol/AvatarExpeditionInfo.proto create mode 100644 NahidaImpact.Protocol/AvatarExpeditionState.proto create mode 100644 NahidaImpact.Protocol/AvatarFetterInfo.proto create mode 100644 NahidaImpact.Protocol/AvatarFightPropNotify.proto create mode 100644 NahidaImpact.Protocol/AvatarFightPropUpdateNotify.proto create mode 100644 NahidaImpact.Protocol/AvatarFlycloakChangeNotify.proto create mode 100644 NahidaImpact.Protocol/AvatarInfo.proto create mode 100644 NahidaImpact.Protocol/AvatarLifeStateChangeNotify.proto create mode 100644 NahidaImpact.Protocol/AvatarRenameInfo.proto create mode 100644 NahidaImpact.Protocol/AvatarSkillInfo.proto create mode 100644 NahidaImpact.Protocol/AvatarTeam.proto create mode 100644 NahidaImpact.Protocol/AvatarTeamUpdateNotify.proto create mode 100644 NahidaImpact.Protocol/AvatarType.proto create mode 100644 NahidaImpact.Protocol/AvatarWearFlycloakReq.proto create mode 100644 NahidaImpact.Protocol/AvatarWearFlycloakRsp.proto create mode 100644 NahidaImpact.Protocol/BackMyWorldReq.proto create mode 100644 NahidaImpact.Protocol/BargainResultType.proto create mode 100644 NahidaImpact.Protocol/BattlePassUnlockStatus.proto create mode 100644 NahidaImpact.Protocol/Birthday.proto create mode 100644 NahidaImpact.Protocol/BlessingAcceptAllGivePicReq.proto create mode 100644 NahidaImpact.Protocol/BlessingGetAllRecvPicRecordListReq.proto create mode 100644 NahidaImpact.Protocol/BlessingGetFriendPicListReq.proto create mode 100644 NahidaImpact.Protocol/BlessingRedeemRewardReq.proto create mode 100644 NahidaImpact.Protocol/BlockInfo.proto create mode 100644 NahidaImpact.Protocol/BlossomChestInfo.proto create mode 100644 NahidaImpact.Protocol/BonusActivityInfoReq.proto create mode 100644 NahidaImpact.Protocol/BossChestInfo.proto create mode 100644 NahidaImpact.Protocol/BreakoutAction.proto create mode 100644 NahidaImpact.Protocol/BreakoutBrickInfo.proto create mode 100644 NahidaImpact.Protocol/BreakoutElementReactionCounter.proto create mode 100644 NahidaImpact.Protocol/BreakoutPhysicalObject.proto create mode 100644 NahidaImpact.Protocol/BreakoutPhysicalObjectModifier.proto create mode 100644 NahidaImpact.Protocol/BreakoutSnapShot.proto create mode 100644 NahidaImpact.Protocol/BreakoutSpawnPoint.proto create mode 100644 NahidaImpact.Protocol/BreakoutSyncConnectUidInfo.proto create mode 100644 NahidaImpact.Protocol/BreakoutVector2.proto create mode 100644 NahidaImpact.Protocol/BrickBreakerQuitReq.proto create mode 100644 NahidaImpact.Protocol/BrickBreakerSetReadyReq.proto create mode 100644 NahidaImpact.Protocol/BrickBreakerStageType.proto create mode 100644 NahidaImpact.Protocol/BrickBreakerTwiceStartReq.proto create mode 100644 NahidaImpact.Protocol/BuyResinReq.proto create mode 100644 NahidaImpact.Protocol/ChallengeFinishType.proto create mode 100644 NahidaImpact.Protocol/ChangeAvatarReq.proto create mode 100644 NahidaImpact.Protocol/ChangeAvatarRsp.proto create mode 100644 NahidaImpact.Protocol/ChangeEnergyReason.proto create mode 100644 NahidaImpact.Protocol/ChangeHpDebts.proto create mode 100644 NahidaImpact.Protocol/ChangeHpReason.proto create mode 100644 NahidaImpact.Protocol/ChangeServerGlobalValueNotify.proto create mode 100644 NahidaImpact.Protocol/ChangeWidgetBackgroundActiveStateReq.proto create mode 100644 NahidaImpact.Protocol/ChangeWidgetBackgroundActiveStateRsp.proto create mode 100644 NahidaImpact.Protocol/ChangeWorldToSingleModeNotify.proto create mode 100644 NahidaImpact.Protocol/ChangeWorldToSingleModeReq.proto create mode 100644 NahidaImpact.Protocol/ChannellerSlabCheckEnterLoopDungeonReq.proto create mode 100644 NahidaImpact.Protocol/ChannellerSlabOneOffDungeonInfoReq.proto create mode 100644 NahidaImpact.Protocol/ChapterState.proto create mode 100644 NahidaImpact.Protocol/ChatChannelInfo.proto create mode 100644 NahidaImpact.Protocol/ChatInfo.proto create mode 100644 NahidaImpact.Protocol/CheckUgcStateReq.proto create mode 100644 NahidaImpact.Protocol/ChessManualRefreshCardsReq.proto create mode 100644 NahidaImpact.Protocol/CityInfo.proto create mode 100644 NahidaImpact.Protocol/ClientBulletCreateNotify.proto create mode 100644 NahidaImpact.Protocol/ClientGadgetInfo.proto create mode 100644 NahidaImpact.Protocol/ClientInputType.proto create mode 100644 NahidaImpact.Protocol/ClientMassiveEntity.proto create mode 100644 NahidaImpact.Protocol/ClientReconnectReason.proto create mode 100644 NahidaImpact.Protocol/CloseCommonTipsNotify.proto create mode 100644 NahidaImpact.Protocol/CmdType.cs create mode 100644 NahidaImpact.Protocol/CodexType.proto create mode 100644 NahidaImpact.Protocol/CoinCollectOperatorInfo.proto create mode 100644 NahidaImpact.Protocol/CoinCollectPrepareReq.proto create mode 100644 NahidaImpact.Protocol/CombatInvocationsNotify.proto create mode 100644 NahidaImpact.Protocol/CombatInvokeEntry.proto create mode 100644 NahidaImpact.Protocol/CombatTypeArgument.proto create mode 100644 NahidaImpact.Protocol/CompoundBoostTakeStatusType.proto create mode 100644 NahidaImpact.Protocol/ContentAuditInfo.proto create mode 100644 NahidaImpact.Protocol/CreateReason.proto create mode 100644 NahidaImpact.Protocol/CrystalLinkRestartDungeonReq.proto create mode 100644 NahidaImpact.Protocol/CurVehicleInfo.proto create mode 100644 NahidaImpact.Protocol/CustomCommonNodeInfo.proto create mode 100644 NahidaImpact.Protocol/CustomDungeonBanType.proto create mode 100644 NahidaImpact.Protocol/CustomDungeonFinishType.proto create mode 100644 NahidaImpact.Protocol/CustomDungeonState.proto create mode 100644 NahidaImpact.Protocol/CustomGadgetTreeInfo.proto create mode 100644 NahidaImpact.Protocol/DealAddFriendResultType.proto create mode 100644 NahidaImpact.Protocol/DeshretObeliskGadgetInfo.proto create mode 100644 NahidaImpact.Protocol/DoSetPlayerBornDataNotify.proto create mode 100644 NahidaImpact.Protocol/DraftInviteFailReason.proto create mode 100644 NahidaImpact.Protocol/DuelHeartCgEndNotify.proto create mode 100644 NahidaImpact.Protocol/DuelHeartRestartDungeonReq.proto create mode 100644 NahidaImpact.Protocol/DungeonCandidateTeamDismissReason.proto create mode 100644 NahidaImpact.Protocol/DungeonCandidateTeamLeaveReq.proto create mode 100644 NahidaImpact.Protocol/DungeonCandidateTeamPlayerLeaveReason.proto create mode 100644 NahidaImpact.Protocol/DungeonCandidateTeamPlayerState.proto create mode 100644 NahidaImpact.Protocol/DungeonEntryBlockReason.proto create mode 100644 NahidaImpact.Protocol/DungeonGetStatueDropReq.proto create mode 100644 NahidaImpact.Protocol/DungeonPlayerDieReq.proto create mode 100644 NahidaImpact.Protocol/DungeonPlayerDieRsp.proto create mode 100644 NahidaImpact.Protocol/DungeonRestartReq.proto create mode 100644 NahidaImpact.Protocol/EchoShellInfo.proto create mode 100644 NahidaImpact.Protocol/EffigyChallengeV2RestartDungeonReq.proto create mode 100644 NahidaImpact.Protocol/EndCameraSceneLookNotify.proto create mode 100644 NahidaImpact.Protocol/EnterCustomDungeonType.proto create mode 100644 NahidaImpact.Protocol/EnterSceneDoneReq.proto create mode 100644 NahidaImpact.Protocol/EnterSceneDoneRsp.proto create mode 100644 NahidaImpact.Protocol/EnterScenePeerNotify.proto create mode 100644 NahidaImpact.Protocol/EnterSceneReadyReq.proto create mode 100644 NahidaImpact.Protocol/EnterSceneReadyRsp.proto create mode 100644 NahidaImpact.Protocol/EnterTransPointRegionNotify.proto create mode 100644 NahidaImpact.Protocol/EnterType.proto create mode 100644 NahidaImpact.Protocol/EntityAiKillSelfNotify.proto create mode 100644 NahidaImpact.Protocol/EntityAuthorityInfo.proto create mode 100644 NahidaImpact.Protocol/EntityClientData.proto create mode 100644 NahidaImpact.Protocol/EntityClientExtraInfo.proto create mode 100644 NahidaImpact.Protocol/EntityEnvironmentInfo.proto create mode 100644 NahidaImpact.Protocol/EntityFightPropChangeReasonNotify.proto create mode 100644 NahidaImpact.Protocol/EntityFightPropNotify.proto create mode 100644 NahidaImpact.Protocol/EntityFightPropUpdateNotify.proto create mode 100644 NahidaImpact.Protocol/EntityJumpNotify.proto create mode 100644 NahidaImpact.Protocol/EntityMoveInfo.proto create mode 100644 NahidaImpact.Protocol/EntityRendererChangedInfo.proto create mode 100644 NahidaImpact.Protocol/Equip.proto create mode 100644 NahidaImpact.Protocol/EquipParam.proto create mode 100644 NahidaImpact.Protocol/EventTriggerType.proto create mode 100644 NahidaImpact.Protocol/EvtAnimatorParameterInfo.proto create mode 100644 NahidaImpact.Protocol/EvtAvatarLockChairReq.proto create mode 100644 NahidaImpact.Protocol/EvtAvatarLockChairRsp.proto create mode 100644 NahidaImpact.Protocol/EvtBeingHitInfo.proto create mode 100644 NahidaImpact.Protocol/EvtCostStaminaNotify.proto create mode 100644 NahidaImpact.Protocol/EvtCreateGadgetNotify.proto create mode 100644 NahidaImpact.Protocol/EvtDestroyGadgetNotify.proto create mode 100644 NahidaImpact.Protocol/EvtDestroyServerGadgetNotify.proto create mode 100644 NahidaImpact.Protocol/EvtDoSkillSuccNotify.proto create mode 100644 NahidaImpact.Protocol/EvtEntityStartDieEndNotify.proto create mode 100644 NahidaImpact.Protocol/EvtFaceToDirInfo.proto create mode 100644 NahidaImpact.Protocol/EvtFixedRushMove.proto create mode 100644 NahidaImpact.Protocol/EvtSetAttackTargetInfo.proto create mode 100644 NahidaImpact.Protocol/ExhibitionDisplayInfo.proto create mode 100644 NahidaImpact.Protocol/ExitCustomDungeonTryReq.proto create mode 100644 NahidaImpact.Protocol/ExitFishingReq.proto create mode 100644 NahidaImpact.Protocol/ExitTransPointRegionNotify.proto create mode 100644 NahidaImpact.Protocol/ExpeditionState.proto create mode 100644 NahidaImpact.Protocol/FeatureBlockInfo.proto create mode 100644 NahidaImpact.Protocol/FetterData.proto create mode 100644 NahidaImpact.Protocol/FightPropPair.proto create mode 100644 NahidaImpact.Protocol/FindHilichurlAcceptQuestNotify.proto create mode 100644 NahidaImpact.Protocol/FireworksLaunchParamType.proto create mode 100644 NahidaImpact.Protocol/FireworksReformParamType.proto create mode 100644 NahidaImpact.Protocol/FishBattleBeginReq.proto create mode 100644 NahidaImpact.Protocol/FishBattleResult.proto create mode 100644 NahidaImpact.Protocol/FishBiteReq.proto create mode 100644 NahidaImpact.Protocol/FishEscapeReason.proto create mode 100644 NahidaImpact.Protocol/FishPoolInfo.proto create mode 100644 NahidaImpact.Protocol/FishtankFishInfo.proto create mode 100644 NahidaImpact.Protocol/FleurFairFinishGalleryStageNotify.proto create mode 100644 NahidaImpact.Protocol/ForceDragBackTransferNotify.proto create mode 100644 NahidaImpact.Protocol/ForceUpdateInfo.proto create mode 100644 NahidaImpact.Protocol/ForgeGetQueueDataReq.proto create mode 100644 NahidaImpact.Protocol/ForgeQueueManipulateType.proto create mode 100644 NahidaImpact.Protocol/ForwardType.proto create mode 100644 NahidaImpact.Protocol/FoundationInfo.proto create mode 100644 NahidaImpact.Protocol/FoundationOpType.proto create mode 100644 NahidaImpact.Protocol/FoundationStatus.proto create mode 100644 NahidaImpact.Protocol/FriendBrief.proto create mode 100644 NahidaImpact.Protocol/FriendEnterHomeOption.proto create mode 100644 NahidaImpact.Protocol/FriendOnlineState.proto create mode 100644 NahidaImpact.Protocol/FungusFighterRestartTraningDungeonReq.proto create mode 100644 NahidaImpact.Protocol/Furniture.proto create mode 100644 NahidaImpact.Protocol/FurnitureMakeFinishNotify.proto create mode 100644 NahidaImpact.Protocol/FurnitureMakeHelpReq.proto create mode 100644 NahidaImpact.Protocol/FurnitureMakeReq.proto create mode 100644 NahidaImpact.Protocol/GCGAskDuelReq.proto create mode 100644 NahidaImpact.Protocol/GCGClientSettleReq.proto create mode 100644 NahidaImpact.Protocol/GCGDiceSideType.proto create mode 100644 NahidaImpact.Protocol/GCGEndReason.proto create mode 100644 NahidaImpact.Protocol/GCGGameMaxNotify.proto create mode 100644 NahidaImpact.Protocol/GCGInitFinishReq.proto create mode 100644 NahidaImpact.Protocol/GCGIntentionChangeType.proto create mode 100644 NahidaImpact.Protocol/GCGMsgPhaseContinue.proto create mode 100644 NahidaImpact.Protocol/GCGOperationPass.proto create mode 100644 NahidaImpact.Protocol/GCGOperationSurrender.proto create mode 100644 NahidaImpact.Protocol/GCGPhaseType.proto create mode 100644 NahidaImpact.Protocol/GCGReason.proto create mode 100644 NahidaImpact.Protocol/GCGSettleOption.proto create mode 100644 NahidaImpact.Protocol/GCGSkillHpChangeType.proto create mode 100644 NahidaImpact.Protocol/GCGSkillPreviewAskReq.proto create mode 100644 NahidaImpact.Protocol/GCGWorldPlayerGCGStateReq.proto create mode 100644 NahidaImpact.Protocol/GCGZoneType.proto create mode 100644 NahidaImpact.Protocol/GachaActivityCreateRobotReq.proto create mode 100644 NahidaImpact.Protocol/GachaActivityNextStageReq.proto create mode 100644 NahidaImpact.Protocol/GadgetBornType.proto create mode 100644 NahidaImpact.Protocol/GadgetCrucibleInfo.proto create mode 100644 NahidaImpact.Protocol/GadgetGeneralRewardInfo.proto create mode 100644 NahidaImpact.Protocol/GadgetPlayInfo.proto create mode 100644 NahidaImpact.Protocol/GalleryStageType.proto create mode 100644 NahidaImpact.Protocol/GalleryStartSource.proto create mode 100644 NahidaImpact.Protocol/GatherGadgetInfo.proto create mode 100644 NahidaImpact.Protocol/GearActivityStartPlayPictureReq.proto create mode 100644 NahidaImpact.Protocol/GetActivityScheduleReq.proto create mode 100644 NahidaImpact.Protocol/GetAllActivatedBargainDataReq.proto create mode 100644 NahidaImpact.Protocol/GetAllH5ActivityInfoReq.proto create mode 100644 NahidaImpact.Protocol/GetAllSceneGalleryInfoReq.proto create mode 100644 NahidaImpact.Protocol/GetAllUnlockNameCardReq.proto create mode 100644 NahidaImpact.Protocol/GetAllUnlockNameCardRsp.proto create mode 100644 NahidaImpact.Protocol/GetChatEmojiCollectionReq.proto create mode 100644 NahidaImpact.Protocol/GetCityReputationMapInfoReq.proto create mode 100644 NahidaImpact.Protocol/GetCompoundDataReq.proto create mode 100644 NahidaImpact.Protocol/GetCustomDungeonReq.proto create mode 100644 NahidaImpact.Protocol/GetExpeditionAssistInfoListReq.proto create mode 100644 NahidaImpact.Protocol/GetFurnitureCurModuleArrangeCountReq.proto create mode 100644 NahidaImpact.Protocol/GetGachaInfoReq.proto create mode 100644 NahidaImpact.Protocol/GetHomeExchangeWoodInfoReq.proto create mode 100644 NahidaImpact.Protocol/GetMapAreaReq.proto create mode 100644 NahidaImpact.Protocol/GetMapMarkTipsReq.proto create mode 100644 NahidaImpact.Protocol/GetMechanicusInfoReq.proto create mode 100644 NahidaImpact.Protocol/GetNextResourceInfoReq.proto create mode 100644 NahidaImpact.Protocol/GetOnlinePlayerListReq.proto create mode 100644 NahidaImpact.Protocol/GetOpActivityInfoReq.proto create mode 100644 NahidaImpact.Protocol/GetPlayerAskFriendListReq.proto create mode 100644 NahidaImpact.Protocol/GetPlayerAskFriendListRsp.proto create mode 100644 NahidaImpact.Protocol/GetPlayerBlacklistReq.proto create mode 100644 NahidaImpact.Protocol/GetPlayerBlacklistRsp.proto create mode 100644 NahidaImpact.Protocol/GetPlayerFriendListReq.proto create mode 100644 NahidaImpact.Protocol/GetPlayerFriendListRsp.proto create mode 100644 NahidaImpact.Protocol/GetPlayerHomeCompInfoReq.proto create mode 100644 NahidaImpact.Protocol/GetPlayerMpModeAvailabilityReq.proto create mode 100644 NahidaImpact.Protocol/GetPlayerSocialDetailReq.proto create mode 100644 NahidaImpact.Protocol/GetPlayerSocialDetailRsp.proto create mode 100644 NahidaImpact.Protocol/GetPlayerTokenReq.proto create mode 100644 NahidaImpact.Protocol/GetPlayerTokenRsp.proto create mode 100644 NahidaImpact.Protocol/GetRecentMpPlayerListReq.proto create mode 100644 NahidaImpact.Protocol/GetRegionSearchReq.proto create mode 100644 NahidaImpact.Protocol/GetRogueDairyRepairInfoReq.proto create mode 100644 NahidaImpact.Protocol/GetSceneAreaReq.proto create mode 100644 NahidaImpact.Protocol/GetSceneAreaRsp.proto create mode 100644 NahidaImpact.Protocol/GetScenePerformanceReq.proto create mode 100644 NahidaImpact.Protocol/GetScenePointReq.proto create mode 100644 NahidaImpact.Protocol/GetScenePointRsp.proto create mode 100644 NahidaImpact.Protocol/GetShopmallDataReq.proto create mode 100644 NahidaImpact.Protocol/GetStoreCustomDungeonReq.proto create mode 100644 NahidaImpact.Protocol/GetUgcType.proto create mode 100644 NahidaImpact.Protocol/GetWidgetSlotReq.proto create mode 100644 NahidaImpact.Protocol/GetWorldMpInfoReq.proto create mode 100644 NahidaImpact.Protocol/GiveUpRoguelikeDungeonCardReq.proto create mode 100644 NahidaImpact.Protocol/HideAndSeekSetReadyReq.proto create mode 100644 NahidaImpact.Protocol/HideAndSeekStageType.proto create mode 100644 NahidaImpact.Protocol/HitColliderType.proto create mode 100644 NahidaImpact.Protocol/HitCollision.proto create mode 100644 NahidaImpact.Protocol/HomeEnterEditModeFinishReq.proto create mode 100644 NahidaImpact.Protocol/HomeGetBasicInfoReq.proto create mode 100644 NahidaImpact.Protocol/HomeGetBlueprintSlotInfoReq.proto create mode 100644 NahidaImpact.Protocol/HomeGetFishFarmingInfoReq.proto create mode 100644 NahidaImpact.Protocol/HomeGetOnlineStatusReq.proto create mode 100644 NahidaImpact.Protocol/HomeLimitedShopGoodsListReq.proto create mode 100644 NahidaImpact.Protocol/HomeLimitedShopInfoReq.proto create mode 100644 NahidaImpact.Protocol/HomeMarkPointFurnitureData.proto create mode 100644 NahidaImpact.Protocol/HomeMarkPointNPCData.proto create mode 100644 NahidaImpact.Protocol/HomeMarkPointSuiteData.proto create mode 100644 NahidaImpact.Protocol/HomePlantFieldStatus.proto create mode 100644 NahidaImpact.Protocol/HomePlantInfoReq.proto create mode 100644 NahidaImpact.Protocol/HomeResourceTakeFetterExpReq.proto create mode 100644 NahidaImpact.Protocol/HomeResourceTakeHomeCoinReq.proto create mode 100644 NahidaImpact.Protocol/HomeSceneInitFinishReq.proto create mode 100644 NahidaImpact.Protocol/HostPlayerNotify.proto create mode 100644 NahidaImpact.Protocol/HuntingOfferState.proto create mode 100644 NahidaImpact.Protocol/InBattleMechanicusCardChallengeState.proto create mode 100644 NahidaImpact.Protocol/InBattleMechanicusStageType.proto create mode 100644 NahidaImpact.Protocol/InterOpType.proto create mode 100644 NahidaImpact.Protocol/InteractDailyDungeonInfoNotify.proto create mode 100644 NahidaImpact.Protocol/InteractType.proto create mode 100644 NahidaImpact.Protocol/InvestigationQuestDailyNotify.proto create mode 100644 NahidaImpact.Protocol/InvestigationReadQuestDailyNotify.proto create mode 100644 NahidaImpact.Protocol/IslandPartySailStage.proto create mode 100644 NahidaImpact.Protocol/Item.proto create mode 100644 NahidaImpact.Protocol/ItemHint.proto create mode 100644 NahidaImpact.Protocol/ItemParam.proto create mode 100644 NahidaImpact.Protocol/KeepAliveNotify.proto create mode 100644 NahidaImpact.Protocol/LanV3BoatGameStartSingleReq.proto create mode 100644 NahidaImpact.Protocol/LanV3BoatInterruptSettleStageReq.proto create mode 100644 NahidaImpact.Protocol/LanternRiteTakeSkinRewardReq.proto create mode 100644 NahidaImpact.Protocol/LastPacketPrintNotify.proto create mode 100644 NahidaImpact.Protocol/LeaveSceneReq.proto create mode 100644 NahidaImpact.Protocol/LeaveWorldNotify.proto create mode 100644 NahidaImpact.Protocol/LifeStateChangeNotify.proto create mode 100644 NahidaImpact.Protocol/LuaShellType.proto create mode 100644 NahidaImpact.Protocol/LunaRiteHintPointType.proto create mode 100644 NahidaImpact.Protocol/LunaRiteHintStatusType.proto create mode 100644 NahidaImpact.Protocol/MPLevelEntityInfo.proto create mode 100644 NahidaImpact.Protocol/MailCollectState.proto create mode 100644 NahidaImpact.Protocol/MailData.proto create mode 100644 NahidaImpact.Protocol/MailItem.proto create mode 100644 NahidaImpact.Protocol/MailTextContent.proto create mode 100644 NahidaImpact.Protocol/MapAreaInfo.proto create mode 100644 NahidaImpact.Protocol/MapMarkFromType.proto create mode 100644 NahidaImpact.Protocol/MapMarkPoint.proto create mode 100644 NahidaImpact.Protocol/MapMarkPointType.proto create mode 100644 NahidaImpact.Protocol/MapMarkTipsInfo.proto create mode 100644 NahidaImpact.Protocol/MapMarkTipsType.proto create mode 100644 NahidaImpact.Protocol/MarkMapReq.proto create mode 100644 NahidaImpact.Protocol/MassiveBoxInfo.proto create mode 100644 NahidaImpact.Protocol/MassiveEntityState.proto create mode 100644 NahidaImpact.Protocol/MassiveGrassInfo.proto create mode 100644 NahidaImpact.Protocol/MassivePropParam.proto create mode 100644 NahidaImpact.Protocol/MassivePropSyncInfo.proto create mode 100644 NahidaImpact.Protocol/MassiveWaterInfo.proto create mode 100644 NahidaImpact.Protocol/MatchReason.proto create mode 100644 NahidaImpact.Protocol/MatchType.proto create mode 100644 NahidaImpact.Protocol/Material.proto create mode 100644 NahidaImpact.Protocol/MaterialDeleteInfo.proto create mode 100644 NahidaImpact.Protocol/MaterialDeleteReturnType.proto create mode 100644 NahidaImpact.Protocol/MaterialDeleteUpdateNotify.proto create mode 100644 NahidaImpact.Protocol/MathQuaternion.proto create mode 100644 NahidaImpact.Protocol/ModifierAction.proto create mode 100644 NahidaImpact.Protocol/ModifierDurability.proto create mode 100644 NahidaImpact.Protocol/ModifierProperty.proto create mode 100644 NahidaImpact.Protocol/MonsterBornType.proto create mode 100644 NahidaImpact.Protocol/MonsterRoute.proto create mode 100644 NahidaImpact.Protocol/MotionInfo.proto create mode 100644 NahidaImpact.Protocol/MotionState.proto create mode 100644 NahidaImpact.Protocol/MovingPlatformType.proto create mode 100644 NahidaImpact.Protocol/MpPlayRewardInfo.proto create mode 100644 NahidaImpact.Protocol/MpSettingType.proto create mode 100644 NahidaImpact.Protocol/MuqadasPotionRestartDungeonReq.proto create mode 100644 NahidaImpact.Protocol/NahidaImpact.Protocol.csproj create mode 100644 NahidaImpact.Protocol/NightCrowGadgetInfo.proto create mode 100644 NahidaImpact.Protocol/NpcPositionInfo.proto create mode 100644 NahidaImpact.Protocol/NpcTalkReq.proto create mode 100644 NahidaImpact.Protocol/NpcTalkRsp.proto create mode 100644 NahidaImpact.Protocol/OfferingInfo.proto create mode 100644 NahidaImpact.Protocol/OnlinePlayerInfo.proto create mode 100644 NahidaImpact.Protocol/OpenStateChangeNotify.proto create mode 100644 NahidaImpact.Protocol/OpenStateUpdateNotify.proto create mode 100644 NahidaImpact.Protocol/OutStuckCustomDungeonReq.proto create mode 100644 NahidaImpact.Protocol/PacketHead.proto create mode 100644 NahidaImpact.Protocol/ParamList.proto create mode 100644 NahidaImpact.Protocol/PathfindingPingNotify.proto create mode 100644 NahidaImpact.Protocol/PerformOperationNotify.proto create mode 100644 NahidaImpact.Protocol/PersonalLineAllDataReq.proto create mode 100644 NahidaImpact.Protocol/PersonalSceneJumpReq.proto create mode 100644 NahidaImpact.Protocol/PersonalSceneJumpRsp.proto create mode 100644 NahidaImpact.Protocol/PingReq.proto create mode 100644 NahidaImpact.Protocol/PingRsp.proto create mode 100644 NahidaImpact.Protocol/PlaceInfo.proto create mode 100644 NahidaImpact.Protocol/PlatformInfo.proto create mode 100644 NahidaImpact.Protocol/PlatformType.proto create mode 100644 NahidaImpact.Protocol/PlayProduct.proto create mode 100644 NahidaImpact.Protocol/PlayTeamEntityInfo.proto create mode 100644 NahidaImpact.Protocol/PlayerChatCDNotify.proto create mode 100644 NahidaImpact.Protocol/PlayerChatNotify.proto create mode 100644 NahidaImpact.Protocol/PlayerDataNotify.proto create mode 100644 NahidaImpact.Protocol/PlayerDieOption.proto create mode 100644 NahidaImpact.Protocol/PlayerDieType.proto create mode 100644 NahidaImpact.Protocol/PlayerEnterSceneInfoNotify.proto create mode 100644 NahidaImpact.Protocol/PlayerEnterSceneNotify.proto create mode 100644 NahidaImpact.Protocol/PlayerForceExitReq.proto create mode 100644 NahidaImpact.Protocol/PlayerGameTimeNotify.proto create mode 100644 NahidaImpact.Protocol/PlayerGetForceQuitBanInfoReq.proto create mode 100644 NahidaImpact.Protocol/PlayerLoginReq.proto create mode 100644 NahidaImpact.Protocol/PlayerLoginRsp.proto create mode 100644 NahidaImpact.Protocol/PlayerLogoutNotify.proto create mode 100644 NahidaImpact.Protocol/PlayerLogoutReq.proto create mode 100644 NahidaImpact.Protocol/PlayerLogoutRsp.proto create mode 100644 NahidaImpact.Protocol/PlayerPropChangeNotify.proto create mode 100644 NahidaImpact.Protocol/PlayerPropNotify.proto create mode 100644 NahidaImpact.Protocol/PlayerRTTInfo.proto create mode 100644 NahidaImpact.Protocol/PlayerStoreNotify.proto create mode 100644 NahidaImpact.Protocol/PlayerWidgetInfo.proto create mode 100644 NahidaImpact.Protocol/PostEnterSceneReq.proto create mode 100644 NahidaImpact.Protocol/PostEnterSceneRsp.proto create mode 100644 NahidaImpact.Protocol/PotionRestartDungeonReq.proto create mode 100644 NahidaImpact.Protocol/PrivateChatNotify.proto create mode 100644 NahidaImpact.Protocol/PrivateChatReq.proto create mode 100644 NahidaImpact.Protocol/PrivateChatRsp.proto create mode 100644 NahidaImpact.Protocol/ProfilePicture.proto create mode 100644 NahidaImpact.Protocol/PropChangeReason.proto create mode 100644 NahidaImpact.Protocol/PropPair.proto create mode 100644 NahidaImpact.Protocol/PropValue.proto create mode 100644 NahidaImpact.Protocol/ProtEntityType.proto create mode 100644 NahidaImpact.Protocol/PullPrivateChatReq.proto create mode 100644 NahidaImpact.Protocol/PullRecentChatReq.proto create mode 100644 NahidaImpact.Protocol/QueryCurrRegionHttpRsp.proto create mode 100644 NahidaImpact.Protocol/QueryRegionListHttpRsp.proto create mode 100644 NahidaImpact.Protocol/Quest.proto create mode 100644 NahidaImpact.Protocol/ReadNicknameAuditReq.proto create mode 100644 NahidaImpact.Protocol/ReadPrivateChatReq.proto create mode 100644 NahidaImpact.Protocol/ReadPrivateChatRsp.proto create mode 100644 NahidaImpact.Protocol/ReadSignatureAuditReq.proto create mode 100644 NahidaImpact.Protocol/RecordUsage.proto create mode 100644 NahidaImpact.Protocol/RedPointData.proto create mode 100644 NahidaImpact.Protocol/RedeemLegendaryKeyReq.proto create mode 100644 NahidaImpact.Protocol/RefreshBackgroundAvatarReq.proto create mode 100644 NahidaImpact.Protocol/RefreshRoguelikeDungeonCardReq.proto create mode 100644 NahidaImpact.Protocol/RegionInfo.proto create mode 100644 NahidaImpact.Protocol/RegionSearchState.proto create mode 100644 NahidaImpact.Protocol/RegionSimpleInfo.proto create mode 100644 NahidaImpact.Protocol/Reliquary.proto create mode 100644 NahidaImpact.Protocol/ReplayCustomDungeonReq.proto create mode 100644 NahidaImpact.Protocol/ReportReasonType.proto create mode 100644 NahidaImpact.Protocol/ResVersionConfig.proto create mode 100644 NahidaImpact.Protocol/ResinCostType.proto create mode 100644 NahidaImpact.Protocol/RestartEffigyChallengeReq.proto create mode 100644 NahidaImpact.Protocol/Retcode.cs create mode 100644 NahidaImpact.Protocol/Retcode.proto create mode 100644 NahidaImpact.Protocol/RetryCurRogueDiaryDungeonReq.proto create mode 100644 NahidaImpact.Protocol/ReunionBriefInfoReq.proto create mode 100644 NahidaImpact.Protocol/ReunionSettleNotify.proto create mode 100644 NahidaImpact.Protocol/Reward.proto create mode 100644 NahidaImpact.Protocol/RogueCellState.proto create mode 100644 NahidaImpact.Protocol/RogueDiaryAvatarDisableStatus.proto create mode 100644 NahidaImpact.Protocol/RogueEliteCellDifficultyType.proto create mode 100644 NahidaImpact.Protocol/RoguelikeGadgetInfo.proto create mode 100644 NahidaImpact.Protocol/RoguelikeMistClearNotify.proto create mode 100644 NahidaImpact.Protocol/Route.proto create mode 100644 NahidaImpact.Protocol/RoutePoint.proto create mode 100644 NahidaImpact.Protocol/SalesmanStatusType.proto create mode 100644 NahidaImpact.Protocol/SalvageEscortStopReason.proto create mode 100644 NahidaImpact.Protocol/SalvagePreventStopReason.proto create mode 100644 NahidaImpact.Protocol/SceneAvatarInfo.proto create mode 100644 NahidaImpact.Protocol/SceneDataNotify.proto create mode 100644 NahidaImpact.Protocol/SceneEntityAiInfo.proto create mode 100644 NahidaImpact.Protocol/SceneEntityAppearNotify.proto create mode 100644 NahidaImpact.Protocol/SceneEntityDisappearNotify.proto create mode 100644 NahidaImpact.Protocol/SceneEntityDrownReq.proto create mode 100644 NahidaImpact.Protocol/SceneEntityInfo.proto create mode 100644 NahidaImpact.Protocol/SceneFishInfo.proto create mode 100644 NahidaImpact.Protocol/SceneGadgetInfo.proto create mode 100644 NahidaImpact.Protocol/SceneInitFinishReq.proto create mode 100644 NahidaImpact.Protocol/SceneInitFinishRsp.proto create mode 100644 NahidaImpact.Protocol/SceneMonsterInfo.proto create mode 100644 NahidaImpact.Protocol/SceneNpcInfo.proto create mode 100644 NahidaImpact.Protocol/ScenePointUnlockNotify.proto create mode 100644 NahidaImpact.Protocol/SceneReliquaryInfo.proto create mode 100644 NahidaImpact.Protocol/SceneTeamAvatar.proto create mode 100644 NahidaImpact.Protocol/SceneTeamUpdateNotify.proto create mode 100644 NahidaImpact.Protocol/SceneTimeNotify.proto create mode 100644 NahidaImpact.Protocol/SceneTransToPointReq.proto create mode 100644 NahidaImpact.Protocol/SceneTransToPointRsp.proto create mode 100644 NahidaImpact.Protocol/SceneWeaponInfo.proto create mode 100644 NahidaImpact.Protocol/ScreenInfo.proto create mode 100644 NahidaImpact.Protocol/SealBattleType.proto create mode 100644 NahidaImpact.Protocol/ServantInfo.proto create mode 100644 NahidaImpact.Protocol/ServerBuff.proto create mode 100644 NahidaImpact.Protocol/ServerGlobalValueChangeNotify.proto create mode 100644 NahidaImpact.Protocol/ServerLogLevel.proto create mode 100644 NahidaImpact.Protocol/ServerLogType.proto create mode 100644 NahidaImpact.Protocol/ServerMassiveEntity.proto create mode 100644 NahidaImpact.Protocol/SetNameCardReq.proto create mode 100644 NahidaImpact.Protocol/SetNameCardRsp.proto create mode 100644 NahidaImpact.Protocol/SetOpenStateReq.proto create mode 100644 NahidaImpact.Protocol/SetOpenStateRsp.proto create mode 100644 NahidaImpact.Protocol/SetPlayerBornDataReq.proto create mode 100644 NahidaImpact.Protocol/SetPlayerBornDataRsp.proto create mode 100644 NahidaImpact.Protocol/SetPlayerNameReq.proto create mode 100644 NahidaImpact.Protocol/SetPlayerPropRsp.proto create mode 100644 NahidaImpact.Protocol/SetUpAvatarTeamReq.proto create mode 100644 NahidaImpact.Protocol/SetUpAvatarTeamRsp.proto create mode 100644 NahidaImpact.Protocol/SetWidgetSlotReq.proto create mode 100644 NahidaImpact.Protocol/SetWidgetSlotRsp.proto create mode 100644 NahidaImpact.Protocol/ShapeBox.proto create mode 100644 NahidaImpact.Protocol/ShapeSphere.proto create mode 100644 NahidaImpact.Protocol/ShopCardProduct.proto create mode 100644 NahidaImpact.Protocol/ShopConcertProduct.proto create mode 100644 NahidaImpact.Protocol/ShopMcoinProduct.proto create mode 100644 NahidaImpact.Protocol/ShortAbilityHashPair.proto create mode 100644 NahidaImpact.Protocol/ShowAvatarInfo.proto create mode 100644 NahidaImpact.Protocol/ShowEquip.proto create mode 100644 NahidaImpact.Protocol/SignInInfoReq.proto create mode 100644 NahidaImpact.Protocol/SocialDetail.proto create mode 100644 NahidaImpact.Protocol/SocialShowAvatarInfo.proto create mode 100644 NahidaImpact.Protocol/StatueGadgetInfo.proto create mode 100644 NahidaImpact.Protocol/StopServerInfo.proto create mode 100644 NahidaImpact.Protocol/StoreType.proto create mode 100644 NahidaImpact.Protocol/StoreWeightLimitNotify.proto create mode 100644 NahidaImpact.Protocol/SummerTimeV2RestartDungeonReq.proto create mode 100644 NahidaImpact.Protocol/SumoLeaveDungeonNotify.proto create mode 100644 NahidaImpact.Protocol/SumoRestartDungeonReq.proto create mode 100644 NahidaImpact.Protocol/SvrMsgId.proto create mode 100644 NahidaImpact.Protocol/TakeFirstShareRewardReq.proto create mode 100644 NahidaImpact.Protocol/TakeReunionFirstGiftRewardReq.proto create mode 100644 NahidaImpact.Protocol/TeamChainTakeCostumeRewardReq.proto create mode 100644 NahidaImpact.Protocol/TeamEnterSceneInfo.proto create mode 100644 NahidaImpact.Protocol/ToTheMoonPingNotify.proto create mode 100644 NahidaImpact.Protocol/TowerMiddleLevelChangeTeamNotify.proto create mode 100644 NahidaImpact.Protocol/TowerRecordHandbookReq.proto create mode 100644 NahidaImpact.Protocol/TowerSurrenderReq.proto create mode 100644 NahidaImpact.Protocol/TrackingIOInfo.proto create mode 100644 NahidaImpact.Protocol/TransmitReason.proto create mode 100644 NahidaImpact.Protocol/TreasureMapGuideTaskDoneNotify.proto create mode 100644 NahidaImpact.Protocol/TreasureMapMpChallengeNotify.proto create mode 100644 NahidaImpact.Protocol/TreasureMapPreTaskDoneNotify.proto create mode 100644 NahidaImpact.Protocol/TrialAvatarActivityRewardDetailInfo.proto create mode 100644 NahidaImpact.Protocol/TrialAvatarGrantRecord.proto create mode 100644 NahidaImpact.Protocol/TrialAvatarInfo.proto create mode 100644 NahidaImpact.Protocol/TrifleGadget.proto create mode 100644 NahidaImpact.Protocol/TryCustomDungeonType.proto create mode 100644 NahidaImpact.Protocol/TryEnterNextRogueDiaryDungeonReq.proto create mode 100644 NahidaImpact.Protocol/TryInterruptRogueDiaryDungeonReq.proto create mode 100644 NahidaImpact.Protocol/UgcType.proto create mode 100644 NahidaImpact.Protocol/Uint32Pair.proto create mode 100644 NahidaImpact.Protocol/UnionCmd.proto create mode 100644 NahidaImpact.Protocol/UnionCmdNotify.proto create mode 100644 NahidaImpact.Protocol/UnlockTransPointReq.proto create mode 100644 NahidaImpact.Protocol/UnlockTransPointRsp.proto create mode 100644 NahidaImpact.Protocol/Vector.proto create mode 100644 NahidaImpact.Protocol/Vector3Int.proto create mode 100644 NahidaImpact.Protocol/VectorPlane.proto create mode 100644 NahidaImpact.Protocol/VehicleInfo.proto create mode 100644 NahidaImpact.Protocol/VehicleInteractType.proto create mode 100644 NahidaImpact.Protocol/VehicleMember.proto create mode 100644 NahidaImpact.Protocol/VintageHuntingThirdStageInfo.proto create mode 100644 NahidaImpact.Protocol/VisionType.proto create mode 100644 NahidaImpact.Protocol/WaterSpritePhaseFinishNotify.proto create mode 100644 NahidaImpact.Protocol/Weapon.proto create mode 100644 NahidaImpact.Protocol/WearEquipReq.proto create mode 100644 NahidaImpact.Protocol/WearEquipRsp.proto create mode 100644 NahidaImpact.Protocol/WeatherInfo.proto create mode 100644 NahidaImpact.Protocol/WeeklyBossResinDiscountInfo.proto create mode 100644 NahidaImpact.Protocol/WidgetCreatorOpType.proto create mode 100644 NahidaImpact.Protocol/WidgetDoBagReq.proto create mode 100644 NahidaImpact.Protocol/WidgetDoBagRsp.proto create mode 100644 NahidaImpact.Protocol/WidgetExtraCdType.proto create mode 100644 NahidaImpact.Protocol/WidgetSlotChangeNotify.proto create mode 100644 NahidaImpact.Protocol/WidgetSlotData.proto create mode 100644 NahidaImpact.Protocol/WidgetSlotOp.proto create mode 100644 NahidaImpact.Protocol/WidgetSlotTag.proto create mode 100644 NahidaImpact.Protocol/WindFieldDungeonFailReason.proto create mode 100644 NahidaImpact.Protocol/WindFieldRestartDungeonReq.proto create mode 100644 NahidaImpact.Protocol/WindSeedType1Notify.proto create mode 100644 NahidaImpact.Protocol/WinterCampAcceptAllGiveItemReq.proto create mode 100644 NahidaImpact.Protocol/WinterCampGetCanGiveFriendItemReq.proto create mode 100644 NahidaImpact.Protocol/WinterCampGetFriendWishListReq.proto create mode 100644 NahidaImpact.Protocol/WinterCampGetRecvItemListReq.proto create mode 100644 NahidaImpact.Protocol/WorktopInfo.proto create mode 100644 NahidaImpact.Protocol/WorldDataNotify.proto create mode 100644 NahidaImpact.Protocol/WorldPlayerInfoNotify.proto create mode 100644 NahidaImpact.Protocol/WorldPlayerReviveReq.proto create mode 100644 NahidaImpact.Protocol/proto_4.2.5.zip create mode 100644 NahidaImpact.Proxy/NahidaImpact.Proxy.csproj create mode 100644 NahidaImpact.Proxy/Program.cs create mode 100644 NahidaImpact.Proxy/ProxyService.cs create mode 100644 NahidaImpact.SDK/Handlers/AuthHandler.cs create mode 100644 NahidaImpact.SDK/Handlers/RegionHandler.cs create mode 100644 NahidaImpact.SDK/Models/AuthAccountData.cs create mode 100644 NahidaImpact.SDK/Models/AuthSuccessData.cs create mode 100644 NahidaImpact.SDK/Models/GranterLoginRequest.cs create mode 100644 NahidaImpact.SDK/Models/ShieldApiAuthResponse.cs create mode 100644 NahidaImpact.SDK/NahidaImpact.SDK.csproj create mode 100644 NahidaImpact.SDK/Program.cs create mode 100644 NahidaImpact.SDK/Properties/launchSettings.json create mode 100644 NahidaImpact.SDK/appsettings.Development.json create mode 100644 NahidaImpact.SDK/appsettings.json create mode 100644 NahidaImpact.sln create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8a30d25 --- /dev/null +++ b/.gitignore @@ -0,0 +1,398 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0ad25db --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/NahidaImpact.Common/Constants/AvatarConstants.cs b/NahidaImpact.Common/Constants/AvatarConstants.cs new file mode 100644 index 0000000..b2f7019 --- /dev/null +++ b/NahidaImpact.Common/Constants/AvatarConstants.cs @@ -0,0 +1,25 @@ +using System.Collections.Immutable; + +namespace NahidaImpact.Common.Constants; +public static class AvatarConstants +{ + public static readonly ImmutableArray CommonAbilities = ImmutableArray.Create + ( + "Avatar_DefaultAbility_VisionReplaceDieInvincible", + "Avatar_DefaultAbility_AvartarInShaderChange", + "Avatar_SprintBS_Invincible", + "Avatar_Freeze_Duration_Reducer", + "Avatar_Attack_ReviveEnergy", + "Avatar_Component_Initializer", + "Avatar_FallAnthem_Achievement_Listener", + "GrapplingHookSkill_Ability", + "Avatar_PlayerBoy_DiveStamina_Reduction", + "Ability_Avatar_Dive_Team", + "Ability_Avatar_Dive_SealEcho", + "Absorb_SealEcho_Bullet_01", + "Absorb_SealEcho_Bullet_02", + "Ability_Avatar_Dive_CrabShield", + "ActivityAbility_Absorb_Shoot", + "SceneAbility_DiveVolume" + ); +} diff --git a/NahidaImpact.Common/Constants/FightProp.cs b/NahidaImpact.Common/Constants/FightProp.cs new file mode 100644 index 0000000..f252477 --- /dev/null +++ b/NahidaImpact.Common/Constants/FightProp.cs @@ -0,0 +1,100 @@ +namespace NahidaImpact.Common.Constants; +public static class FightProp +{ + public const uint FIGHT_PROP_NONE = 0; + public const uint FIGHT_PROP_BASE_HP = 1; + public const uint FIGHT_PROP_HP = 2; + public const uint FIGHT_PROP_HP_PERCENT = 3; + public const uint FIGHT_PROP_BASE_ATTACK = 4; + public const uint FIGHT_PROP_ATTACK = 5; + public const uint FIGHT_PROP_ATTACK_PERCENT = 6; + public const uint FIGHT_PROP_BASE_DEFENSE = 7; + public const uint FIGHT_PROP_DEFENSE = 8; + public const uint FIGHT_PROP_DEFENSE_PERCENT = 9; + public const uint FIGHT_PROP_BASE_SPEED = 10; + public const uint FIGHT_PROP_SPEED_PERCENT = 11; + public const uint FIGHT_PROP_HP_MP_PERCENT = 12; + public const uint FIGHT_PROP_ATTACK_MP_PERCENT = 13; + public const uint FIGHT_PROP_CRITICAL = 20; + public const uint FIGHT_PROP_ANTI_CRITICAL = 21; + public const uint FIGHT_PROP_CRITICAL_HURT = 22; + public const uint FIGHT_PROP_CHARGE_EFFICIENCY = 23; + public const uint FIGHT_PROP_ADD_HURT = 24; + public const uint FIGHT_PROP_SUB_HURT = 25; + public const uint FIGHT_PROP_HEAL_ADD = 26; + public const uint FIGHT_PROP_HEALED_ADD = 27; + public const uint FIGHT_PROP_ELEMENT_MASTERY = 28; + public const uint FIGHT_PROP_PHYSICAL_SUB_HURT = 29; + public const uint FIGHT_PROP_PHYSICAL_ADD_HURT = 30; + public const uint FIGHT_PROP_DEFENCE_IGNORE_RATIO = 31; + public const uint FIGHT_PROP_DEFENCE_IGNORE_DELTA = 32; + public const uint FIGHT_PROP_FIRE_ADD_HURT = 40; + public const uint FIGHT_PROP_ELEC_ADD_HURT = 41; + public const uint FIGHT_PROP_WATER_ADD_HURT = 42; + public const uint FIGHT_PROP_GRASS_ADD_HURT = 43; + public const uint FIGHT_PROP_WIND_ADD_HURT = 44; + public const uint FIGHT_PROP_ROCK_ADD_HURT = 45; + public const uint FIGHT_PROP_ICE_ADD_HURT = 46; + public const uint FIGHT_PROP_HIT_HEAD_ADD_HURT = 47; + public const uint FIGHT_PROP_FIRE_SUB_HURT = 50; + public const uint FIGHT_PROP_ELEC_SUB_HURT = 51; + public const uint FIGHT_PROP_WATER_SUB_HURT = 52; + public const uint FIGHT_PROP_GRASS_SUB_HURT = 53; + public const uint FIGHT_PROP_WIND_SUB_HURT = 54; + public const uint FIGHT_PROP_ROCK_SUB_HURT = 55; + public const uint FIGHT_PROP_ICE_SUB_HURT = 56; + public const uint FIGHT_PROP_EFFECT_HIT = 60; + public const uint FIGHT_PROP_EFFECT_RESIST = 61; + public const uint FIGHT_PROP_FREEZE_RESIST = 62; + public const uint FIGHT_PROP_TORPOR_RESIST = 63; + public const uint FIGHT_PROP_DIZZY_RESIST = 64; + public const uint FIGHT_PROP_FREEZE_SHORTEN = 65; + public const uint FIGHT_PROP_TORPOR_SHORTEN = 66; + public const uint FIGHT_PROP_DIZZY_SHORTEN = 67; + public const uint FIGHT_PROP_MAX_FIRE_ENERGY = 70; + public const uint FIGHT_PROP_MAX_ELEC_ENERGY = 71; + public const uint FIGHT_PROP_MAX_WATER_ENERGY = 72; + public const uint FIGHT_PROP_MAX_GRASS_ENERGY = 73; + public const uint FIGHT_PROP_MAX_WIND_ENERGY = 74; + public const uint FIGHT_PROP_MAX_ICE_ENERGY = 75; + public const uint FIGHT_PROP_MAX_ROCK_ENERGY = 76; + public const uint FIGHT_PROP_SKILL_CD_MINUS_RATIO = 80; + public const uint FIGHT_PROP_SHIELD_COST_MINUS_RATIO = 81; + public const uint FIGHT_PROP_CUR_FIRE_ENERGY = 1000; + public const uint FIGHT_PROP_CUR_ELEC_ENERGY = 1001; + public const uint FIGHT_PROP_CUR_WATER_ENERGY = 1002; + public const uint FIGHT_PROP_CUR_GRASS_ENERGY = 1003; + public const uint FIGHT_PROP_CUR_WIND_ENERGY = 1004; + public const uint FIGHT_PROP_CUR_ICE_ENERGY = 1005; + public const uint FIGHT_PROP_CUR_ROCK_ENERGY = 1006; + public const uint FIGHT_PROP_CUR_HP = 1010; + public const uint FIGHT_PROP_MAX_HP = 2000; + public const uint FIGHT_PROP_CUR_ATTACK = 2001; + public const uint FIGHT_PROP_CUR_DEFENSE = 2002; + public const uint FIGHT_PROP_CUR_SPEED = 2003; + public const uint FIGHT_PROP_NONEXTRA_ATTACK = 3000; + public const uint FIGHT_PROP_NONEXTRA_DEFENSE = 3001; + public const uint FIGHT_PROP_NONEXTRA_CRITICAL = 3002; + public const uint FIGHT_PROP_NONEXTRA_ANTI_CRITICAL = 3003; + public const uint FIGHT_PROP_NONEXTRA_CRITICAL_HURT = 3004; + public const uint FIGHT_PROP_NONEXTRA_CHARGE_EFFICIENCY = 3005; + public const uint FIGHT_PROP_NONEXTRA_ELEMENT_MASTERY = 3006; + public const uint FIGHT_PROP_NONEXTRA_PHYSICAL_SUB_HURT = 3007; + public const uint FIGHT_PROP_NONEXTRA_FIRE_ADD_HURT = 3008; + public const uint FIGHT_PROP_NONEXTRA_ELEC_ADD_HURT = 3009; + public const uint FIGHT_PROP_NONEXTRA_WATER_ADD_HURT = 3010; + public const uint FIGHT_PROP_NONEXTRA_GRASS_ADD_HURT = 3011; + public const uint FIGHT_PROP_NONEXTRA_WIND_ADD_HURT = 3012; + public const uint FIGHT_PROP_NONEXTRA_ROCK_ADD_HURT = 3013; + public const uint FIGHT_PROP_NONEXTRA_ICE_ADD_HURT = 3014; + public const uint FIGHT_PROP_NONEXTRA_FIRE_SUB_HURT = 3015; + public const uint FIGHT_PROP_NONEXTRA_ELEC_SUB_HURT = 3016; + public const uint FIGHT_PROP_NONEXTRA_WATER_SUB_HURT = 3017; + public const uint FIGHT_PROP_NONEXTRA_GRASS_SUB_HURT = 3018; + public const uint FIGHT_PROP_NONEXTRA_WIND_SUB_HURT = 3019; + public const uint FIGHT_PROP_NONEXTRA_ROCK_SUB_HURT = 3020; + public const uint FIGHT_PROP_NONEXTRA_ICE_SUB_HURT = 3021; + public const uint FIGHT_PROP_NONEXTRA_SKILL_CD_MINUS_RATIO = 3022; + public const uint FIGHT_PROP_NONEXTRA_SHIELD_COST_MINUS_RATIO = 3023; + public const uint FIGHT_PROP_NONEXTRA_PHYSICAL_ADD_HURT = 3024; +} diff --git a/NahidaImpact.Common/Constants/PlayerProp.cs b/NahidaImpact.Common/Constants/PlayerProp.cs new file mode 100644 index 0000000..bfbd634 --- /dev/null +++ b/NahidaImpact.Common/Constants/PlayerProp.cs @@ -0,0 +1,49 @@ +namespace NahidaImpact.Common.Constants; +public static class PlayerProp +{ + public const uint PROP_NONE = 0; + + public const uint PROP_EXP = 1001; + public const uint PROP_BREAK_LEVEL = 1002; + public const uint PROP_SATIATION_VAL = 1003; + public const uint PROP_SATIATION_PENALTY_TIME = 1004; + public const uint PROP_LEVEL = 4001; + + public const uint PROP_LAST_CHANGE_AVATAR_TIME = 10001; + public const uint PROP_MAX_SPRING_VOLUME = 10002; + public const uint PROP_CUR_SPRING_VOLUME = 10003; + public const uint PROP_IS_SPRING_AUTO_USE = 10004; + public const uint PROP_SPRING_AUTO_USE_PERCENT = 10005; + public const uint PROP_IS_FLYABLE = 10006; + public const uint PROP_IS_WEATHER_LOCKED = 10007; + public const uint PROP_IS_GAME_TIME_LOCKED = 10008; + public const uint PROP_IS_TRANSFERABLE = 10009; + public const uint PROP_MAX_STAMINA = 10010; + public const uint PROP_CUR_PERSIST_STAMINA = 10011; + public const uint PROP_CUR_TEMPORARY_STAMINA = 10012; + public const uint PROP_PLAYER_LEVEL = 10013; + public const uint PROP_PLAYER_EXP = 10014; + public const uint PROP_PLAYER_HCOIN = 10015; + public const uint PROP_PLAYER_SCOIN = 10016; + public const uint PROP_PLAYER_MP_SETTING_TYPE = 10017; + public const uint PROP_IS_MP_MODE_AVAILABLE = 10018; + public const uint PROP_PLAYER_WORLD_LEVEL = 10019; + public const uint PROP_PLAYER_RESIN = 10020; + public const uint PROP_PLAYER_WAIT_SUB_HCOIN = 10022; + public const uint PROP_PLAYER_WAIT_SUB_SCOIN = 10023; + public const uint PROP_IS_ONLY_MP_WITH_PS_PLAYER = 10024; + public const uint PROP_PLAYER_MCOIN = 10025; + public const uint PROP_PLAYER_WAIT_SUB_MCOIN = 10026; + public const uint PROP_PLAYER_LEGENDARY_KEY = 10027; + public const uint PROP_IS_HAS_FIRST_SHARE = 10028; + public const uint PROP_PLAYER_FORGE_POINT = 10029; + public const uint PROP_CUR_CLIMATE_METER = 10035; + public const uint PROP_CUR_CLIMATE_TYPE = 10036; + public const uint PROP_CUR_CLIMATE_AREA_ID = 10037; + public const uint PROP_CUR_CLIMATE_AREA_CLIMATE_TYPE = 10038; + public const uint PROP_PLAYER_WORLD_LEVEL_LIMIT = 10039; + public const uint PROP_PLAYER_WORLD_LEVEL_ADJUST_CD = 10040; + public const uint PROP_PLAYER_LEGENDARY_DAILY_TASK_NUM = 10041; + public const uint PROP_PLAYER_HOME_COIN = 10042; + public const uint PROP_PLAYER_WAIT_SUB_HOME_COIN = 10043; +} diff --git a/NahidaImpact.Common/Data/Binout/Ability/AbilityData.cs b/NahidaImpact.Common/Data/Binout/Ability/AbilityData.cs new file mode 100644 index 0000000..8a8d33e --- /dev/null +++ b/NahidaImpact.Common/Data/Binout/Ability/AbilityData.cs @@ -0,0 +1,17 @@ +using System.Text.Json.Serialization; + +namespace NahidaImpact.Common.Data.Binout.Ability; +public class AbilityData +{ + [JsonPropertyName("abilityID")] + public required string AbilityId { get; set; } + + [JsonPropertyName("abilityName")] + public required string AbilityName { get; set; } + + [JsonPropertyName("abilityOverride")] + public required string AbilityOverride { get; set; } + + public string GetAbilityOverride() + => string.IsNullOrEmpty(AbilityOverride) ? "Default" : AbilityOverride; +} diff --git a/NahidaImpact.Common/Data/Binout/AvatarConfig.cs b/NahidaImpact.Common/Data/Binout/AvatarConfig.cs new file mode 100644 index 0000000..3356657 --- /dev/null +++ b/NahidaImpact.Common/Data/Binout/AvatarConfig.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; +using NahidaImpact.Common.Data.Binout.Ability; + +namespace NahidaImpact.Common.Data.Binout; +public class AvatarConfig +{ + [JsonPropertyName("abilities")] + public List Abilities { get; set; } + + public AvatarConfig() + { + Abilities = new(); + } +} diff --git a/NahidaImpact.Common/Data/Binout/BinDataCollection.cs b/NahidaImpact.Common/Data/Binout/BinDataCollection.cs new file mode 100644 index 0000000..e81ceeb --- /dev/null +++ b/NahidaImpact.Common/Data/Binout/BinDataCollection.cs @@ -0,0 +1,50 @@ +using System.Collections.Immutable; +using System.Text.Json; +using NahidaImpact.Common.Data.Provider; +using Microsoft.Extensions.Logging; + +namespace NahidaImpact.Common.Data.Binout; +public class BinDataCollection +{ + private readonly ImmutableDictionary _avatarConfigs; + + public BinDataCollection(IAssetProvider assetProvider, ILogger logger, DataHelper dataHelper) + { + _avatarConfigs = LoadAvatarConfigs(assetProvider, dataHelper); + + logger.LogInformation("Loaded {count} avatar configs", _avatarConfigs.Count); + } + + public AvatarConfig GetAvatarConfig(uint id) + { + return _avatarConfigs[id]; + } + + private static ImmutableDictionary LoadAvatarConfigs(IAssetProvider assetProvider, DataHelper dataHelper) + { + ImmutableDictionary.Builder builder = ImmutableDictionary.CreateBuilder(); + IEnumerable avatarConfigFiles = assetProvider.EnumerateAvatarConfigFiles(); + + foreach (string avatarConfigFile in avatarConfigFiles) + { + string avatarName = avatarConfigFile[(avatarConfigFile.LastIndexOf('_') + 1)..]; + avatarName = avatarName.Remove(avatarName.IndexOf('.')); + + if (dataHelper.TryResolveAvatarIdByName(avatarName, out uint id)) + { + JsonDocument configJson = assetProvider.GetFileAsJsonDocument(avatarConfigFile); + if (configJson.RootElement.ValueKind != JsonValueKind.Object) + throw new JsonException($"BinDataCollection::LoadAvatarConfigs - expected an object, got {configJson.RootElement.ValueKind}"); + + AvatarConfig avatarConfig = configJson.RootElement.Deserialize()!; + builder.Add(id, avatarConfig); + } + else + { + throw new KeyNotFoundException($"BinDataCollection::LoadAvatarConfigs - failed to resolve avatar id for {avatarName}"); + } + } + + return builder.ToImmutable(); + } +} diff --git a/NahidaImpact.Common/Data/DataHelper.cs b/NahidaImpact.Common/Data/DataHelper.cs new file mode 100644 index 0000000..17ba545 --- /dev/null +++ b/NahidaImpact.Common/Data/DataHelper.cs @@ -0,0 +1,34 @@ +using System.Collections.Immutable; +using NahidaImpact.Common.Data.Excel; + +namespace NahidaImpact.Common.Data; +public class DataHelper +{ + private readonly ImmutableDictionary _avatarNameToIdTable; + + public DataHelper(ExcelTableCollection excelTables) + { + _avatarNameToIdTable = BuildAvatarNameToIdTable(excelTables); + } + + public bool TryResolveAvatarIdByName(string avatarName, out uint id) + { + return _avatarNameToIdTable.TryGetValue(avatarName, out id); + } + + private static ImmutableDictionary BuildAvatarNameToIdTable(ExcelTableCollection excelTables) + { + ImmutableDictionary.Builder builder = ImmutableDictionary.CreateBuilder(); + ExcelTable avatarTable = excelTables.GetTable(ExcelType.Avatar); + + for (int i = 0; i < avatarTable.Count; i++) + { + AvatarExcel excel = avatarTable.GetItemAt(i); + + string avatarName = excel.IconName[(excel.IconName.LastIndexOf('_') + 1)..]; + builder.TryAdd(avatarName, excel.Id); + } + + return builder.ToImmutable(); + } +} diff --git a/NahidaImpact.Common/Data/Excel/Attributes/ExcelAttribute.cs b/NahidaImpact.Common/Data/Excel/Attributes/ExcelAttribute.cs new file mode 100644 index 0000000..e934819 --- /dev/null +++ b/NahidaImpact.Common/Data/Excel/Attributes/ExcelAttribute.cs @@ -0,0 +1,16 @@ +using NahidaImpact.Common.Data.Excel; + +namespace NahidaImpact.Common.Data.Excel.Attributes; + +[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] +internal class ExcelAttribute : Attribute +{ + public ExcelType Type { get; } + public string AssetName { get; } + + public ExcelAttribute(ExcelType type, string assetName) + { + Type = type; + AssetName = assetName; + } +} diff --git a/NahidaImpact.Common/Data/Excel/AvatarExcel.cs b/NahidaImpact.Common/Data/Excel/AvatarExcel.cs new file mode 100644 index 0000000..edcc42e --- /dev/null +++ b/NahidaImpact.Common/Data/Excel/AvatarExcel.cs @@ -0,0 +1,136 @@ +using System.Text.Json.Serialization; +using NahidaImpact.Common.Data.Excel.Attributes; + +namespace NahidaImpact.Common.Data.Excel; + +[Excel(ExcelType.Avatar, "AvatarExcelConfigData.json")] +public class AvatarExcel : ExcelItem +{ + // TODO: implement enums for some fields! + + public override uint ExcelId => Id; + + [JsonPropertyName("attackBase")] + public double AttackBase { get; set; } + + [JsonPropertyName("avatarIdentityType")] + public string? AvatarIdentityType { get; set; } + + [JsonPropertyName("avatarPromoteId")] + public uint AvatarPromoteId { get; set; } + + [JsonPropertyName("avatarPromoteRewardIdList")] + public List AvatarPromoteRewardIdList { get; set; } + + [JsonPropertyName("avatarPromoteRewardLevelList")] + public List AvatarPromoteRewardLevelList { get; set; } + + [JsonPropertyName("bodyType")] + public required string BodyType { get; set; } + + [JsonPropertyName("iconName")] + public required string IconName { get; set; } + + [JsonPropertyName("chargeEfficiency")] + public double ChargeEfficiency { get; set; } + + [JsonPropertyName("combatConfigHashSuffix")] + public ulong CombatConfigHashSuffix { get; set; } + + [JsonPropertyName("controllerPathHashSuffix")] + public ulong ControllerPathHashSuffix { get; set; } + + [JsonPropertyName("controllerPathRemoteHashSuffix")] + public ulong ControllerPathRemoteHashSuffix { get; set; } + + [JsonPropertyName("coopPicNameHashSuffix")] + public ulong CoopPicNameHashSuffix { get; set; } + + [JsonPropertyName("critical")] + public double Critical { get; set; } + + [JsonPropertyName("criticalHurt")] + public double CriticalHurt { get; set; } + + [JsonPropertyName("defenseBase")] + public double DefenseBase { get; set; } + + [JsonPropertyName("descTextMapHash")] + public ulong DescTextMapHash { get; set; } + + [JsonPropertyName("featureTagGroupId")] + public uint FeatureTagGroupId { get; set; } + + [JsonPropertyName("gachaCardNameHashSuffix")] + public ulong GachaCardNameHashSuffix { get; set; } + + [JsonPropertyName("gachaImageNameHashSuffix")] + public ulong GachaImageNameHashSuffix { get; set; } + + [JsonPropertyName("hpBase")] + public double HpBase { get; set; } + + [JsonPropertyName("id")] + public uint Id { get; set; } + + [JsonPropertyName("infoDesc")] + public long InfoDesc { get; set; } + + [JsonPropertyName("initialWeapon")] + public uint InitialWeapon { get; set; } + + [JsonPropertyName("manekinJsonConfigHashSuffix")] + public long ManekinJsonConfigHashSuffix { get; set; } + + [JsonPropertyName("manekinMotionConfig")] + public uint ManekinMotionConfig { get; set; } + + [JsonPropertyName("manekinPathHashSuffix")] + public ulong ManekinPathHashSuffix { get; set; } + + [JsonPropertyName("nameTextMapHash")] + public ulong NameTextMapHash { get; set; } + + [JsonPropertyName("prefabPathHashSuffix")] + public ulong PrefabPathHashSuffix { get; set; } + + [JsonPropertyName("prefabPathRagdollHashSuffix")] + public ulong PrefabPathRagdollHashSuffix { get; set; } + + [JsonPropertyName("prefabPathRemoteHashSuffix")] + public ulong PrefabPathRemoteHashSuffix { get; set; } + + [JsonPropertyName("propGrowCurves")] + public List PropGrowCurves { get; set; } + + [JsonPropertyName("qualityType")] + public required string QualityType { get; set; } + + [JsonPropertyName("skillDepotId")] + public uint SkillDepotId { get; set; } + + [JsonPropertyName("staminaRecoverSpeed")] + public double StaminaRecoverSpeed { get; set; } + + [JsonPropertyName("useType")] + public string? UseType { get; set; } + + [JsonPropertyName("weaponType")] + public required string WeaponType { get; set; } + + public AvatarExcel() + { + AvatarPromoteRewardIdList = new(); + AvatarPromoteRewardLevelList = new(); + PropGrowCurves = new(); + } +} + +public class PropGrowCurve +{ + [JsonPropertyName("growCurve")] + public required string GrowCurve { get; set; } + + [JsonPropertyName("type")] + public required string Type { get; set; } +} \ No newline at end of file diff --git a/NahidaImpact.Common/Data/Excel/ExcelItem.cs b/NahidaImpact.Common/Data/Excel/ExcelItem.cs new file mode 100644 index 0000000..c657203 --- /dev/null +++ b/NahidaImpact.Common/Data/Excel/ExcelItem.cs @@ -0,0 +1,5 @@ +namespace NahidaImpact.Common.Data.Excel; +public abstract class ExcelItem +{ + public abstract uint ExcelId { get; } +} diff --git a/NahidaImpact.Common/Data/Excel/ExcelTable.cs b/NahidaImpact.Common/Data/Excel/ExcelTable.cs new file mode 100644 index 0000000..15dc079 --- /dev/null +++ b/NahidaImpact.Common/Data/Excel/ExcelTable.cs @@ -0,0 +1,46 @@ +using System.Collections.Immutable; +using System.Text.Json; + +namespace NahidaImpact.Common.Data.Excel; +public class ExcelTable +{ + public int Count => _items.Length; + private readonly ImmutableArray _items; + + public ExcelTable(JsonDocument document, Type type) + { + _items = LoadData(document, type); + } + + private static ImmutableArray LoadData(JsonDocument document, Type type) + { + ImmutableArray.Builder items = ImmutableArray.CreateBuilder(); + + foreach (JsonElement element in document.RootElement.EnumerateArray()) + { + if (element.ValueKind != JsonValueKind.Object) + throw new ArgumentException($"ExcelTable::LoadData - expected an object, got {element.ValueKind}"); + + ExcelItem deserialized = (element.Deserialize(type) as ExcelItem)!; + items.Add(deserialized); + } + + return items.ToImmutable(); + } + + public TExcel GetItemAt(int index) where TExcel : ExcelItem + { + return (_items[index] as TExcel)!; + } + + public TExcel? GetItemById(uint id) where TExcel : ExcelItem + { + foreach (ExcelItem item in _items) + { + if (item.ExcelId == id) + return item as TExcel; + } + + return null; + } +} diff --git a/NahidaImpact.Common/Data/Excel/ExcelTableCollection.cs b/NahidaImpact.Common/Data/Excel/ExcelTableCollection.cs new file mode 100644 index 0000000..2f4789a --- /dev/null +++ b/NahidaImpact.Common/Data/Excel/ExcelTableCollection.cs @@ -0,0 +1,41 @@ +using System.Collections.Immutable; +using System.Reflection; +using System.Text.Json; +using NahidaImpact.Common.Data.Excel.Attributes; +using NahidaImpact.Common.Data.Provider; +using Microsoft.Extensions.Logging; + +namespace NahidaImpact.Common.Data.Excel; +public class ExcelTableCollection +{ + private readonly ImmutableDictionary _tables; + + public ExcelTableCollection(IAssetProvider assetProvider, ILogger logger) + { + _tables = LoadTables(assetProvider); + logger.LogInformation("Loaded {count} excel tables", _tables.Count); + } + + public TExcel? GetExcel(ExcelType type, uint id) where TExcel : ExcelItem + => _tables[type].GetItemById(id); + + public ExcelTable GetTable(ExcelType type) => _tables[type]; + + private static ImmutableDictionary LoadTables(IAssetProvider assetProvider) + { + ImmutableDictionary.Builder tables = ImmutableDictionary.CreateBuilder(); + + IEnumerable types = Assembly.GetExecutingAssembly().GetTypes() + .Where(type => type.GetCustomAttribute() != null); + + foreach (Type type in types) + { + ExcelAttribute attribute = type.GetCustomAttribute()!; + + JsonDocument tableJson = assetProvider.GetExcelTableJson(attribute.AssetName); + tables.Add(attribute.Type, new ExcelTable(tableJson, type)); + } + + return tables.ToImmutable(); + } +} diff --git a/NahidaImpact.Common/Data/Excel/ExcelType.cs b/NahidaImpact.Common/Data/Excel/ExcelType.cs new file mode 100644 index 0000000..f17e5c5 --- /dev/null +++ b/NahidaImpact.Common/Data/Excel/ExcelType.cs @@ -0,0 +1,5 @@ +namespace NahidaImpact.Common.Data.Excel; +public enum ExcelType +{ + Avatar +} diff --git a/NahidaImpact.Common/Data/Provider/IAssetProvider.cs b/NahidaImpact.Common/Data/Provider/IAssetProvider.cs new file mode 100644 index 0000000..fd16629 --- /dev/null +++ b/NahidaImpact.Common/Data/Provider/IAssetProvider.cs @@ -0,0 +1,9 @@ +using System.Text.Json; + +namespace NahidaImpact.Common.Data.Provider; +public interface IAssetProvider +{ + JsonDocument GetExcelTableJson(string assetName); + IEnumerable EnumerateAvatarConfigFiles(); + JsonDocument GetFileAsJsonDocument(string fullPath); +} diff --git a/NahidaImpact.Common/Data/Provider/LocalAssetProvider.cs b/NahidaImpact.Common/Data/Provider/LocalAssetProvider.cs new file mode 100644 index 0000000..3dc90bb --- /dev/null +++ b/NahidaImpact.Common/Data/Provider/LocalAssetProvider.cs @@ -0,0 +1,27 @@ +using System.Text.Json; + +namespace NahidaImpact.Common.Data.Provider; +internal sealed class LocalAssetProvider : IAssetProvider +{ + private const string ExcelDirectory = "assets/excel/"; + private const string AvatarConfigDirectory = "assets/binout/avatar/"; + + public IEnumerable EnumerateAvatarConfigFiles() + { + return Directory.GetFiles(AvatarConfigDirectory); + } + + public JsonDocument GetFileAsJsonDocument(string fullPath) + { + using FileStream fileStream = new(fullPath, FileMode.Open, FileAccess.Read); + return JsonDocument.Parse(fileStream); + } + + public JsonDocument GetExcelTableJson(string assetName) + { + string filePath = string.Concat(ExcelDirectory, assetName); + using FileStream fileStream = new(filePath, FileMode.Open, FileAccess.Read); + + return JsonDocument.Parse(fileStream); + } +} diff --git a/NahidaImpact.Common/Data/Provider/ServiceCollectionExtensions.cs b/NahidaImpact.Common/Data/Provider/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..19c106f --- /dev/null +++ b/NahidaImpact.Common/Data/Provider/ServiceCollectionExtensions.cs @@ -0,0 +1,10 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace NahidaImpact.Common.Data.Provider; +public static class ServiceCollectionExtensions +{ + public static IServiceCollection UseLocalAssets(this IServiceCollection services) + { + return services.AddSingleton(); + } +} diff --git a/NahidaImpact.Common/Extensions/StringExtensions.cs b/NahidaImpact.Common/Extensions/StringExtensions.cs new file mode 100644 index 0000000..f50837a --- /dev/null +++ b/NahidaImpact.Common/Extensions/StringExtensions.cs @@ -0,0 +1,14 @@ +namespace NahidaImpact.Common.Extensions; +public static class StringExtensions +{ + public static uint GetStableHash(this string str) + { + uint hash = 0; + + for (int i = 0; i < str.Length; i++) + { + hash = ((str[i] + 131 * hash) & 0xFFFFFFFF) >> 0; + } + return hash; + } +} diff --git a/NahidaImpact.Common/NahidaImpact.Common.csproj b/NahidaImpact.Common/NahidaImpact.Common.csproj new file mode 100644 index 0000000..c91de79 --- /dev/null +++ b/NahidaImpact.Common/NahidaImpact.Common.csproj @@ -0,0 +1,270 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + diff --git a/NahidaImpact.Common/Security/MhySecurity.cs b/NahidaImpact.Common/Security/MhySecurity.cs new file mode 100644 index 0000000..7f203e2 --- /dev/null +++ b/NahidaImpact.Common/Security/MhySecurity.cs @@ -0,0 +1,79 @@ +using System.Buffers.Binary; +using System.Security.Cryptography; +using System.Text; +using NahidaImpact.Security.Util; + +namespace NahidaImpact.Common.Security; +public static class MhySecurity +{ + public static byte[] InitialKey { get; } + public static byte[] InitialKeyEc2b { get; } + public static byte[] RSAClientPublicKey { get; } + + static MhySecurity() + { + InitialKey = File.ReadAllBytes("assets/security/initial_key.bin"); + InitialKeyEc2b = File.ReadAllBytes("assets/security/initial_key.ec2b"); + RSAClientPublicKey = File.ReadAllBytes("assets/security/client_public_key.der"); + } + + public static byte[] GenerateSecretKey(ulong seed) + { + byte[] key = GC.AllocateUninitializedArray(0x1000); + Span keySpan = key.AsSpan(); + + MT19937 mt = new(seed); + mt.Int63(); + + for (int i = 0; i < 0x1000; i += 8) + { + BinaryPrimitives.WriteUInt64BigEndian(keySpan[i..], mt.Int63()); + } + + return key; + } + + public static byte[] EncryptWithRSA(ReadOnlySpan data) + { + using RSA cipher = RSA.Create(); + cipher.ImportSubjectPublicKeyInfo(RSAClientPublicKey, out _); + + const int chunkSize = 256 - 11; + int dataLength = data.Length; + + int numChunks = dataLength / chunkSize; + if ((dataLength - (chunkSize * numChunks)) % chunkSize != 0) ++numChunks; + + if (numChunks < 2) + { + return cipher.Encrypt(data, RSAEncryptionPadding.Pkcs1); + } + + using MemoryStream stream = new(); + for (int i = 0; i < numChunks; i++) + { + ReadOnlySpan chunk = data.Slice(i * chunkSize, Math.Min(dataLength, chunkSize)); + stream.Write(cipher.Encrypt(chunk, RSAEncryptionPadding.Pkcs1)); + + dataLength -= chunkSize; + } + + return stream.ToArray(); + } + + public static byte[] Xor(string data, ReadOnlySpan key) + { + byte[] result = Encoding.UTF8.GetBytes(data); + Xor(result, key); + + return result; + } + + public static void Xor(Span data, ReadOnlySpan key) + { + for (int i = 0; i < data.Length; i++) + { + data[i] ^= key[i % key.Length]; + } + } +} diff --git a/NahidaImpact.Common/Security/Util/MT19937.cs b/NahidaImpact.Common/Security/Util/MT19937.cs new file mode 100644 index 0000000..76f83a5 --- /dev/null +++ b/NahidaImpact.Common/Security/Util/MT19937.cs @@ -0,0 +1,68 @@ +namespace NahidaImpact.Security.Util; + +internal class MT19937 +{ + private const ulong N = 312; + private const ulong M = 156; + private const ulong MATRIX_A = 0xB5026F5AA96619E9L; + private const ulong UPPER_MASK = 0xFFFFFFFF80000000; + private const ulong LOWER_MASK = 0X7FFFFFFFUL; + + private readonly ulong[] _mt = new ulong[N + 1]; + private ulong _mti = N + 1; + + public MT19937(ulong seed) + { + this.Seed(seed); + } + + public void Seed(ulong seed) + { + _mt[0] = seed; + for (_mti = 1; _mti < N; _mti++) + { + _mt[_mti] = (6364136223846793005L * (_mt[_mti - 1] ^ (_mt[_mti - 1] >> 62)) + _mti); + } + } + + public ulong Int63() + { + ulong x = 0; + ulong[] mag01 = new ulong[2] { 0x0UL, MATRIX_A }; + + if (_mti >= N) + { + ulong kk; + if (_mti == N + 1) + { + Seed(5489UL); + } + for (kk = 0; kk < (N - M); kk++) + { + x = (_mt[kk] & UPPER_MASK) | (_mt[kk + 1] & LOWER_MASK); + _mt[kk] = _mt[kk + M] ^ (x >> 1) ^ mag01[x & 0x1UL]; + } + for (; kk < N - 1; kk++) + { + x = (_mt[kk] & UPPER_MASK) | (_mt[kk + 1] & LOWER_MASK); + _mt[kk] = _mt[kk - M] ^ (x >> 1) ^ mag01[x & 0x1UL]; + } + x = (_mt[N - 1] & UPPER_MASK) | (_mt[0] & LOWER_MASK); + _mt[N - 1] = _mt[M - 1] ^ (x >> 1) ^ mag01[x & 0x1UL]; + + _mti = 0; + } + + x = _mt[_mti++]; + x ^= (x >> 29) & 0x5555555555555555L; + x ^= (x << 17) & 0x71D67FFFEDA60000L; + x ^= (x << 37) & 0xFFF7EEE000000000L; + x ^= (x >> 43); + return x; + } + + public ulong IntN(ulong value) + { + return Int63() % value; + } +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Albedo.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Albedo.json new file mode 100644 index 0000000..fc54bec --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Albedo.json @@ -0,0 +1,114 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Albedo_ExtraAttack", + "abilityName": "Avatar_Albedo_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_SkillHoldCharge", + "abilityName": "Avatar_Albedo_SkillHoldCharge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_FullRockAlchemist", + "abilityName": "Avatar_Albedo_FullRockAlchemist", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_FullRockAlchemist_Custom", + "abilityName": "Avatar_Albedo_FullRockAlchemist_Custom", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_AlchemicalBreakOut", + "abilityName": "Avatar_Albedo_AlchemicalBreakOut", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_DamageHandler", + "abilityName": "Avatar_Albedo_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_FallingAnthem", + "abilityName": "Avatar_Albedo_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo", + "abilityName": "Avatar_Albedo", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_Skill_ElementalArt", + "abilityName": "Avatar_Albedo_Skill_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_Skill_ElementalArt_AS", + "abilityName": "Avatar_Albedo_Skill_ElementalArt_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_Skill_ElementalArt_BS", + "abilityName": "Avatar_Albedo_Skill_ElementalArt_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_TeamConfig_01BS", + "abilityName": "Avatar_Albedo_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_TeamConfig_01Loop", + "abilityName": "Avatar_Albedo_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_TeamConfig_01AS", + "abilityName": "Avatar_Albedo_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_Skill_ElementalArt_Charge", + "abilityName": "Avatar_Albedo_Skill_ElementalArt_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_ElementalBurst_Spine", + "abilityName": "Avatar_Albedo_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_ElementalBurst_Spine_Hand", + "abilityName": "Avatar_Albedo_ElementalBurst_Spine_Hand", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_Spine", + "abilityName": "Avatar_Albedo_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_ElementalBurst_BS", + "abilityName": "Avatar_Albedo_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_ElementalBurst_Hit", + "abilityName": "Avatar_Albedo_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_Spine_Loop", + "abilityName": "Avatar_Albedo_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Albedo_Spine_Loop_Hand", + "abilityName": "Avatar_Albedo_Spine_Loop_Hand", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Alhatham.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Alhatham.json new file mode 100644 index 0000000..3247942 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Alhatham.json @@ -0,0 +1,154 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Alhatham_ExtraAttack", + "abilityName": "Avatar_Alhatham_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_SkillHoldCharge", + "abilityName": "Avatar_Alhatham_SkillHoldCharge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_ElementalArt", + "abilityName": "Avatar_Alhatham_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_ElementalArt_SkillStart", + "abilityName": "Avatar_Alhatham_ElementalArt_SkillStart", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_Constellation_6", + "abilityName": "Avatar_Alhatham_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_ElementalArt_Custom", + "abilityName": "Avatar_Alhatham_ElementalArt_Custom", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_ForlornLotus", + "abilityName": "Avatar_Alhatham_ForlornLotus", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_NormalAttack_Mark", + "abilityName": "Avatar_Alhatham_NormalAttack_Mark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_IN_ForlornLotus", + "abilityName": "Avatar_Alhatham_IN_ForlornLotus", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_NormalMode", + "abilityName": "Avatar_Alhatham_NormalMode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_ForlornLotusMode", + "abilityName": "Avatar_Alhatham_ForlornLotusMode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_ForlornLotus_Attack", + "abilityName": "Avatar_Alhatham_ForlornLotus_Attack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_ForlornLotus_Attack_LV1", + "abilityName": "Avatar_Alhatham_ForlornLotus_Attack_LV1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_ForlornLotus_Attack_LV2", + "abilityName": "Avatar_Alhatham_ForlornLotus_Attack_LV2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_ForlornLotus_Attack_LV2_Helper", + "abilityName": "Avatar_Alhatham_ForlornLotus_Attack_LV2_Helper", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_ForlornLotus_Attack_LV3", + "abilityName": "Avatar_Alhatham_ForlornLotus_Attack_LV3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_ForlornLotus_Attack_LV3_Helper", + "abilityName": "Avatar_Alhatham_ForlornLotus_Attack_LV3_Helper", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_ElementalBurst", + "abilityName": "Avatar_Alhatham_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_Constellation_6J", + "abilityName": "Avatar_Alhatham_Constellation_6J", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_ElementalBurst_Aftermath", + "abilityName": "Avatar_Alhatham_ElementalBurst_Aftermath", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_DamageHandler", + "abilityName": "Avatar_Alhatham_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_PermanentSkill_2", + "abilityName": "Avatar_Alhatham_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_PermanentSkill_1", + "abilityName": "Avatar_Alhatham_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_PermanentSkill_1_CD", + "abilityName": "Avatar_Alhatham_PermanentSkill_1_CD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_Constellation_6_FX", + "abilityName": "Avatar_Alhatham_Constellation_6_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_FallingAnthem", + "abilityName": "Avatar_Alhatham_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham", + "abilityName": "Avatar_Alhatham", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_TeamConfig_01BS", + "abilityName": "Avatar_Alhatham_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_TeamConfig_01Loop", + "abilityName": "Avatar_Alhatham_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Alhatham_TeamConfig_01AS", + "abilityName": "Avatar_Alhatham_TeamConfig_01AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Aloy.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Aloy.json new file mode 100644 index 0000000..a39c16a --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Aloy.json @@ -0,0 +1,214 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Aloy_PressShoot", + "abilityName": "Avatar_Aloy_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_AimPressShoot", + "abilityName": "Avatar_Aloy_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_PressShoot_Charge", + "abilityName": "Avatar_Aloy_PressShoot_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_PressShoot_Shooting", + "abilityName": "Avatar_Aloy_PressShoot_Shooting", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_ShootArrow_01_01", + "abilityName": "Avatar_Aloy_ShootArrow_01_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_ShootArrow_01_02", + "abilityName": "Avatar_Aloy_ShootArrow_01_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_ShootArrow_02", + "abilityName": "Avatar_Aloy_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_ShootArrow_03", + "abilityName": "Avatar_Aloy_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_ShootArrow_04", + "abilityName": "Avatar_Aloy_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_NormalAttack_LightEffect", + "abilityName": "Avatar_AloyGadgetSkill_NormalAttack_LightEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_NormalAttack_HeavyFX", + "abilityName": "Avatar_AloyGadgetSkill_NormalAttack_HeavyFX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_NormalAttack_LightEffect_UltraMode", + "abilityName": "Avatar_AloyGadgetSkill_NormalAttack_LightEffect_UltraMode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_NormalAttack_HeavyFX_UltraMode", + "abilityName": "Avatar_AloyGadgetSkill_NormalAttack_HeavyFX_UltraMode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_ExtraAttack_WithoutIce", + "abilityName": "Avatar_AloyGadgetSkill_ExtraAttack_WithoutIce", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_ExtraAttack_Ice", + "abilityName": "Avatar_AloyGadgetSkill_ExtraAttack_Ice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_Coil_Handler", + "abilityName": "Avatar_Aloy_Coil_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_ElementalArt", + "abilityName": "Avatar_Aloy_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_ElementalArt_Bullet", + "abilityName": "Avatar_AloyGadgetSkill_ElementalArt_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_ElementalArt_TriggerBullet", + "abilityName": "Avatar_AloyGadgetSkill_ElementalArt_TriggerBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_ElementalArt_Mine", + "abilityName": "Avatar_AloyGadgetSkill_ElementalArt_Mine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_ElementalBurst_Camera", + "abilityName": "Avatar_Aloy_ElementalBurst_Camera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_ElementalBurst", + "abilityName": "Avatar_Aloy_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_ElementalBurst", + "abilityName": "Avatar_AloyGadgetSkill_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_NormalAttack_01_01_Damage", + "abilityName": "Avatar_AloyGadgetSkill_NormalAttack_01_01_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_NormalAttack_01_02_Damage", + "abilityName": "Avatar_AloyGadgetSkill_NormalAttack_01_02_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_NormalAttack_02_Damage", + "abilityName": "Avatar_AloyGadgetSkill_NormalAttack_02_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_NormalAttack_03_Damage", + "abilityName": "Avatar_AloyGadgetSkill_NormalAttack_03_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_NormalAttack_04_Damage", + "abilityName": "Avatar_AloyGadgetSkill_NormalAttack_04_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_FallingAnthem", + "abilityName": "Avatar_Aloy_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy", + "abilityName": "Avatar_Aloy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_NormalAttack_HeavyFX9Avatar_AloyGadgetSkill_NormalAttack_LightEffect_UltraMode5Avatar_AloyGadgetSkill_NormalAttack_HeavyFX_UltraMode", + "abilityName": "Avatar_AloyGadgetSkill_NormalAttack_HeavyFX9Avatar_AloyGadgetSkill_NormalAttack_LightEffect_UltraMode5Avatar_AloyGadgetSkill_NormalAttack_HeavyFX_UltraMode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_ElementalArt_Bullet1Avatar_AloyGadgetSkill_ElementalArt_TriggerBullet", + "abilityName": "Avatar_AloyGadgetSkill_ElementalArt_Bullet1Avatar_AloyGadgetSkill_ElementalArt_TriggerBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_ElementalBurst0Avatar_AloyGadgetSkill_NormalAttack_01_01_Damage0Avatar_AloyGadgetSkill_NormalAttack_01_02_Damage", + "abilityName": "Avatar_AloyGadgetSkill_ElementalBurst0Avatar_AloyGadgetSkill_NormalAttack_01_01_Damage0Avatar_AloyGadgetSkill_NormalAttack_01_02_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_Skill_ElementalArt_BS", + "abilityName": "Avatar_Aloy_Skill_ElementalArt_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_Skill_ElementalArt", + "abilityName": "Avatar_Aloy_Skill_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_TeamConfig_01BS", + "abilityName": "Avatar_Aloy_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_TeamConfig_01Loop", + "abilityName": "Avatar_Aloy_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_TeamConfig_01AS", + "abilityName": "Avatar_Aloy_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Aloy_Skill_ElementalArt_AS", + "abilityName": "Avatar_Aloy_Skill_ElementalArt_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_NormalAttack_01_01_Damage0Avatar_AloyGadgetSkill_NormalAttack_01_01_Damage", + "abilityName": "Avatar_AloyGadgetSkill_NormalAttack_01_01_Damage0Avatar_AloyGadgetSkill_NormalAttack_01_01_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_NormalAttack_01_02_Damage0Avatar_AloyGadgetSkill_NormalAttack_01_02_Damage", + "abilityName": "Avatar_AloyGadgetSkill_NormalAttack_01_02_Damage0Avatar_AloyGadgetSkill_NormalAttack_01_02_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_AloyGadgetSkill_ElementalArt_TriggerBullet1Avatar_AloyGadgetSkill_ElementalArt_TriggerBullet", + "abilityName": "Avatar_AloyGadgetSkill_ElementalArt_TriggerBullet1Avatar_AloyGadgetSkill_ElementalArt_TriggerBullet", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ambor.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ambor.json new file mode 100644 index 0000000..3b8dc3d --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ambor.json @@ -0,0 +1,314 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Ambor_Arrow_FX", + "abilityName": "Avatar_Ambor_Arrow_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_PressShoot", + "abilityName": "Avatar_Ambor_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_AimPressShoot", + "abilityName": "Avatar_Ambor_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ShootAimingArrow_Charge", + "abilityName": "Avatar_Ambor_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ShootArrow_01", + "abilityName": "Avatar_Ambor_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ShootArrow_02", + "abilityName": "Avatar_Ambor_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ShootArrow_03", + "abilityName": "Avatar_Ambor_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ShootArrow_04", + "abilityName": "Avatar_Ambor_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ShootArrow_05", + "abilityName": "Avatar_Ambor_ShootArrow_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ShootArrow_Aiming", + "abilityName": "Avatar_Ambor_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_BlowUpDummy", + "abilityName": "Avatar_Ambor_BlowUpDummy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_DoubleArrow_01", + "abilityName": "Avatar_Ambor_DoubleArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_DoubleArrow_02", + "abilityName": "Avatar_Ambor_DoubleArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_DummyTrigger", + "abilityName": "Avatar_Ambor_DummyTrigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ThrowDummy_UseSkill", + "abilityName": "Avatar_Ambor_ThrowDummy_UseSkill", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ThrowDummy_Short", + "abilityName": "Avatar_Ambor_ThrowDummy_Short", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ThrowDummy_4M", + "abilityName": "Avatar_Ambor_ThrowDummy_4M", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ThrowDummy_7M", + "abilityName": "Avatar_Ambor_ThrowDummy_7M", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ThrowDummy", + "abilityName": "Avatar_Ambor_ThrowDummy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_Dummy_Speed_Fix", + "abilityName": "Avatar_Ambor_Dummy_Speed_Fix", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_CreateDummy", + "abilityName": "Avatar_Ambor_CreateDummy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_BlowUpByTrigger", + "abilityName": "Avatar_Ambor_BlowUpByTrigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_CreateBlowUpTrigger", + "abilityName": "Avatar_Ambor_CreateBlowUpTrigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_BlowUpByTriggerh", + "abilityName": "Avatar_Ambor_BlowUpByTriggerh", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_DummyDropBall", + "abilityName": "Avatar_Ambor_DummyDropBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ArrowRain_Alert", + "abilityName": "Avatar_Ambor_ArrowRain_Alert", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ArrowRain", + "abilityName": "Avatar_Ambor_ArrowRain", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ArrowRainField", + "abilityName": "Avatar_Ambor_ArrowRainField", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_AirShoot", + "abilityName": "Avatar_Ambor_AirShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ChangeMainSkill", + "abilityName": "Avatar_Ambor_ChangeMainSkill", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_FlyStamina_Reduction", + "abilityName": "Avatar_Ambor_FlyStamina_Reduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ProudSkill_21", + "abilityName": "Avatar_Ambor_ProudSkill_21", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_FallingAnthem", + "abilityName": "Avatar_Ambor_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor", + "abilityName": "Avatar_Ambor", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_Skill_Holdup", + "abilityName": "Avatar_Ambor_Skill_Holdup", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_Skill_HoldupStandby", + "abilityName": "Avatar_Ambor_Skill_HoldupStandby", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_Skill_Long_01", + "abilityName": "Avatar_Ambor_Skill_Long_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_Skill_Long_02", + "abilityName": "Avatar_Ambor_Skill_Long_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_Skill_Middle_01", + "abilityName": "Avatar_Ambor_Skill_Middle_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_Skill_Middle_02", + "abilityName": "Avatar_Ambor_Skill_Middle_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_Skill_PreForRun", + "abilityName": "Avatar_Ambor_Skill_PreForRun", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_Skill_PreForWalk", + "abilityName": "Avatar_Ambor_Skill_PreForWalk", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_Skill_Short", + "abilityName": "Avatar_Ambor_Skill_Short", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_TeamConfig_01BS", + "abilityName": "Avatar_Ambor_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_TeamConfig_01Loop", + "abilityName": "Avatar_Ambor_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_TeamConfig_01AS", + "abilityName": "Avatar_Ambor_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_Skill_ArrowRain", + "abilityName": "Avatar_Ambor_Skill_ArrowRain", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ElementalBurst_Spine", + "abilityName": "Avatar_Ambor_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ElementalBurst_Hit", + "abilityName": "Avatar_Ambor_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ElementalBurst_BS", + "abilityName": "Avatar_Ambor_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_ElementalBurst_Hit_02", + "abilityName": "Avatar_Ambor_ElementalBurst_Hit_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_Spine_Loop", + "abilityName": "Avatar_Ambor_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_VO_MDAQ020_Ambor_01", + "abilityName": "Avatar_Ambor_VO_MDAQ020_Ambor_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_VO_Emotion_Ambor_Speculate_01", + "abilityName": "Avatar_Ambor_VO_Emotion_Ambor_Speculate_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_VO_Emotion_Ambor_Hesitate_01", + "abilityName": "Avatar_Ambor_VO_Emotion_Ambor_Hesitate_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_VO_Emotion_Ambor_Pity_01", + "abilityName": "Avatar_Ambor_VO_Emotion_Ambor_Pity_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_VO_MDAQ020_Ambor_02", + "abilityName": "Avatar_Ambor_VO_MDAQ020_Ambor_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_VO_Emotion_Ambor_Satisfaction_02", + "abilityName": "Avatar_Ambor_VO_Emotion_Ambor_Satisfaction_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_Normal", + "abilityName": "Avatar_Ambor_Normal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_VO_MDAQ021_Ambor_01", + "abilityName": "Avatar_Ambor_VO_MDAQ021_Ambor_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_VO_Emotion_Ambor_Vigilant_02", + "abilityName": "Avatar_Ambor_VO_Emotion_Ambor_Vigilant_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ambor_VO_Emotion_Ambor_Excited_02", + "abilityName": "Avatar_Ambor_VO_Emotion_Ambor_Excited_02", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ayaka.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ayaka.json new file mode 100644 index 0000000..85d79ed --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ayaka.json @@ -0,0 +1,254 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Ayaka_ExtraAttack", + "abilityName": "Avatar_Ayaka_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_ExtraAttack_Damage", + "abilityName": "Avatar_Ayaka_ExtraAttack_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_ExtraAttack_Damage_Gadget", + "abilityName": "Avatar_Ayaka_ExtraAttack_Damage_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_ExtraAttack_Damage_Handler", + "abilityName": "Avatar_Ayaka_ExtraAttack_Damage_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_ExtraAttack_Damage_Gadget_1", + "abilityName": "Avatar_Ayaka_ExtraAttack_Damage_Gadget_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_ExtraAttack_Damage_Gadget_2", + "abilityName": "Avatar_Ayaka_ExtraAttack_Damage_Gadget_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_NormalAttack05_CreateBullet", + "abilityName": "Avatar_Ayaka_NormalAttack05_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_NormalAttack05_Bullet", + "abilityName": "Avatar_Ayaka_NormalAttack05_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_IceSlash", + "abilityName": "Avatar_Ayaka_IceSlash", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_Liquid_TriggerAbility", + "abilityName": "Avatar_Ayaka_Liquid_TriggerAbility", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_LiquidStrike", + "abilityName": "Avatar_Ayaka_LiquidStrike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_LiquidStrike_YayoiKaeshi", + "abilityName": "Avatar_Ayaka_LiquidStrike_YayoiKaeshi", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_EndLiquidStrike", + "abilityName": "Avatar_Ayaka_EndLiquidStrike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_Icespine", + "abilityName": "Avatar_Ayaka_Icespine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_Icespine_Sensu_Remover", + "abilityName": "Avatar_Ayaka_Icespine_Sensu_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_Icespine_Strike_New", + "abilityName": "Avatar_Ayaka_Icespine_Strike_New", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_FrozenWindmill_SkillStart", + "abilityName": "Avatar_Ayaka_FrozenWindmill_SkillStart", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_FrozenWindmill", + "abilityName": "Avatar_Ayaka_FrozenWindmill", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_Oboro", + "abilityName": "Avatar_Ayaka_Oboro", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_Windmill_CameraController", + "abilityName": "Avatar_Ayaka_Windmill_CameraController", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_Windmill_Sensu_Remover", + "abilityName": "Avatar_Ayaka_Windmill_Sensu_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_FrozenWindmillDamage", + "abilityName": "Avatar_Ayaka_FrozenWindmillDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_FrozenWindmillDissipate", + "abilityName": "Avatar_Ayaka_FrozenWindmillDissipate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_FrozenWindmill_Sub_Damage", + "abilityName": "Avatar_Ayaka_FrozenWindmill_Sub_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_FrozenWindmill_Sub_Dissipate", + "abilityName": "Avatar_Ayaka_FrozenWindmill_Sub_Dissipate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_FrozenButterfly_Area", + "abilityName": "Avatar_Ayaka_FrozenButterfly_Area", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_FrostFall", + "abilityName": "Avatar_Ayaka_FrostFall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_MagicSheathe_Add", + "abilityName": "Avatar_Ayaka_MagicSheathe_Add", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_MagicSheathe_Remove", + "abilityName": "Avatar_Ayaka_MagicSheathe_Remove", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_MagicSheathe_Attack05_Add", + "abilityName": "Avatar_Ayaka_MagicSheathe_Attack05_Add", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_MagicSheathe_NormalAttack_Remove", + "abilityName": "Avatar_Ayaka_MagicSheathe_NormalAttack_Remove", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_ChangeMainSkill", + "abilityName": "Avatar_Ayaka_ChangeMainSkill", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_CloseCollider", + "abilityName": "Avatar_Ayaka_CloseCollider", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_PermanentSkill_2", + "abilityName": "Avatar_Ayaka_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_Constellation_6", + "abilityName": "Avatar_Ayaka_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_NormalAttack_DamageHandler", + "abilityName": "Avatar_Ayaka_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_FallingAnthem", + "abilityName": "Avatar_Ayaka_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka", + "abilityName": "Avatar_Ayaka", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_TeamConfig_01BS", + "abilityName": "Avatar_Ayaka_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_TeamConfig_01Loop", + "abilityName": "Avatar_Ayaka_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_TeamConfig_01AS", + "abilityName": "Avatar_Ayaka_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "AvatarItem_Ayaka_Kitsune_Mask", + "abilityName": "AvatarItem_Ayaka_Kitsune_Mask", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_ElementalBurst_Spine", + "abilityName": "Avatar_Ayaka_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_ElementalBurst_BS", + "abilityName": "Avatar_Ayaka_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_ElementalBurst", + "abilityName": "Avatar_Ayaka_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_ElementBurst", + "abilityName": "Avatar_Ayaka_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_ElementalBurst_Hit", + "abilityName": "Avatar_Ayaka_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_Spine_Loop", + "abilityName": "Avatar_Ayaka_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_Spine", + "abilityName": "Avatar_Ayaka_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayaka_Normal", + "abilityName": "Avatar_Ayaka_Normal", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ayato.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ayato.json new file mode 100644 index 0000000..f67969c --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ayato.json @@ -0,0 +1,249 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Ayato_ExtraAttack", + "abilityName": "Avatar_Ayato_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_ExtraAttack_CreateBullet", + "abilityName": "Avatar_Ayato_ExtraAttack_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_ExtraAttack_Bullet", + "abilityName": "Avatar_Ayato_ExtraAttack_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_ElementalArt", + "abilityName": "Avatar_Ayato_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_Buff_Level", + "abilityName": "Avatar_Ayato_KendoPose_Buff_Level", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose", + "abilityName": "Avatar_Ayato_KendoPose", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_State", + "abilityName": "Avatar_Ayato_KendoPose_State", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_Buff_Level_Remove", + "abilityName": "Avatar_Ayato_KendoPose_Buff_Level_Remove", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_BuffAdd", + "abilityName": "Avatar_Ayato_KendoPose_BuffAdd", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_Buff", + "abilityName": "Avatar_Ayato_KendoPose_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_Click", + "abilityName": "Avatar_Ayato_KendoPose_Click", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_Hold_SpecialAttack", + "abilityName": "Avatar_Ayato_Hold_SpecialAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_Buff0", + "abilityName": "Avatar_Ayato_KendoPose_Buff0", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_Buff1", + "abilityName": "Avatar_Ayato_KendoPose_Buff1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_Buff2", + "abilityName": "Avatar_Ayato_KendoPose_Buff2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_Buff3", + "abilityName": "Avatar_Ayato_KendoPose_Buff3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_Buff4", + "abilityName": "Avatar_Ayato_KendoPose_Buff4", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_Buff5", + "abilityName": "Avatar_Ayato_KendoPose_Buff5", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_BuffTimer", + "abilityName": "Avatar_Ayato_KendoPose_BuffTimer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_HPBuff", + "abilityName": "Avatar_Ayato_KendoPose_HPBuff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_BuffEffect", + "abilityName": "Avatar_Ayato_KendoPose_BuffEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_BuffEffect_Delay", + "abilityName": "Avatar_Ayato_KendoPose_BuffEffect_Delay", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_KendoPose_BuffTimerM", + "abilityName": "Avatar_Ayato_KendoPose_BuffTimerM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_ElementalArt_Gadget", + "abilityName": "Avatar_Ayato_ElementalArt_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_ElementalBurst", + "abilityName": "Avatar_Ayato_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_ElementalBurst_Gadget", + "abilityName": "Avatar_Ayato_ElementalBurst_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_ElementalBurst_Gadget_Select", + "abilityName": "Avatar_Ayato_ElementalBurst_Gadget_Select", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_ElementalBurst_NormalAttackUp", + "abilityName": "Avatar_Ayato_ElementalBurst_NormalAttackUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_PermanentSkill_2_ReviveEnergy", + "abilityName": "Avatar_Ayato_PermanentSkill_2_ReviveEnergy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_IsOffStage", + "abilityName": "Avatar_Ayato_IsOffStage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_OffStage", + "abilityName": "Avatar_Ayato_OffStage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_ReviveEnergy_OffStage", + "abilityName": "Avatar_Ayato_ReviveEnergy_OffStage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_NormalAttack_DamageHandler", + "abilityName": "Avatar_Ayato_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_FallingAnthem", + "abilityName": "Avatar_Ayato_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato", + "abilityName": "Avatar_Ayato", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_Skill_ElementalArt", + "abilityName": "Avatar_Ayato_Skill_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_Skill_ElementalArt_AS", + "abilityName": "Avatar_Ayato_Skill_ElementalArt_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_Skill_ElementalArt_Retreat", + "abilityName": "Avatar_Ayato_Skill_ElementalArt_Retreat", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_Skill_ElementalArt_Retreat_AS", + "abilityName": "Avatar_Ayato_Skill_ElementalArt_Retreat_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_Skill_SpecialAttack_01", + "abilityName": "Avatar_Ayato_Skill_SpecialAttack_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_Skill_SpecialAttack_02", + "abilityName": "Avatar_Ayato_Skill_SpecialAttack_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_TeamConfig_01BS", + "abilityName": "Avatar_Ayato_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_TeamConfig_01Loop", + "abilityName": "Avatar_Ayato_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_TeamConfig_01AS", + "abilityName": "Avatar_Ayato_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_Skill_SpecialAttack_03", + "abilityName": "Avatar_Ayato_Skill_SpecialAttack_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_ElementalBurst_Spine", + "abilityName": "Avatar_Ayato_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_ElementalBurst_BS", + "abilityName": "Avatar_Ayato_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_ElementalBurst_Hit", + "abilityName": "Avatar_Ayato_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ayato_Spine_Loop", + "abilityName": "Avatar_Ayato_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Baizhuer.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Baizhuer.json new file mode 100644 index 0000000..276d1b5 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Baizhuer.json @@ -0,0 +1,204 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Baizhuer_ExtraAttack", + "abilityName": "Avatar_Baizhuer_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ExtraAttack_Gadget", + "abilityName": "Avatar_Baizhuer_ExtraAttack_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ExtraAttack_Gadget_Fx", + "abilityName": "Avatar_Baizhuer_ExtraAttack_Gadget_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ExtraAttack_Delay_Damage", + "abilityName": "Avatar_Baizhuer_ExtraAttack_Delay_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_Attack01", + "abilityName": "Avatar_Baizhuer_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_Attack02", + "abilityName": "Avatar_Baizhuer_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_Attack03", + "abilityName": "Avatar_Baizhuer_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_Attack04", + "abilityName": "Avatar_Baizhuer_Attack04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalArt", + "abilityName": "Avatar_Baizhuer_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalArt_AngularVelocity", + "abilityName": "Avatar_Baizhuer_ElementalArt_AngularVelocity", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalBurst", + "abilityName": "Avatar_Baizhuer_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalArt_AngularVelocity_Timer", + "abilityName": "Avatar_Baizhuer_ElementalArt_AngularVelocity_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalArt_AvatarCheck", + "abilityName": "Avatar_Baizhuer_ElementalArt_AvatarCheck", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_Heal_ControlAbiilty", + "abilityName": "Avatar_Baizhuer_Heal_ControlAbiilty", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalBurst_Funnel_Handler", + "abilityName": "Avatar_Baizhuer_ElementalBurst_Funnel_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalBurst_Funnel_Trigger", + "abilityName": "Avatar_Baizhuer_ElementalBurst_Funnel_Trigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalBurst_GetLocalAvatarTarget", + "abilityName": "Avatar_Baizhuer_ElementalBurst_GetLocalAvatarTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalBurst_Funnel_Shoot", + "abilityName": "Avatar_Baizhuer_ElementalBurst_Funnel_Shoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_Burst_HasTarget", + "abilityName": "Avatar_Baizhuer_Burst_HasTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_Funnel_ShootPos", + "abilityName": "Avatar_Baizhuer_Funnel_ShootPos", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalBurst_AngularVelocity_Timer", + "abilityName": "Avatar_Baizhuer_ElementalBurst_AngularVelocity_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalBurst_AngularVelocity", + "abilityName": "Avatar_Baizhuer_ElementalBurst_AngularVelocity", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_PermanentSkill_1", + "abilityName": "Avatar_Baizhuer_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_HPRatio_Check", + "abilityName": "Avatar_Baizhuer_HPRatio_Check", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_Constellation_ShootPos", + "abilityName": "Avatar_Baizhuer_Constellation_ShootPos", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_HealWhenGather", + "abilityName": "Avatar_Baizhuer_HealWhenGather", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_FallingAnthem", + "abilityName": "Avatar_Baizhuer_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer", + "abilityName": "Avatar_Baizhuer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_TeamConfig_01BS", + "abilityName": "Avatar_Baizhuer_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_TeamConfig_01Loop", + "abilityName": "Avatar_Baizhuer_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_TeamConfig_01AS", + "abilityName": "Avatar_Baizhuer_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalBurst_Spine", + "abilityName": "Avatar_Baizhuer_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalBurst_Spine_Hand", + "abilityName": "Avatar_Baizhuer_ElementalBurst_Spine_Hand", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_Spine", + "abilityName": "Avatar_Baizhuer_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalBurst_BS", + "abilityName": "Avatar_Baizhuer_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalBurst_BuffBS", + "abilityName": "Avatar_Baizhuer_ElementalBurst_BuffBS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalBurst_Buff", + "abilityName": "Avatar_Baizhuer_ElementalBurst_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementBurst", + "abilityName": "Avatar_Baizhuer_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_ElementalBurst_BuffHit", + "abilityName": "Avatar_Baizhuer_ElementalBurst_BuffHit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Baizhuer_Spine_Loop", + "abilityName": "Avatar_Baizhuer_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Barbara.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Barbara.json new file mode 100644 index 0000000..26ea021 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Barbara.json @@ -0,0 +1,144 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Barbara_ExtraAttack", + "abilityName": "Avatar_Barbara_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_ExtraAttack_FX", + "abilityName": "Avatar_Barbara_ExtraAttack_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_ExtraAttack_Damage", + "abilityName": "Avatar_Barbara_ExtraAttack_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_Attack01", + "abilityName": "Avatar_Barbara_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_Attack02", + "abilityName": "Avatar_Barbara_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_Attack03", + "abilityName": "Avatar_Barbara_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_Attack04", + "abilityName": "Avatar_Barbara_Attack04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_Attack04Damage", + "abilityName": "Avatar_Barbara_Attack04Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_WetShiled_Clear", + "abilityName": "Avatar_Barbara_WetShiled_Clear", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_WetShiled", + "abilityName": "Avatar_Barbara_WetShiled", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_WetShiled_Heal", + "abilityName": "Avatar_Barbara_WetShiled_Heal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_WetShiled_Impact", + "abilityName": "Avatar_Barbara_WetShiled_Impact", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_IdolHeal", + "abilityName": "Avatar_Barbara_IdolHeal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_Trigger_Weather", + "abilityName": "Avatar_Barbara_Trigger_Weather", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_ReviveElemEnergy", + "abilityName": "Avatar_Barbara_ReviveElemEnergy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_ReBorn_Pre", + "abilityName": "Avatar_Barbara_ReBorn_Pre", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_ReBorn", + "abilityName": "Avatar_Barbara_ReBorn", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_ReBornEffect_01", + "abilityName": "Avatar_Barbara_ReBornEffect_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_ReBornEffect_02", + "abilityName": "Avatar_Barbara_ReBornEffect_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_FallingAnthem", + "abilityName": "Avatar_Barbara_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara", + "abilityName": "Avatar_Barbara", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_TeamConfig_01BS", + "abilityName": "Avatar_Barbara_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_TeamConfig_01Loop", + "abilityName": "Avatar_Barbara_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_TeamConfig_01AS", + "abilityName": "Avatar_Barbara_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_ElementalBurst_Spine", + "abilityName": "Avatar_Barbara_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_ElementalBurst", + "abilityName": "Avatar_Barbara_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_Spine_Loop", + "abilityName": "Avatar_Barbara_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Barbara_VO_MDAQ054_Barbara_01", + "abilityName": "Avatar_Barbara_VO_MDAQ054_Barbara_01", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Beidou.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Beidou.json new file mode 100644 index 0000000..4f0c3bd --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Beidou.json @@ -0,0 +1,109 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Beidou_ExtraAttack", + "abilityName": "Avatar_Beidou_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_ThunderCounter_Handler", + "abilityName": "Avatar_Beidou_ThunderCounter_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_ThunderCounter_Strike", + "abilityName": "Avatar_Beidou_ThunderCounter_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_ThunderShield_CameraHandler", + "abilityName": "Avatar_Beidou_ThunderShield_CameraHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_ThunderShield_Gadget", + "abilityName": "Avatar_Beidou_ThunderShield_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_ThunderShield", + "abilityName": "Avatar_Beidou_ThunderShield", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_NormalAttackDamage", + "abilityName": "Avatar_Beidou_NormalAttackDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_FallingAnthem", + "abilityName": "Avatar_Beidou_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_ProudSkill_FlashSlash", + "abilityName": "Avatar_Beidou_ProudSkill_FlashSlash", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_SwimStamina_Reduction", + "abilityName": "Avatar_Beidou_SwimStamina_Reduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_ExtraAttack_Chongyun", + "abilityName": "Avatar_Beidou_ExtraAttack_Chongyun", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou", + "abilityName": "Avatar_Beidou", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_TeamConfig_01BS", + "abilityName": "Avatar_Beidou_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_TeamConfig_01Loop", + "abilityName": "Avatar_Beidou_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_TeamConfig_01AS", + "abilityName": "Avatar_Beidou_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_ElementalBurst_Spine", + "abilityName": "Avatar_Beidou_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_Spine", + "abilityName": "Avatar_Beidou_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_ElementalBurst_Hit", + "abilityName": "Avatar_Beidou_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_ElementalBurst_Buff", + "abilityName": "Avatar_Beidou_ElementalBurst_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_Spine_Loop", + "abilityName": "Avatar_Beidou_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Beidou_Spine_Loop_Water", + "abilityName": "Avatar_Beidou_Spine_Loop_Water", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Bennett.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Bennett.json new file mode 100644 index 0000000..63d9d78 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Bennett.json @@ -0,0 +1,134 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Bennett_ExtraAttack", + "abilityName": "Avatar_Bennett_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_Shake", + "abilityName": "Avatar_Bennett_Shake", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalArt_Handler", + "abilityName": "Avatar_Bennett_ElementalArt_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalArt_Strike01_01", + "abilityName": "Avatar_Bennett_ElementalArt_Strike01_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalArt_Strike02_01", + "abilityName": "Avatar_Bennett_ElementalArt_Strike02_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalArt_Strike02_02", + "abilityName": "Avatar_Bennett_ElementalArt_Strike02_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalArt_Strike02_03", + "abilityName": "Avatar_Bennett_ElementalArt_Strike02_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalArt_Strike03_01", + "abilityName": "Avatar_Bennett_ElementalArt_Strike03_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalArt_Strike03_02", + "abilityName": "Avatar_Bennett_ElementalArt_Strike03_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalArt_Explode", + "abilityName": "Avatar_Bennett_ElementalArt_Explode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalBurst_Strike", + "abilityName": "Avatar_Bennett_ElementalBurst_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalBurst", + "abilityName": "Avatar_Bennett_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalBurst_Gadget", + "abilityName": "Avatar_Bennett_ElementalBurst_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_NormalAttackDamage", + "abilityName": "Avatar_Bennett_NormalAttackDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_FallingAnthem", + "abilityName": "Avatar_Bennett_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett", + "abilityName": "Avatar_Bennett", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_TeamConfig_01BS", + "abilityName": "Avatar_Bennett_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_TeamConfig_01Loop", + "abilityName": "Avatar_Bennett_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_TeamConfig_01AS", + "abilityName": "Avatar_Bennett_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalBurst_Spine", + "abilityName": "Avatar_Bennett_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalBurst_BS", + "abilityName": "Avatar_Bennett_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_ElementalBurst_Hit", + "abilityName": "Avatar_Bennett_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_elementalBurst_BS_Normal", + "abilityName": "Avatar_Bennett_elementalBurst_BS_Normal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_Spine_Loop", + "abilityName": "Avatar_Bennett_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_Spine_Loop_Star", + "abilityName": "Avatar_Bennett_Spine_Loop_Star", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Bennett_Spine", + "abilityName": "Avatar_Bennett_Spine", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Candace.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Candace.json new file mode 100644 index 0000000..e5c8c3a --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Candace.json @@ -0,0 +1,174 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Candace_ExtraAttack", + "abilityName": "Avatar_Candace_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_ExtraAttack_CreateBullet", + "abilityName": "Avatar_Candace_ExtraAttack_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_ElementalArt_HoldCharge", + "abilityName": "Avatar_Candace_ElementalArt_HoldCharge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_ElementalArt_ChargeShield", + "abilityName": "Avatar_Candace_ElementalArt_ChargeShield", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_ElementalArt_H", + "abilityName": "Avatar_Candace_ElementalArt_H", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_ElementalArt_ElemBall_Handler", + "abilityName": "Avatar_Candace_ElementalArt_ElemBall_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_ElementalArt_L", + "abilityName": "Avatar_Candace_ElementalArt_L", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_ElementalBurst", + "abilityName": "Avatar_Candace_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "AvatarIn_Attack_Constellation_61Candace_ElementalBurst_WaterField_AvatarIn_Attack", + "abilityName": "AvatarIn_Attack_Constellation_61Candace_ElementalBurst_WaterField_AvatarIn_Attack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_NormalAttack_DamageHandler", + "abilityName": "Avatar_Candace_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_FallingAnthem", + "abilityName": "Avatar_Candace_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_ClimbStamina_Reduction", + "abilityName": "Avatar_Candace_ClimbStamina_Reduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace", + "abilityName": "Avatar_Candace", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Skill_ElementalArt_BS", + "abilityName": "Avatar_Candace_Skill_ElementalArt_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Skill_ElementalArt_Charge01", + "abilityName": "Avatar_Candace_Skill_ElementalArt_Charge01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Skill_ElementalArt_Charge02", + "abilityName": "Avatar_Candace_Skill_ElementalArt_Charge02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Skill_ElementalArt_Charge03", + "abilityName": "Avatar_Candace_Skill_ElementalArt_Charge03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Skill_ElementalArt_L", + "abilityName": "Avatar_Candace_Skill_ElementalArt_L", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Skill_ElementalArt_H", + "abilityName": "Avatar_Candace_Skill_ElementalArt_H", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Skill_ElementalArt_L_AS", + "abilityName": "Avatar_Candace_Skill_ElementalArt_L_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Skill_ElementalArt_H_AS", + "abilityName": "Avatar_Candace_Skill_ElementalArt_H_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Skill_ElementalBurst", + "abilityName": "Avatar_Candace_Skill_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_TeamConfig_01BS", + "abilityName": "Avatar_Candace_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_TeamConfig_01Loop", + "abilityName": "Avatar_Candace_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_TeamConfig_01AS", + "abilityName": "Avatar_Candace_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Skill_ElementalBurst_AS", + "abilityName": "Avatar_Candace_Skill_ElementalBurst_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_ElementalBurst_Spine", + "abilityName": "Avatar_Candace_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Spine", + "abilityName": "Avatar_Candace_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_ElementalBurst_BS", + "abilityName": "Avatar_Candace_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_ElementalBurst_Hit", + "abilityName": "Avatar_Candace_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_ElementalBurst_Buff", + "abilityName": "Avatar_Candace_ElementalBurst_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Spine_Loop", + "abilityName": "Avatar_Candace_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Spine_Loop_BG", + "abilityName": "Avatar_Candace_Spine_Loop_BG", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Candace_Sub_Spine", + "abilityName": "Avatar_Candace_Sub_Spine", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Charlotte.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Charlotte.json new file mode 100644 index 0000000..98bb070 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Charlotte.json @@ -0,0 +1,429 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Charlotte_ExtraAttack", + "abilityName": "Avatar_Charlotte_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ExtraAttack_BS_Check", + "abilityName": "Avatar_Charlotte_ExtraAttack_BS_Check", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Attack01", + "abilityName": "Avatar_Charlotte_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Attack01_onMonster", + "abilityName": "Avatar_Charlotte_Attack01_onMonster", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Attack01_None", + "abilityName": "Avatar_Charlotte_Attack01_None", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Attack02", + "abilityName": "Avatar_Charlotte_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Attack02_onMonster", + "abilityName": "Avatar_Charlotte_Attack02_onMonster", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Attack02_None", + "abilityName": "Avatar_Charlotte_Attack02_None", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Attack03", + "abilityName": "Avatar_Charlotte_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ExtraAttack_DoAttack", + "abilityName": "Avatar_Charlotte_ExtraAttack_DoAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ExtraAttack_Gadget", + "abilityName": "Avatar_Charlotte_ExtraAttack_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ExtraAttack_GadgetEffect", + "abilityName": "Avatar_Charlotte_ExtraAttack_GadgetEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ExtraAttack_Damage", + "abilityName": "Avatar_Charlotte_ExtraAttack_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ExtraAttack_Arkhe_Strike", + "abilityName": "Avatar_Charlotte_ExtraAttack_Arkhe_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ExtraAttack_Arkhe_CDTimer_", + "abilityName": "Avatar_Charlotte_ExtraAttack_Arkhe_CDTimer_", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ExtraAttack_Arkhe_CDTimer", + "abilityName": "Avatar_Charlotte_ExtraAttack_Arkhe_CDTimer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArt", + "abilityName": "Avatar_Charlotte_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArt_DropBall_Handler", + "abilityName": "Avatar_Charlotte_ElementalArt_DropBall_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArt_Click", + "abilityName": "Avatar_Charlotte_ElementalArt_Click", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArt_Click_Strike", + "abilityName": "Avatar_Charlotte_ElementalArt_Click_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArt_Click_CameraReborn", + "abilityName": "Avatar_Charlotte_ElementalArt_Click_CameraReborn", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArtHold_RayCast", + "abilityName": "Avatar_Charlotte_ElementalArtHold_RayCast", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_InAim_SetGV", + "abilityName": "Avatar_Charlotte_RayCast_InAim_SetGV", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_Trigger", + "abilityName": "Avatar_Charlotte_RayCast_Trigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_CloseFx", + "abilityName": "Avatar_Charlotte_RayCast_CloseFx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_Handler", + "abilityName": "Avatar_Charlotte_RayCast_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_Camera_Fx", + "abilityName": "Avatar_Charlotte_RayCast_Camera_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_HoldTimeChangeRayCast", + "abilityName": "Avatar_Charlotte_HoldTimeChangeRayCast", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_InHoldTime", + "abilityName": "Avatar_Charlotte_InHoldTime", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_MaxHoldTime_TriggerDot", + "abilityName": "Avatar_Charlotte_MaxHoldTime_TriggerDot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_CloseFx_Detect", + "abilityName": "Avatar_Charlotte_RayCast_CloseFx_Detect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_InterruptFx", + "abilityName": "Avatar_Charlotte_RayCast_InterruptFx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_Bomb_OnMonster_CountLayerHandler", + "abilityName": "Avatar_Charlotte_RayCast_Bomb_OnMonster_CountLayerHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_Bomb_OnMonster_CountLayerHandler02", + "abilityName": "Avatar_Charlotte_RayCast_Bomb_OnMonster_CountLayerHandler02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_Bomb_OnMonster_Damage", + "abilityName": "Avatar_Charlotte_RayCast_Bomb_OnMonster_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArt_ScreenEffect", + "abilityName": "Avatar_Charlotte_ElementalArt_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_Bomb_OnMonster_Dot_Handler", + "abilityName": "Avatar_Charlotte_RayCast_Bomb_OnMonster_Dot_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_Bomb_OnMonster_Effect_Weak", + "abilityName": "Avatar_Charlotte_RayCast_Bomb_OnMonster_Effect_Weak", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_Bomb_OnMonster_Effect_Strong", + "abilityName": "Avatar_Charlotte_RayCast_Bomb_OnMonster_Effect_Strong", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_Bomb_OnMonster_Weak", + "abilityName": "Avatar_Charlotte_RayCast_Bomb_OnMonster_Weak", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_Bomb_OnMonster_Strong", + "abilityName": "Avatar_Charlotte_RayCast_Bomb_OnMonster_Strong", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_Bomb_OnMonster_ToFullLayer", + "abilityName": "Avatar_Charlotte_RayCast_Bomb_OnMonster_ToFullLayer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_RayCast_Camera_Fx_OnTeam", + "abilityName": "Avatar_Charlotte_RayCast_Camera_Fx_OnTeam", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_HoldTimeChangeRayCast_Trigger", + "abilityName": "Avatar_Charlotte_HoldTimeChangeRayCast_Trigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArt_TagNum_Clear", + "abilityName": "Avatar_Charlotte_ElementalArt_TagNum_Clear", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArt_Click_AddDotHandler", + "abilityName": "Avatar_Charlotte_ElementalArt_Click_AddDotHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArt_TagNum_Clear0Avatar_Charlotte_ElementalArt_Hold_AddDotHandler", + "abilityName": "Avatar_Charlotte_ElementalArt_TagNum_Clear0Avatar_Charlotte_ElementalArt_Hold_AddDotHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArt_Hold_AddDotHandler", + "abilityName": "Avatar_Charlotte_ElementalArt_Hold_AddDotHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArt_WidgetMode", + "abilityName": "Avatar_Charlotte_ElementalArt_WidgetMode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArt_WidgetMode_Check", + "abilityName": "Avatar_Charlotte_ElementalArt_WidgetMode_Check", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalArt_Loop_WidgetMode", + "abilityName": "Avatar_Charlotte_ElementalArt_Loop_WidgetMode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalBurst_Init", + "abilityName": "Avatar_Charlotte_ElementalBurst_Init", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_ElementalBurst", + "abilityName": "Avatar_Charlotte_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_FallingAnthem", + "abilityName": "Avatar_Charlotte_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_WaistCamera_DisAppear", + "abilityName": "Avatar_Charlotte_WaistCamera_DisAppear", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_WaistCamera_Appear", + "abilityName": "Avatar_Charlotte_WaistCamera_Appear", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_PermanentSkill_1", + "abilityName": "Avatar_Charlotte_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_PermanentSkill_1_Handler", + "abilityName": "Avatar_Charlotte_PermanentSkill_1_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_PermanentSkill_2", + "abilityName": "Avatar_Charlotte_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_PermanentSkill_2_IsNotFengdan", + "abilityName": "Avatar_Charlotte_PermanentSkill_2_IsNotFengdan", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_PermanentSkill_2_NotFengdanCount", + "abilityName": "Avatar_Charlotte_PermanentSkill_2_NotFengdanCount", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_Extra_Hot", + "abilityName": "Avatar_Charlotte_Constellation_Extra_Hot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_Extra_Hot_Handler", + "abilityName": "Avatar_Charlotte_Constellation_Extra_Hot_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_Extra_Hot_EffectHandler", + "abilityName": "Avatar_Charlotte_Constellation_Extra_Hot_EffectHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_Extra_Hot_Tick", + "abilityName": "Avatar_Charlotte_Constellation_Extra_Hot_Tick", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_ElementalArt_AddAtkUp", + "abilityName": "Avatar_Charlotte_Constellation_ElementalArt_AddAtkUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_ElementalArt_AddAtk_ClearCount", + "abilityName": "Avatar_Charlotte_Constellation_ElementalArt_AddAtk_ClearCount", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_ReviveElemEnergy", + "abilityName": "Avatar_Charlotte_Constellation_ReviveElemEnergy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_ExtraCameraAttack", + "abilityName": "Avatar_Charlotte_Constellation_ExtraCameraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_ExtraCameraAttack_Handler", + "abilityName": "Avatar_Charlotte_Constellation_ExtraCameraAttack_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_ExtraCameraAttack_TeamHandler", + "abilityName": "Avatar_Charlotte_Constellation_ExtraCameraAttack_TeamHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_ExtraCameraAttack_TeamHandlerCUNIQUE_Avatar_Charlotte_Constellation_ExtraCameraAttack_TeamHandler", + "abilityName": "Avatar_Charlotte_Constellation_ExtraCameraAttack_TeamHandlerCUNIQUE_Avatar_Charlotte_Constellation_ExtraCameraAttack_TeamHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_ExtraCamera_Gadget", + "abilityName": "Avatar_Charlotte_Constellation_ExtraCamera_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_ExtraCamera_Effect", + "abilityName": "Avatar_Charlotte_Constellation_ExtraCamera_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte", + "abilityName": "Avatar_Charlotte", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_Extra_Hot4Avatar_Charlotte_Constellation_ElementalArt_AddAtkUp", + "abilityName": "Avatar_Charlotte_Constellation_Extra_Hot4Avatar_Charlotte_Constellation_ElementalArt_AddAtkUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Skill_ElementalArt_BS", + "abilityName": "Avatar_Charlotte_Skill_ElementalArt_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Skill_ElementalArt_Click0Emo_Avatar_Charlotte_Skill_ElementalArt_Click_AS0Emo_Avatar_Charlotte_Skill_ElementalArt_AimFocus1Emo_Avatar_Charlotte_Skill_ElementalArt_QuitFocus4Emo_Avatar_Charlotte_Skill_ElementalArt_QuitFocus_AS", + "abilityName": "Avatar_Charlotte_Skill_ElementalArt_Click0Emo_Avatar_Charlotte_Skill_ElementalArt_Click_AS0Emo_Avatar_Charlotte_Skill_ElementalArt_AimFocus1Emo_Avatar_Charlotte_Skill_ElementalArt_QuitFocus4Emo_Avatar_Charlotte_Skill_ElementalArt_QuitFocus_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Skill_ElementalBurst", + "abilityName": "Avatar_Charlotte_Skill_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Skill_ElementalBurst_AS", + "abilityName": "Avatar_Charlotte_Skill_ElementalBurst_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_TeamConfig_01BS", + "abilityName": "Avatar_Charlotte_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_TeamConfig_01Loop", + "abilityName": "Avatar_Charlotte_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_TeamConfig_01AS", + "abilityName": "Avatar_Charlotte_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Charlotte_Constellation_ExtraCamera_Gadget1Avatar_Charlotte_Constellation_ExtraCamera_Gadget", + "abilityName": "Avatar_Charlotte_Constellation_ExtraCamera_Gadget1Avatar_Charlotte_Constellation_ExtraCamera_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "AvatarIcon_Charlotte", + "abilityName": "AvatarIcon_Charlotte", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Chevreuse.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Chevreuse.json new file mode 100644 index 0000000..f7858c8 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Chevreuse.json @@ -0,0 +1,174 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Chevreuse_ExtraAttack", + "abilityName": "Avatar_Chevreuse_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ExtraAttack_Cast", + "abilityName": "Avatar_Chevreuse_ExtraAttack_Cast", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ExtraAttack_Bullet", + "abilityName": "Avatar_Chevreuse_ExtraAttack_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ElementalArt", + "abilityName": "Avatar_Chevreuse_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_Has_Target_Mark", + "abilityName": "Avatar_Chevreuse_Has_Target_Mark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ElementalArt_Click", + "abilityName": "Avatar_Chevreuse_ElementalArt_Click", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ElementalArt_Shoot", + "abilityName": "Avatar_Chevreuse_ElementalArt_Shoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_Damage_Up", + "abilityName": "Avatar_Chevreuse_Damage_Up", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ExtraArt_Chance", + "abilityName": "Avatar_Chevreuse_ExtraArt_Chance", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ExtraBomb", + "abilityName": "Avatar_Chevreuse_ExtraBomb", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_DropBall", + "abilityName": "Avatar_Chevreuse_DropBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ArkheGrade", + "abilityName": "Avatar_Chevreuse_ArkheGrade", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ArkheGrade_CD", + "abilityName": "Avatar_Chevreuse_ArkheGrade_CD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ElementalBurst", + "abilityName": "Avatar_Chevreuse_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ElementalArt_UpgradeBullet", + "abilityName": "Avatar_Chevreuse_ElementalArt_UpgradeBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ElementalArt_UpgradeBullet_Driver", + "abilityName": "Avatar_Chevreuse_ElementalArt_UpgradeBullet_Driver", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_SuperBullet_Buff", + "abilityName": "Avatar_Chevreuse_SuperBullet_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ElementalArt_UpgradeBullet_Handler", + "abilityName": "Avatar_Chevreuse_ElementalArt_UpgradeBullet_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ElementalArt_UpgradeBullet_Driver2Avatar_Chevreuse_ElementalArt_UpgradeBullet_Driver", + "abilityName": "Avatar_Chevreuse_ElementalArt_UpgradeBullet_Driver2Avatar_Chevreuse_ElementalArt_UpgradeBullet_Driver", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_ElementalArt_Feedback", + "abilityName": "Avatar_Chevreuse_ElementalArt_Feedback", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_SuperBullet_Eff", + "abilityName": "Avatar_Chevreuse_SuperBullet_Eff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_Buff", + "abilityName": "Avatar_Chevreuse_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_ElementalArt_Buff_Chevreuse", + "abilityName": "Avatar_ElementalArt_Buff_Chevreuse", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_ElementalArt_Buff_Chevreuse_Driver", + "abilityName": "Avatar_ElementalArt_Buff_Chevreuse_Driver", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_ElementalArt_Buff_Chevreuse_Driver0UNIQUE_Avatar_ElementalArt_Buff_Chevreuse_Driver", + "abilityName": "Avatar_ElementalArt_Buff_Chevreuse_Driver0UNIQUE_Avatar_ElementalArt_Buff_Chevreuse_Driver", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_ElementalArt_Buff_Chevreuse_Feedback", + "abilityName": "Avatar_ElementalArt_Buff_Chevreuse_Feedback", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_CreateBomb", + "abilityName": "Avatar_Chevreuse_CreateBomb", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_DashStamina_Reduction", + "abilityName": "Avatar_Chevreuse_DashStamina_Reduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_NormalAttack_DamageHandler", + "abilityName": "Avatar_Chevreuse_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_FallingAnthem", + "abilityName": "Avatar_Chevreuse_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse", + "abilityName": "Avatar_Chevreuse", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_TeamConfig_01BS", + "abilityName": "Avatar_Chevreuse_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_TeamConfig_01Loop", + "abilityName": "Avatar_Chevreuse_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chevreuse_TeamConfig_01AS", + "abilityName": "Avatar_Chevreuse_TeamConfig_01AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Chongyun.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Chongyun.json new file mode 100644 index 0000000..190666c --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Chongyun.json @@ -0,0 +1,124 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Beidou_ExtraAttack_Chongyun", + "abilityName": "Avatar_Beidou_ExtraAttack_Chongyun", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_ElementalArt_Initiate", + "abilityName": "Avatar_Chongyun_ElementalArt_Initiate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_ElementalArt_Damage", + "abilityName": "Avatar_Chongyun_ElementalArt_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_IceCrystal", + "abilityName": "Avatar_Chongyun_IceCrystal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_IceCrystal_Dummy", + "abilityName": "Avatar_Chongyun_IceCrystal_Dummy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_SoulUnleash_Single_Initiate", + "abilityName": "Avatar_Chongyun_SoulUnleash_Single_Initiate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_SoulUnleash_Initiate", + "abilityName": "Avatar_Chongyun_SoulUnleash_Initiate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_SoulUnleash_SoulBlades_Quadra", + "abilityName": "Avatar_Chongyun_SoulUnleash_SoulBlades_Quadra", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_SoulUnleash_SoulBlades", + "abilityName": "Avatar_Chongyun_SoulUnleash_SoulBlades", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_SoulUnleash_Damage", + "abilityName": "Avatar_Chongyun_SoulUnleash_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_SoulUnleash_Quadra_Damage", + "abilityName": "Avatar_Chongyun_SoulUnleash_Quadra_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_HitReviveElemEnergy", + "abilityName": "Avatar_Chongyun_HitReviveElemEnergy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_NormalAttack_DamageHandler", + "abilityName": "Avatar_Chongyun_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_IceBlade", + "abilityName": "Avatar_Chongyun_IceBlade", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_FallingAnthem", + "abilityName": "Avatar_Chongyun_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun", + "abilityName": "Avatar_Chongyun", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_TeamConfig_01BS", + "abilityName": "Avatar_Chongyun_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_TeamConfig_01Loop", + "abilityName": "Avatar_Chongyun_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_TeamConfig_01AS", + "abilityName": "Avatar_Chongyun_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_ElementalBurst_Spine", + "abilityName": "Avatar_Chongyun_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_ElementalBurst_Hit", + "abilityName": "Avatar_Chongyun_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_ElementalBurst_BS", + "abilityName": "Avatar_Chongyun_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_ElementalBurst_Hit_NoSpine", + "abilityName": "Avatar_Chongyun_ElementalBurst_Hit_NoSpine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Chongyun_Spine_Loop", + "abilityName": "Avatar_Chongyun_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Collei.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Collei.json new file mode 100644 index 0000000..b3184bd --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Collei.json @@ -0,0 +1,144 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Collei_PressShoot", + "abilityName": "Avatar_Collei_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_AimPressShoot", + "abilityName": "Avatar_Collei_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_Arrow_FX", + "abilityName": "Avatar_Collei_Arrow_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_ShootAimingArrow_Charge", + "abilityName": "Avatar_Collei_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_ShootArrow_01", + "abilityName": "Avatar_Collei_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_ShootArrow_02", + "abilityName": "Avatar_Collei_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_ShootArrow_03", + "abilityName": "Avatar_Collei_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_ShootArrow_04", + "abilityName": "Avatar_Collei_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_ShootArrow_Aiming", + "abilityName": "Avatar_Collei_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_ElementalArt", + "abilityName": "Avatar_Collei_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_ElementalBurst", + "abilityName": "Avatar_Collei_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_FallingAnthem", + "abilityName": "Avatar_Collei_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_FlyStamina_Reduction", + "abilityName": "Avatar_Collei_FlyStamina_Reduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei", + "abilityName": "Avatar_Collei", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_PermanentSkill_2", + "abilityName": "Avatar_Collei_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_Skill_ElementalArt", + "abilityName": "Avatar_Collei_Skill_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_Skill_ElementalArt_AS", + "abilityName": "Avatar_Collei_Skill_ElementalArt_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_Skill_ElementalBurst", + "abilityName": "Avatar_Collei_Skill_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_Skill_ElementalBurst_AS", + "abilityName": "Avatar_Collei_Skill_ElementalBurst_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_TeamConfig_01BS", + "abilityName": "Avatar_Collei_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_TeamConfig_01Loop", + "abilityName": "Avatar_Collei_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_TeamConfig_01AS", + "abilityName": "Avatar_Collei_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_ElementalBurst_Spine", + "abilityName": "Avatar_Collei_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_ElementalBurst_BS", + "abilityName": "Avatar_Collei_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_ElementBurst", + "abilityName": "Avatar_Collei_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_ElementalBurst_Hit", + "abilityName": "Avatar_Collei_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_elementalBurst_BS_Normal", + "abilityName": "Avatar_Collei_elementalBurst_BS_Normal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Collei_Spine_Loop", + "abilityName": "Avatar_Collei_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Cyno.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Cyno.json new file mode 100644 index 0000000..7b63c72 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Cyno.json @@ -0,0 +1,319 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Cyno_ExtraAttack", + "abilityName": "Avatar_Cyno_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Attack05_TurndDirection", + "abilityName": "Avatar_Cyno_Attack05_TurndDirection", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Attack03_FireHitEffect_Handler", + "abilityName": "Avatar_Cyno_Attack03_FireHitEffect_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Attack03_Hit", + "abilityName": "Avatar_Cyno_Attack03_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Attack03_Hit_0", + "abilityName": "Avatar_Cyno_Attack03_Hit_0", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Attack03_Hit_1", + "abilityName": "Avatar_Cyno_Attack03_Hit_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Attack03_Hit_2", + "abilityName": "Avatar_Cyno_Attack03_Hit_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ExtraAttack_CreateBullet", + "abilityName": "Avatar_Cyno_ExtraAttack_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ExtraAttack_Bullet", + "abilityName": "Avatar_Cyno_ExtraAttack_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalArt_DropBallCheck", + "abilityName": "Avatar_Cyno_ElementalArt_DropBallCheck", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalArt_DropBall", + "abilityName": "Avatar_Cyno_ElementalArt_DropBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalArt_Bullet", + "abilityName": "Avatar_Cyno_ElementalArt_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_BurstMode_ElementalArt_Onstart", + "abilityName": "Avatar_Cyno_BurstMode_ElementalArt_Onstart", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Constellation_6", + "abilityName": "Avatar_Cyno_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalArt_Muya_Success_Handler", + "abilityName": "Avatar_Cyno_ElementalArt_Muya_Success_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst", + "abilityName": "Avatar_Cyno_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_Invincible", + "abilityName": "Avatar_Cyno_ElementalBurst_Invincible", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_CameraBlur_Handler", + "abilityName": "Avatar_Cyno_ElementalBurst_CameraBlur_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_CameraBlur_Effect", + "abilityName": "Avatar_Cyno_ElementalBurst_CameraBlur_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_ChangeVisible", + "abilityName": "Avatar_Cyno_ElementalBurst_ChangeVisible", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_ResetInit", + "abilityName": "Avatar_Cyno_ElementalBurst_ResetInit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_Fog_Handler", + "abilityName": "Avatar_Cyno_ElementalBurst_Fog_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_Weather_DisPlayHandler", + "abilityName": "Avatar_Cyno_ElementalBurst_Weather_DisPlayHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_Weather_LoopHandler", + "abilityName": "Avatar_Cyno_ElementalBurst_Weather_LoopHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_ChangeWeather", + "abilityName": "Avatar_Cyno_ElementalBurst_ChangeWeather", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_BigArmAppear", + "abilityName": "Avatar_Cyno_BigArmAppear", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ArmBreak", + "abilityName": "Avatar_Cyno_ArmBreak", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_BurstMode_State_Badao", + "abilityName": "Avatar_Cyno_BurstMode_State_Badao", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_BigArmDisAppear", + "abilityName": "Avatar_Cyno_BigArmDisAppear", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_WarningCameraEffect", + "abilityName": "Avatar_Cyno_ElementalBurst_WarningCameraEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_JackalMode", + "abilityName": "Avatar_Cyno_ElementalBurst_JackalMode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_WarningCameraEffectM", + "abilityName": "Avatar_Cyno_ElementalBurst_WarningCameraEffectM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_MuyaHandlerT", + "abilityName": "Avatar_Cyno_ElementalBurst_MuyaHandlerT", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_MuyaHandler", + "abilityName": "Avatar_Cyno_ElementalBurst_MuyaHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_Renderer_HandlerR", + "abilityName": "Avatar_Cyno_ElementalBurst_Renderer_HandlerR", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Constellation_6_BulletHandlerR", + "abilityName": "Avatar_Cyno_Constellation_6_BulletHandlerR", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_EndMode", + "abilityName": "Avatar_Cyno_ElementalBurst_EndMode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_Renderer_Handler", + "abilityName": "Avatar_Cyno_ElementalBurst_Renderer_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_Renderer_AttackHandler", + "abilityName": "Avatar_Cyno_ElementalBurst_Renderer_AttackHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_MuyaAddTime", + "abilityName": "Avatar_Cyno_ElementalBurst_MuyaAddTime", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Constellation_6_BulletHandler", + "abilityName": "Avatar_Cyno_Constellation_6_BulletHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_EndHanlder", + "abilityName": "Avatar_Cyno_ElementalBurst_EndHanlder", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_Buff_AddDurability", + "abilityName": "Avatar_Cyno_ElementalBurst_Buff_AddDurability", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_FallingAnthem", + "abilityName": "Avatar_Cyno_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_onReconnectHandler", + "abilityName": "Avatar_Cyno_ElementalBurst_onReconnectHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_BigArm_DisAppear", + "abilityName": "Avatar_Cyno_BigArm_DisAppear", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ExtraAttack_BurstMode_Damage", + "abilityName": "Avatar_Cyno_ExtraAttack_BurstMode_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_BurstMode_ExtraAttack_Bullet", + "abilityName": "Avatar_Cyno_BurstMode_ExtraAttack_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Attack_DamageHandler", + "abilityName": "Avatar_Cyno_Attack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Constellation_6_BulletCdHandler", + "abilityName": "Avatar_Cyno_Constellation_6_BulletCdHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno", + "abilityName": "Avatar_Cyno", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_TeamConfig_01BS", + "abilityName": "Avatar_Cyno_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_TeamConfig_01Loop", + "abilityName": "Avatar_Cyno_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_TeamConfig_01AS", + "abilityName": "Avatar_Cyno_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_BurstMode_ExtraAttack_Bulletr", + "abilityName": "Avatar_Cyno_BurstMode_ExtraAttack_Bulletr", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_Spine", + "abilityName": "Avatar_Cyno_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_BS", + "abilityName": "Avatar_Cyno_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_ElementalBurst_Hit", + "abilityName": "Avatar_Cyno_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Spine_Loop_01", + "abilityName": "Avatar_Cyno_Spine_Loop_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Spine", + "abilityName": "Avatar_Cyno_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Spine_Loop_02", + "abilityName": "Avatar_Cyno_Spine_Loop_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_02_Spine", + "abilityName": "Avatar_Cyno_02_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Cyno_Attack_DamageHandler1Cyno_PermanentSkill_2_Ratio_BurstModeNormalAttack", + "abilityName": "Avatar_Cyno_Attack_DamageHandler1Cyno_PermanentSkill_2_Ratio_BurstModeNormalAttack", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Dehya.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Dehya.json new file mode 100644 index 0000000..2858bc8 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Dehya.json @@ -0,0 +1,489 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Dehya_ExtraAttack", + "abilityName": "Avatar_Dehya_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Insert", + "abilityName": "Avatar_Dehya_ElementalArt_Insert", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Insert_Initialize", + "abilityName": "Avatar_Dehya_ElementalArt_Insert_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_PermanentSkill_1_B", + "abilityName": "Avatar_Dehya_PermanentSkill_1_B", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_DropBall_Handler", + "abilityName": "Avatar_Dehya_ElementalArt_DropBall_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_DropBall", + "abilityName": "Avatar_Dehya_ElementalArt_DropBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Recycle", + "abilityName": "Avatar_Dehya_ElementalArt_Recycle", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_TriggerRecycle", + "abilityName": "Avatar_Dehya_ElementalArt_TriggerRecycle", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_RecycleDamage", + "abilityName": "Avatar_Dehya_ElementalArt_RecycleDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_RecycleDamage_Remover", + "abilityName": "Avatar_Dehya_ElementalArt_RecycleDamage_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_PermanentSkill_1_A", + "abilityName": "Avatar_Dehya_PermanentSkill_1_A", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_TriggerRecycle_Fx", + "abilityName": "Avatar_Dehya_ElementalArt_TriggerRecycle_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_RecycleDamageV", + "abilityName": "Avatar_Dehya_ElementalArt_RecycleDamageV", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_LoanHandler", + "abilityName": "Avatar_Dehya_ElementalArt_LoanHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_LoanFx", + "abilityName": "Avatar_Dehya_ElementalArt_LoanFx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_LoanFx_Handler", + "abilityName": "Avatar_Dehya_ElementalArt_LoanFx_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_LoanFx_Lv1", + "abilityName": "Avatar_Dehya_ElementalArt_LoanFx_Lv1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_LoanFx_Lv2", + "abilityName": "Avatar_Dehya_ElementalArt_LoanFx_Lv2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_LoanFx_Lv1M", + "abilityName": "Avatar_Dehya_ElementalArt_LoanFx_Lv1M", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_Initialize", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_LifeTimer", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_LifeTimer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_CDInherit", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_CDInherit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_Fx", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_Fx_01", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_Fx_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_Fx_02", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_Fx_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_Fx_LevelHandler", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_Fx_LevelHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_CheckInField", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_CheckInField", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_PermanentSkill_EndureUp", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_PermanentSkill_EndureUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_OnDehya", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_OnDehya", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_OnDehya_SwitchSkill", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_OnDehya_SwitchSkill", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_AttackHandler", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_AttackHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_OnMonster", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_OnMonster", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_AttackByGrave", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_AttackByGrave", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_CheckInFieldM", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_CheckInFieldM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_Bullet_Trail", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_Bullet_Trail", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Grave_Bullet_Timer", + "abilityName": "Avatar_Dehya_ElementalArt_Grave_Bullet_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Recycleh", + "abilityName": "Avatar_Dehya_ElementalArt_Recycleh", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst", + "abilityName": "Avatar_Dehya_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Initialize", + "abilityName": "Avatar_Dehya_ElementalBurst_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Starter", + "abilityName": "Avatar_Dehya_ElementalBurst_Starter", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Timer", + "abilityName": "Avatar_Dehya_ElementalBurst_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Fx", + "abilityName": "Avatar_Dehya_ElementalBurst_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_EmotionControl", + "abilityName": "Avatar_Dehya_ElementalBurst_EmotionControl", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Camera_Handler", + "abilityName": "Avatar_Dehya_ElementalBurst_Camera_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Camera_PushTarget", + "abilityName": "Avatar_Dehya_ElementalBurst_Camera_PushTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Invincible", + "abilityName": "Avatar_Dehya_ElementalBurst_Invincible", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_WeatherChange", + "abilityName": "Avatar_Dehya_ElementalBurst_WeatherChange", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_BladeStorm_SwitchSkill", + "abilityName": "Avatar_Dehya_BladeStorm_SwitchSkill", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_BladeStorm", + "abilityName": "Avatar_Dehya_ElementalBurst_BladeStorm", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_BladeStorm_Remover", + "abilityName": "Avatar_Dehya_ElementalBurst_BladeStorm_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Camera_DungeonEffect", + "abilityName": "Avatar_Dehya_ElementalBurst_Camera_DungeonEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_PermanentSkill_1_AR", + "abilityName": "Avatar_Dehya_PermanentSkill_1_AR", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_SprintCancle", + "abilityName": "Avatar_Dehya_ElementalBurst_SprintCancle", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_StandbyCancle", + "abilityName": "Avatar_Dehya_ElementalBurst_StandbyCancle", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Controller", + "abilityName": "Avatar_Dehya_ElementalBurst_Controller", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_BladeStorm_ClearTrigger", + "abilityName": "Avatar_Dehya_BladeStorm_ClearTrigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_BladeStorm_QTE_Success", + "abilityName": "Avatar_Dehya_BladeStorm_QTE_Success", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_BladeStorm_Strike_A", + "abilityName": "Avatar_Dehya_BladeStorm_Strike_A", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_BladeStorm_Strike_B", + "abilityName": "Avatar_Dehya_BladeStorm_Strike_B", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_BladeStorm_TurnDir", + "abilityName": "Avatar_Dehya_ElementalBurst_BladeStorm_TurnDir", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_BladeStorm_TurnDir_Last", + "abilityName": "Avatar_Dehya_ElementalBurst_BladeStorm_TurnDir_Last", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_BladeStorm_Fx_Remover", + "abilityName": "Avatar_Dehya_BladeStorm_Fx_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_BladeStorm_Speed_Handler", + "abilityName": "Avatar_Dehya_BladeStorm_Speed_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_BladeStorm_SpeedUp", + "abilityName": "Avatar_Dehya_BladeStorm_SpeedUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_PermanentSkill_1_Buff", + "abilityName": "Avatar_Dehya_PermanentSkill_1_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_PermanentSkill_A_Timer", + "abilityName": "Avatar_Dehya_PermanentSkill_A_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_PermanentSkill_B_Timer", + "abilityName": "Avatar_Dehya_PermanentSkill_B_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_PermanentSkill_B_Buff", + "abilityName": "Avatar_Dehya_PermanentSkill_B_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_PermanentSkill_2", + "abilityName": "Avatar_Dehya_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_PermanentSkill_2_Handler", + "abilityName": "Avatar_Dehya_PermanentSkill_2_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_PermanentSkill_2_HotBuff", + "abilityName": "Avatar_Dehya_PermanentSkill_2_HotBuff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_PermanentSkill_2_CDTimer", + "abilityName": "Avatar_Dehya_PermanentSkill_2_CDTimer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_Constellation_6", + "abilityName": "Avatar_Dehya_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_Constellation_6_CritUp", + "abilityName": "Avatar_Dehya_Constellation_6_CritUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_Constellation_6_CritHurtUp", + "abilityName": "Avatar_Dehya_Constellation_6_CritHurtUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_Constellation_6_Handler", + "abilityName": "Avatar_Dehya_Constellation_6_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_Constellation_6_Initialize", + "abilityName": "Avatar_Dehya_Constellation_6_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_Constellation_6_Remover", + "abilityName": "Avatar_Dehya_Constellation_6_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_Constellation_6_Crit_CountUp", + "abilityName": "Avatar_Dehya_Constellation_6_Crit_CountUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_Attack_DamageHandler", + "abilityName": "Avatar_Dehya_Attack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_FallingAnthem", + "abilityName": "Avatar_Dehya_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya", + "abilityName": "Avatar_Dehya", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Insert_AS", + "abilityName": "Avatar_Dehya_ElementalArt_Insert_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalArt_Recycle_AS", + "abilityName": "Avatar_Dehya_ElementalArt_Recycle_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Loop_A", + "abilityName": "Avatar_Dehya_ElementalBurst_Loop_A", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Loop_B", + "abilityName": "Avatar_Dehya_ElementalBurst_Loop_B", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_End", + "abilityName": "Avatar_Dehya_ElementalBurst_End", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_AS", + "abilityName": "Avatar_Dehya_ElementalBurst_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_TeamConfig_01BS", + "abilityName": "Avatar_Dehya_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_TeamConfig_01Loop", + "abilityName": "Avatar_Dehya_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_TeamConfig_01AS", + "abilityName": "Avatar_Dehya_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "AvatarItem_Dehya_SumeruHairpin", + "abilityName": "AvatarItem_Dehya_SumeruHairpin", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Spine", + "abilityName": "Avatar_Dehya_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_BS", + "abilityName": "Avatar_Dehya_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Hit", + "abilityName": "Avatar_Dehya_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_ElementalBurst_Hit_02", + "abilityName": "Avatar_Dehya_ElementalBurst_Hit_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dehya_Spine_Loop", + "abilityName": "Avatar_Dehya_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Diluc.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Diluc.json new file mode 100644 index 0000000..ef37b64 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Diluc.json @@ -0,0 +1,174 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Diluc_ExtraAttack", + "abilityName": "Avatar_Diluc_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_Fire_Blade", + "abilityName": "Avatar_Diluc_Fire_Blade", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_Fire_BladeSet1", + "abilityName": "Avatar_Diluc_Fire_BladeSet1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_AfterFireBlade", + "abilityName": "Avatar_Diluc_AfterFireBlade", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_Fire_BladeSet2", + "abilityName": "Avatar_Diluc_Fire_BladeSet2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_Fire_BladeSet3", + "abilityName": "Avatar_Diluc_Fire_BladeSet3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_Fire_Enhancement", + "abilityName": "Avatar_Diluc_Fire_Enhancement", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_FireCrossCamera", + "abilityName": "Avatar_Diluc_FireCrossCamera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_FireCross_Push1", + "abilityName": "Avatar_Diluc_FireCross_Push1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_FireCross_Strike", + "abilityName": "Avatar_Diluc_FireCross_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_FireCross", + "abilityName": "Avatar_Diluc_FireCross", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_FireCross_Explode", + "abilityName": "Avatar_Diluc_FireCross_Explode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_NormalAttackDamage", + "abilityName": "Avatar_Diluc_NormalAttackDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_ElementArt", + "abilityName": "Avatar_Diluc_ElementArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_GiantKiller", + "abilityName": "Avatar_Diluc_GiantKiller", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_FireHowl", + "abilityName": "Avatar_Diluc_FireHowl", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_AfterFireBladeCountDown", + "abilityName": "Avatar_Diluc_AfterFireBladeCountDown", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_NextFireBlade1", + "abilityName": "Avatar_Diluc_NextFireBlade1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_NextFireBlade2", + "abilityName": "Avatar_Diluc_NextFireBlade2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_FallingAnthem", + "abilityName": "Avatar_Diluc_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc", + "abilityName": "Avatar_Diluc", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_TeamConfig_01BS", + "abilityName": "Avatar_Diluc_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_TeamConfig_01Loop", + "abilityName": "Avatar_Diluc_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_TeamConfig_01AS", + "abilityName": "Avatar_Diluc_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "AvatarItem_Diluc_Mask", + "abilityName": "AvatarItem_Diluc_Mask", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_Fire_Enchantment", + "abilityName": "Avatar_Diluc_Fire_Enchantment", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_ElementalBurst_Spine", + "abilityName": "Avatar_Diluc_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_ElementalBurst_Spine_MotionBlur", + "abilityName": "Avatar_Diluc_ElementalBurst_Spine_MotionBlur", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_Spine", + "abilityName": "Avatar_Diluc_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_ElementalBurst", + "abilityName": "Avatar_Diluc_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_ElementBurst", + "abilityName": "Avatar_Diluc_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_ElementalBurst_Hit", + "abilityName": "Avatar_Diluc_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_Spine_Loop", + "abilityName": "Avatar_Diluc_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diluc_Spine_BG", + "abilityName": "Avatar_Diluc_Spine_BG", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Diona.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Diona.json new file mode 100644 index 0000000..0b16ef0 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Diona.json @@ -0,0 +1,224 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Diona_Arrow_FX", + "abilityName": "Avatar_Diona_Arrow_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ShootAimingArrow_Charge", + "abilityName": "Avatar_Diona_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_PressShoot", + "abilityName": "Avatar_Diona_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ShootArrow_Aiming", + "abilityName": "Avatar_Diona_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ShootArrow_ResetGlobalValue", + "abilityName": "Avatar_Diona_ShootArrow_ResetGlobalValue", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_AimPressShoot", + "abilityName": "Avatar_Diona_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ShootArrow_Enchanted_WithoutIce", + "abilityName": "Avatar_Diona_ShootArrow_Enchanted_WithoutIce", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ShootArrow_01", + "abilityName": "Avatar_Diona_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ShootArrow_02", + "abilityName": "Avatar_Diona_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ShootArrow_03", + "abilityName": "Avatar_Diona_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ShootArrow_04", + "abilityName": "Avatar_Diona_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ShootArrow_05", + "abilityName": "Avatar_Diona_ShootArrow_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_NekoShoot_Press", + "abilityName": "Avatar_Diona_NekoShoot_Press", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_NekoShoot_Holdup", + "abilityName": "Avatar_Diona_NekoShoot_Holdup", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ElementalArt_Shield", + "abilityName": "Avatar_Diona_ElementalArt_Shield", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ElementalArt_Bullet_Trail_01", + "abilityName": "Avatar_Diona_ElementalArt_Bullet_Trail_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ElementalArt_Bullet_Trail_02", + "abilityName": "Avatar_Diona_ElementalArt_Bullet_Trail_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_Elemental_Burst_Attack", + "abilityName": "Avatar_Diona_Elemental_Burst_Attack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_Elemental_Art_Flask", + "abilityName": "Avatar_Diona_Elemental_Art_Flask", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_Elemental_Burst_Creata_IceWine_Fog", + "abilityName": "Avatar_Diona_Elemental_Burst_Creata_IceWine_Fog", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_IceWine_Fog", + "abilityName": "Avatar_Diona_IceWine_Fog", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ShootArrow_Damage", + "abilityName": "Avatar_Diona_ShootArrow_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_FallingAnthem", + "abilityName": "Avatar_Diona_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona", + "abilityName": "Avatar_Diona", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_Skill_ElementalArt_Short", + "abilityName": "Avatar_Diona_Skill_ElementalArt_Short", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_Skill_ElementalArt_Short_AS", + "abilityName": "Avatar_Diona_Skill_ElementalArt_Short_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_Skill_ElementalArt_Short_BS", + "abilityName": "Avatar_Diona_Skill_ElementalArt_Short_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_Skill_ElementalArt_Throw", + "abilityName": "Avatar_Diona_Skill_ElementalArt_Throw", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_Skill_ElementalArt_Throw_AS", + "abilityName": "Avatar_Diona_Skill_ElementalArt_Throw_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_Skill_ElementalArt_Throw_BS", + "abilityName": "Avatar_Diona_Skill_ElementalArt_Throw_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_Skill_ElementalBurst", + "abilityName": "Avatar_Diona_Skill_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_Skill_ElementalBurst_AS", + "abilityName": "Avatar_Diona_Skill_ElementalBurst_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_TeamConfig_01BS", + "abilityName": "Avatar_Diona_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_TeamConfig_01Loop", + "abilityName": "Avatar_Diona_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_TeamConfig_01AS", + "abilityName": "Avatar_Diona_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ElementalBurst_Spine_Trail", + "abilityName": "Avatar_Diona_ElementalBurst_Spine_Trail", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ElementalBurst_Spine", + "abilityName": "Avatar_Diona_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_Spine", + "abilityName": "Avatar_Diona_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ElementalBurst_BS", + "abilityName": "Avatar_Diona_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ElementalBurst", + "abilityName": "Avatar_Diona_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ElementBurst", + "abilityName": "Avatar_Diona_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ElementalBurst_Hit", + "abilityName": "Avatar_Diona_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_ElementalBurst_BS_Normal", + "abilityName": "Avatar_Diona_ElementalBurst_BS_Normal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Diona_Spine_Loop", + "abilityName": "Avatar_Diona_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Dori.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Dori.json new file mode 100644 index 0000000..1708c25 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Dori.json @@ -0,0 +1,119 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Dori_ExtraAttack", + "abilityName": "Avatar_Dori_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_NormalAttack_Sprite_Controller", + "abilityName": "Avatar_Dori_NormalAttack_Sprite_Controller", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_ExtraAttack_Sprite_Remover", + "abilityName": "Avatar_Dori_ExtraAttack_Sprite_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_ElementalArt_Sprite_Remover", + "abilityName": "Avatar_Dori_ElementalArt_Sprite_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_ElementalArt_Sprite", + "abilityName": "Avatar_Dori_ElementalArt_Sprite", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_ElementalArt", + "abilityName": "Avatar_Dori_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_ElementalBurst", + "abilityName": "Avatar_Dori_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_ChargingStation_Bullet_Bullet", + "abilityName": "Avatar_Dori_ChargingStation_Bullet_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_ElementalBurst_CreateGadgeth", + "abilityName": "Avatar_Dori_ElementalBurst_CreateGadgeth", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_ElementalBurst_CreateGadget", + "abilityName": "Avatar_Dori_ElementalBurst_CreateGadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_ChargingStation", + "abilityName": "Avatar_Dori_ChargingStation", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_NormalAttack_DamageHandler", + "abilityName": "Avatar_Dori_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_FallingAnthem", + "abilityName": "Avatar_Dori_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_Constellation_6", + "abilityName": "Avatar_Dori_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori", + "abilityName": "Avatar_Dori", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_TeamConfig_01BS", + "abilityName": "Avatar_Dori_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_TeamConfig_01Loop", + "abilityName": "Avatar_Dori_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_TeamConfig_01AS", + "abilityName": "Avatar_Dori_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_ElementalBurst_Spine", + "abilityName": "Avatar_Dori_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_ElementalBurst_BS", + "abilityName": "Avatar_Dori_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_ElementBurst", + "abilityName": "Avatar_Dori_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_ElementalBurst_Hit", + "abilityName": "Avatar_Dori_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Dori_Spine_Loop", + "abilityName": "Avatar_Dori_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Eula.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Eula.json new file mode 100644 index 0000000..1cbd3e9 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Eula.json @@ -0,0 +1,174 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Eula_ExtraAttack", + "abilityName": "Avatar_Eula_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalArt_ExtraAttack_1", + "abilityName": "Avatar_Eula_ElementalArt_ExtraAttack_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalArt_ExtraAttack_2", + "abilityName": "Avatar_Eula_ElementalArt_ExtraAttack_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalArt", + "abilityName": "Avatar_Eula_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalArt_SetMark", + "abilityName": "Avatar_Eula_ElementalArt_SetMark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalArt_Click", + "abilityName": "Avatar_Eula_ElementalArt_Click", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalArt_Burst", + "abilityName": "Avatar_Eula_ElementalArt_Burst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalBurst", + "abilityName": "Avatar_Eula_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalBurst_PostEffect", + "abilityName": "Avatar_Eula_ElementalBurst_PostEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Eula_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalBurst_Attack", + "abilityName": "Avatar_Eula_ElementalBurst_Attack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalBurst_Judgment", + "abilityName": "Avatar_Eula_ElementalBurst_Judgment", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_NormalAttackDamage_Handler", + "abilityName": "Avatar_Eula_NormalAttackDamage_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_FallingAnthem", + "abilityName": "Avatar_Eula_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_Plot1", + "abilityName": "Avatar_Eula_Plot1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_Plot_NoHarm", + "abilityName": "Avatar_Eula_Plot_NoHarm", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_Plot_Fail", + "abilityName": "Avatar_Eula_Plot_Fail", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_Plot2", + "abilityName": "Avatar_Eula_Plot2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_Plot_Throw", + "abilityName": "Avatar_Eula_Plot_Throw", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_Plot3", + "abilityName": "Avatar_Eula_Plot3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_Plot_Nofrozen", + "abilityName": "Avatar_Eula_Plot_Nofrozen", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula", + "abilityName": "Avatar_Eula", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_plot", + "abilityName": "Avatar_Eula_plot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalArt_BS", + "abilityName": "Avatar_Eula_ElementalArt_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalArt_Click_AS", + "abilityName": "Avatar_Eula_ElementalArt_Click_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalArt_Charge", + "abilityName": "Avatar_Eula_ElementalArt_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_TeamConfig_01BS", + "abilityName": "Avatar_Eula_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_TeamConfig_01Loop", + "abilityName": "Avatar_Eula_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_TeamConfig_01AS", + "abilityName": "Avatar_Eula_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalArt_Charge_AS", + "abilityName": "Avatar_Eula_ElementalArt_Charge_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalBurst_Spine", + "abilityName": "Avatar_Eula_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalBurst_BS", + "abilityName": "Avatar_Eula_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_ElementalBurst_Hit", + "abilityName": "Avatar_Eula_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Eula_Spine_Loop", + "abilityName": "Avatar_Eula_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Faruzan.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Faruzan.json new file mode 100644 index 0000000..5d9128c --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Faruzan.json @@ -0,0 +1,264 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Faruzan_PressShoot", + "abilityName": "Avatar_Faruzan_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_AimPressShoot", + "abilityName": "Avatar_Faruzan_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ShootAimingArrow_Charge", + "abilityName": "Avatar_Faruzan_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ShootArrow_ResetGlobalValue", + "abilityName": "Avatar_Faruzan_ShootArrow_ResetGlobalValue", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_Arrow_FX", + "abilityName": "Avatar_Faruzan_Arrow_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ShootArrow_Aiming", + "abilityName": "Avatar_Faruzan_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ShootArrow_01", + "abilityName": "Avatar_Faruzan_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ShootArrow_02", + "abilityName": "Avatar_Faruzan_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ShootArrow_03", + "abilityName": "Avatar_Faruzan_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ShootArrow_04", + "abilityName": "Avatar_Faruzan_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ShootArrow_05", + "abilityName": "Avatar_Faruzan_ShootArrow_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ShootArrow_06", + "abilityName": "Avatar_Faruzan_ShootArrow_06", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ShootArrow_Enchanted_Wind", + "abilityName": "Avatar_Faruzan_ShootArrow_Enchanted_Wind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ShootArrow_Enchanted_WithoutWind", + "abilityName": "Avatar_Faruzan_ShootArrow_Enchanted_WithoutWind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_FallingAnthem", + "abilityName": "Avatar_Faruzan_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_Elemental_Art", + "abilityName": "Avatar_Faruzan_Elemental_Art", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_Wind_Arashi", + "abilityName": "Avatar_Faruzan_Wind_Arashi", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_Wind_Arashi_Bullet", + "abilityName": "Avatar_Faruzan_Wind_Arashi_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_Bullet_Landed_WindBlackHole", + "abilityName": "Avatar_Faruzan_Bullet_Landed_WindBlackHole", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_WindZone_Avatar", + "abilityName": "Avatar_Faruzan_WindZone_Avatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_WindZone_Monster", + "abilityName": "Avatar_Faruzan_WindZone_Monster", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_WindZone_Monster_Constellation6", + "abilityName": "Avatar_Faruzan_WindZone_Monster_Constellation6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_WindBlackHole_Gadget", + "abilityName": "Avatar_Faruzan_WindBlackHole_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_Elemental_Burst_BS", + "abilityName": "Avatar_Faruzan_Elemental_Burst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_GadgetLifeController", + "abilityName": "Avatar_Faruzan_ElementalBurst_GadgetLifeController", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_Elemental_Burst", + "abilityName": "Avatar_Faruzan_Elemental_Burst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_PermanentSkill2_WindDamageExtraUp", + "abilityName": "Avatar_Faruzan_PermanentSkill2_WindDamageExtraUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_WindDamageValueUp_ApplyRange", + "abilityName": "Avatar_Faruzan_ElementalBurst_WindDamageValueUp_ApplyRange", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_WindAddHurtUp", + "abilityName": "Avatar_Faruzan_ElementalBurst_WindAddHurtUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_WindAddHurtUp_EffOnAdd_Handler9UNIQUE_Avatar_Faruzan_ElementalBurst_GadgetLifeController", + "abilityName": "Avatar_Faruzan_ElementalBurst_WindAddHurtUp_EffOnAdd_Handler9UNIQUE_Avatar_Faruzan_ElementalBurst_GadgetLifeController", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_WindAddHurtUp_LoopEff", + "abilityName": "Avatar_Faruzan_ElementalBurst_WindAddHurtUp_LoopEff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_WindDamageValueUp_Handler", + "abilityName": "Avatar_Faruzan_ElementalBurst_WindDamageValueUp_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_WindCriticalHurtUp", + "abilityName": "Avatar_Faruzan_ElementalBurst_WindCriticalHurtUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_AutoHurricaneArrow", + "abilityName": "Avatar_Faruzan_ElementalBurst_AutoHurricaneArrow", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_WindDamageValueUp", + "abilityName": "Avatar_Faruzan_ElementalBurst_WindDamageValueUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_WindDamageValueUp_CD9UNIQUE_Avatar_Faruzan_ElementalBurst_WindDamageValueUp_CD", + "abilityName": "Avatar_Faruzan_ElementalBurst_WindDamageValueUp_CD9UNIQUE_Avatar_Faruzan_ElementalBurst_WindDamageValueUp_CD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_AutoHurricaneArrow_CD", + "abilityName": "Avatar_Faruzan_ElementalBurst_AutoHurricaneArrow_CD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_WindAddHurtUp_EffOnAdd_Handler", + "abilityName": "Avatar_Faruzan_ElementalBurst_WindAddHurtUp_EffOnAdd_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_WindAddHurtUp_EffOnAdd", + "abilityName": "Avatar_Faruzan_ElementalBurst_WindAddHurtUp_EffOnAdd", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_Constellation4_ReviveEnergy", + "abilityName": "Avatar_Faruzan_Constellation4_ReviveEnergy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_Constellation6_AutoHurricaneArrow_BulletTrigger", + "abilityName": "Avatar_Faruzan_Constellation6_AutoHurricaneArrow_BulletTrigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan", + "abilityName": "Avatar_Faruzan", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_Skill_ElementalArt", + "abilityName": "Avatar_Faruzan_Skill_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_Skill_ElementalArt_AS", + "abilityName": "Avatar_Faruzan_Skill_ElementalArt_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_Skill_ElementalBurst", + "abilityName": "Avatar_Faruzan_Skill_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_TeamConfig_01BS", + "abilityName": "Avatar_Faruzan_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_TeamConfig_01Loop", + "abilityName": "Avatar_Faruzan_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_TeamConfig_01AS", + "abilityName": "Avatar_Faruzan_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_PermanentSkill2_WindDamageExtraUp0Avatar_Faruzan_PermanentSkill2_WindDamageExtraUp", + "abilityName": "Avatar_Faruzan_PermanentSkill2_WindDamageExtraUp0Avatar_Faruzan_PermanentSkill2_WindDamageExtraUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_Skill_ElementalBurst_AS", + "abilityName": "Avatar_Faruzan_Skill_ElementalBurst_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_WindDamageValueUp_Remove", + "abilityName": "Avatar_Faruzan_ElementalBurst_WindDamageValueUp_Remove", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Faruzan_ElementalBurst_WindDamageValueUp_CD", + "abilityName": "Avatar_Faruzan_ElementalBurst_WindDamageValueUp_CD", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Feiyan.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Feiyan.json new file mode 100644 index 0000000..cd31d17 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Feiyan.json @@ -0,0 +1,154 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Feiyan_Attack01", + "abilityName": "Avatar_Feiyan_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_Attack02", + "abilityName": "Avatar_Feiyan_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_Attack03", + "abilityName": "Avatar_Feiyan_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_FeiyanGadgetSkill_NormalAttackDamage01", + "abilityName": "Avatar_FeiyanGadgetSkill_NormalAttackDamage01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_FeiyanGadgetSkill_NormalAttackDamage02", + "abilityName": "Avatar_FeiyanGadgetSkill_NormalAttackDamage02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_FeiyanGadgetSkill_NormalAttackDamage03", + "abilityName": "Avatar_FeiyanGadgetSkill_NormalAttackDamage03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_FeiyanGadgetSkill_Effect_Normal", + "abilityName": "Avatar_FeiyanGadgetSkill_Effect_Normal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_FeiyanGadgetSkill_Effect_Last", + "abilityName": "Avatar_FeiyanGadgetSkill_Effect_Last", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_ExtraAttack", + "abilityName": "Avatar_Feiyan_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_ExtraAttack_Charge", + "abilityName": "Avatar_Feiyan_ExtraAttack_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_ExtraAttack_DoAttack", + "abilityName": "Avatar_Feiyan_ExtraAttack_DoAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_FeiyanGadgetSkill_ExtraAttack_Damage", + "abilityName": "Avatar_FeiyanGadgetSkill_ExtraAttack_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_ExtraAttack_Weight_Clear", + "abilityName": "Avatar_Feiyan_ExtraAttack_Weight_Clear", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_ExtraAttack_Weight_Handler", + "abilityName": "Avatar_Feiyan_ExtraAttack_Weight_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_ExtraAttack_Weight_Timer", + "abilityName": "Avatar_Feiyan_ExtraAttack_Weight_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_FeiyanGadgetSkill_Weight_Count", + "abilityName": "Avatar_FeiyanGadgetSkill_Weight_Count", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_ElementalArt_BS", + "abilityName": "Avatar_Feiyan_ElementalArt_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_ElementalArt", + "abilityName": "Avatar_Feiyan_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_ElementalBurst_BS", + "abilityName": "Avatar_Feiyan_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_ElementalBurst", + "abilityName": "Avatar_Feiyan_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_FallingAnthem", + "abilityName": "Avatar_Feiyan_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_Attack04", + "abilityName": "Avatar_Feiyan_Attack04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_Radar_Collectables_Liyue", + "abilityName": "Avatar_Feiyan_Radar_Collectables_Liyue", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan", + "abilityName": "Avatar_Feiyan", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_TeamConfig_01BS", + "abilityName": "Avatar_Feiyan_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_TeamConfig_01Loop", + "abilityName": "Avatar_Feiyan_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_TeamConfig_01AS", + "abilityName": "Avatar_Feiyan_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_ElementalBurst_Spine", + "abilityName": "Avatar_Feiyan_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_ElementalBurst_Hit", + "abilityName": "Avatar_Feiyan_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Feiyan_Spine_Loop", + "abilityName": "Avatar_Feiyan_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Fischl.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Fischl.json new file mode 100644 index 0000000..d506bad --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Fischl.json @@ -0,0 +1,259 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Fischl_PressShoot", + "abilityName": "Avatar_Fischl_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_AimPressShoot", + "abilityName": "Avatar_Fischl_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ShootAimingArrow_FX", + "abilityName": "Avatar_Fischl_ShootAimingArrow_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ShootAimingArrow_Charge", + "abilityName": "Avatar_Fischl_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ShootArrow_Aiming", + "abilityName": "Avatar_Fischl_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ExtraAttack_Element_Hit", + "abilityName": "Avatar_Fischl_ExtraAttack_Element_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ProudSkill_21_ExteaAttackThunder", + "abilityName": "Avatar_Fischl_ProudSkill_21_ExteaAttackThunder", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ExtraAttack_Element_FindCrow", + "abilityName": "Avatar_Fischl_ExtraAttack_Element_FindCrow", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ExtraAttack_Element_BulletFx", + "abilityName": "Avatar_Fischl_ExtraAttack_Element_BulletFx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ExtraAttack_WithoutElement_Hit", + "abilityName": "Avatar_Fischl_ExtraAttack_WithoutElement_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ExtraAttack_WithoutElement_BulletFx", + "abilityName": "Avatar_Fischl_ExtraAttack_WithoutElement_BulletFx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ShootArrow_01", + "abilityName": "Avatar_Fischl_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ShootArrow_02", + "abilityName": "Avatar_Fischl_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ShootArrow_03", + "abilityName": "Avatar_Fischl_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ShootArrow_04", + "abilityName": "Avatar_Fischl_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ShootArrow_05", + "abilityName": "Avatar_Fischl_ShootArrow_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_NormalAttack_Smoke", + "abilityName": "Avatar_Fischl_NormalAttack_Smoke", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_CrowSummon_Init", + "abilityName": "Avatar_Fischl_CrowSummon_Init", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_CrowSummon_InitJ", + "abilityName": "Avatar_Fischl_CrowSummon_InitJ", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_Crow_BeAttackedTrigger_Init", + "abilityName": "Avatar_Fischl_Crow_BeAttackedTrigger_Init", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ElectricalCrow_Crow_Attack", + "abilityName": "Avatar_Fischl_ElectricalCrow_Crow_Attack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ProudSkill_22", + "abilityName": "Avatar_Fischl_ProudSkill_22", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ProudSkill_ExteaAttackThunderh", + "abilityName": "Avatar_Fischl_ProudSkill_ExteaAttackThunderh", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ProudSkill_ExteaAttackThunder", + "abilityName": "Avatar_Fischl_ProudSkill_ExteaAttackThunder", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_Skill_S_Crow_Handle", + "abilityName": "Avatar_Fischl_Skill_S_Crow_Handle", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ProudSkill_ElementReactionAttackThunder", + "abilityName": "Avatar_Fischl_ProudSkill_ElementReactionAttackThunder", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ProudSkill_ElementReaction", + "abilityName": "Avatar_Fischl_ProudSkill_ElementReaction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ProudSkill_21_ExteaAttackThunder7", + "abilityName": "Avatar_Fischl_ProudSkill_21_ExteaAttackThunder7", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_Skill_S_Crow_AutoAttack_Hit_01", + "abilityName": "Avatar_Fischl_Skill_S_Crow_AutoAttack_Hit_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_Skill_E_CrowQueen_ScreenEffect333", + "abilityName": "Avatar_Fischl_Skill_E_CrowQueen_ScreenEffect333", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_FallingAnthem", + "abilityName": "Avatar_Fischl_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl", + "abilityName": "Avatar_Fischl", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ExtraAttack_WithoutElement_Hit1Avatar_Fischl_ExtraAttack_WithoutElement_BulletFx", + "abilityName": "Avatar_Fischl_ExtraAttack_WithoutElement_Hit1Avatar_Fischl_ExtraAttack_WithoutElement_BulletFx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_TeamConfig_01BS", + "abilityName": "Avatar_Fischl_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_TeamConfig_01Loop", + "abilityName": "Avatar_Fischl_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_TeamConfig_01AS", + "abilityName": "Avatar_Fischl_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ExtraAttack_WithoutElement_BulletFx1Avatar_Fischl_ExtraAttack_WithoutElement_BulletFx", + "abilityName": "Avatar_Fischl_ExtraAttack_WithoutElement_BulletFx1Avatar_Fischl_ExtraAttack_WithoutElement_BulletFx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ProudSkill_ElementReactionAttackThunder5Avatar_Fischl_ProudSkill_ElementReactionAttackThunder", + "abilityName": "Avatar_Fischl_ProudSkill_ElementReactionAttackThunder5Avatar_Fischl_ProudSkill_ElementReactionAttackThunder", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ElementalBurst_Spine", + "abilityName": "Avatar_Fischl_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ElementalBurst", + "abilityName": "Avatar_Fischl_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ElementBurst", + "abilityName": "Avatar_Fischl_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ElementalBurst_BS", + "abilityName": "Avatar_Fischl_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ElementalBurst_Hit", + "abilityName": "Avatar_Fischl_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ElementalBurst_Buff_Hit", + "abilityName": "Avatar_Fischl_ElementalBurst_Buff_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_elementalBurst_BS_Normal", + "abilityName": "Avatar_Fischl_elementalBurst_BS_Normal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ElementalBurst_Buff", + "abilityName": "Avatar_Fischl_ElementalBurst_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_Spine_Loop", + "abilityName": "Avatar_Fischl_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_Skill_E_CrowQueen_ScreenEffect", + "abilityName": "Avatar_Fischl_Skill_E_CrowQueen_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ProudSkill_ElementReactionAttackThunder9AS_Fischl_ProudSkill_22_ElementReactionAttack_AttackRatio", + "abilityName": "Avatar_Fischl_ProudSkill_ElementReactionAttackThunder9AS_Fischl_ProudSkill_22_ElementReactionAttack_AttackRatio", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ExtraAttack_WithoutElement_HitDFischl_ProudSkill_31_P6_ExtraAttack_WithoutElement_Damage_Percentage", + "abilityName": "Avatar_Fischl_ExtraAttack_WithoutElement_HitDFischl_ProudSkill_31_P6_ExtraAttack_WithoutElement_Damage_Percentage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Fischl_ExtraAttack_Element_Hit6Fischl_ProudSkill_31_P7_ChargeElementDamage_Percentage", + "abilityName": "Avatar_Fischl_ExtraAttack_Element_Hit6Fischl_ProudSkill_31_P7_ChargeElementDamage_Percentage", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Freminet.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Freminet.json new file mode 100644 index 0000000..614fef9 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Freminet.json @@ -0,0 +1,154 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Freminet_ExtraAttack", + "abilityName": "Avatar_Freminet_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_DropBall", + "abilityName": "Avatar_Freminet_DropBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_Attack04_Hide", + "abilityName": "Avatar_Freminet_Attack04_Hide", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_Attack04_HideEff", + "abilityName": "Avatar_Freminet_Attack04_HideEff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_ElementalArt", + "abilityName": "Avatar_Freminet_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_SkillBuff", + "abilityName": "Avatar_Freminet_SkillBuff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_Attack01_Ice", + "abilityName": "Avatar_Freminet_Attack01_Ice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_Attack02_IceB", + "abilityName": "Avatar_Freminet_Attack02_IceB", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_Attack03_IceJ", + "abilityName": "Avatar_Freminet_Attack03_IceJ", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_Attack04_Ice", + "abilityName": "Avatar_Freminet_Attack04_Ice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_SkillBuff_EffEnd", + "abilityName": "Avatar_Freminet_SkillBuff_EffEnd", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_Attack02_Ice", + "abilityName": "Avatar_Freminet_Attack02_Ice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_Attack03_Ice", + "abilityName": "Avatar_Freminet_Attack03_Ice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_ElementalArt_Strike", + "abilityName": "Avatar_Freminet_ElementalArt_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_ArkheGrade", + "abilityName": "Avatar_Freminet_ArkheGrade", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_ArkheGrade_CD", + "abilityName": "Avatar_Freminet_ArkheGrade_CD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_ElementalArt_2", + "abilityName": "Avatar_Freminet_ElementalArt_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_ElementalArt_3", + "abilityName": "Avatar_Freminet_ElementalArt_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_ElementalBurst_Strike", + "abilityName": "Avatar_Freminet_ElementalBurst_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_ElementalBurst", + "abilityName": "Avatar_Freminet_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_Utral_Buff", + "abilityName": "Avatar_Freminet_Utral_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_FallingAnthem", + "abilityName": "Avatar_Freminet_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_DamageHandler", + "abilityName": "Avatar_Freminet_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_PermanentSkill_2", + "abilityName": "Avatar_Freminet_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_Constellation_6", + "abilityName": "Avatar_Freminet_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_DivingStamina_Reduction", + "abilityName": "Avatar_Freminet_DivingStamina_Reduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet", + "abilityName": "Avatar_Freminet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_TeamConfig_01BS", + "abilityName": "Avatar_Freminet_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_TeamConfig_01Loop", + "abilityName": "Avatar_Freminet_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Freminet_TeamConfig_01AS", + "abilityName": "Avatar_Freminet_TeamConfig_01AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Furina.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Furina.json new file mode 100644 index 0000000..b26f15b --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Furina.json @@ -0,0 +1,144 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Furina_ExtraAttack", + "abilityName": "Avatar_Furina_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_Attack04_CreateBullet", + "abilityName": "Avatar_Furina_Attack04_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_Attack04_WaterEnhanced_CreateBullet", + "abilityName": "Avatar_Furina_Attack04_WaterEnhanced_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ArkheGrade_Handler", + "abilityName": "Avatar_Furina_ArkheGrade_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_DamageHandler", + "abilityName": "Avatar_Furina_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ElementalArt", + "abilityName": "Avatar_Furina_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ElementalBurst", + "abilityName": "Avatar_Furina_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ElementalBurst_Invincible", + "abilityName": "Avatar_Furina_ElementalBurst_Invincible", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ElementalBurst_BuffStart", + "abilityName": "Avatar_Furina_ElementalBurst_BuffStart", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ElementalBurst_Camera", + "abilityName": "Avatar_Furina_ElementalBurst_Camera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ElementalBurst_EmotionControl", + "abilityName": "Avatar_Furina_ElementalBurst_EmotionControl", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ElementalBurst_FogM", + "abilityName": "Avatar_Furina_ElementalBurst_FogM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ElementalBurst_FairyStage_ShadeM", + "abilityName": "Avatar_Furina_ElementalBurst_FairyStage_ShadeM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ElementalBurst_FairyStageM", + "abilityName": "Avatar_Furina_ElementalBurst_FairyStageM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ElementalBurst_FairyStage_3rdView", + "abilityName": "Avatar_Furina_ElementalBurst_FairyStage_3rdView", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ElementalBurst_FairyStage", + "abilityName": "Avatar_Furina_ElementalBurst_FairyStage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ElementalBurst_FairyStage_Shade", + "abilityName": "Avatar_Furina_ElementalBurst_FairyStage_Shade", + "abilityOverride": "" + }, + { + "abilityID": "AvatarChangeHP_MinCount3_ABILITY_Furina_ElementalBurst_AvatarChangeHP_Count", + "abilityName": "AvatarChangeHP_MinCount3_ABILITY_Furina_ElementalBurst_AvatarChangeHP_Count", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_ElementalBurst_Fog", + "abilityName": "Avatar_Furina_ElementalBurst_Fog", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_PermanentSkill_1", + "abilityName": "Avatar_Furina_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_PermanentSkill_2", + "abilityName": "Avatar_Furina_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_FallingAnthem", + "abilityName": "Avatar_Furina_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_MoveOnWater_FootRipple_Left", + "abilityName": "Avatar_Furina_MoveOnWater_FootRipple_Left", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_MoveOnWater_FootRipple_Right", + "abilityName": "Avatar_Furina_MoveOnWater_FootRipple_Right", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_PermanentSkill_3", + "abilityName": "Avatar_Furina_PermanentSkill_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina", + "abilityName": "Avatar_Furina", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_Attack04_CreateBullet1Avatar_Furina_Attack04_WaterEnhanced_CreateBullet", + "abilityName": "Avatar_Furina_Attack04_CreateBullet1Avatar_Furina_Attack04_WaterEnhanced_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Furina_Attack04_WaterEnhanced_CreateBullet1Avatar_Furina_Attack04_WaterEnhanced_CreateBullet", + "abilityName": "Avatar_Furina_Attack04_WaterEnhanced_CreateBullet1Avatar_Furina_Attack04_WaterEnhanced_CreateBullet", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Gaming.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Gaming.json new file mode 100644 index 0000000..1dbf9e2 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Gaming.json @@ -0,0 +1,5 @@ +{ + "abilities": [ + + ] +} diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ganyu.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ganyu.json new file mode 100644 index 0000000..e2a283e --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ganyu.json @@ -0,0 +1,189 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Ganyu_PressShoot", + "abilityName": "Avatar_Ganyu_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_AimPressShoot", + "abilityName": "Avatar_Ganyu_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_Arrow_FX", + "abilityName": "Avatar_Ganyu_Arrow_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ShootAimingArrow_Charge", + "abilityName": "Avatar_Ganyu_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ShootArrow_01", + "abilityName": "Avatar_Ganyu_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ShootArrow_02", + "abilityName": "Avatar_Ganyu_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ShootArrow_03", + "abilityName": "Avatar_Ganyu_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ShootArrow_04", + "abilityName": "Avatar_Ganyu_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ShootArrow_05", + "abilityName": "Avatar_Ganyu_ShootArrow_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ShootArrow_06", + "abilityName": "Avatar_Ganyu_ShootArrow_06", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ShootArrow_Aiming", + "abilityName": "Avatar_Ganyu_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ShootArrow_Enchanted_WithoutIce", + "abilityName": "Avatar_Ganyu_ShootArrow_Enchanted_WithoutIce", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_Fission_GainEnergy", + "abilityName": "Avatar_Ganyu_Fission_GainEnergy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_EnchantedFission", + "abilityName": "Avatar_Ganyu_EnchantedFission", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_IceBreaker_PrePosCheck", + "abilityName": "Avatar_Ganyu_IceBreaker_PrePosCheck", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_IceBreaker_PosCheck", + "abilityName": "Avatar_Ganyu_IceBreaker_PosCheck", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_IceBreaker", + "abilityName": "Avatar_Ganyu_IceBreaker", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_UnbreakableIce", + "abilityName": "Avatar_Ganyu_UnbreakableIce", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_FallingAnthem", + "abilityName": "Avatar_Ganyu_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu", + "abilityName": "Avatar_Ganyu", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_TeamConfig_01BS", + "abilityName": "Avatar_Ganyu_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_TeamConfig_01Loop", + "abilityName": "Avatar_Ganyu_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_TeamConfig_01AS", + "abilityName": "Avatar_Ganyu_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ElementalBurst_Spine", + "abilityName": "Avatar_Ganyu_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ElementalBurst", + "abilityName": "Avatar_Ganyu_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ElementalBurst_Areahit", + "abilityName": "Avatar_Ganyu_ElementalBurst_Areahit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_elementalBurst_Areahit_Golden", + "abilityName": "Avatar_Ganyu_elementalBurst_Areahit_Golden", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ElementalBurst_Hit", + "abilityName": "Avatar_Ganyu_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ElementalArt_Special_BS", + "abilityName": "Avatar_Ganyu_ElementalArt_Special_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ElementalArt_Special_Bullet", + "abilityName": "Avatar_Ganyu_ElementalArt_Special_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ElementalArt_Special_Hit", + "abilityName": "Avatar_Ganyu_ElementalArt_Special_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ElementalArt_Special_Bullet_Fission", + "abilityName": "Avatar_Ganyu_ElementalArt_Special_Bullet_Fission", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ElementalArt_Special_Hit_Fission", + "abilityName": "Avatar_Ganyu_ElementalArt_Special_Hit_Fission", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_ElementalBurst_NoSpine", + "abilityName": "Avatar_Ganyu_ElementalBurst_NoSpine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_elementalBurst_Areahit", + "abilityName": "Avatar_Ganyu_elementalBurst_Areahit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_Spine_Loop", + "abilityName": "Avatar_Ganyu_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ganyu_Spine", + "abilityName": "Avatar_Ganyu_Spine", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Gorou.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Gorou.json new file mode 100644 index 0000000..507414e --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Gorou.json @@ -0,0 +1,234 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Gorou_Arrow_FX", + "abilityName": "Avatar_Gorou_Arrow_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_PressShoot", + "abilityName": "Avatar_Gorou_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_AimPressShoot", + "abilityName": "Avatar_Gorou_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ShootAimingArrow_Charge", + "abilityName": "Avatar_Gorou_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ShootArrow_Aiming", + "abilityName": "Avatar_Gorou_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ShootArrow_01", + "abilityName": "Avatar_Gorou_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ShootArrow_02", + "abilityName": "Avatar_Gorou_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ShootArrow_03", + "abilityName": "Avatar_Gorou_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ShootArrow_04", + "abilityName": "Avatar_Gorou_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ShootArrow_05", + "abilityName": "Avatar_Gorou_ShootArrow_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ShootArrow_Damage", + "abilityName": "Avatar_Gorou_ShootArrow_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalArt_SkillHoldCharge", + "abilityName": "Avatar_Gorou_ElementalArt_SkillHoldCharge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalArt_Layer", + "abilityName": "Avatar_Gorou_ElementalArt_Layer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layer3_Avatars4UNIQUE_Gorou_Constellation_RockAvatar_Layer1_Avatars", + "abilityName": "Avatar_Layer3_Avatars4UNIQUE_Gorou_Constellation_RockAvatar_Layer1_Avatars", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalArt", + "abilityName": "Avatar_Gorou_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalArt_Layer1_Modifier", + "abilityName": "Avatar_Gorou_ElementalArt_Layer1_Modifier", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalArt_Layer2_Modifier", + "abilityName": "Avatar_Gorou_ElementalArt_Layer2_Modifier", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalArt_Layer3_Modifier", + "abilityName": "Avatar_Gorou_ElementalArt_Layer3_Modifier", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalArt_Layer_Controller", + "abilityName": "Avatar_Gorou_ElementalArt_Layer_Controller", + "abilityOverride": "" + }, + { + "abilityID": "Avatar1UNIQUE_Avatar_Gorou_ElementalArt_Layer_Controller", + "abilityName": "Avatar1UNIQUE_Avatar_Gorou_ElementalArt_Layer_Controller", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalArt_Layer1", + "abilityName": "Avatar_Gorou_ElementalArt_Layer1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalArt_Layer2", + "abilityName": "Avatar_Gorou_ElementalArt_Layer2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalArt_Layer3", + "abilityName": "Avatar_Gorou_ElementalArt_Layer3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalBurst_PutAwayGadget", + "abilityName": "Avatar_Gorou_ElementalBurst_PutAwayGadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalBurst_KillGadget", + "abilityName": "Avatar_Gorou_ElementalBurst_KillGadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalBurst_KillSelf", + "abilityName": "Avatar_Gorou_ElementalBurst_KillSelf", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalBurst", + "abilityName": "Avatar_Gorou_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalBurst_Camera_Handler", + "abilityName": "Avatar_Gorou_ElementalBurst_Camera_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalBurst_Duration", + "abilityName": "Avatar_Gorou_ElementalBurst_Duration", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalBurst_SelfHanler", + "abilityName": "Avatar_Gorou_ElementalBurst_SelfHanler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalBurst_End_PutAwayGadget", + "abilityName": "Avatar_Gorou_ElementalBurst_End_PutAwayGadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalBurst_WindZone", + "abilityName": "Avatar_Gorou_ElementalBurst_WindZone", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_ElementalBurst_Heal_Handler", + "abilityName": "Avatar_Gorou_ElementalBurst_Heal_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_Radar_Collectables_Daoqi", + "abilityName": "Avatar_Gorou_Radar_Collectables_Daoqi", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_FallingAnthem", + "abilityName": "Avatar_Gorou_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou", + "abilityName": "Avatar_Gorou", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_Skill_ElementalArt_BS", + "abilityName": "Avatar_Gorou_Skill_ElementalArt_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_Skill_ElementalArt", + "abilityName": "Avatar_Gorou_Skill_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_Skill_ElementalArt_AS", + "abilityName": "Avatar_Gorou_Skill_ElementalArt_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_Skill_ElementalArt_Hold_Charge", + "abilityName": "Avatar_Gorou_Skill_ElementalArt_Hold_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_Skill_ElementalBurst", + "abilityName": "Avatar_Gorou_Skill_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_Skill_ElementalBurst_AS01", + "abilityName": "Avatar_Gorou_Skill_ElementalBurst_AS01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_Skill_ElementalBurst_AS02", + "abilityName": "Avatar_Gorou_Skill_ElementalBurst_AS02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_TeamConfig_01BS", + "abilityName": "Avatar_Gorou_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_TeamConfig_01Loop", + "abilityName": "Avatar_Gorou_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Gorou_TeamConfig_01AS", + "abilityName": "Avatar_Gorou_TeamConfig_01AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Heizo.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Heizo.json new file mode 100644 index 0000000..f6a6ca7 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Heizo.json @@ -0,0 +1,119 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Heizo_ExtraAttack", + "abilityName": "Avatar_Heizo_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_NormalAttack_Handler", + "abilityName": "Avatar_Heizo_NormalAttack_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalArt_Handler", + "abilityName": "Avatar_Heizo_ElementalArt_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalArt_Reset", + "abilityName": "Avatar_Heizo_ElementalArt_Reset", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalArt_Strike", + "abilityName": "Avatar_Heizo_ElementalArt_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalArt_Strike_Max", + "abilityName": "Avatar_Heizo_ElementalArt_Strike_Max", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalBurst_Strike", + "abilityName": "Avatar_Heizo_ElementalBurst_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Heizo_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalBurst_WindHole", + "abilityName": "Avatar_Heizo_ElementalBurst_WindHole", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalBurst_HitCheck", + "abilityName": "Avatar_Heizo_ElementalBurst_HitCheck", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalBurst_SetElementBomb", + "abilityName": "Avatar_Heizo_ElementalBurst_SetElementBomb", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalBurst_WindZone_Default_Handler", + "abilityName": "Avatar_Heizo_ElementalBurst_WindZone_Default_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalBurst_WindZone_Handler", + "abilityName": "Avatar_Heizo_ElementalBurst_WindZone_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalBurst_WindZone_Monster_Small", + "abilityName": "Avatar_Heizo_ElementalBurst_WindZone_Monster_Small", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalBurst_WindZone_Monster_Big", + "abilityName": "Avatar_Heizo_ElementalBurst_WindZone_Monster_Big", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalBurst_WindZone_Other2Avatar_Heizo_ElementalBurst_WindZone_Monster_Small", + "abilityName": "Avatar_Heizo_ElementalBurst_WindZone_Other2Avatar_Heizo_ElementalBurst_WindZone_Monster_Small", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_ElementalBurst_WindZone_Other", + "abilityName": "Avatar_Heizo_ElementalBurst_WindZone_Other", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_FallingAnthem", + "abilityName": "Avatar_Heizo_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_DashStamina_Reduction", + "abilityName": "Avatar_Heizo_DashStamina_Reduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo", + "abilityName": "Avatar_Heizo", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_TeamConfig_01BS", + "abilityName": "Avatar_Heizo_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_TeamConfig_01Loop", + "abilityName": "Avatar_Heizo_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Heizo_TeamConfig_01AS", + "abilityName": "Avatar_Heizo_TeamConfig_01AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Hutao.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Hutao.json new file mode 100644 index 0000000..efe035f --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Hutao.json @@ -0,0 +1,179 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Hutao_ExtraAttack", + "abilityName": "Avatar_Hutao_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_ExtraAttack_CreateBullet", + "abilityName": "Avatar_Hutao_ExtraAttack_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_ExtraAttack_Bullet", + "abilityName": "Avatar_Hutao_ExtraAttack_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_ExtraAttack_CrimsonPlum_CreateBullet", + "abilityName": "Avatar_Hutao_ExtraAttack_CrimsonPlum_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_ExtraAttack_CrimsonPlum_Bullet", + "abilityName": "Avatar_Hutao_ExtraAttack_CrimsonPlum_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_ExtraAttack_KillBullet", + "abilityName": "Avatar_Hutao_ExtraAttack_KillBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_CrimsonPlum", + "abilityName": "Avatar_Hutao_CrimsonPlum", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_PermanentSkill_1", + "abilityName": "Avatar_Hutao_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_Constellation_Kill", + "abilityName": "Avatar_Hutao_Constellation_Kill", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_Constellation_LifeBonus", + "abilityName": "Avatar_Hutao_Constellation_LifeBonus", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_VermilionBite_CameraController", + "abilityName": "Avatar_Hutao_VermilionBite_CameraController", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_VermilionBite_PostEffect", + "abilityName": "Avatar_Hutao_VermilionBite_PostEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Hutao_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_VermilionBite", + "abilityName": "Avatar_Hutao_VermilionBite", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_VermilionBite_BakeMesh", + "abilityName": "Avatar_Hutao_VermilionBite_BakeMesh", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_Sprint_CloseCollider", + "abilityName": "Avatar_Hutao_Sprint_CloseCollider", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_Constellation_Limbo", + "abilityName": "Avatar_Hutao_Constellation_Limbo", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_Constellation_Limbo_Trigger", + "abilityName": "Avatar_Hutao_Constellation_Limbo_Trigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_Constellation_Limbo_Trigger2UNIQUE_Hutao_Constellation_Limbo_Untriggered_Limbo", + "abilityName": "Avatar_Hutao_Constellation_Limbo_Trigger2UNIQUE_Hutao_Constellation_Limbo_Untriggered_Limbo", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_PermanentSkill_2", + "abilityName": "Avatar_Hutao_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_NormalAttack_DamageHandler", + "abilityName": "Avatar_Hutao_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_FallingAnthem", + "abilityName": "Avatar_Hutao_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_DropBall", + "abilityName": "Avatar_Hutao_DropBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao", + "abilityName": "Avatar_Hutao", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_ExtraAttack_Bullet1Avatar_Hutao_ExtraAttack_CrimsonPlum_CreateBullet", + "abilityName": "Avatar_Hutao_ExtraAttack_Bullet1Avatar_Hutao_ExtraAttack_CrimsonPlum_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_TeamConfig_01BS", + "abilityName": "Avatar_Hutao_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_TeamConfig_01Loop", + "abilityName": "Avatar_Hutao_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_TeamConfig_01AS", + "abilityName": "Avatar_Hutao_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_ElementalBurst_Spine", + "abilityName": "Avatar_Hutao_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_ElementalBurst_Hit", + "abilityName": "Avatar_Hutao_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_ElementArt_Buff", + "abilityName": "Avatar_Hutao_ElementArt_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_Spine_Loop", + "abilityName": "Avatar_Hutao_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_CrimsonPlum1CrimsonPlum_Debuff_Constellation_LifeBonus_Factor", + "abilityName": "Avatar_Hutao_CrimsonPlum1CrimsonPlum_Debuff_Constellation_LifeBonus_Factor", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_CrimsonPlum4CrimsonPlum_Debuff_Constellation_Kill_Critical_Delta", + "abilityName": "Avatar_Hutao_CrimsonPlum4CrimsonPlum_Debuff_Constellation_Kill_Critical_Delta", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Hutao_CrimsonPlum3CrimsonPlum_PermanentSkill_CriticalUp_CriticalDelta", + "abilityName": "Avatar_Hutao_CrimsonPlum3CrimsonPlum_PermanentSkill_CriticalUp_CriticalDelta", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Itto.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Itto.json new file mode 100644 index 0000000..d19ffe0 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Itto.json @@ -0,0 +1,364 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Itto_ExtraAttack", + "abilityName": "Avatar_Itto_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ExtraHoldChargingM", + "abilityName": "Avatar_Itto_ExtraHoldChargingM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ExtraAttackTrigger_HighTickFrequencyU", + "abilityName": "Avatar_Itto_ExtraAttackTrigger_HighTickFrequencyU", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ExtraHoldCharging", + "abilityName": "Avatar_Itto_ExtraHoldCharging", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ExtraAttackTrigger_HighTickFrequency", + "abilityName": "Avatar_Itto_ExtraAttackTrigger_HighTickFrequency", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ExtraAttackTrigger_HighTickFrequencyM", + "abilityName": "Avatar_Itto_ExtraAttackTrigger_HighTickFrequencyM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_SpecialExtra_Damage", + "abilityName": "Avatar_Itto_SpecialExtra_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_SpecialExtra_Damage_Ghost", + "abilityName": "Avatar_Itto_SpecialExtra_Damage_Ghost", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Symbol_Handler", + "abilityName": "Avatar_Itto_Symbol_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Calculate_ExtraCombo", + "abilityName": "Avatar_Itto_Calculate_ExtraCombo", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Calculate_ClearExtraCombo", + "abilityName": "Avatar_Itto_Calculate_ClearExtraCombo", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_SpecialExtra_TipEffect", + "abilityName": "Avatar_Itto_SpecialExtra_TipEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ComboAddSymbol_Handler", + "abilityName": "Avatar_Itto_ComboAddSymbol_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_2ndNormalAttack_AddSymbol", + "abilityName": "Avatar_Itto_2ndNormalAttack_AddSymbol", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_LastNormalAttack_AddSymbol", + "abilityName": "Avatar_Itto_LastNormalAttack_AddSymbol", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ForeNormalAttack_AddSymbol", + "abilityName": "Avatar_Itto_ForeNormalAttack_AddSymbol", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Mask_Timer", + "abilityName": "Avatar_Itto_Mask_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalArtAddSymbol_Handler", + "abilityName": "Avatar_Itto_ElementalArtAddSymbol_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_SymbolEffect_Handler", + "abilityName": "Avatar_Itto_SymbolEffect_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Mask_Handler", + "abilityName": "Avatar_Itto_Mask_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Symbol_Cost", + "abilityName": "Avatar_Itto_Symbol_Cost", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ExtraAttack_Mask", + "abilityName": "Avatar_Itto_ExtraAttack_Mask", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalArt", + "abilityName": "Avatar_Itto_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalArt_ChargeRune", + "abilityName": "Avatar_Itto_ElementalArt_ChargeRune", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalArt_SaveNormalCombo", + "abilityName": "Avatar_Itto_ElementalArt_SaveNormalCombo", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalArt_Strike", + "abilityName": "Avatar_Itto_ElementalArt_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalArt_HitCheck", + "abilityName": "Avatar_Itto_ElementalArt_HitCheck", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalArt_DropBall", + "abilityName": "Avatar_Itto_ElementalArt_DropBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalArt_CreateBull", + "abilityName": "Avatar_Itto_ElementalArt_CreateBull", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalArt_CreateBullM", + "abilityName": "Avatar_Itto_ElementalArt_CreateBullM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalArt_CreateGadget", + "abilityName": "Avatar_Itto_ElementalArt_CreateGadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Gadget_OniBull_Bullet", + "abilityName": "Avatar_Itto_Gadget_OniBull_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalArt_CreateGadgeth", + "abilityName": "Avatar_Itto_ElementalArt_CreateGadgeth", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Gadget_OniBull", + "abilityName": "Avatar_Itto_Gadget_OniBull", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Mask_TimerU", + "abilityName": "Avatar_Itto_Mask_TimerU", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst", + "abilityName": "Avatar_Itto_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_Initialize", + "abilityName": "Avatar_Itto_ElementalBurst_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_Camera_Handler", + "abilityName": "Avatar_Itto_ElementalBurst_Camera_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_Camera_PushTarget", + "abilityName": "Avatar_Itto_ElementalBurst_Camera_PushTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_CameraBlur", + "abilityName": "Avatar_Itto_ElementalBurst_CameraBlur", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_EmotionControl", + "abilityName": "Avatar_Itto_ElementalBurst_EmotionControl", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_WeatherChange_Pre", + "abilityName": "Avatar_Itto_ElementalBurst_WeatherChange_Pre", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_Invincible", + "abilityName": "Avatar_Itto_ElementalBurst_Invincible", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_Buff_AddDurability", + "abilityName": "Avatar_Itto_ElementalBurst_Buff_AddDurability", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_Buff", + "abilityName": "Avatar_Itto_ElementalBurst_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_CameraEffectS", + "abilityName": "Avatar_Itto_ElementalBurst_CameraEffectS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_CameraEffect", + "abilityName": "Avatar_Itto_ElementalBurst_CameraEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_WeatherChange", + "abilityName": "Avatar_Itto_ElementalBurst_WeatherChange", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_WeatherChangeJ", + "abilityName": "Avatar_Itto_ElementalBurst_WeatherChangeJ", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_FallingAnthem", + "abilityName": "Avatar_Itto_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Attack_DamageHandler", + "abilityName": "Avatar_Itto_Attack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_PermanentSkill_1", + "abilityName": "Avatar_Itto_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ExtraAttack_AddEndure", + "abilityName": "Avatar_Itto_ExtraAttack_AddEndure", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ExtraAttack_ComboSpeed_Handler", + "abilityName": "Avatar_Itto_ExtraAttack_ComboSpeed_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ExtraAttack_ComboSpeed", + "abilityName": "Avatar_Itto_ExtraAttack_ComboSpeed", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_PermanentSkill_2", + "abilityName": "Avatar_Itto_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ExtraAttack_DamageUp", + "abilityName": "Avatar_Itto_ExtraAttack_DamageUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Constellation_SymbolBurst", + "abilityName": "Avatar_Itto_Constellation_SymbolBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Constellation_HotReviveSymbol_Delay", + "abilityName": "Avatar_Itto_Constellation_HotReviveSymbol_Delay", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Constellation_HotReviveSymbol", + "abilityName": "Avatar_Itto_Constellation_HotReviveSymbol", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Constellation_CalculateRockAvatar", + "abilityName": "Avatar_Itto_Constellation_CalculateRockAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Constellation_ReduceCD", + "abilityName": "Avatar_Itto_Constellation_ReduceCD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Constellation_6", + "abilityName": "Avatar_Itto_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Constellation_CritDamageUp", + "abilityName": "Avatar_Itto_Constellation_CritDamageUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto", + "abilityName": "Avatar_Itto", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_TeamConfig_01BS", + "abilityName": "Avatar_Itto_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_TeamConfig_01Loop", + "abilityName": "Avatar_Itto_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_TeamConfig_01AS", + "abilityName": "Avatar_Itto_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_Spine", + "abilityName": "Avatar_Itto_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_BS", + "abilityName": "Avatar_Itto_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_ElementalBurst_Hit", + "abilityName": "Avatar_Itto_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Itto_Spine_Loop", + "abilityName": "Avatar_Itto_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kaeya.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kaeya.json new file mode 100644 index 0000000..07ff731 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kaeya.json @@ -0,0 +1,94 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Kaeya_ExtraAttack", + "abilityName": "Avatar_Kaeya_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_DamageHandler", + "abilityName": "Avatar_Kaeya_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_DashStamina_Reduction", + "abilityName": "Avatar_Kaeya_DashStamina_Reduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_FallingAnthem", + "abilityName": "Avatar_Kaeya_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya", + "abilityName": "Avatar_Kaeya", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_TeamConfig_01BS", + "abilityName": "Avatar_Kaeya_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_TeamConfig_01Loop", + "abilityName": "Avatar_Kaeya_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_TeamConfig_01AS", + "abilityName": "Avatar_Kaeya_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_ElementalBurst_Spine", + "abilityName": "Avatar_Kaeya_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_ElementalBurst_Spine_Coin", + "abilityName": "Avatar_Kaeya_ElementalBurst_Spine_Coin", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_Spine", + "abilityName": "Avatar_Kaeya_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_ElementalBurst_BS", + "abilityName": "Avatar_Kaeya_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_ElementalBurst", + "abilityName": "Avatar_Kaeya_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_ElementBurst", + "abilityName": "Avatar_Kaeya_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_ElementalBurst_Hit", + "abilityName": "Avatar_Kaeya_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_Spine_Loop", + "abilityName": "Avatar_Kaeya_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_VO_Emotion_Kaeya_Deny_01", + "abilityName": "Avatar_Kaeya_VO_Emotion_Kaeya_Deny_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaeya_VO_MDAQ036_Kaeya_01", + "abilityName": "Avatar_Kaeya_VO_MDAQ036_Kaeya_01", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kaveh.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kaveh.json new file mode 100644 index 0000000..07ea704 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kaveh.json @@ -0,0 +1,224 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Kaveh_ExtraAttack", + "abilityName": "Avatar_Kaveh_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ExtraAttack_Flag", + "abilityName": "Avatar_Kaveh_ExtraAttack_Flag", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_Chest_Handler", + "abilityName": "Avatar_Kaveh_Chest_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalArt", + "abilityName": "Avatar_Kaveh_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalArt_Strike", + "abilityName": "Avatar_Kaveh_ElementalArt_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalArt_ElementalBall_Handler", + "abilityName": "Avatar_Kaveh_ElementalArt_ElementalBall_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalArt_ElementalBall", + "abilityName": "Avatar_Kaveh_ElementalArt_ElementalBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalArt_HealBuff", + "abilityName": "Avatar_Kaveh_ElementalArt_HealBuff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_OvergrowSeed_Trigger", + "abilityName": "Avatar_Kaveh_OvergrowSeed_Trigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst", + "abilityName": "Avatar_Kaveh_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_Pre_Weather", + "abilityName": "Avatar_Kaveh_ElementalBurst_Pre_Weather", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_ExitCamera", + "abilityName": "Avatar_Kaveh_ElementalBurst_ExitCamera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_VFX", + "abilityName": "Avatar_Kaveh_ElementalBurst_VFX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_Invincible", + "abilityName": "Avatar_Kaveh_ElementalBurst_Invincible", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_Handler", + "abilityName": "Avatar_Kaveh_ElementalBurst_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_AtkSpeedBuff", + "abilityName": "Avatar_Kaveh_ElementalBurst_AtkSpeedBuff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_ReactionDamageUp_TeamBuff", + "abilityName": "Avatar_Kaveh_ElementalBurst_ReactionDamageUp_TeamBuff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_ElementMastery_Handler", + "abilityName": "Avatar_Kaveh_ElementalBurst_ElementMastery_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_ExtraStrike_Handler", + "abilityName": "Avatar_Kaveh_ElementalBurst_ExtraStrike_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_FallingAttack_Flag", + "abilityName": "Avatar_Kaveh_FallingAttack_Flag", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_FallingAttackVFX_Flag", + "abilityName": "Avatar_Kaveh_FallingAttackVFX_Flag", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_Handler5Avatar_Kaveh_ElementalBurst_ReactionDamageUp_TeamBuff", + "abilityName": "Avatar_Kaveh_ElementalBurst_Handler5Avatar_Kaveh_ElementalBurst_ReactionDamageUp_TeamBuff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_ExtraStrike_Attack", + "abilityName": "Avatar_Kaveh_ElementalBurst_ExtraStrike_Attack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_ExtraStrike_CD", + "abilityName": "Avatar_Kaveh_ElementalBurst_ExtraStrike_CD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_ExtraStrike_CD2Avatar_Kaveh_ElementalBurst_ElementMastery_Handler", + "abilityName": "Avatar_Kaveh_ElementalBurst_ExtraStrike_CD2Avatar_Kaveh_ElementalBurst_ElementMastery_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_ElementMastery_Buff", + "abilityName": "Avatar_Kaveh_ElementalBurst_ElementMastery_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst_ElementMastery_CD", + "abilityName": "Avatar_Kaveh_ElementalBurst_ElementMastery_CD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_Overgrow_HealHP", + "abilityName": "Avatar_Kaveh_Overgrow_HealHP", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_Overgrow_HealHP_Handler", + "abilityName": "Avatar_Kaveh_Overgrow_HealHP_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_Overgrow_ReactionDamageUp", + "abilityName": "Avatar_Kaveh_Overgrow_ReactionDamageUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_Overgrow_ReactionDamageUp_Buff", + "abilityName": "Avatar_Kaveh_Overgrow_ReactionDamageUp_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_FallingAnthem", + "abilityName": "Avatar_Kaveh_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_FallingAttackVFX_Handler4Avatar_Kaveh_FallingAttackVFX_ElementalBurst_Handler", + "abilityName": "Avatar_Kaveh_FallingAttackVFX_Handler4Avatar_Kaveh_FallingAttackVFX_ElementalBurst_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_FallingAttackVFX_Handler", + "abilityName": "Avatar_Kaveh_FallingAttackVFX_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_FallingAttackVFX_ElementalBurst_Handler", + "abilityName": "Avatar_Kaveh_FallingAttackVFX_ElementalBurst_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_NormalAttack_DamageHandler", + "abilityName": "Avatar_Kaveh_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh", + "abilityName": "Avatar_Kaveh", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_TeamConfig_01BS", + "abilityName": "Avatar_Kaveh_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_TeamConfig_01Loop", + "abilityName": "Avatar_Kaveh_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_TeamConfig_01AS", + "abilityName": "Avatar_Kaveh_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "AvatarItem_Kaveh_Spnotebook", + "abilityName": "AvatarItem_Kaveh_Spnotebook", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst1Kaveh_ElementalBurst_ElementMastery_Buff_StackNum", + "abilityName": "Avatar_Kaveh_ElementalBurst1Kaveh_ElementalBurst_ElementMastery_Buff_StackNum", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurst9Kaveh_ElementalBurst_ElementMastery_Buff_ElemMasteryDelta", + "abilityName": "Avatar_Kaveh_ElementalBurst9Kaveh_ElementalBurst_ElementMastery_Buff_ElemMasteryDelta", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kaveh_ElementalBurstEKaveh_ElementalBurst_ReactionDamageUp_TeamBuff_ElemReactOvergrowDelta", + "abilityName": "Avatar_Kaveh_ElementalBurstEKaveh_ElementalBurst_ReactionDamageUp_TeamBuff_ElemReactOvergrowDelta", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kazuha.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kazuha.json new file mode 100644 index 0000000..837550c --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kazuha.json @@ -0,0 +1,634 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Kazuha_ExtraAttack", + "abilityName": "Avatar_Kazuha_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_NormalAttack_Handler", + "abilityName": "Avatar_Kazuha_NormalAttack_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_NormalAttack_05_Damage", + "abilityName": "Avatar_Kazuha_NormalAttack_05_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Hide_Fx", + "abilityName": "Avatar_Kazuha_Hide_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Hide", + "abilityName": "Avatar_Kazuha_Hide", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_NormalAttack_MagicSheath", + "abilityName": "Avatar_Kazuha_NormalAttack_MagicSheath", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_NormalAttack_05", + "abilityName": "Avatar_Kazuha_NormalAttack_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_NormalAttack_05_Handler", + "abilityName": "Avatar_Kazuha_NormalAttack_05_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_NormalAttack_05_Damage01", + "abilityName": "Avatar_Kazuha_NormalAttack_05_Damage01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_NormalAttack_05_Damage02", + "abilityName": "Avatar_Kazuha_NormalAttack_05_Damage02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_NormalAttack_05_Damage03", + "abilityName": "Avatar_Kazuha_NormalAttack_05_Damage03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_Check", + "abilityName": "Avatar_Kazuha_ElementalArt_Check", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_ResetMixType", + "abilityName": "Avatar_Kazuha_ElementalArt_ResetMixType", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_HitCheck", + "abilityName": "Avatar_Kazuha_ElementalArt_HitCheck", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_AddHitMark", + "abilityName": "Avatar_Kazuha_ElementalArt_AddHitMark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_DropBall", + "abilityName": "Avatar_Kazuha_ElementalArt_DropBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_MonsterTail", + "abilityName": "Avatar_Kazuha_ElementalArt_MonsterTail", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_AirCheck", + "abilityName": "Avatar_Kazuha_ElementalArt_AirCheck", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_Air_AddMark", + "abilityName": "Avatar_Kazuha_ElementalArt_Air_AddMark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_Air_RemoveMark", + "abilityName": "Avatar_Kazuha_ElementalArt_Air_RemoveMark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_ClearVelocity", + "abilityName": "Avatar_Kazuha_ElementalArt_ClearVelocity", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_ChangeSkillButton", + "abilityName": "Avatar_Kazuha_ElementalArt_ChangeSkillButton", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_Air_Handler", + "abilityName": "Avatar_Kazuha_ElementalArt_Air_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_WindEffect_Delay", + "abilityName": "Avatar_Kazuha_ElementalArt_WindEffect_Delay", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_WindEffect", + "abilityName": "Avatar_Kazuha_ElementalArt_WindEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_Charge", + "abilityName": "Avatar_Kazuha_ElementalArt_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_Charge_WindZone", + "abilityName": "Avatar_Kazuha_ElementalArt_Charge_WindZone", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_Charge_Remove", + "abilityName": "Avatar_Kazuha_ElementalArt_Charge_Remove", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_EmptyJump", + "abilityName": "Avatar_Kazuha_ElementalArt_EmptyJump", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_EmptyJump_Effect", + "abilityName": "Avatar_Kazuha_EmptyJump_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_EnterCD", + "abilityName": "Avatar_Kazuha_ElementalArt_EnterCD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_Click_Detect", + "abilityName": "Avatar_Kazuha_ElementalArt_Click_Detect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_EmptyJump_Strike", + "abilityName": "Avatar_Kazuha_EmptyJump_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_EmptyJump_MixDetect", + "abilityName": "Avatar_Kazuha_EmptyJump_MixDetect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_EmptyJump_CreateWindZone", + "abilityName": "Avatar_Kazuha_EmptyJump_CreateWindZone", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_EmptyJump_DragCamera", + "abilityName": "Avatar_Kazuha_EmptyJump_DragCamera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_EmptyJump_MixDetectJ", + "abilityName": "Avatar_Kazuha_EmptyJump_MixDetectJ", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_1_MixJ", + "abilityName": "Avatar_Kazuha_PermanentSkill_1_MixJ", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Constellation_6", + "abilityName": "Avatar_Kazuha_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_EmptyJump_WindHole", + "abilityName": "Avatar_Kazuha_EmptyJump_WindHole", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_WindZone_Monster_Small", + "abilityName": "Avatar_Kazuha_ElementalArt_WindZone_Monster_Small", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_WindZone_Monster_Big", + "abilityName": "Avatar_Kazuha_ElementalArt_WindZone_Monster_Big", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_WindZone_Other", + "abilityName": "Avatar_Kazuha_ElementalArt_WindZone_Other", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_FlyAway", + "abilityName": "Avatar_Kazuha_ElementalArt_FlyAway", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_Hold_EnterCD", + "abilityName": "Avatar_Kazuha_ElementalArt_Hold_EnterCD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_Hold_Detect", + "abilityName": "Avatar_Kazuha_ElementalArt_Hold_Detect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_FlyAway_Strike", + "abilityName": "Avatar_Kazuha_FlyAway_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_FlyAway_MixDetect", + "abilityName": "Avatar_Kazuha_FlyAway_MixDetect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_FlyAway_WindZone", + "abilityName": "Avatar_Kazuha_FlyAway_WindZone", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_FlyAway_CameraBlur", + "abilityName": "Avatar_Kazuha_FlyAway_CameraBlur", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_FlyAway_DragCamera", + "abilityName": "Avatar_Kazuha_FlyAway_DragCamera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_FlyAway_MixDetectJ", + "abilityName": "Avatar_Kazuha_FlyAway_MixDetectJ", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_EmptyJump_Hold_WindHole", + "abilityName": "Avatar_Kazuha_EmptyJump_Hold_WindHole", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_Hold_WindZone_Monster_Small", + "abilityName": "Avatar_Kazuha_ElementalArt_Hold_WindZone_Monster_Small", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_Hold_WindZone_Monster_Big", + "abilityName": "Avatar_Kazuha_ElementalArt_Hold_WindZone_Monster_Big", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_Hold_WindZone_Other", + "abilityName": "Avatar_Kazuha_ElementalArt_Hold_WindZone_Other", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst", + "abilityName": "Avatar_Kazuha_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Initialize", + "abilityName": "Avatar_Kazuha_ElementalBurst_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Camera_Handler", + "abilityName": "Avatar_Kazuha_ElementalBurst_Camera_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_EmotionControl", + "abilityName": "Avatar_Kazuha_ElementalBurst_EmotionControl", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Camera_PushTarget", + "abilityName": "Avatar_Kazuha_ElementalBurst_Camera_PushTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_WeatherChange", + "abilityName": "Avatar_Kazuha_ElementalBurst_WeatherChange", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Invincible", + "abilityName": "Avatar_Kazuha_ElementalBurst_Invincible", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_CameraEffect", + "abilityName": "Avatar_Kazuha_ElementalBurst_CameraEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_CameraBlur", + "abilityName": "Avatar_Kazuha_ElementalBurst_CameraBlur", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Strike_Damage", + "abilityName": "Avatar_Kazuha_ElementalBurst_Strike_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_CreateMist", + "abilityName": "Avatar_Kazuha_ElementalBurst_CreateMist", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Reconnect", + "abilityName": "Avatar_Kazuha_Reconnect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_CreateMistJ", + "abilityName": "Avatar_Kazuha_ElementalBurst_CreateMistJ", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Kazuha_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Strike_Mix", + "abilityName": "Avatar_Kazuha_ElementalBurst_Strike_Mix", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Mist", + "abilityName": "Avatar_Kazuha_ElementalBurst_Mist", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Mist_Initialize", + "abilityName": "Avatar_Kazuha_ElementalBurst_Mist_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Mist_FieldEffect", + "abilityName": "Avatar_Kazuha_ElementalBurst_Mist_FieldEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Mist_Dissipate", + "abilityName": "Avatar_Kazuha_ElementalBurst_Mist_Dissipate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_MistStrike_Delay", + "abilityName": "Avatar_Kazuha_ElementalBurst_MistStrike_Delay", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_MistStrike", + "abilityName": "Avatar_Kazuha_ElementalBurst_MistStrike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_MistStrike_Effect", + "abilityName": "Avatar_Kazuha_ElementalBurst_MistStrike_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_MistStrike_Fire", + "abilityName": "Avatar_Kazuha_ElementalBurst_MistStrike_Fire", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_MistStrike_Water", + "abilityName": "Avatar_Kazuha_ElementalBurst_MistStrike_Water", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_MistStrike_Electric", + "abilityName": "Avatar_Kazuha_ElementalBurst_MistStrike_Electric", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_MistStrike_Ice", + "abilityName": "Avatar_Kazuha_ElementalBurst_MistStrike_Ice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_MistStrike_Wind", + "abilityName": "Avatar_Kazuha_ElementalBurst_MistStrike_Wind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Mist_Mix", + "abilityName": "Avatar_Kazuha_ElementalBurst_Mist_Mix", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_FallingAnthem", + "abilityName": "Avatar_Kazuha_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_FallingAttack_HideCollider", + "abilityName": "Avatar_Kazuha_ElementalArt_FallingAttack_HideCollider", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_FallingAttack_LoopDamage", + "abilityName": "Avatar_Kazuha_ElementalArt_FallingAttack_LoopDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalArt_FallingAttack_DragCamera", + "abilityName": "Avatar_Kazuha_ElementalArt_FallingAttack_DragCamera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_1", + "abilityName": "Avatar_Kazuha_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_NormalAttack_DamageHandler", + "abilityName": "Avatar_Kazuha_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_1_Effect", + "abilityName": "Avatar_Kazuha_PermanentSkill_1_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_1_ExtraDamage", + "abilityName": "Avatar_Kazuha_PermanentSkill_1_ExtraDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_1_Mix", + "abilityName": "Avatar_Kazuha_PermanentSkill_1_Mix", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_2", + "abilityName": "Avatar_Kazuha_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_2_Handler", + "abilityName": "Avatar_Kazuha_PermanentSkill_2_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_2_Fire", + "abilityName": "Avatar_Kazuha_PermanentSkill_2_Fire", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_2_Firec", + "abilityName": "Avatar_Kazuha_PermanentSkill_2_Firec", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_2_Water", + "abilityName": "Avatar_Kazuha_PermanentSkill_2_Water", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_2_Waterc", + "abilityName": "Avatar_Kazuha_PermanentSkill_2_Waterc", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_2_Electric", + "abilityName": "Avatar_Kazuha_PermanentSkill_2_Electric", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_2_Electricc", + "abilityName": "Avatar_Kazuha_PermanentSkill_2_Electricc", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_PermanentSkill_2_Ice", + "abilityName": "Avatar_Kazuha_PermanentSkill_2_Ice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Constellation_6_WindEnchant", + "abilityName": "Avatar_Kazuha_Constellation_6_WindEnchant", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Constellation_6_DamageUp", + "abilityName": "Avatar_Kazuha_Constellation_6_DamageUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_DashStamina_Reduction", + "abilityName": "Avatar_Kazuha_DashStamina_Reduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_RegionAbility_Dreamland_KazuhaMovie", + "abilityName": "Avatar_RegionAbility_Dreamland_KazuhaMovie", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha", + "abilityName": "Avatar_Kazuha", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Mist_Dissipate1Avatar_Kauzha_ElementalArt_FallingAttack_WindZone", + "abilityName": "Avatar_Kazuha_ElementalBurst_Mist_Dissipate1Avatar_Kauzha_ElementalArt_FallingAttack_WindZone", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Skill_ElementalArt_BS", + "abilityName": "Avatar_Kazuha_Skill_ElementalArt_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Skill_ElementalArt_Charge", + "abilityName": "Avatar_Kazuha_Skill_ElementalArt_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Skill_ElementalArt", + "abilityName": "Avatar_Kazuha_Skill_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Skill_ElementalArt_Hold", + "abilityName": "Avatar_Kazuha_Skill_ElementalArt_Hold", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Skill_ElementalArt_Hold_AS5Emo_Avatar_Kazuha_Skill_ElementalArt_FallingAttack_BS7Emo_Avatar_Kazuha_Skill_ElementalArt_FallingAttack_Loop9Emo_Avatar_Kazuha_Skill_ElementalArt_FallingAttack_Strike", + "abilityName": "Avatar_Kazuha_Skill_ElementalArt_Hold_AS5Emo_Avatar_Kazuha_Skill_ElementalArt_FallingAttack_BS7Emo_Avatar_Kazuha_Skill_ElementalArt_FallingAttack_Loop9Emo_Avatar_Kazuha_Skill_ElementalArt_FallingAttack_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_TeamConfig_01BS", + "abilityName": "Avatar_Kazuha_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_TeamConfig_01Loop", + "abilityName": "Avatar_Kazuha_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_TeamConfig_01AS", + "abilityName": "Avatar_Kazuha_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Skill_ElementalArt_Hold_AS", + "abilityName": "Avatar_Kazuha_Skill_ElementalArt_Hold_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Skill_ElementalArt_FallingAttack_BS", + "abilityName": "Avatar_Kazuha_Skill_ElementalArt_FallingAttack_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Skill_ElementalArt_FallingAttack_Loop", + "abilityName": "Avatar_Kazuha_Skill_ElementalArt_FallingAttack_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Skill_ElementalArt_FallingAttack_Strike", + "abilityName": "Avatar_Kazuha_Skill_ElementalArt_FallingAttack_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Skill_ElementalArt_FallingAttack_Strike_AS", + "abilityName": "Avatar_Kazuha_Skill_ElementalArt_FallingAttack_Strike_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Spine", + "abilityName": "Avatar_Kazuha_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_BS", + "abilityName": "Avatar_Kazuha_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_ElementalBurst_Hit", + "abilityName": "Avatar_Kazuha_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Spine_Loop", + "abilityName": "Avatar_Kazuha_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kazuha_Spine", + "abilityName": "Avatar_Kazuha_Spine", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Keqing.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Keqing.json new file mode 100644 index 0000000..84df2d0 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Keqing.json @@ -0,0 +1,314 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Keqing_ExtraAttack", + "abilityName": "Avatar_Keqing_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ExtraAttack_ExplodeGadget_Eff", + "abilityName": "Avatar_Keqing_ExtraAttack_ExplodeGadget_Eff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ExtraAttack_ExplodeGadget", + "abilityName": "Avatar_Keqing_ExtraAttack_ExplodeGadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_NormalAttack_Handler", + "abilityName": "Avatar_Keqing_NormalAttack_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_NormalAttack05_CreateBullet", + "abilityName": "Avatar_Keqing_NormalAttack05_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_NormalAttack05_Bullet", + "abilityName": "Avatar_Keqing_NormalAttack05_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Electrans_Click", + "abilityName": "Avatar_Keqing_Electrans_Click", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Electrans_Charge", + "abilityName": "Avatar_Keqing_Electrans_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalArt_Charge_Aim", + "abilityName": "Avatar_Keqing_ElementalArt_Charge_Aim", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Electrans_SetGadget", + "abilityName": "Avatar_Keqing_Electrans_SetGadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Electrans_Part2", + "abilityName": "Avatar_Keqing_Electrans_Part2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalArt_HideSpark", + "abilityName": "Avatar_Keqing_ElementalArt_HideSpark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Break1_Buff", + "abilityName": "Avatar_Keqing_Break1_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Electrans_Strike", + "abilityName": "Avatar_Keqing_Electrans_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalArt_Strike_Hit", + "abilityName": "Avatar_Keqing_ElementalArt_Strike_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalArt_Bullet", + "abilityName": "Avatar_Keqing_ElementalArt_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalArt_Hit", + "abilityName": "Avatar_Keqing_ElementalArt_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalArt_Trap", + "abilityName": "Avatar_Keqing_ElementalArt_Trap", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalArt_Trap_Die", + "abilityName": "Avatar_Keqing_ElementalArt_Trap_Die", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalArt_TrapBurst", + "abilityName": "Avatar_Keqing_ElementalArt_TrapBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_Camera", + "abilityName": "Avatar_Keqing_ElementalBurst_Camera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_ScreenEffect_01", + "abilityName": "Avatar_Keqing_ElementalBurst_ScreenEffect_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_CameraEff", + "abilityName": "Avatar_Keqing_ElementalBurst_CameraEff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_Field", + "abilityName": "Avatar_Keqing_ElementalBurst_Field", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst", + "abilityName": "Avatar_Keqing_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_Attack00", + "abilityName": "Avatar_Keqing_ElementalBurst_Attack00", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_Attack01", + "abilityName": "Avatar_Keqing_ElementalBurst_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_Attack02", + "abilityName": "Avatar_Keqing_ElementalBurst_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_Attack03", + "abilityName": "Avatar_Keqing_ElementalBurst_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_Attack03_NoCamera", + "abilityName": "Avatar_Keqing_ElementalBurst_Attack03_NoCamera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_Attack_Hit", + "abilityName": "Avatar_Keqing_ElementalBurst_Attack_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_ScreenEffect_02", + "abilityName": "Avatar_Keqing_ElementalBurst_ScreenEffect_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_NormalAttack_DamageHandler", + "abilityName": "Avatar_Keqing_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_FallingAnthem", + "abilityName": "Avatar_Keqing_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing", + "abilityName": "Avatar_Keqing", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_TeamConfig_01BS", + "abilityName": "Avatar_Keqing_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_TeamConfig_01Loop", + "abilityName": "Avatar_Keqing_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_TeamConfig_01AS", + "abilityName": "Avatar_Keqing_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_Spine", + "abilityName": "Avatar_Keqing_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Spine", + "abilityName": "Avatar_Keqing_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_Hit", + "abilityName": "Avatar_Keqing_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_BS", + "abilityName": "Avatar_Keqing_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_Hit_01", + "abilityName": "Avatar_Keqing_ElementalBurst_Hit_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_Hit_02", + "abilityName": "Avatar_Keqing_ElementalBurst_Hit_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Spine_Loop", + "abilityName": "Avatar_Keqing_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Attack_01", + "abilityName": "Avatar_Keqing_Attack_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Attack_02", + "abilityName": "Avatar_Keqing_Attack_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Attack_03", + "abilityName": "Avatar_Keqing_Attack_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Attack04_Dust", + "abilityName": "Avatar_Keqing_Attack04_Dust", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Attack_04_01", + "abilityName": "Avatar_Keqing_Attack_04_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Attack_04_02", + "abilityName": "Avatar_Keqing_Attack_04_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Attack_HideSpark_04", + "abilityName": "Avatar_Keqing_Attack_HideSpark_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Attack_HideSpark_05", + "abilityName": "Avatar_Keqing_Attack_HideSpark_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Attack_05", + "abilityName": "Avatar_Keqing_Attack_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Attack05_Dust", + "abilityName": "Avatar_Keqing_Attack05_Dust", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ExtraAttack_SpeedLine", + "abilityName": "Avatar_Keqing_ExtraAttack_SpeedLine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_Attack_ExtraAttack_00", + "abilityName": "Avatar_Keqing_Attack_ExtraAttack_00", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalArt_Cast", + "abilityName": "Avatar_Keqing_ElementalArt_Cast", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalArt_Charge_Cast", + "abilityName": "Avatar_Keqing_ElementalArt_Charge_Cast", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalArt_Fly_Attack", + "abilityName": "Avatar_Keqing_ElementalArt_Fly_Attack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalArt_Charge_Lock", + "abilityName": "Avatar_Keqing_ElementalArt_Charge_Lock", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Keqing_ElementalBurst_Attack032Eff_Avatar_Keqing_ElementalBurst_Attack03_NoCamera", + "abilityName": "Avatar_Keqing_ElementalBurst_Attack032Eff_Avatar_Keqing_ElementalBurst_Attack03_NoCamera", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Klee.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Klee.json new file mode 100644 index 0000000..3e33f25 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Klee.json @@ -0,0 +1,209 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Klee_ExtraAttack", + "abilityName": "Avatar_Klee_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_ExtraAttack_CreateClover", + "abilityName": "Avatar_Klee_ExtraAttack_CreateClover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_ExtraAttack_Clover", + "abilityName": "Avatar_Klee_ExtraAttack_Clover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_ExtraAttack_Clover_Bullet", + "abilityName": "Avatar_Klee_ExtraAttack_Clover_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_NoarmalAttack_01_Damage", + "abilityName": "Avatar_Klee_NoarmalAttack_01_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_NoarmalAttack_02_Damage", + "abilityName": "Avatar_Klee_NoarmalAttack_02_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_NoarmalAttack_03_Damage", + "abilityName": "Avatar_Klee_NoarmalAttack_03_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_ElementalArt_ClearTrigger", + "abilityName": "Avatar_Klee_ElementalArt_ClearTrigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_Attack01", + "abilityName": "Avatar_Klee_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_Attack02", + "abilityName": "Avatar_Klee_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_Attack03", + "abilityName": "Avatar_Klee_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_NormalAttack", + "abilityName": "Avatar_Klee_NormalAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_JumpingBomb", + "abilityName": "Avatar_Klee_JumpingBomb", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_ThrowMine", + "abilityName": "Avatar_Klee_ThrowMine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_Mine", + "abilityName": "Avatar_Klee_Mine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_Clover_Clear", + "abilityName": "Avatar_Klee_Clover_Clear", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_CameraRadialBlur", + "abilityName": "Avatar_Klee_CameraRadialBlur", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_Elemental_Burst", + "abilityName": "Avatar_Klee_Elemental_Burst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_Elemental_Burst_Trigger", + "abilityName": "Avatar_Klee_Elemental_Burst_Trigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_ElementalBurst_CreateFunnel", + "abilityName": "Avatar_Klee_ElementalBurst_CreateFunnel", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_Elemental_Burst_Explode", + "abilityName": "Avatar_Klee_Elemental_Burst_Explode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_Constellation_Explode", + "abilityName": "Avatar_Klee_Constellation_Explode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_Constellation_6", + "abilityName": "Avatar_Klee_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_PermanentSkill_1", + "abilityName": "Avatar_Klee_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_PermanentSkill_Free_ExtraAttack_CD", + "abilityName": "Avatar_Klee_PermanentSkill_Free_ExtraAttack_CD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_PermanentSkill_2", + "abilityName": "Avatar_Klee_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_FallingAnthem", + "abilityName": "Avatar_Klee_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_Radar_Collectables_Mengde", + "abilityName": "Avatar_Klee_Radar_Collectables_Mengde", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee", + "abilityName": "Avatar_Klee", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_Skill_ElementalArt", + "abilityName": "Avatar_Klee_Skill_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_Skill_ElementalArt_AS", + "abilityName": "Avatar_Klee_Skill_ElementalArt_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_TeamConfig_01BS", + "abilityName": "Avatar_Klee_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_TeamConfig_01Loop", + "abilityName": "Avatar_Klee_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_TeamConfig_01AS", + "abilityName": "Avatar_Klee_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_ElementalBurst_Spine", + "abilityName": "Avatar_Klee_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_ElementalBurst", + "abilityName": "Avatar_Klee_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_ElementBurst", + "abilityName": "Avatar_Klee_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_ElementBurst_02", + "abilityName": "Avatar_Klee_ElementBurst_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_ElementalBurst_BS", + "abilityName": "Avatar_Klee_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_ElementalBurst_Hit", + "abilityName": "Avatar_Klee_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Klee_ElementalBurst_Buff", + "abilityName": "Avatar_Klee_ElementalBurst_Buff", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kokomi.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kokomi.json new file mode 100644 index 0000000..7f7dece --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Kokomi.json @@ -0,0 +1,374 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Kokomi_ExtraAttack", + "abilityName": "Avatar_Kokomi_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ExtraAttack_Charge", + "abilityName": "Avatar_Kokomi_ExtraAttack_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ExtraAttack_BurstMark", + "abilityName": "Avatar_Kokomi_ExtraAttack_BurstMark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ExtraAttack_Charge_HasTarget", + "abilityName": "Avatar_Kokomi_ExtraAttack_Charge_HasTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ExtraAttack_Charge_NoTarget", + "abilityName": "Avatar_Kokomi_ExtraAttack_Charge_NoTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ExtraAttack_Initiate", + "abilityName": "Avatar_Kokomi_ExtraAttack_Initiate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Attack01", + "abilityName": "Avatar_Kokomi_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Attack02", + "abilityName": "Avatar_Kokomi_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Attack03", + "abilityName": "Avatar_Kokomi_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_NormalAttack_BounceBullet", + "abilityName": "Avatar_Kokomi_NormalAttack_BounceBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_NormalAttack_Bullet_1_Damage", + "abilityName": "Avatar_Kokomi_NormalAttack_Bullet_1_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_NormalAttack_AngularVelocity_Timer", + "abilityName": "Avatar_Kokomi_NormalAttack_AngularVelocity_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_NormalAttack_AngularVelocity", + "abilityName": "Avatar_Kokomi_NormalAttack_AngularVelocity", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_NormalAttack_Bullet_2_Damage", + "abilityName": "Avatar_Kokomi_NormalAttack_Bullet_2_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_NormalAttack_Bullet_3_Damage", + "abilityName": "Avatar_Kokomi_NormalAttack_Bullet_3_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_NormalAttack_Bullet_1_Burst_Damage", + "abilityName": "Avatar_Kokomi_NormalAttack_Bullet_1_Burst_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_NormalAttack_Heal_Handler", + "abilityName": "Avatar_Kokomi_NormalAttack_Heal_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Heal", + "abilityName": "Avatar_Kokomi_ElementalBurst_Heal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_AtkSpeeddBuff", + "abilityName": "Avatar_Kokomi_ElementalBurst_AtkSpeeddBuff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_ReviveEnergy", + "abilityName": "Avatar_Kokomi_ElementalBurst_ReviveEnergy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_NormalAttack_Bullet_2_Burst_Damage", + "abilityName": "Avatar_Kokomi_NormalAttack_Bullet_2_Burst_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_NormalAttack_Bullet_3_Burst_Damage", + "abilityName": "Avatar_Kokomi_NormalAttack_Bullet_3_Burst_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalArt", + "abilityName": "Avatar_Kokomi_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalArt_KillGadget", + "abilityName": "Avatar_Kokomi_ElementalArt_KillGadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalArt_WaterBuff", + "abilityName": "Avatar_Kokomi_ElementalArt_WaterBuff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalArt_ElemBall", + "abilityName": "Avatar_Kokomi_ElementalArt_ElemBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalArt_Heal", + "abilityName": "Avatar_Kokomi_ElementalArt_Heal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Hagoromo", + "abilityName": "Avatar_Kokomi_ElementalBurst_Hagoromo", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Reset", + "abilityName": "Avatar_Kokomi_ElementalBurst_Reset", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Hagoromo_Move", + "abilityName": "Avatar_Kokomi_Hagoromo_Move", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Hagoromo_Attack01", + "abilityName": "Avatar_Kokomi_Hagoromo_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Hagoromo_Attack02", + "abilityName": "Avatar_Kokomi_Hagoromo_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Hagoromo_Attack03", + "abilityName": "Avatar_Kokomi_Hagoromo_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Hagoromo_ExtraAttack", + "abilityName": "Avatar_Kokomi_Hagoromo_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Hagoromo_ElementalArt", + "abilityName": "Avatar_Kokomi_Hagoromo_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Hagoromo_Hide", + "abilityName": "Avatar_Kokomi_Hagoromo_Hide", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Ripple_Hide", + "abilityName": "Avatar_Kokomi_Ripple_Hide", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Hagoromo_ChangeFollowDampTime", + "abilityName": "Avatar_Kokomi_Hagoromo_ChangeFollowDampTime", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Hagoromo", + "abilityName": "Avatar_Kokomi_Hagoromo", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_FootRipple_Left", + "abilityName": "Avatar_Kokomi_ElementalBurst_FootRipple_Left", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_FootRipple_Right", + "abilityName": "Avatar_Kokomi_ElementalBurst_FootRipple_Right", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Initiate", + "abilityName": "Avatar_Kokomi_ElementalBurst_Initiate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_States", + "abilityName": "Avatar_Kokomi_ElementalBurst_States", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Camera", + "abilityName": "Avatar_Kokomi_ElementalBurst_Camera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Pre_Weather", + "abilityName": "Avatar_Kokomi_ElementalBurst_Pre_Weather", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Emotion", + "abilityName": "Avatar_Kokomi_ElementalBurst_Emotion", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Weathert", + "abilityName": "Avatar_Kokomi_ElementalBurst_Weathert", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Weather", + "abilityName": "Avatar_Kokomi_ElementalBurst_Weather", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_DamageBuff_HealAdd", + "abilityName": "Avatar_Kokomi_ElementalBurst_DamageBuff_HealAdd", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_AtkSpeedBuff", + "abilityName": "Avatar_Kokomi_ElementalBurst_AtkSpeedBuff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Hagoromo_Remover", + "abilityName": "Avatar_Kokomi_Hagoromo_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_MoveOnWater_Remover", + "abilityName": "Avatar_Kokomi_MoveOnWater_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Hagoromo6UNIQUE_Avatar_Kokomi_ElementalBurst_DamageBuff_HealAdd", + "abilityName": "Avatar_Kokomi_Hagoromo6UNIQUE_Avatar_Kokomi_ElementalBurst_DamageBuff_HealAdd", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Heal_Predicate_LowHP", + "abilityName": "Avatar_Kokomi_ElementalBurst_Heal_Predicate_LowHP", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Heal_LowHPTarget", + "abilityName": "Avatar_Kokomi_ElementalBurst_Heal_LowHPTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Heal_Predicate_Overheal", + "abilityName": "Avatar_Kokomi_ElementalBurst_Heal_Predicate_Overheal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Heal_Predicate_Overheal4Avatar_Kokomi_ElementalBurst_Heal_Predicate_Overheal", + "abilityName": "Avatar_Kokomi_ElementalBurst_Heal_Predicate_Overheal4Avatar_Kokomi_ElementalBurst_Heal_Predicate_Overheal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ExtraHeal_OverHeal", + "abilityName": "Avatar_Kokomi_ExtraHeal_OverHeal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_OverHeal", + "abilityName": "Avatar_Kokomi_ElementalBurst_OverHeal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_OverHeal_Buff1UNIQUE_Avatar_Kokomi_ElementalBurst_OverHeal_Buff", + "abilityName": "Avatar_Kokomi_ElementalBurst_OverHeal_Buff1UNIQUE_Avatar_Kokomi_ElementalBurst_OverHeal_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_FallingAnthem", + "abilityName": "Avatar_Kokomi_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_SwimStamina_Reduction", + "abilityName": "Avatar_Kokomi_SwimStamina_Reduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_CritRateDown", + "abilityName": "Avatar_Kokomi_CritRateDown", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_CritRate_Delta", + "abilityName": "Avatar_Kokomi_CritRate_Delta", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_HealAdd_Delta", + "abilityName": "Avatar_Kokomi_HealAdd_Delta", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi", + "abilityName": "Avatar_Kokomi", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_NormalAttack_Bullet_3_Damage0Avatar_Kokomi_NormalAttack_Bullet_1_Burst_Damage0Avatar_Kokomi_NormalAttack_Bullet_2_Burst_Damage0Avatar_Kokomi_NormalAttack_Bullet_3_Burst_Damage", + "abilityName": "Avatar_Kokomi_NormalAttack_Bullet_3_Damage0Avatar_Kokomi_NormalAttack_Bullet_1_Burst_Damage0Avatar_Kokomi_NormalAttack_Bullet_2_Burst_Damage0Avatar_Kokomi_NormalAttack_Bullet_3_Burst_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_TeamConfig_01BS", + "abilityName": "Avatar_Kokomi_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_TeamConfig_01Loop", + "abilityName": "Avatar_Kokomi_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_TeamConfig_01AS", + "abilityName": "Avatar_Kokomi_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Spine", + "abilityName": "Avatar_Kokomi_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_BS", + "abilityName": "Avatar_Kokomi_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_ElementalBurst_Hit", + "abilityName": "Avatar_Kokomi_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Kokomi_Spine_Loop", + "abilityName": "Avatar_Kokomi_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Layla.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Layla.json new file mode 100644 index 0000000..49494a5 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Layla.json @@ -0,0 +1,109 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Layla_ExtraAttack", + "abilityName": "Avatar_Layla_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_ElementalArt", + "abilityName": "Avatar_Layla_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_HasTeamShield", + "abilityName": "Avatar_Layla_HasTeamShield", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_ElementalArt_Handler", + "abilityName": "Avatar_Layla_ElementalArt_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_IceShield_GV_Count", + "abilityName": "Avatar_Layla_IceShield_GV_Count", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_IceShield_Can_Count", + "abilityName": "Avatar_Layla_IceShield_Can_Count", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_ToughShield_Level", + "abilityName": "Avatar_Layla_ToughShield_Level", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_ElementalArt_Gadget", + "abilityName": "Avatar_Layla_ElementalArt_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_IceShield_GV_Gadget", + "abilityName": "Avatar_Layla_IceShield_GV_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_Shoot_TeamBuff", + "abilityName": "Avatar_Layla_Shoot_TeamBuff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_ArtAndBurst_ReviveEnergy", + "abilityName": "Avatar_Layla_ArtAndBurst_ReviveEnergy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_ElementalBurst", + "abilityName": "Avatar_Layla_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_ElementalBurst_Gadget", + "abilityName": "Avatar_Layla_ElementalBurst_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_NormalAttack_DamageHandler", + "abilityName": "Avatar_Layla_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_ArtAndBurst_DamageExtra", + "abilityName": "Avatar_Layla_ArtAndBurst_DamageExtra", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_ArtAndBurst_DamageUp", + "abilityName": "Avatar_Layla_ArtAndBurst_DamageUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_FallingAnthem", + "abilityName": "Avatar_Layla_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla", + "abilityName": "Avatar_Layla", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_TeamConfig_01BS", + "abilityName": "Avatar_Layla_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_TeamConfig_01Loop", + "abilityName": "Avatar_Layla_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Layla_TeamConfig_01AS", + "abilityName": "Avatar_Layla_TeamConfig_01AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Linette.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Linette.json new file mode 100644 index 0000000..451af12 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Linette.json @@ -0,0 +1,169 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Linette_ExtraAttack", + "abilityName": "Avatar_Linette_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ArkheGrade", + "abilityName": "Avatar_Linette_ArkheGrade", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ArkheGrade_CD", + "abilityName": "Avatar_Linette_ArkheGrade_CD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalArt", + "abilityName": "Avatar_Linette_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalArt_DropBall_Handler", + "abilityName": "Avatar_Linette_ElementalArt_DropBall_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalArt_Executed", + "abilityName": "Avatar_Linette_ElementalArt_Executed", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalArt_Short_Strike", + "abilityName": "Avatar_Linette_ElementalArt_Short_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalArt_Executed_Strike", + "abilityName": "Avatar_Linette_ElementalArt_Executed_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalArt_RushMove", + "abilityName": "Avatar_Linette_ElementalArt_RushMove", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_Constellation_6", + "abilityName": "Avatar_Linette_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_Constellation_6_WindEnchant", + "abilityName": "Avatar_Linette_Constellation_6_WindEnchant", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_Constellation_6_DamageUp", + "abilityName": "Avatar_Linette_Constellation_6_DamageUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalArt_Executed_Bullet", + "abilityName": "Avatar_Linette_ElementalArt_Executed_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalBurst", + "abilityName": "Avatar_Linette_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_PermanentSkill_1", + "abilityName": "Avatar_Linette_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalBurst_Strike", + "abilityName": "Avatar_Linette_ElementalBurst_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalBurst_MagicBox", + "abilityName": "Avatar_Linette_ElementalBurst_MagicBox", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalBurst_MagicBox_Bullet_Ice", + "abilityName": "Avatar_Linette_ElementalBurst_MagicBox_Bullet_Ice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalBurst_MagicBox_Bullet_Fire", + "abilityName": "Avatar_Linette_ElementalBurst_MagicBox_Bullet_Fire", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalBurst_MagicBox_Bullet_Water", + "abilityName": "Avatar_Linette_ElementalBurst_MagicBox_Bullet_Water", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalBurst_MagicBox_Bullet_Electric", + "abilityName": "Avatar_Linette_ElementalBurst_MagicBox_Bullet_Electric", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalBurst_HitBox", + "abilityName": "Avatar_Linette_ElementalBurst_HitBox", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_Constellation_WindZone", + "abilityName": "Avatar_Linette_Constellation_WindZone", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_PermanentSkill_1_AttackUp", + "abilityName": "Avatar_Linette_PermanentSkill_1_AttackUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_NormalAttack_DamageHandler", + "abilityName": "Avatar_Linette_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_FallingAnthem", + "abilityName": "Avatar_Linette_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalBurst_MagicBox_Bullet_Wind", + "abilityName": "Avatar_Linette_ElementalBurst_MagicBox_Bullet_Wind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_PermanentSkill_3", + "abilityName": "Avatar_Linette_PermanentSkill_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette", + "abilityName": "Avatar_Linette", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_ElementalBurst_MagicBox1Avatar_Linette_ElementalBurst_MagicBox_Bullet_Ice2Avatar_Linette_ElementalBurst_MagicBox_Bullet_Fire3Avatar_Linette_ElementalBurst_MagicBox_Bullet_Water6Avatar_Linette_ElementalBurst_MagicBox_Bullet_Electric", + "abilityName": "Avatar_Linette_ElementalBurst_MagicBox1Avatar_Linette_ElementalBurst_MagicBox_Bullet_Ice2Avatar_Linette_ElementalBurst_MagicBox_Bullet_Fire3Avatar_Linette_ElementalBurst_MagicBox_Bullet_Water6Avatar_Linette_ElementalBurst_MagicBox_Bullet_Electric", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_TeamConfig_01BS", + "abilityName": "Avatar_Linette_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_TeamConfig_01Loop", + "abilityName": "Avatar_Linette_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Linette_TeamConfig_01AS", + "abilityName": "Avatar_Linette_TeamConfig_01AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Liney.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Liney.json new file mode 100644 index 0000000..76a44dd --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Liney.json @@ -0,0 +1,129 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Liney_PressShoot", + "abilityName": "Avatar_Liney_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_AimPressShoot", + "abilityName": "Avatar_Liney_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_Arrow_FX", + "abilityName": "Avatar_Liney_Arrow_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_ShootAimingArrow_Charge", + "abilityName": "Avatar_Liney_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_ShootArrow_01", + "abilityName": "Avatar_Liney_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_ShootArrow_02", + "abilityName": "Avatar_Liney_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_ShootArrow_03_01", + "abilityName": "Avatar_Liney_ShootArrow_03_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_ShootArrow_03_02", + "abilityName": "Avatar_Liney_ShootArrow_03_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_ShootArrow_04", + "abilityName": "Avatar_Liney_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_ShootArrow_Aiming", + "abilityName": "Avatar_Liney_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_ShootArrow_Enchanted_WithoutFire", + "abilityName": "Avatar_Liney_ShootArrow_Enchanted_WithoutFire", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_ExtraAttack", + "abilityName": "Avatar_Liney_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_ElementalArt", + "abilityName": "Avatar_Liney_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_ElementalBurst", + "abilityName": "Avatar_Liney_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_ExitSpecialMove", + "abilityName": "Avatar_Liney_ExitSpecialMove", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_FallingAnthem", + "abilityName": "Avatar_Liney_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_PermanentSkill_3", + "abilityName": "Avatar_Liney_PermanentSkill_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_PermanentSkill_2", + "abilityName": "Avatar_Liney_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_CriticalHurt_GrandHandler", + "abilityName": "Avatar_Liney_CriticalHurt_GrandHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_CriticalHurt_Handler", + "abilityName": "Avatar_Liney_CriticalHurt_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_CriticalHurt_Buff", + "abilityName": "Avatar_Liney_CriticalHurt_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney", + "abilityName": "Avatar_Liney", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_TeamConfig_01BS", + "abilityName": "Avatar_Liney_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_TeamConfig_01Loop", + "abilityName": "Avatar_Liney_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liney_TeamConfig_01AS", + "abilityName": "Avatar_Liney_TeamConfig_01AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Lisa.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Lisa.json new file mode 100644 index 0000000..622600b --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Lisa.json @@ -0,0 +1,189 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Lisa_ExtraAttack", + "abilityName": "Avatar_Lisa_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_ExtraAttack_Damage", + "abilityName": "Avatar_Lisa_ExtraAttack_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_NormalAttack04_Blink", + "abilityName": "Avatar_Lisa_NormalAttack04_Blink", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_TriggerAbility2", + "abilityName": "Avatar_Lisa_TriggerAbility2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_Weather_Trigger", + "abilityName": "Avatar_Lisa_Weather_Trigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_Weather_Remove", + "abilityName": "Avatar_Lisa_Weather_Remove", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_Attack01", + "abilityName": "Avatar_Lisa_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_Attack02", + "abilityName": "Avatar_Lisa_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_Attack03", + "abilityName": "Avatar_Lisa_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_Attack04", + "abilityName": "Avatar_Lisa_Attack04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_NormalAttack_Burst", + "abilityName": "Avatar_Lisa_NormalAttack_Burst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_NormalAttack_Hit_Fx", + "abilityName": "Avatar_Lisa_NormalAttack_Hit_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_FlickerWave_Hit_Fx", + "abilityName": "Avatar_Lisa_FlickerWave_Hit_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_FlickerWave", + "abilityName": "Avatar_Lisa_FlickerWave", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_FlickerWaveDamage", + "abilityName": "Avatar_Lisa_FlickerWaveDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_StaticElecFieldh", + "abilityName": "Avatar_Lisa_StaticElecFieldh", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_StaticElecField", + "abilityName": "Avatar_Lisa_StaticElecField", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_Constellation_6", + "abilityName": "Avatar_Lisa_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_ThunderFall", + "abilityName": "Avatar_Lisa_ThunderFall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_PierceLightning", + "abilityName": "Avatar_Lisa_PierceLightning", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_PierceLightning_Ball", + "abilityName": "Avatar_Lisa_PierceLightning_Ball", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_PierceLightning_Ball_Attack", + "abilityName": "Avatar_Lisa_PierceLightning_Ball_Attack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_PierceLightning_Ball_FX", + "abilityName": "Avatar_Lisa_PierceLightning_Ball_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_Captain", + "abilityName": "Avatar_Lisa_Captain", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_FallingAnthem", + "abilityName": "Avatar_Lisa_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa", + "abilityName": "Avatar_Lisa", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_PierceLightning_AS", + "abilityName": "Avatar_Lisa_PierceLightning_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_TeamConfig_01BS", + "abilityName": "Avatar_Lisa_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_TeamConfig_01Loop", + "abilityName": "Avatar_Lisa_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_TeamConfig_01AS", + "abilityName": "Avatar_Lisa_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_ElementalBurst_Spine", + "abilityName": "Avatar_Lisa_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_ElementalBurst_Hit", + "abilityName": "Avatar_Lisa_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_ElementalBurst_BS", + "abilityName": "Avatar_Lisa_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_Spine_Loop", + "abilityName": "Avatar_Lisa_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_VO_Emotion_Lisa_Strange_01", + "abilityName": "Avatar_Lisa_VO_Emotion_Lisa_Strange_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_VO_Emotion_Lisa_Wu_03", + "abilityName": "Avatar_Lisa_VO_Emotion_Lisa_Wu_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Lisa_VO_Emotion_Lisa_Deny_01", + "abilityName": "Avatar_Lisa_VO_Emotion_Lisa_Deny_01", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Liuyun.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Liuyun.json new file mode 100644 index 0000000..aeeff60 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Liuyun.json @@ -0,0 +1,129 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Liuyun_ExtraAttack", + "abilityName": "Avatar_Liuyun_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_ExtraAttack_Bullet", + "abilityName": "Avatar_Liuyun_ExtraAttack_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_Attack01", + "abilityName": "Avatar_Liuyun_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_NormalAttack_Bullet_01", + "abilityName": "Avatar_Liuyun_NormalAttack_Bullet_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_Attack02", + "abilityName": "Avatar_Liuyun_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_NormalAttack_Bullet_02", + "abilityName": "Avatar_Liuyun_NormalAttack_Bullet_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_Attack03", + "abilityName": "Avatar_Liuyun_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_NormalAttack_Bullet_03", + "abilityName": "Avatar_Liuyun_NormalAttack_Bullet_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_Attack04", + "abilityName": "Avatar_Liuyun_Attack04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_NormalAttack_Bullet_04", + "abilityName": "Avatar_Liuyun_NormalAttack_Bullet_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_ElementalArt", + "abilityName": "Avatar_Liuyun_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_ElementalArt_CameraControl", + "abilityName": "Avatar_Liuyun_ElementalArt_CameraControl", + "abilityOverride": "" + }, + { + "abilityID": "Liuyun_ElementalArt_Move_Collider", + "abilityName": "Liuyun_ElementalArt_Move_Collider", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_ElementalArt_ExtraFallingAttack", + "abilityName": "Avatar_Liuyun_ElementalArt_ExtraFallingAttack", + "abilityOverride": "" + }, + { + "abilityID": "Liuyun_ElementalArt_Crane_Collider", + "abilityName": "Liuyun_ElementalArt_Crane_Collider", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_ElementBurst", + "abilityName": "Avatar_Liuyun_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_ElementBurst_Drone", + "abilityName": "Avatar_Liuyun_ElementBurst_Drone", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_ElementBurst_HealHandler", + "abilityName": "Avatar_Liuyun_ElementBurst_HealHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_FallingAnthem", + "abilityName": "Avatar_Liuyun_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_PermanentSkill_1", + "abilityName": "Avatar_Liuyun_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Liuyun_ElementalArt_WindHole", + "abilityName": "Liuyun_ElementalArt_WindHole", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_Constellation_2", + "abilityName": "Avatar_Liuyun_Constellation_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_Constellation_4", + "abilityName": "Avatar_Liuyun_Constellation_4", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_Constellation_6", + "abilityName": "Avatar_Liuyun_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Liuyun_PermanentSkill_3", + "abilityName": "Avatar_Liuyun_PermanentSkill_3", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Mika.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Mika.json new file mode 100644 index 0000000..7c2b399 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Mika.json @@ -0,0 +1,254 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Mika_ExtraAttack", + "abilityName": "Avatar_Mika_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_ExtraAttack_CreateBullet", + "abilityName": "Avatar_Mika_ExtraAttack_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_ExtraAttack_Bullet", + "abilityName": "Avatar_Mika_ExtraAttack_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_ElementalArt", + "abilityName": "Avatar_Mika_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_ElementalArt_Buff_Controller", + "abilityName": "Avatar_Mika_ElementalArt_Buff_Controller", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Attack_Speed_Up", + "abilityName": "Avatar_Mika_Attack_Speed_Up", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_ElementalArt_Buff_Team_Ratio", + "abilityName": "Avatar_Mika_ElementalArt_Buff_Team_Ratio", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Attack_Speed_Up_Sub_Controller", + "abilityName": "Avatar_Mika_Attack_Speed_Up_Sub_Controller", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_ElementalArt_Buff_Mark", + "abilityName": "Avatar_Mika_ElementalArt_Buff_Mark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_C6_Sub_LocalAvatar", + "abilityName": "Avatar_Mika_C6_Sub_LocalAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Attack_Speed_Up_Sub_1", + "abilityName": "Avatar_Mika_Attack_Speed_Up_Sub_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Attack_Speed_Up_Sub_2", + "abilityName": "Avatar_Mika_Attack_Speed_Up_Sub_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Attack_Speed_Up_Sub_3", + "abilityName": "Avatar_Mika_Attack_Speed_Up_Sub_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Attack_Speed_Up_Sub_4", + "abilityName": "Avatar_Mika_Attack_Speed_Up_Sub_4", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Attack_Speed_Up_Sub_5", + "abilityName": "Avatar_Mika_Attack_Speed_Up_Sub_5", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_P2_Mark", + "abilityName": "Avatar_Mika_P2_Mark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Buff_Eff_Trigger_Mode", + "abilityName": "Avatar_Mika_Buff_Eff_Trigger_Mode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Sub_Buff_GV_AddOne", + "abilityName": "Avatar_Mika_Sub_Buff_GV_AddOne", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Attack_Speed_Up_Sub_1_LocalAvatar", + "abilityName": "Avatar_Mika_Attack_Speed_Up_Sub_1_LocalAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Attack_Speed_Up_Sub_2_LocalAvatar", + "abilityName": "Avatar_Mika_Attack_Speed_Up_Sub_2_LocalAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Attack_Speed_Up_Sub_3_LocalAvatar", + "abilityName": "Avatar_Mika_Attack_Speed_Up_Sub_3_LocalAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Attack_Speed_Up_Sub_4_LocalAvatar", + "abilityName": "Avatar_Mika_Attack_Speed_Up_Sub_4_LocalAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Attack_Speed_Up_Sub_5_LocalAvatar", + "abilityName": "Avatar_Mika_Attack_Speed_Up_Sub_5_LocalAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_C6_Sub_1_LocalAvatar", + "abilityName": "Avatar_Mika_C6_Sub_1_LocalAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_C6_Sub_2_LocalAvatar", + "abilityName": "Avatar_Mika_C6_Sub_2_LocalAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_C6_Sub_3_LocalAvatar", + "abilityName": "Avatar_Mika_C6_Sub_3_LocalAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_C6_Sub_4_LocalAvatar", + "abilityName": "Avatar_Mika_C6_Sub_4_LocalAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_C6_Sub_5_LocalAvatar", + "abilityName": "Avatar_Mika_C6_Sub_5_LocalAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Sub_Buff_Trigger_Eff_Mode_1", + "abilityName": "Avatar_Mika_Sub_Buff_Trigger_Eff_Mode_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Buff_Eff_Trigger_Mode_In_1", + "abilityName": "Avatar_Mika_Buff_Eff_Trigger_Mode_In_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Buff_Eff_Trigger_Mode_In_2", + "abilityName": "Avatar_Mika_Buff_Eff_Trigger_Mode_In_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Sub_Buff_Trigger_Eff", + "abilityName": "Avatar_Mika_Sub_Buff_Trigger_Eff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Sub_Buff_Trigger_Eff_Mode_2", + "abilityName": "Avatar_Mika_Sub_Buff_Trigger_Eff_Mode_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_ElementalArt_NoChargeShoot", + "abilityName": "Avatar_Mika_ElementalArt_NoChargeShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_ElementalArt_Buff_Controller_", + "abilityName": "Avatar_Mika_ElementalArt_Buff_Controller_", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_ElementalArt_Sub_Bullet_Launch", + "abilityName": "Avatar_Mika_ElementalArt_Sub_Bullet_Launch", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_ElementalArt_ChargeShoot", + "abilityName": "Avatar_Mika_ElementalArt_ChargeShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Aim_Mixin", + "abilityName": "Avatar_Mika_Aim_Mixin", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_RayCast_CloseFx", + "abilityName": "Avatar_Mika_RayCast_CloseFx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_EArt_Has_Target_Mark", + "abilityName": "Avatar_Mika_EArt_Has_Target_Mark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_ElementBurst", + "abilityName": "Avatar_Mika_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_C4_Stack", + "abilityName": "Avatar_Mika_C4_Stack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Burst_Energy_Revive", + "abilityName": "Avatar_Mika_Burst_Energy_Revive", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_FallingAnthem", + "abilityName": "Avatar_Mika_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Attack_DamageHandler", + "abilityName": "Avatar_Mika_Attack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_Radar_Collectables_Mengde", + "abilityName": "Avatar_Mika_Radar_Collectables_Mengde", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika", + "abilityName": "Avatar_Mika", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_TeamConfig_01BS", + "abilityName": "Avatar_Mika_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_TeamConfig_01Loop", + "abilityName": "Avatar_Mika_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mika_TeamConfig_01AS", + "abilityName": "Avatar_Mika_TeamConfig_01AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Momoka.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Momoka.json new file mode 100644 index 0000000..0d80fc3 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Momoka.json @@ -0,0 +1,134 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Momoka_ExtraAttack", + "abilityName": "Avatar_Momoka_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_ElementalArt_Check", + "abilityName": "Avatar_Momoka_ElementalArt_Check", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_ElementalArt_Click", + "abilityName": "Avatar_Momoka_ElementalArt_Click", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_ElementalArt_DropBall_Handler", + "abilityName": "Avatar_Momoka_ElementalArt_DropBall_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_AddShieldMode", + "abilityName": "Avatar_Momoka_AddShieldMode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_ElementalArt_Hold", + "abilityName": "Avatar_Momoka_ElementalArt_Hold", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_ElementalArt_Inactive_Detect", + "abilityName": "Avatar_Momoka_ElementalArt_Inactive_Detect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_ElementalArt_onReconnect", + "abilityName": "Avatar_Momoka_ElementalArt_onReconnect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_HasTeamShield", + "abilityName": "Avatar_Momoka_HasTeamShield", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_Constellation_AddAttack", + "abilityName": "Avatar_Momoka_Constellation_AddAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_ElementalArt_Charge_Strike", + "abilityName": "Avatar_Momoka_ElementalArt_Charge_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_ElementalBurst", + "abilityName": "Avatar_Momoka_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_ElementalBurst_ExpressDamage", + "abilityName": "Avatar_Momoka_ElementalBurst_ExpressDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_NormalAttack_DamageHandler", + "abilityName": "Avatar_Momoka_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_FallingAnthem", + "abilityName": "Avatar_Momoka_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_PermanentSkill_2", + "abilityName": "Avatar_Momoka_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_PermanentSkill_2_Handler", + "abilityName": "Avatar_Momoka_PermanentSkill_2_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_Constellation_6", + "abilityName": "Avatar_Momoka_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_Constellation_6_ElemDamageUp_Effect", + "abilityName": "Avatar_Momoka_Constellation_6_ElemDamageUp_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_Constellation_AddAttack_CDHandler", + "abilityName": "Avatar_Momoka_Constellation_AddAttack_CDHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_Constellation_AddAttack_Effect", + "abilityName": "Avatar_Momoka_Constellation_AddAttack_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_PermanentSkill_3", + "abilityName": "Avatar_Momoka_PermanentSkill_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka", + "abilityName": "Avatar_Momoka", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_TeamConfig_01BS", + "abilityName": "Avatar_Momoka_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_TeamConfig_01Loop", + "abilityName": "Avatar_Momoka_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Momoka_TeamConfig_01AS", + "abilityName": "Avatar_Momoka_TeamConfig_01AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Mona.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Mona.json new file mode 100644 index 0000000..bc1c3ec --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Mona.json @@ -0,0 +1,169 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Mona_Liquid_TriggerAbility", + "abilityName": "Avatar_Mona_Liquid_TriggerAbility", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_LiquidStrike", + "abilityName": "Avatar_Mona_LiquidStrike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_EndLiquidStrike", + "abilityName": "Avatar_Mona_EndLiquidStrike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_ExtraAttack", + "abilityName": "Avatar_Mona_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_ExtraAttack_FX", + "abilityName": "Avatar_Mona_ExtraAttack_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_ExtraAttack_Damage", + "abilityName": "Avatar_Mona_ExtraAttack_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_NormalAttack_01", + "abilityName": "Avatar_Mona_NormalAttack_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_NormalAttack_02", + "abilityName": "Avatar_Mona_NormalAttack_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_NormalAttack_03_BS", + "abilityName": "Avatar_Mona_NormalAttack_03_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_NormalAttack_03_Blink", + "abilityName": "Avatar_Mona_NormalAttack_03_Blink", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_NormalAttack_03", + "abilityName": "Avatar_Mona_NormalAttack_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_NormalAttack_04", + "abilityName": "Avatar_Mona_NormalAttack_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_NormalAttack_04_Hit", + "abilityName": "Avatar_Mona_NormalAttack_04_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_Phantom_BS", + "abilityName": "Avatar_Mona_Phantom_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_Phantom_Blink_BS", + "abilityName": "Avatar_Mona_Phantom_Blink_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_Phantom", + "abilityName": "Avatar_Mona_Phantom", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_Phantom_Blink", + "abilityName": "Avatar_Mona_Phantom_Blink", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_Phantom_Blink_SetVisible", + "abilityName": "Avatar_Mona_Phantom_Blink_SetVisible", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_MonaGadgetSkill_Phantom", + "abilityName": "Avatar_MonaGadgetSkill_Phantom", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_MonaGadgetSkill_PhantomLastAttack", + "abilityName": "Avatar_MonaGadgetSkill_PhantomLastAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_StarChart_Camera", + "abilityName": "Avatar_Mona_StarChart_Camera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_StarChart", + "abilityName": "Avatar_Mona_StarChart", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_FallingAnthem", + "abilityName": "Avatar_Mona_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona", + "abilityName": "Avatar_Mona", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_TeamConfig_01BS", + "abilityName": "Avatar_Mona_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_TeamConfig_01Loop", + "abilityName": "Avatar_Mona_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_TeamConfig_01AS", + "abilityName": "Avatar_Mona_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_elementalBurst_BS_Normal", + "abilityName": "Avatar_Mona_elementalBurst_BS_Normal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_ElementalBurst_Spine", + "abilityName": "Avatar_Mona_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_ElementalBurst_Hit", + "abilityName": "Avatar_Mona_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_ElementalBurst_BS", + "abilityName": "Avatar_Mona_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_Spine_Loop", + "abilityName": "Avatar_Mona_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Mona_StarChart1AS_Mona_StarChart_RemovedDamage_HurtUp_DamageRate", + "abilityName": "Avatar_Mona_StarChart1AS_Mona_StarChart_RemovedDamage_HurtUp_DamageRate", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Nahida.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Nahida.json new file mode 100644 index 0000000..152598a --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Nahida.json @@ -0,0 +1,454 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Nahida_ExtraAttack", + "abilityName": "Avatar_Nahida_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ExtraAttack_BS_Check", + "abilityName": "Avatar_Nahida_ExtraAttack_BS_Check", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ExtraAttack_Damage", + "abilityName": "Avatar_Nahida_ExtraAttack_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ExtraAttack_Hand_FX", + "abilityName": "Avatar_Nahida_ExtraAttack_Hand_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ExtraAttack_Block_FXy", + "abilityName": "Avatar_Nahida_ExtraAttack_Block_FXy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ExtraAttack_Initialize", + "abilityName": "Avatar_Nahida_ExtraAttack_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ExtraAttack_Block_FX", + "abilityName": "Avatar_Nahida_ExtraAttack_Block_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ExtraAttack_Gadget", + "abilityName": "Avatar_Nahida_ExtraAttack_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ExtraAttack_Delay_Damage", + "abilityName": "Avatar_Nahida_ExtraAttack_Delay_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Attack01", + "abilityName": "Avatar_Nahida_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Block_Die_01", + "abilityName": "Avatar_Nahida_Block_Die_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Attack02", + "abilityName": "Avatar_Nahida_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Block_Die_02D", + "abilityName": "Avatar_Nahida_Block_Die_02D", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Block_Die_02", + "abilityName": "Avatar_Nahida_Block_Die_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Attack03", + "abilityName": "Avatar_Nahida_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Block_Die_03", + "abilityName": "Avatar_Nahida_Block_Die_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Attack04", + "abilityName": "Avatar_Nahida_Attack04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalArt", + "abilityName": "Avatar_Nahida_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalArt_HairEmission", + "abilityName": "Avatar_Nahida_ElementalArt_HairEmission", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalArt_HairEmission_Remover", + "abilityName": "Avatar_Nahida_ElementalArt_HairEmission_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalArt_Tag_Handler", + "abilityName": "Avatar_Nahida_ElementalArt_Tag_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_RayTag_OnMonster", + "abilityName": "Avatar_Nahida_RayTag_OnMonster", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalArt_Tag_ClearTimer", + "abilityName": "Avatar_Nahida_ElementalArt_Tag_ClearTimer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalArt_ChainCD_Handler", + "abilityName": "Avatar_Nahida_ElementalArt_ChainCD_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalArt_DropBall_Handler", + "abilityName": "Avatar_Nahida_ElementalArt_DropBall_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalArt_DropBall", + "abilityName": "Avatar_Nahida_ElementalArt_DropBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalArt_Click", + "abilityName": "Avatar_Nahida_ElementalArt_Click", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalArt_Click_Strike", + "abilityName": "Avatar_Nahida_ElementalArt_Click_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalArt_Click_Effect", + "abilityName": "Avatar_Nahida_ElementalArt_Click_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalArt_RayCast", + "abilityName": "Avatar_Nahida_ElementalArt_RayCast", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_RayCast_Trigger", + "abilityName": "Avatar_Nahida_RayCast_Trigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_RayCast_CloseFx", + "abilityName": "Avatar_Nahida_RayCast_CloseFx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_RayCast_Handler", + "abilityName": "Avatar_Nahida_RayCast_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_RayCast_Camera_Fx", + "abilityName": "Avatar_Nahida_RayCast_Camera_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_RayCast_HitBoxOffset", + "abilityName": "Avatar_Nahida_RayCast_HitBoxOffset", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_RayCast_Bomb_OnMonster_Fx", + "abilityName": "Avatar_Nahida_RayCast_Bomb_OnMonster_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_RayCast_Bomb_OnMonster_Damage", + "abilityName": "Avatar_Nahida_RayCast_Bomb_OnMonster_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalArt_ScreenEffect", + "abilityName": "Avatar_Nahida_ElementalArt_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Reconnect_Handler", + "abilityName": "Avatar_Nahida_Reconnect_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_RayCast_Camera_Fx_OnTeam", + "abilityName": "Avatar_Nahida_RayCast_Camera_Fx_OnTeam", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst", + "abilityName": "Avatar_Nahida_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Initialize", + "abilityName": "Avatar_Nahida_ElementalBurst_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_EmotionControl", + "abilityName": "Avatar_Nahida_ElementalBurst_EmotionControl", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Camera_Effect", + "abilityName": "Avatar_Nahida_ElementalBurst_Camera_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Camera_Handler", + "abilityName": "Avatar_Nahida_ElementalBurst_Camera_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Camera_PushTarget333", + "abilityName": "Avatar_Nahida_ElementalBurst_Camera_PushTarget333", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Invincible", + "abilityName": "Avatar_Nahida_ElementalBurst_Invincible", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_WeatherChange", + "abilityName": "Avatar_Nahida_ElementalBurst_WeatherChange", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_CreateHollow", + "abilityName": "Avatar_Nahida_ElementalBurst_CreateHollow", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Camera_DungeonEffect", + "abilityName": "Avatar_Nahida_ElementalBurst_Camera_DungeonEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Camera_PushTarget", + "abilityName": "Avatar_Nahida_ElementalBurst_Camera_PushTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_CheckAvatarElement", + "abilityName": "Avatar_Nahida_ElementalBurst_CheckAvatarElement", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_GVinitialize", + "abilityName": "Avatar_Nahida_ElementalBurst_GVinitialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Hollow_Gadget", + "abilityName": "Avatar_Nahida_ElementalBurst_Hollow_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Hollow_TeamFormula", + "abilityName": "Avatar_Nahida_ElementalBurst_Hollow_TeamFormula", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Hollow_Fx", + "abilityName": "Avatar_Nahida_ElementalBurst_Hollow_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Hollow_LifeTimer", + "abilityName": "Avatar_Nahida_ElementalBurst_Hollow_LifeTimer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_CheckInHollowh", + "abilityName": "Avatar_Nahida_ElementalBurst_CheckInHollowh", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_CheckInHollow", + "abilityName": "Avatar_Nahida_ElementalBurst_CheckInHollow", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Hollow_InDistance_Keeper5UNIQUE_Nahida_ElementalBurst_Hollow_InDistance_OnTeam", + "abilityName": "Avatar_Nahida_ElementalBurst_Hollow_InDistance_Keeper5UNIQUE_Nahida_ElementalBurst_Hollow_InDistance_OnTeam", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Hollow_InDistance_Keeper", + "abilityName": "Avatar_Nahida_ElementalBurst_Hollow_InDistance_Keeper", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_HairEmission", + "abilityName": "Avatar_Nahida_ElementalBurst_HairEmission", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_FallingAnthem", + "abilityName": "Avatar_Nahida_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_PermanentSkill_1", + "abilityName": "Avatar_Nahida_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_PermanentSkill_2", + "abilityName": "Avatar_Nahida_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_PermanentSkill_EnhanceChainDamage", + "abilityName": "Avatar_Nahida_PermanentSkill_EnhanceChainDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Constellation_6", + "abilityName": "Avatar_Nahida_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Constellation_6_AttackState", + "abilityName": "Avatar_Nahida_Constellation_6_AttackState", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Constellation_6_Trigger", + "abilityName": "Avatar_Nahida_Constellation_6_Trigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Constellation_6_Fx", + "abilityName": "Avatar_Nahida_Constellation_6_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Constellation_6_Timer", + "abilityName": "Avatar_Nahida_Constellation_6_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Constellation_6_ReduceNum", + "abilityName": "Avatar_Nahida_Constellation_6_ReduceNum", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_RayCast_Quest_Gadget_Call", + "abilityName": "Avatar_Nahida_RayCast_Quest_Gadget_Call", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida", + "abilityName": "Avatar_Nahida", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Skill_ElementalArt_BS", + "abilityName": "Avatar_Nahida_Skill_ElementalArt_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Skill_ElementalArt_Click", + "abilityName": "Avatar_Nahida_Skill_ElementalArt_Click", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Skill_ElementalArt_Click_AS", + "abilityName": "Avatar_Nahida_Skill_ElementalArt_Click_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Skill_ElementalArt_Move", + "abilityName": "Avatar_Nahida_Skill_ElementalArt_Move", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Skill_ElementalArt_Loop", + "abilityName": "Avatar_Nahida_Skill_ElementalArt_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Skill_ElementalArt_Hold", + "abilityName": "Avatar_Nahida_Skill_ElementalArt_Hold", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Skill_ElementalArt_Hold_AS", + "abilityName": "Avatar_Nahida_Skill_ElementalArt_Hold_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_TeamConfig_01BS", + "abilityName": "Avatar_Nahida_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_TeamConfig_01Loop", + "abilityName": "Avatar_Nahida_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_TeamConfig_01AS", + "abilityName": "Avatar_Nahida_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Spine", + "abilityName": "Avatar_Nahida_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_BS", + "abilityName": "Avatar_Nahida_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementalBurst_Hit", + "abilityName": "Avatar_Nahida_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_ElementArt_Buff", + "abilityName": "Avatar_Nahida_ElementArt_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Spine_Loop", + "abilityName": "Avatar_Nahida_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nahida_Spine", + "abilityName": "Avatar_Nahida_Spine", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Navia.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Navia.json new file mode 100644 index 0000000..6084306 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Navia.json @@ -0,0 +1,144 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Navia_ExtraAttack", + "abilityName": "Avatar_Navia_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_Attack_3_Create_Gadget", + "abilityName": "Avatar_Navia_Attack_3_Create_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_Crystal_Seed_Get_Controller", + "abilityName": "Avatar_Navia_Crystal_Seed_Get_Controller", + "abilityOverride": "" + }, + { + "abilityID": "Avatar2Navia_Crystal_Seed_Get_Controller_Self_State_Param", + "abilityName": "Avatar2Navia_Crystal_Seed_Get_Controller_Self_State_Param", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_ElementalArt", + "abilityName": "Avatar_Navia_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_RayCast_CloseFx", + "abilityName": "Avatar_Navia_RayCast_CloseFx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_EArt_Real_Attak", + "abilityName": "Avatar_Navia_EArt_Real_Attak", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_EArt_Real_Attako", + "abilityName": "Avatar_Navia_EArt_Real_Attako", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_Elemental_Art_ElemBall_Handler", + "abilityName": "Avatar_Navia_Elemental_Art_ElemBall_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_PermanentSkill_1J", + "abilityName": "Avatar_Navia_PermanentSkill_1J", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_ElementalArt_Pneuma", + "abilityName": "Avatar_Navia_ElementalArt_Pneuma", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_ElementalArt_ShotGun_Bullet", + "abilityName": "Avatar_Navia_ElementalArt_ShotGun_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_ElementalBurst", + "abilityName": "Avatar_Navia_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Navia_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_Burst", + "abilityName": "Avatar_Navia_Burst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_NormalAttackDamage", + "abilityName": "Avatar_Navia_NormalAttackDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_PermanentSkill_1", + "abilityName": "Avatar_Navia_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_PermanentSkill_1_NA_Up_Buff", + "abilityName": "Avatar_Navia_PermanentSkill_1_NA_Up_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_FallingAnthem", + "abilityName": "Avatar_Navia_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia", + "abilityName": "Avatar_Navia", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_ElementalArt_Insert", + "abilityName": "Avatar_Navia_ElementalArt_Insert", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_ElementalArt_Insert_AS", + "abilityName": "Avatar_Navia_ElementalArt_Insert_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_ElementalArt_Recycle", + "abilityName": "Avatar_Navia_ElementalArt_Recycle", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_ElementalArt_Recycle_AS", + "abilityName": "Avatar_Navia_ElementalArt_Recycle_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_ElementalBurst_Loop_A", + "abilityName": "Avatar_Navia_ElementalBurst_Loop_A", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_ElementalBurst_Loop_B", + "abilityName": "Avatar_Navia_ElementalBurst_Loop_B", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_ElementalBurst_End", + "abilityName": "Avatar_Navia_ElementalBurst_End", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Navia_ElementalBurst_AS", + "abilityName": "Avatar_Navia_ElementalBurst_AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Neuvillette.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Neuvillette.json new file mode 100644 index 0000000..4955378 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Neuvillette.json @@ -0,0 +1,504 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Neuvillette_Attack01", + "abilityName": "Avatar_Neuvillette_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Attack02", + "abilityName": "Avatar_Neuvillette_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Attack03", + "abilityName": "Avatar_Neuvillette_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Stick_Handler", + "abilityName": "Avatar_Neuvillette_Stick_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_StickRemover", + "abilityName": "Avatar_Neuvillette_ExtraAttack_StickRemover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack", + "abilityName": "Avatar_Neuvillette_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Levitate", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Levitate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Levitate_HitBoxOffset", + "abilityName": "Avatar_Neuvillette_Levitate_HitBoxOffset", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_CountFx", + "abilityName": "Avatar_Neuvillette_ExtraAttack_CountFx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Absorb", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Absorb", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Attack", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Attack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Attack_StateMark", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Attack_StateMark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Attack_UnreadyF", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Attack_UnreadyF", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Charge_Handler", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Charge_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Trans_CameraShake", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Trans_CameraShake", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Wing_FxFadeR", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Wing_FxFadeR", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Wing_FxFade", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Wing_FxFade", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_ScreenEffect", + "abilityName": "Avatar_Neuvillette_ExtraAttack_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_WeatherChange", + "abilityName": "Avatar_Neuvillette_ElementalBurst_WeatherChange", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Attack_Unready", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Attack_Unready", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Core_Handler", + "abilityName": "Avatar_Neuvillette_Core_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_AddCore", + "abilityName": "Avatar_Neuvillette_AddCore", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_CostCore", + "abilityName": "Avatar_Neuvillette_CostCore", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_AddCore_DelayTimer", + "abilityName": "Avatar_Neuvillette_AddCore_DelayTimer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_AddCore_DelayTimer7", + "abilityName": "Avatar_Neuvillette_AddCore_DelayTimer7", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_FullAttack_Delay", + "abilityName": "Avatar_Neuvillette_FullAttack_Delay", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Absorb_Gadget", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Absorb_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Core_GadgetJ", + "abilityName": "Avatar_Neuvillette_Core_GadgetJ", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Attack_Gadget", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Attack_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Camera_Shake", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Camera_Shake", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_StateCheck", + "abilityName": "Avatar_Neuvillette_ExtraAttack_StateCheck", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Wing_FxFadeM", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Wing_FxFadeM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_LoseHp", + "abilityName": "Avatar_Neuvillette_ExtraAttack_LoseHp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_Buff_Handler", + "abilityName": "Avatar_Neuvillette_ExtraAttack_Buff_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_StateCheckM", + "abilityName": "Avatar_Neuvillette_ExtraAttack_StateCheckM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Core_Gadget", + "abilityName": "Avatar_Neuvillette_Core_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Core_Gadget_Eff", + "abilityName": "Avatar_Neuvillette_Core_Gadget_Eff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Core_Fx", + "abilityName": "Avatar_Neuvillette_Core_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Core_Bullet", + "abilityName": "Avatar_Neuvillette_Core_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalArt", + "abilityName": "Avatar_Neuvillette_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalArt_DropCore_Handler", + "abilityName": "Avatar_Neuvillette_ElementalArt_DropCore_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalArt_DropCore", + "abilityName": "Avatar_Neuvillette_ElementalArt_DropCore", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalArt_DropBall", + "abilityName": "Avatar_Neuvillette_ElementalArt_DropBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalArt_Camera", + "abilityName": "Avatar_Neuvillette_ElementalArt_Camera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalArt_Arkhe_Handler", + "abilityName": "Avatar_Neuvillette_ElementalArt_Arkhe_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalArt_Arkhe_CDTimer", + "abilityName": "Avatar_Neuvillette_ElementalArt_Arkhe_CDTimer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalArt_Arkhe_DelayStrike", + "abilityName": "Avatar_Neuvillette_ElementalArt_Arkhe_DelayStrike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst", + "abilityName": "Avatar_Neuvillette_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_Initialize", + "abilityName": "Avatar_Neuvillette_ElementalBurst_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_EmotionControl", + "abilityName": "Avatar_Neuvillette_ElementalBurst_EmotionControl", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_Camera_Fx", + "abilityName": "Avatar_Neuvillette_ElementalBurst_Camera_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_Camera_Handler", + "abilityName": "Avatar_Neuvillette_ElementalBurst_Camera_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_CameraShakeB", + "abilityName": "Avatar_Neuvillette_ElementalBurst_CameraShakeB", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_ExitCamera", + "abilityName": "Avatar_Neuvillette_ElementalBurst_ExitCamera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_Camera_PushTarget333", + "abilityName": "Avatar_Neuvillette_ElementalBurst_Camera_PushTarget333", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_Invincible", + "abilityName": "Avatar_Neuvillette_ElementalBurst_Invincible", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_Camera_FogEffect", + "abilityName": "Avatar_Neuvillette_ElementalBurst_Camera_FogEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Neuvillette_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_Camera_PushTarget", + "abilityName": "Avatar_Neuvillette_ElementalBurst_Camera_PushTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_CameraShake", + "abilityName": "Avatar_Neuvillette_ElementalBurst_CameraShake", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_Strike_Once", + "abilityName": "Avatar_Neuvillette_ElementalBurst_Strike_Once", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_Strike_Twice", + "abilityName": "Avatar_Neuvillette_ElementalBurst_Strike_Twice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_Strike_Thrice", + "abilityName": "Avatar_Neuvillette_ElementalBurst_Strike_Thrice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ElementalBurst_WeatherChange6UNIQUE_Avatar_Neuvillette_ElementalBurst_WeatherChange", + "abilityName": "Avatar_Neuvillette_ElementalBurst_WeatherChange6UNIQUE_Avatar_Neuvillette_ElementalBurst_WeatherChange", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_FallingAnthem", + "abilityName": "Avatar_Neuvillette_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_PermanentSkill_1", + "abilityName": "Avatar_Neuvillette_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_PermanentSkill_1_BuffHandler", + "abilityName": "Avatar_Neuvillette_PermanentSkill_1_BuffHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_PermanentSkill_1_Handler", + "abilityName": "Avatar_Neuvillette_PermanentSkill_1_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_CheckWaterReaction_OnAvatar", + "abilityName": "Avatar_Neuvillette_CheckWaterReaction_OnAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ReactionType_Streamc", + "abilityName": "Avatar_Neuvillette_ReactionType_Streamc", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ReactionType_Overgrowc", + "abilityName": "Avatar_Neuvillette_ReactionType_Overgrowc", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ReactionType_Freezec", + "abilityName": "Avatar_Neuvillette_ReactionType_Freezec", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ReactionType_Shockc", + "abilityName": "Avatar_Neuvillette_ReactionType_Shockc", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ReactionType_SwirlWaterc", + "abilityName": "Avatar_Neuvillette_ReactionType_SwirlWaterc", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ReactionType_CrystallizeWater", + "abilityName": "Avatar_Neuvillette_ReactionType_CrystallizeWater", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ReactionType_Stream", + "abilityName": "Avatar_Neuvillette_ReactionType_Stream", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ReactionType_Overgrow", + "abilityName": "Avatar_Neuvillette_ReactionType_Overgrow", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ReactionType_Freeze", + "abilityName": "Avatar_Neuvillette_ReactionType_Freeze", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ReactionType_Shock", + "abilityName": "Avatar_Neuvillette_ReactionType_Shock", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ReactionType_SwirlWater", + "abilityName": "Avatar_Neuvillette_ReactionType_SwirlWater", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_PermanentSkill_Lv1", + "abilityName": "Avatar_Neuvillette_PermanentSkill_Lv1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_PermanentSkill_Lv2", + "abilityName": "Avatar_Neuvillette_PermanentSkill_Lv2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_PermanentSkill_Lv3", + "abilityName": "Avatar_Neuvillette_PermanentSkill_Lv3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_PermanentSkill_2", + "abilityName": "Avatar_Neuvillette_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_PermanentSkill_2_Handler", + "abilityName": "Avatar_Neuvillette_PermanentSkill_2_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_PermanentSkill_2_CalculatorM", + "abilityName": "Avatar_Neuvillette_PermanentSkill_2_CalculatorM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_PermanentSkill_2_Buff", + "abilityName": "Avatar_Neuvillette_PermanentSkill_2_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_PermanentSkill_2_Calculator", + "abilityName": "Avatar_Neuvillette_PermanentSkill_2_Calculator", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Constellation_6", + "abilityName": "Avatar_Neuvillette_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Constellation_6_Handler", + "abilityName": "Avatar_Neuvillette_Constellation_6_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Constellation_6_Attack", + "abilityName": "Avatar_Neuvillette_Constellation_6_Attack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Constellation_6_Absorb", + "abilityName": "Avatar_Neuvillette_Constellation_6_Absorb", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Core_HandlerD", + "abilityName": "Avatar_Neuvillette_Core_HandlerD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Constellation_6_CDTimer", + "abilityName": "Avatar_Neuvillette_Constellation_6_CDTimer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_Constellation_6_Bullet", + "abilityName": "Avatar_Neuvillette_Constellation_6_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_DiveDashSpeedUp", + "abilityName": "Avatar_Neuvillette_DiveDashSpeedUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette", + "abilityName": "Avatar_Neuvillette", + "abilityOverride": "" + }, + { + "abilityID": "AvatarItem_Neuvillette_Stick", + "abilityName": "AvatarItem_Neuvillette_Stick", + "abilityOverride": "" + }, + { + "abilityID": "AvatarItem_Neuvillette_Stick_Nolight", + "abilityName": "AvatarItem_Neuvillette_Stick_Nolight", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Neuvillette_ExtraAttack_HitOnEnemy", + "abilityName": "Avatar_Neuvillette_ExtraAttack_HitOnEnemy", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Nilou.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Nilou.json new file mode 100644 index 0000000..ad7e1a1 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Nilou.json @@ -0,0 +1,264 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Nilou_ExtraAttack", + "abilityName": "Avatar_Nilou_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Attack_01_Spec", + "abilityName": "Avatar_Nilou_Attack_01_Spec", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Recombo_Mark", + "abilityName": "Avatar_Nilou_Recombo_Mark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Attack_02_Spec", + "abilityName": "Avatar_Nilou_Attack_02_Spec", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_ElementalDance", + "abilityName": "Avatar_Nilou_ElementalDance", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_In_NormalAttack_Mark", + "abilityName": "Avatar_Nilou_In_NormalAttack_Mark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_NilouAllCount_1", + "abilityName": "Avatar_NilouAllCount_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_NilouAllCount_2", + "abilityName": "Avatar_NilouAllCount_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Change_ECount_To_4", + "abilityName": "Avatar_Nilou_Change_ECount_To_4", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Combo_Complete_Mark", + "abilityName": "Avatar_Nilou_Combo_Complete_Mark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Keep_Attack_Combo_Handler", + "abilityName": "Avatar_Nilou_Keep_Attack_Combo_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Elemental_Art_ElemBall_Handler", + "abilityName": "Avatar_Nilou_Elemental_Art_ElemBall_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Keep_Attack_Combo_Handler_", + "abilityName": "Avatar_Nilou_Keep_Attack_Combo_Handler_", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_ElementalDanceFake", + "abilityName": "Avatar_Nilou_ElementalDanceFake", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Spec_Attack_Count_Add1", + "abilityName": "Avatar_Nilou_Spec_Attack_Count_Add1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Spec_E_2", + "abilityName": "Avatar_Nilou_Spec_E_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Spec_E_3", + "abilityName": "Avatar_Nilou_Spec_E_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Spec_Attack_Over", + "abilityName": "Avatar_Nilou_Spec_Attack_Over", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_AOver_Dance_Buff", + "abilityName": "Avatar_Nilou_AOver_Dance_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_AOver_Dance_Buff_Driver", + "abilityName": "Avatar_Nilou_AOver_Dance_Buff_Driver", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_ElementalArt_Buff_Controller", + "abilityName": "Avatar_Nilou_ElementalArt_Buff_Controller", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Spec_EArt_Over", + "abilityName": "Avatar_Nilou_Spec_EArt_Over", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_ElementalArt_Buff_ControllerM", + "abilityName": "Avatar_Nilou_ElementalArt_Buff_ControllerM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_ElementalArt_Buff_Nilou", + "abilityName": "Avatar_ElementalArt_Buff_Nilou", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_ElementalArt_Buff_Nilou_Driver", + "abilityName": "Avatar_ElementalArt_Buff_Nilou_Driver", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Resistance_Reduce_Avatar", + "abilityName": "Avatar_Nilou_Resistance_Reduce_Avatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Overgrow_Damage_Up", + "abilityName": "Avatar_Nilou_Overgrow_Damage_Up", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Max_HP_Refresh", + "abilityName": "Avatar_Nilou_Max_HP_Refresh", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_SpecE_Energy_Revive", + "abilityName": "Avatar_Nilou_SpecE_Energy_Revive", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Water_Bubble_Bullet", + "abilityName": "Avatar_Nilou_Water_Bubble_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Recombo_Mark_Bullet", + "abilityName": "Avatar_Nilou_Recombo_Mark_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_ElementalBurst_Camera", + "abilityName": "Avatar_Nilou_ElementalBurst_Camera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Nilou_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Burst_Attacker", + "abilityName": "Avatar_Nilou_Burst_Attacker", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Burst_Delay_Attacker", + "abilityName": "Avatar_Nilou_Burst_Delay_Attacker", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_NormalAttack_DamageHandler", + "abilityName": "Avatar_Nilou_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_MaxHP_Trans_Crit", + "abilityName": "Avatar_Nilou_MaxHP_Trans_Crit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_FallingAnthem", + "abilityName": "Avatar_Nilou_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_QuestAbility_NilouFullMP", + "abilityName": "Avatar_QuestAbility_NilouFullMP", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_NilouFullMP", + "abilityName": "Avatar_NilouFullMP", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou", + "abilityName": "Avatar_Nilou", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_TeamConfig_01BS", + "abilityName": "Avatar_Nilou_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_TeamConfig_01Loop", + "abilityName": "Avatar_Nilou_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_TeamConfig_01AS", + "abilityName": "Avatar_Nilou_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "AvatarItem_Nilou_HushangWreaths", + "abilityName": "AvatarItem_Nilou_HushangWreaths", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_ElementalBurst_Spine", + "abilityName": "Avatar_Nilou_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_ElementalBurst_BS", + "abilityName": "Avatar_Nilou_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_ElementalBurst_Hit", + "abilityName": "Avatar_Nilou_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_ElementalBurst_Buff", + "abilityName": "Avatar_Nilou_ElementalBurst_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Spine_Loop", + "abilityName": "Avatar_Nilou_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Spine_Loop_Floor", + "abilityName": "Avatar_Nilou_Spine_Loop_Floor", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Nilou_Spine", + "abilityName": "Avatar_Nilou_Spine", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ningguang.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ningguang.json new file mode 100644 index 0000000..7ce965f --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Ningguang.json @@ -0,0 +1,289 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Ningguang_Roulette", + "abilityName": "Avatar_Ningguang_Roulette", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ExtraAttack", + "abilityName": "Avatar_Ningguang_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ExtraAttack_Fx", + "abilityName": "Avatar_Ningguang_ExtraAttack_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ExtraAttack_BulletTrigger", + "abilityName": "Avatar_Ningguang_ExtraAttack_BulletTrigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Constellation_Attack_Up_BulletTrigger", + "abilityName": "Avatar_Ningguang_Constellation_Attack_Up_BulletTrigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ExtraAttack_GemBullet_Handler", + "abilityName": "Avatar_Ningguang_ExtraAttack_GemBullet_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ExtraAttack_Damage", + "abilityName": "Avatar_Ningguang_ExtraAttack_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_NormalAttack_Dummy", + "abilityName": "Avatar_Ningguang_NormalAttack_Dummy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_NormalAttackDamage", + "abilityName": "Avatar_Ningguang_NormalAttackDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_NormalAttack_LifeOver_Fx", + "abilityName": "Avatar_Ningguang_NormalAttack_LifeOver_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Elemental_Burst_LifeOver_Orange", + "abilityName": "Avatar_Ningguang_Elemental_Burst_LifeOver_Orange", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Elemental_Burst_LifeOver_Red", + "abilityName": "Avatar_Ningguang_Elemental_Burst_LifeOver_Red", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Elemental_Burst_LifeOver_Yellow", + "abilityName": "Avatar_Ningguang_Elemental_Burst_LifeOver_Yellow", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Attack01", + "abilityName": "Avatar_Ningguang_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Attack02", + "abilityName": "Avatar_Ningguang_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Attack03", + "abilityName": "Avatar_Ningguang_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Attack04", + "abilityName": "Avatar_Ningguang_Attack04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ServantStone", + "abilityName": "Avatar_Ningguang_ServantStone", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Charge_ServantStone", + "abilityName": "Avatar_Ningguang_Charge_ServantStone", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Change_Gadget_BornState", + "abilityName": "Avatar_Ningguang_Change_Gadget_BornState", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ServantStone_Switch", + "abilityName": "Avatar_Ningguang_ServantStone_Switch", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Trigger_ElementalArt_CD", + "abilityName": "Avatar_Ningguang_Trigger_ElementalArt_CD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_GemStone_Impact", + "abilityName": "Avatar_Ningguang_GemStone_Impact", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementalBurst_BulletTrigger", + "abilityName": "Avatar_Ningguang_ElementalBurst_BulletTrigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementalBurst_BulletTrigger_WithOutTarget", + "abilityName": "Avatar_Ningguang_ElementalBurst_BulletTrigger_WithOutTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementalBurst_ServantStoneTrigger", + "abilityName": "Avatar_Ningguang_ElementalBurst_ServantStoneTrigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementalBurst_Bullet_Hit_Fx_1", + "abilityName": "Avatar_Ningguang_ElementalBurst_Bullet_Hit_Fx_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementalBurst_Bullet_Hit_Fx_2", + "abilityName": "Avatar_Ningguang_ElementalBurst_Bullet_Hit_Fx_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementalBurst_Bullet_Hit_Fx_3", + "abilityName": "Avatar_Ningguang_ElementalBurst_Bullet_Hit_Fx_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ReviveElemEnergy", + "abilityName": "Avatar_Ningguang_ReviveElemEnergy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Constellation_6", + "abilityName": "Avatar_Ningguang_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_PermanentSkill_2", + "abilityName": "Avatar_Ningguang_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_SkillUpgrade_3", + "abilityName": "Avatar_Ningguang_SkillUpgrade_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_GemBullet_Damage", + "abilityName": "Avatar_Ningguang_GemBullet_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_FallingAnthem", + "abilityName": "Avatar_Ningguang_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Radar_Ore", + "abilityName": "Avatar_Ningguang_Radar_Ore", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang", + "abilityName": "Avatar_Ningguang", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_NormalAttack_LifeOver_Fx0Avatar_Ningguang_Elemental_Burst_LifeOver_Orange", + "abilityName": "Avatar_Ningguang_NormalAttack_LifeOver_Fx0Avatar_Ningguang_Elemental_Burst_LifeOver_Orange", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Elemental_Burst_LifeOver_Red0Avatar_Ningguang_Elemental_Burst_LifeOver_Yellow", + "abilityName": "Avatar_Ningguang_Elemental_Burst_LifeOver_Red0Avatar_Ningguang_Elemental_Burst_LifeOver_Yellow", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementalBurst_BulletTrigger_WithOutTarget3Avatar_Ningguang_ElementalBurst_ServantStoneTrigger", + "abilityName": "Avatar_Ningguang_ElementalBurst_BulletTrigger_WithOutTarget3Avatar_Ningguang_ElementalBurst_ServantStoneTrigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_TeamConfig_01BS", + "abilityName": "Avatar_Ningguang_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_TeamConfig_01Loop", + "abilityName": "Avatar_Ningguang_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_TeamConfig_01AS", + "abilityName": "Avatar_Ningguang_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementalBurst_Spine", + "abilityName": "Avatar_Ningguang_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementalBurst_BS", + "abilityName": "Avatar_Ningguang_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementalBurst_Yellow", + "abilityName": "Avatar_Ningguang_ElementalBurst_Yellow", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementBurst_01", + "abilityName": "Avatar_Ningguang_ElementBurst_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementBurst_04", + "abilityName": "Avatar_Ningguang_ElementBurst_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementalBurst_Orange", + "abilityName": "Avatar_Ningguang_ElementalBurst_Orange", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementBurst_02", + "abilityName": "Avatar_Ningguang_ElementBurst_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementBurst_05", + "abilityName": "Avatar_Ningguang_ElementBurst_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementalBurst_Red", + "abilityName": "Avatar_Ningguang_ElementalBurst_Red", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementBurst_03", + "abilityName": "Avatar_Ningguang_ElementBurst_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementBurst_06", + "abilityName": "Avatar_Ningguang_ElementBurst_06", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_ElementalBurst_Hit", + "abilityName": "Avatar_Ningguang_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_elementalBurst_BS_Normal", + "abilityName": "Avatar_Ningguang_elementalBurst_BS_Normal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Ningguang_Spine_Loop", + "abilityName": "Avatar_Ningguang_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Noel.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Noel.json new file mode 100644 index 0000000..6931f06 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Noel.json @@ -0,0 +1,119 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Noel_ExtraAttack", + "abilityName": "Avatar_Noel_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_Skill_S", + "abilityName": "Avatar_Noel_Skill_S", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_Skill_E", + "abilityName": "Avatar_Noel_Skill_E", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_Skill_E_ExitCamera", + "abilityName": "Avatar_Noel_Skill_E_ExitCamera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_ProudSkill_NormalAttack_DamageHandler", + "abilityName": "Avatar_Noel_ProudSkill_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_ProudSkill_21", + "abilityName": "Avatar_Noel_ProudSkill_21", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_ProudSkill_21_Shield", + "abilityName": "Avatar_Noel_ProudSkill_21_Shield", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_ProudSkill_22", + "abilityName": "Avatar_Noel_ProudSkill_22", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_FallingAnthem", + "abilityName": "Avatar_Noel_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel", + "abilityName": "Avatar_Noel", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_Skill_E_ExitCamera1Avatar_Noel_ProudSkill_NormalAttack_DamageHandler", + "abilityName": "Avatar_Noel_Skill_E_ExitCamera1Avatar_Noel_ProudSkill_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_TeamConfig_01BS", + "abilityName": "Avatar_Noel_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_TeamConfig_01Loop", + "abilityName": "Avatar_Noel_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_TeamConfig_01AS", + "abilityName": "Avatar_Noel_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_ProudSkill_NormalAttack_DamageHandler1Avatar_Noel_ProudSkill_NormalAttack_DamageHandler", + "abilityName": "Avatar_Noel_ProudSkill_NormalAttack_DamageHandler1Avatar_Noel_ProudSkill_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_Spine", + "abilityName": "Avatar_Noel_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_ElementalBurst_Spine", + "abilityName": "Avatar_Noel_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_ElementalBurst", + "abilityName": "Avatar_Noel_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_ElementalBurst_BS", + "abilityName": "Avatar_Noel_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_ElementalBurst_Hit", + "abilityName": "Avatar_Noel_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_ElementalBurst_Buff", + "abilityName": "Avatar_Noel_ElementalBurst_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_ElementalBurst_Buff_Hit", + "abilityName": "Avatar_Noel_ElementalBurst_Buff_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Noel_Spine_Loop", + "abilityName": "Avatar_Noel_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_PlayerBoy.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_PlayerBoy.json new file mode 100644 index 0000000..17cff34 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_PlayerBoy.json @@ -0,0 +1,5 @@ +{ + "abilities": [ + + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Qin.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Qin.json new file mode 100644 index 0000000..65dc141 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Qin.json @@ -0,0 +1,304 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Qin_ExtraAttack", + "abilityName": "Avatar_Qin_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_VortexSmash", + "abilityName": "Avatar_Qin_VortexSmash", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_DandelionWind_Camera", + "abilityName": "Avatar_Qin_DandelionWind_Camera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_DandelionWind", + "abilityName": "Avatar_Qin_DandelionWind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_DandelionWind_Heal", + "abilityName": "Avatar_Qin_DandelionWind_Heal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_DandelionWind_Harm", + "abilityName": "Avatar_Qin_DandelionWind_Harm", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_DandelionWind_Harm_FieldDamage", + "abilityName": "Avatar_Qin_DandelionWind_Harm_FieldDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_DandelionWind_Push", + "abilityName": "Avatar_Qin_DandelionWind_Push", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_HinowaSlash", + "abilityName": "Avatar_Qin_HinowaSlash", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_GreaterSelfHeal", + "abilityName": "Avatar_Qin_GreaterSelfHeal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_AttackCritic", + "abilityName": "Avatar_Qin_AttackCritic", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_TeamSpeedWhenGetElementBall", + "abilityName": "Avatar_Qin_TeamSpeedWhenGetElementBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_NormalAttackDamage", + "abilityName": "Avatar_Qin_NormalAttackDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_AutoDefend", + "abilityName": "Avatar_Qin_AutoDefend", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_FallingAnthem", + "abilityName": "Avatar_Qin_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin", + "abilityName": "Avatar_Qin", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_PlayQin01BS_0", + "abilityName": "Avatar_PlayQin01BS_0", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_PlayQin01Loop_0", + "abilityName": "Avatar_PlayQin01Loop_0", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_PlayQin01AS_0", + "abilityName": "Avatar_PlayQin01AS_0", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Common_PlayMusic_Qin", + "abilityName": "Avatar_Common_PlayMusic_Qin", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_KeQing_Skill_ElementalArt", + "abilityName": "Avatar_KeQing_Skill_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_KeQing_Skill_ElementalArt_AS", + "abilityName": "Avatar_KeQing_Skill_ElementalArt_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_KeQing_Skill_ElementalArt_BS", + "abilityName": "Avatar_KeQing_Skill_ElementalArt_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_KeQing_Skill_ElementalArt_Charge", + "abilityName": "Avatar_KeQing_Skill_ElementalArt_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_KeQing_Skill_ElementalArt_Charge_02", + "abilityName": "Avatar_KeQing_Skill_ElementalArt_Charge_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_KeQing_Skill_ElementalArt_Charge_AS", + "abilityName": "Avatar_KeQing_Skill_ElementalArt_Charge_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_KeQing_Skill_ElementalArt_Fly", + "abilityName": "Avatar_KeQing_Skill_ElementalArt_Fly", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_KeQing_Skill_ElementalArt_Fly_AS", + "abilityName": "Avatar_KeQing_Skill_ElementalArt_Fly_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_KeQing_Skill_ElementalArt_FlyAir", + "abilityName": "Avatar_KeQing_Skill_ElementalArt_FlyAir", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_TeamConfig_01BS", + "abilityName": "Avatar_Qin_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_TeamConfig_01Loop", + "abilityName": "Avatar_Qin_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_TeamConfig_01AS", + "abilityName": "Avatar_Qin_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_PlayMusic_Qin_AS", + "abilityName": "Avatar_PlayMusic_Qin_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_PlayMusic_Qin", + "abilityName": "Avatar_PlayMusic_Qin", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_KeQing_Skill_ElementalArt_FlyAir_AS", + "abilityName": "Avatar_KeQing_Skill_ElementalArt_FlyAir_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_ElementalBurst_Spine", + "abilityName": "Avatar_Qin_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_ElementalBurst", + "abilityName": "Avatar_Qin_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_Spine_Loop", + "abilityName": "Avatar_Qin_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_VO_MDAQ037_Qin_01", + "abilityName": "Avatar_Qin_VO_MDAQ037_Qin_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_VO_Emotion_Qin_Hesitate_01", + "abilityName": "Avatar_Qin_VO_Emotion_Qin_Hesitate_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_VO_Emotion_Qin_Vigilant_01", + "abilityName": "Avatar_Qin_VO_Emotion_Qin_Vigilant_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_VO_Emotion_Qin_Affirm_01", + "abilityName": "Avatar_Qin_VO_Emotion_Qin_Affirm_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_VO_Emotion_Qin_Satisfaction_01", + "abilityName": "Avatar_Qin_VO_Emotion_Qin_Satisfaction_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_VO_MDAQ053_Qin_01", + "abilityName": "Avatar_Qin_VO_MDAQ053_Qin_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_4901001", + "abilityName": "Avatar_Qin_4901001", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_4901004", + "abilityName": "Avatar_Qin_4901004", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_4901006", + "abilityName": "Avatar_Qin_4901006", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_4901008", + "abilityName": "Avatar_Qin_4901008", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_4901010", + "abilityName": "Avatar_Qin_4901010", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_4901011", + "abilityName": "Avatar_Qin_4901011", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_4901013", + "abilityName": "Avatar_Qin_4901013", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_4901014", + "abilityName": "Avatar_Qin_4901014", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_4901015", + "abilityName": "Avatar_Qin_4901015", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_4901017", + "abilityName": "Avatar_Qin_4901017", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qin_4901019", + "abilityName": "Avatar_Qin_4901019", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_PlayMusic_Qin_01_AS", + "abilityName": "Avatar_PlayMusic_Qin_01_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_PlayMusic_Qin_01", + "abilityName": "Avatar_PlayMusic_Qin_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_PlayMusic_Qin_01_Loli", + "abilityName": "Avatar_PlayMusic_Qin_01_Loli", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_PlayMusic_Qin_Loli", + "abilityName": "Avatar_PlayMusic_Qin_Loli", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_PlayMusic_Qin_Loli_AS", + "abilityName": "Avatar_PlayMusic_Qin_Loli_AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Qiqi.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Qiqi.json new file mode 100644 index 0000000..fde3584 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Qiqi.json @@ -0,0 +1,139 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Qiqi_ExtraAttack", + "abilityName": "Avatar_Qiqi_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalArt_Clear", + "abilityName": "Avatar_Qiqi_ElementalArt_Clear", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalArt", + "abilityName": "Avatar_Qiqi_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalArt_CD", + "abilityName": "Avatar_Qiqi_ElementalArt_CD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalArt_Bullet", + "abilityName": "Avatar_Qiqi_ElementalArt_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalBurst", + "abilityName": "Avatar_Qiqi_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalBurst_PostEffect", + "abilityName": "Avatar_Qiqi_ElementalBurst_PostEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Qiqi_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_Revive", + "abilityName": "Avatar_Qiqi_Revive", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalBurst_ApplyModifier", + "abilityName": "Avatar_Qiqi_ElementalBurst_ApplyModifier", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalBurst_TriggerAttack", + "abilityName": "Avatar_Qiqi_ElementalBurst_TriggerAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalBurst_CameraRadialBlur", + "abilityName": "Avatar_Qiqi_ElementalBurst_CameraRadialBlur", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_NormalAttackDamage", + "abilityName": "Avatar_Qiqi_NormalAttackDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalArt_Damage", + "abilityName": "Avatar_Qiqi_ElementalArt_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_Frozen_AttackUp", + "abilityName": "Avatar_Qiqi_Frozen_AttackUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_FallingAnthem", + "abilityName": "Avatar_Qiqi_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_Radar_Collectables_Liyue", + "abilityName": "Avatar_Qiqi_Radar_Collectables_Liyue", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi", + "abilityName": "Avatar_Qiqi", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_Skill_ElementalArt", + "abilityName": "Avatar_Qiqi_Skill_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_TeamConfig_01BS", + "abilityName": "Avatar_Qiqi_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_TeamConfig_01Loop", + "abilityName": "Avatar_Qiqi_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_TeamConfig_01AS", + "abilityName": "Avatar_Qiqi_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_Skill_ElementalArt_AS", + "abilityName": "Avatar_Qiqi_Skill_ElementalArt_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalBurst_Spine", + "abilityName": "Avatar_Qiqi_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalBurst_BS", + "abilityName": "Avatar_Qiqi_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_ElementalBurst_Hit", + "abilityName": "Avatar_Qiqi_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Qiqi_Spine_Loop", + "abilityName": "Avatar_Qiqi_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Razor.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Razor.json new file mode 100644 index 0000000..dc58358 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Razor.json @@ -0,0 +1,139 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Razor_ExtraAttack", + "abilityName": "Avatar_Razor_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_General_Handler", + "abilityName": "Avatar_Razor_General_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_ClawMark_Main", + "abilityName": "Avatar_Razor_ClawMark_Main", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_ClawMark_Click", + "abilityName": "Avatar_Razor_ClawMark_Click", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_ClawMark_SetMark", + "abilityName": "Avatar_Razor_ClawMark_SetMark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_ClawMark_Charging", + "abilityName": "Avatar_Razor_ClawMark_Charging", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_ClawMark_Weather_Remove", + "abilityName": "Avatar_Razor_ClawMark_Weather_Remove", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_ClawMark_Burst", + "abilityName": "Avatar_Razor_ClawMark_Burst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_ClawMark_EnergyRegain", + "abilityName": "Avatar_Razor_ClawMark_EnergyRegain", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_LycanMode", + "abilityName": "Avatar_Razor_LycanMode", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_LycanMode_LycanSimulator", + "abilityName": "Avatar_Razor_LycanMode_LycanSimulator", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_LycanMode_FirstAttackGuaranteer", + "abilityName": "Avatar_Razor_LycanMode_FirstAttackGuaranteer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_DashStamina_Reduction", + "abilityName": "Avatar_Razor_DashStamina_Reduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_NormalAttack_DamageHandler", + "abilityName": "Avatar_Razor_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_FallingAnthem", + "abilityName": "Avatar_Razor_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor", + "abilityName": "Avatar_Razor", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_TeamConfig_01BS", + "abilityName": "Avatar_Razor_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_TeamConfig_01Loop", + "abilityName": "Avatar_Razor_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_TeamConfig_01AS", + "abilityName": "Avatar_Razor_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_ElementalBurst_Spine", + "abilityName": "Avatar_Razor_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_ElementalBurst_01", + "abilityName": "Avatar_Razor_ElementalBurst_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_ElementalBurst_Hit_01", + "abilityName": "Avatar_Razor_ElementalBurst_Hit_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_ElementalBurst_Hit_02", + "abilityName": "Avatar_Razor_ElementalBurst_Hit_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_ElementalBurst_02", + "abilityName": "Avatar_Razor_ElementalBurst_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_ElementalBurst_03", + "abilityName": "Avatar_Razor_ElementalBurst_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_Spine_Loop", + "abilityName": "Avatar_Razor_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Razor_Spine", + "abilityName": "Avatar_Razor_Spine", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Rosaria.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Rosaria.json new file mode 100644 index 0000000..e48f979 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Rosaria.json @@ -0,0 +1,114 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Rosaria_ExtraAttack", + "abilityName": "Avatar_Rosaria_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_ExtraAttack_CreateBullet", + "abilityName": "Avatar_Rosaria_ExtraAttack_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_ExtraAttack_Bullet", + "abilityName": "Avatar_Rosaria_ExtraAttack_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_ElementalArt", + "abilityName": "Avatar_Rosaria_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_ElementalArt_Strike_01", + "abilityName": "Avatar_Rosaria_ElementalArt_Strike_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_ElementalArt_Strike_02", + "abilityName": "Avatar_Rosaria_ElementalArt_Strike_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_ElementalBurst_Camera", + "abilityName": "Avatar_Rosaria_ElementalBurst_Camera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_ElementalBurst_Strike_01", + "abilityName": "Avatar_Rosaria_ElementalBurst_Strike_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_ElementalBurst_Create_Gadget", + "abilityName": "Avatar_Rosaria_ElementalBurst_Create_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_GadgetEndEffect_Played", + "abilityName": "Avatar_Rosaria_GadgetEndEffect_Played", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_NormalAttack_DamageHandler", + "abilityName": "Avatar_Rosaria_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_FallingAnthem", + "abilityName": "Avatar_Rosaria_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria", + "abilityName": "Avatar_Rosaria", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_Skill_ElementalArt_BS", + "abilityName": "Avatar_Rosaria_Skill_ElementalArt_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_Skill_ElementalArt", + "abilityName": "Avatar_Rosaria_Skill_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_Skill_ElementalArt_AS", + "abilityName": "Avatar_Rosaria_Skill_ElementalArt_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_Skill_ElementalBurst_BS", + "abilityName": "Avatar_Rosaria_Skill_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_Skill_ElementalBurst", + "abilityName": "Avatar_Rosaria_Skill_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_TeamConfig_01BS", + "abilityName": "Avatar_Rosaria_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_TeamConfig_01Loop", + "abilityName": "Avatar_Rosaria_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_TeamConfig_01AS", + "abilityName": "Avatar_Rosaria_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Rosaria_Skill_ElementalBurst_AS", + "abilityName": "Avatar_Rosaria_Skill_ElementalBurst_AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Sara.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Sara.json new file mode 100644 index 0000000..65006a9 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Sara.json @@ -0,0 +1,179 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Sara_Arrow_FX", + "abilityName": "Avatar_Sara_Arrow_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_PressShoot", + "abilityName": "Avatar_Sara_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_AimPressShoot", + "abilityName": "Avatar_Sara_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ShootAimingArrow_Charge", + "abilityName": "Avatar_Sara_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ShootArrow_ResetGlobalValue", + "abilityName": "Avatar_Sara_ShootArrow_ResetGlobalValue", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ShootArrow_Aiming", + "abilityName": "Avatar_Sara_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ShootArrow_01", + "abilityName": "Avatar_Sara_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ShootArrow_02", + "abilityName": "Avatar_Sara_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ShootArrow_03", + "abilityName": "Avatar_Sara_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ShootArrow_04", + "abilityName": "Avatar_Sara_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_Hide_Fxo", + "abilityName": "Avatar_Sara_Hide_Fxo", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_Hide_Fx", + "abilityName": "Avatar_Sara_Hide_Fx", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ShootArrow_05", + "abilityName": "Avatar_Sara_ShootArrow_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_Elemental_Art", + "abilityName": "Avatar_Sara_Elemental_Art", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_KarasShoot_DelayAttack", + "abilityName": "Avatar_Sara_KarasShoot_DelayAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_Elemental_Burst", + "abilityName": "Avatar_Sara_Elemental_Burst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_Elemental_Burst_AttackWave_Trigger", + "abilityName": "Avatar_Sara_Elemental_Burst_AttackWave_Trigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_Elemental_Burst_AttackWave", + "abilityName": "Avatar_Sara_Elemental_Burst_AttackWave", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ElementalBurst_PostEffect", + "abilityName": "Avatar_Sara_ElementalBurst_PostEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Sara_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_AttackUp", + "abilityName": "Avatar_Sara_AttackUp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_BaseAttack", + "abilityName": "Avatar_Sara_BaseAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_PermanentSkill_1", + "abilityName": "Avatar_Sara_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ShootArrow_Damage", + "abilityName": "Avatar_Sara_ShootArrow_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_PermanentSkill_1_ReduceColdDown", + "abilityName": "Avatar_Sara_PermanentSkill_1_ReduceColdDown", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_PermanentSkill_2", + "abilityName": "Avatar_Sara_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_FallingAnthem", + "abilityName": "Avatar_Sara_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara", + "abilityName": "Avatar_Sara", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_TeamConfig_01BS", + "abilityName": "Avatar_Sara_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_TeamConfig_01Loop", + "abilityName": "Avatar_Sara_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_TeamConfig_01AS", + "abilityName": "Avatar_Sara_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ElementalBurst_Spine", + "abilityName": "Avatar_Sara_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ElementalBurst_BS", + "abilityName": "Avatar_Sara_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_ElementalBurst_Hit", + "abilityName": "Avatar_Sara_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sara_Spine_Loop", + "abilityName": "Avatar_Sara_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Sayu.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Sayu.json new file mode 100644 index 0000000..53a35ba --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Sayu.json @@ -0,0 +1,239 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Sayu_ExtraAttack", + "abilityName": "Avatar_Sayu_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_NormalAttack_Handler", + "abilityName": "Avatar_Sayu_NormalAttack_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_NormalAttack_Hide", + "abilityName": "Avatar_Sayu_NormalAttack_Hide", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Check", + "abilityName": "Avatar_Sayu_ElementalArt_Check", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_DropBall_Handler", + "abilityName": "Avatar_Sayu_ElementalArt_DropBall_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Click", + "abilityName": "Avatar_Sayu_ElementalArt_Click", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Click_EnterCD", + "abilityName": "Avatar_Sayu_ElementalArt_Click_EnterCD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Click_TriggerBullet", + "abilityName": "Avatar_Sayu_ElementalArt_Click_TriggerBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Click_Effect", + "abilityName": "Avatar_Sayu_ElementalArt_Click_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Bullet", + "abilityName": "Avatar_Sayu_ElementalArt_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Hold", + "abilityName": "Avatar_Sayu_ElementalArt_Hold", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Roll_CDHandler", + "abilityName": "Avatar_Sayu_ElementalArt_Roll_CDHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Roll_Handler", + "abilityName": "Avatar_Sayu_ElementalArt_Roll_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Roll_CloseCollider", + "abilityName": "Avatar_Sayu_ElementalArt_Roll_CloseCollider", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Roll_Effect", + "abilityName": "Avatar_Sayu_ElementalArt_Roll_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Roll_TriggerBullet", + "abilityName": "Avatar_Sayu_ElementalArt_Roll_TriggerBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Hold_Strike", + "abilityName": "Avatar_Sayu_ElementalArt_Hold_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Roll_TriggerFire", + "abilityName": "Avatar_Sayu_ElementalArt_Roll_TriggerFire", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Roll_TriggerWater", + "abilityName": "Avatar_Sayu_ElementalArt_Roll_TriggerWater", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Roll_TriggerElectric", + "abilityName": "Avatar_Sayu_ElementalArt_Roll_TriggerElectric", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Roll_TriggerIce", + "abilityName": "Avatar_Sayu_ElementalArt_Roll_TriggerIce", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Roll_Bullet", + "abilityName": "Avatar_Sayu_ElementalArt_Roll_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalArt_Roll_Mix", + "abilityName": "Avatar_Sayu_ElementalArt_Roll_Mix", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst", + "abilityName": "Avatar_Sayu_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_Initialize", + "abilityName": "Avatar_Sayu_ElementalBurst_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_Camera_Handler", + "abilityName": "Avatar_Sayu_ElementalBurst_Camera_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_Strike", + "abilityName": "Avatar_Sayu_ElementalBurst_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_Heal", + "abilityName": "Avatar_Sayu_ElementalBurst_Heal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_EmotionControl", + "abilityName": "Avatar_Sayu_ElementalBurst_EmotionControl", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_Invincible", + "abilityName": "Avatar_Sayu_ElementalBurst_Invincible", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_CameraBlur", + "abilityName": "Avatar_Sayu_ElementalBurst_CameraBlur", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_TriggerDaruma", + "abilityName": "Avatar_Sayu_ElementalBurst_TriggerDaruma", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_Phantom", + "abilityName": "Avatar_Sayu_ElementalBurst_Phantom", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_Phantom_Delay", + "abilityName": "Avatar_Sayu_ElementalBurst_Phantom_Delay", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_Phantom_Handler", + "abilityName": "Avatar_Sayu_ElementalBurst_Phantom_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_Phantom_PlayAnim", + "abilityName": "Avatar_Sayu_ElementalBurst_Phantom_PlayAnim", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_Phantom_Heal", + "abilityName": "Avatar_Sayu_ElementalBurst_Phantom_Heal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_Phantom_Attack", + "abilityName": "Avatar_Sayu_ElementalBurst_Phantom_Attack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_ElementalBurst_Phantom_AttackAndHeal", + "abilityName": "Avatar_Sayu_ElementalBurst_Phantom_AttackAndHeal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_Constellation_6_Handler", + "abilityName": "Avatar_Sayu_Constellation_6_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_FallingAnthem", + "abilityName": "Avatar_Sayu_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_NormalAttack_DamageHandler", + "abilityName": "Avatar_Sayu_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_PermanentSkill_1", + "abilityName": "Avatar_Sayu_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu", + "abilityName": "Avatar_Sayu", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_TeamConfig_01BS", + "abilityName": "Avatar_Sayu_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_TeamConfig_01Loop", + "abilityName": "Avatar_Sayu_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sayu_TeamConfig_01AS", + "abilityName": "Avatar_Sayu_TeamConfig_01AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Shenhe.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Shenhe.json new file mode 100644 index 0000000..e134fd0 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Shenhe.json @@ -0,0 +1,134 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Shenhe_ExtraAttack", + "abilityName": "Avatar_Shenhe_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_CreateBullet", + "abilityName": "Avatar_Shenhe_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_ExtraAttack_Bullet", + "abilityName": "Avatar_Shenhe_ExtraAttack_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_ElementalArt_Bullet", + "abilityName": "Avatar_Shenhe_ElementalArt_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_ElementalArt_FX", + "abilityName": "Avatar_Shenhe_ElementalArt_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_ElementalArt_Attack_L", + "abilityName": "Avatar_Shenhe_ElementalArt_Attack_L", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_ElementalArt_Attack_H", + "abilityName": "Avatar_Shenhe_ElementalArt_Attack_H", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_ElementalBurst", + "abilityName": "Avatar_Shenhe_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Shenhe_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_NormalAttack_DamageHandler", + "abilityName": "Avatar_Shenhe_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_FallingAnthem", + "abilityName": "Avatar_Shenhe_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe", + "abilityName": "Avatar_Shenhe", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_Skill_ElementalArt_BS", + "abilityName": "Avatar_Shenhe_Skill_ElementalArt_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_Skill_ElementalArt_L", + "abilityName": "Avatar_Shenhe_Skill_ElementalArt_L", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_Skill_ElementalArt_H", + "abilityName": "Avatar_Shenhe_Skill_ElementalArt_H", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_Skill_ElementalArt_L_AS", + "abilityName": "Avatar_Shenhe_Skill_ElementalArt_L_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_Skill_ElementalArt_H_AS", + "abilityName": "Avatar_Shenhe_Skill_ElementalArt_H_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_Skill_ElementalBurst_BS", + "abilityName": "Avatar_Shenhe_Skill_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_Skill_ElementalBurst", + "abilityName": "Avatar_Shenhe_Skill_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_TeamConfig_01BS", + "abilityName": "Avatar_Shenhe_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_TeamConfig_01Loop", + "abilityName": "Avatar_Shenhe_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_TeamConfig_01AS", + "abilityName": "Avatar_Shenhe_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_ElementalBurst_Spine", + "abilityName": "Avatar_Shenhe_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_ElementalBurst_BS", + "abilityName": "Avatar_Shenhe_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_ElementalBurst_Hit", + "abilityName": "Avatar_Shenhe_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shenhe_Spine_Loop", + "abilityName": "Avatar_Shenhe_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Shinobu.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Shinobu.json new file mode 100644 index 0000000..6ead00b --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Shinobu.json @@ -0,0 +1,139 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Shinobu_ExtraAttack", + "abilityName": "Avatar_Shinobu_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_NormalAttack_Handler", + "abilityName": "Avatar_Shinobu_NormalAttack_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_ElementalArt_Init", + "abilityName": "Avatar_Shinobu_ElementalArt_Init", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_ElementalArt_ElemBall_Handler", + "abilityName": "Avatar_Shinobu_ElementalArt_ElemBall_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_ElementalArt", + "abilityName": "Avatar_Shinobu_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_ElementalArt_Constellation_Attack_Handler", + "abilityName": "Avatar_Shinobu_ElementalArt_Constellation_Attack_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_ElementalArt_Bullet_KillGadget", + "abilityName": "Avatar_Shinobu_ElementalArt_Bullet_KillGadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_ElementalArt_ElemBall", + "abilityName": "Avatar_Shinobu_ElementalArt_ElemBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_Constellation_Attack_Detect", + "abilityName": "Avatar_Shinobu_Constellation_Attack_Detect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_Constellation_AddAttack", + "abilityName": "Avatar_Shinobu_Constellation_AddAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_ElementalArt_TickLogic", + "abilityName": "Avatar_Shinobu_ElementalArt_TickLogic", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_ElementalArt_TickLogic_Effect", + "abilityName": "Avatar_Shinobu_ElementalArt_TickLogic_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_Constellation_AddAttack_IntoCD", + "abilityName": "Avatar_Shinobu_Constellation_AddAttack_IntoCD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_Constellation_AddAttack_Effect", + "abilityName": "Avatar_Shinobu_Constellation_AddAttack_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_ElementalBurst", + "abilityName": "Avatar_Shinobu_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_ElementalBurst_Init", + "abilityName": "Avatar_Shinobu_ElementalBurst_Init", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_NormalAttack_DamageHandler", + "abilityName": "Avatar_Shinobu_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_FallingAnthem", + "abilityName": "Avatar_Shinobu_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_PermanentSkill_WhenLowHp", + "abilityName": "Avatar_Shinobu_PermanentSkill_WhenLowHp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_PermanentSkill_HealUpWhenLowHp", + "abilityName": "Avatar_Shinobu_PermanentSkill_HealUpWhenLowHp", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_Constellation6_Limbo", + "abilityName": "Avatar_Shinobu_Constellation6_Limbo", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_Constellation6_Limbo_Trigger_Protect", + "abilityName": "Avatar_Shinobu_Constellation6_Limbo_Trigger_Protect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_Constellation6_Limbo_Trigger_ElemMastery", + "abilityName": "Avatar_Shinobu_Constellation6_Limbo_Trigger_ElemMastery", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu", + "abilityName": "Avatar_Shinobu", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_TeamConfig_01BS", + "abilityName": "Avatar_Shinobu_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_TeamConfig_01Loop", + "abilityName": "Avatar_Shinobu_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shinobu_TeamConfig_01AS", + "abilityName": "Avatar_Shinobu_TeamConfig_01AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Shougun.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Shougun.json new file mode 100644 index 0000000..80d204d --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Shougun.json @@ -0,0 +1,124 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Shougun_ExtraAttack", + "abilityName": "Avatar_Shougun_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_ElementalArt", + "abilityName": "Avatar_Shougun_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_Elfh", + "abilityName": "Avatar_Shougun_Elfh", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_Elf", + "abilityName": "Avatar_Shougun_Elf", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_ChargeLevel", + "abilityName": "Avatar_Shougun_ChargeLevel", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_ElementalBurst", + "abilityName": "Avatar_Shougun_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_FallingAnthem", + "abilityName": "Avatar_Shougun_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "AvatarOMonster_Shougun_Mitakenarukami_Mitakenarukami_BurstAtk02_AbsorbEnergyFromAvatar", + "abilityName": "AvatarOMonster_Shougun_Mitakenarukami_Mitakenarukami_BurstAtk02_AbsorbEnergyFromAvatar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun", + "abilityName": "Avatar_Shougun", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_Skill_ElementalArt", + "abilityName": "Avatar_Shougun_Skill_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_Skill_ElementalArt_AS", + "abilityName": "Avatar_Shougun_Skill_ElementalArt_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_FallingAttack_AS_01", + "abilityName": "Avatar_Shougun_FallingAttack_AS_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_FallingAttack_AS_02", + "abilityName": "Avatar_Shougun_FallingAttack_AS_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_Katana_FallingAttack_AS_01", + "abilityName": "Avatar_Shougun_Katana_FallingAttack_AS_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_TeamConfig_01BS", + "abilityName": "Avatar_Shougun_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_TeamConfig_01Loop", + "abilityName": "Avatar_Shougun_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_TeamConfig_01AS", + "abilityName": "Avatar_Shougun_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_Katana_FallingAttack_AS_02", + "abilityName": "Avatar_Shougun_Katana_FallingAttack_AS_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_Spine", + "abilityName": "Avatar_Shougun_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_ElementalBurst_Spine", + "abilityName": "Avatar_Shougun_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_ElementalBurst_BS", + "abilityName": "Avatar_Shougun_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_ElementalBurst_Hit", + "abilityName": "Avatar_Shougun_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_Spine_Loop", + "abilityName": "Avatar_Shougun_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Shougun_ChargeLevel0BurstSkillEnergy_ExtraChargeLevel_OtherElemRatio", + "abilityName": "Avatar_Shougun_ChargeLevel0BurstSkillEnergy_ExtraChargeLevel_OtherElemRatio", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Sucrose.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Sucrose.json new file mode 100644 index 0000000..be5bebc --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Sucrose.json @@ -0,0 +1,244 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Sucrose_ExtraAttack", + "abilityName": "Avatar_Sucrose_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_Attack01", + "abilityName": "Avatar_Sucrose_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_Attack02", + "abilityName": "Avatar_Sucrose_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_Attack03", + "abilityName": "Avatar_Sucrose_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_Attack04_Pre", + "abilityName": "Avatar_Sucrose_Attack04_Pre", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_Attack04_Gadget", + "abilityName": "Avatar_Sucrose_Attack04_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_Attack04", + "abilityName": "Avatar_Sucrose_Attack04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_WindBlackHole", + "abilityName": "Avatar_Sucrose_WindBlackHole", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_WindBlackHole_Gadget", + "abilityName": "Avatar_Sucrose_WindBlackHole_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_DemiHurricane", + "abilityName": "Avatar_Sucrose_DemiHurricane", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_DemiHurricane_Flusk", + "abilityName": "Avatar_Sucrose_DemiHurricane_Flusk", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_DemiHurricane_Gadget", + "abilityName": "Avatar_Sucrose_DemiHurricane_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_DemiHurricane_Dissipate", + "abilityName": "Avatar_Sucrose_DemiHurricane_Dissipate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_DemiHurricane_Damage", + "abilityName": "Avatar_Sucrose_DemiHurricane_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_DemiHurricane_Mix", + "abilityName": "Avatar_Sucrose_DemiHurricane_Mix", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_Contellation_6", + "abilityName": "Avatar_Sucrose_Contellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_FallingAnthem", + "abilityName": "Avatar_Sucrose_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_Catalysa", + "abilityName": "Avatar_Sucrose_PermanentSkill_Catalysa", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_Catalysa_Handler", + "abilityName": "Avatar_Sucrose_PermanentSkill_Catalysa_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_Catalysa_Fire", + "abilityName": "Avatar_Sucrose_PermanentSkill_Catalysa_Fire", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_Catalysa_Firec", + "abilityName": "Avatar_Sucrose_PermanentSkill_Catalysa_Firec", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_Catalysa_Water", + "abilityName": "Avatar_Sucrose_PermanentSkill_Catalysa_Water", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_Catalysa_Waterc", + "abilityName": "Avatar_Sucrose_PermanentSkill_Catalysa_Waterc", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_Catalysa_Ice", + "abilityName": "Avatar_Sucrose_PermanentSkill_Catalysa_Ice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_Catalysa_Icec", + "abilityName": "Avatar_Sucrose_PermanentSkill_Catalysa_Icec", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_Catalysa_Electric", + "abilityName": "Avatar_Sucrose_PermanentSkill_Catalysa_Electric", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_Catalysa_Electric2UNIQUE_Avatar_Sucrose_PermanentSkill_Catalysa_Fire", + "abilityName": "Avatar_Sucrose_PermanentSkill_Catalysa_Electric2UNIQUE_Avatar_Sucrose_PermanentSkill_Catalysa_Fire", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_NetherWind", + "abilityName": "Avatar_Sucrose_PermanentSkill_NetherWind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_NetherWind_Handler", + "abilityName": "Avatar_Sucrose_PermanentSkill_NetherWind_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_NetherWind_Buff", + "abilityName": "Avatar_Sucrose_PermanentSkill_NetherWind_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_NetherWind_Buff4UNIQUE_Avatar_Sucrose_PermanentSkill_NetherWind_Buff", + "abilityName": "Avatar_Sucrose_PermanentSkill_NetherWind_Buff4UNIQUE_Avatar_Sucrose_PermanentSkill_NetherWind_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_NormalAttack_DamageHandler", + "abilityName": "Avatar_Sucrose_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_NormalAttack_DamageHandler_Paranoid", + "abilityName": "Avatar_Sucrose_NormalAttack_DamageHandler_Paranoid", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_NormalAttack_DamageHandler_Paranoid_AddCount", + "abilityName": "Avatar_Sucrose_NormalAttack_DamageHandler_Paranoid_AddCount", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_NormalAttack_DamageHandler_Paranoid_ReduceColdDown", + "abilityName": "Avatar_Sucrose_NormalAttack_DamageHandler_Paranoid_ReduceColdDown", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_Contellation_4", + "abilityName": "Avatar_Sucrose_Contellation_4", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose", + "abilityName": "Avatar_Sucrose", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_TeamConfig_01BS", + "abilityName": "Avatar_Sucrose_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_TeamConfig_01Loop", + "abilityName": "Avatar_Sucrose_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_TeamConfig_01AS", + "abilityName": "Avatar_Sucrose_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_ElementalBurst_Spine", + "abilityName": "Avatar_Sucrose_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_ElementalBurst_BS", + "abilityName": "Avatar_Sucrose_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_ElementalBurst", + "abilityName": "Avatar_Sucrose_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_ElementBurst", + "abilityName": "Avatar_Sucrose_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_ElementalBurst_Hit", + "abilityName": "Avatar_Sucrose_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_elementalBurst_BS_Normal", + "abilityName": "Avatar_Sucrose_elementalBurst_BS_Normal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_Spine_Loop", + "abilityName": "Avatar_Sucrose_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Sucrose_PermanentSkill_Catalysa0Sucrose_PermanentSkill_Catalysa_ElemMasteryDelta", + "abilityName": "Avatar_Sucrose_PermanentSkill_Catalysa0Sucrose_PermanentSkill_Catalysa_ElemMasteryDelta", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Tartaglia.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Tartaglia.json new file mode 100644 index 0000000..87ca33f --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Tartaglia.json @@ -0,0 +1,239 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Tartaglia_Arrow_FX", + "abilityName": "Avatar_Tartaglia_Arrow_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_PressShoot", + "abilityName": "Avatar_Tartaglia_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_AimPressShoot", + "abilityName": "Avatar_Tartaglia_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ShootArrow_01", + "abilityName": "Avatar_Tartaglia_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ShootArrow_02", + "abilityName": "Avatar_Tartaglia_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ShootArrow_03", + "abilityName": "Avatar_Tartaglia_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ShootArrow_04", + "abilityName": "Avatar_Tartaglia_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ShootArrow_05", + "abilityName": "Avatar_Tartaglia_ShootArrow_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ShootArrow_06", + "abilityName": "Avatar_Tartaglia_ShootArrow_06", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ShootArrow_Aiming", + "abilityName": "Avatar_Tartaglia_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ShootArrow_Enchanted_Water", + "abilityName": "Avatar_Tartaglia_ShootArrow_Enchanted_Water", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ShootArrow_Enchanted_WithoutWater", + "abilityName": "Avatar_Tartaglia_ShootArrow_Enchanted_WithoutWater", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ShootAimingArrow_Charge", + "abilityName": "Avatar_Tartaglia_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ChangeMainSkill", + "abilityName": "Avatar_Tartaglia_ChangeMainSkill", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_WaterFlower_Handler", + "abilityName": "Avatar_Tartaglia_WaterFlower_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_EddyBlade", + "abilityName": "Avatar_Tartaglia_EddyBlade", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_Ripple", + "abilityName": "Avatar_Tartaglia_Ripple", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_EndOfIris", + "abilityName": "Avatar_Tartaglia_EndOfIris", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_Gandalfr", + "abilityName": "Avatar_Tartaglia_Gandalfr", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_Gandalfr_Remover", + "abilityName": "Avatar_Tartaglia_Gandalfr_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_Gandalfr_Attack05", + "abilityName": "Avatar_Tartaglia_Gandalfr_Attack05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_Gandalfr_Trigger", + "abilityName": "Avatar_Tartaglia_Gandalfr_Trigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_GandalfrU", + "abilityName": "Avatar_Tartaglia_GandalfrU", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_Gandalfr_TriggerOff", + "abilityName": "Avatar_Tartaglia_Gandalfr_TriggerOff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_Gandalfr_RemoverU", + "abilityName": "Avatar_Tartaglia_Gandalfr_RemoverU", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_AquariaBlade_Melee", + "abilityName": "Avatar_Tartaglia_AquariaBlade_Melee", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ThousandWithers7", + "abilityName": "Avatar_Tartaglia_ThousandWithers7", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_AquariaBlade_Range", + "abilityName": "Avatar_Tartaglia_AquariaBlade_Range", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_AquariaBlade_Range_Gadget", + "abilityName": "Avatar_Tartaglia_AquariaBlade_Range_Gadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_Blade_Manager", + "abilityName": "Avatar_Tartaglia_Blade_Manager", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_AquariaBlade_CameraController", + "abilityName": "Avatar_Tartaglia_AquariaBlade_CameraController", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_FallingAnthem", + "abilityName": "Avatar_Tartaglia_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia", + "abilityName": "Avatar_Tartaglia", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ShootArrow_Enchanted_Water2Avatar_Tartaglia_ShootArrow_Enchanted_WithoutWater", + "abilityName": "Avatar_Tartaglia_ShootArrow_Enchanted_Water2Avatar_Tartaglia_ShootArrow_Enchanted_WithoutWater", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_TeamConfig_01BS", + "abilityName": "Avatar_Tartaglia_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_TeamConfig_01Loop", + "abilityName": "Avatar_Tartaglia_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_TeamConfig_01AS", + "abilityName": "Avatar_Tartaglia_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ElementalBurst_01_Spine", + "abilityName": "Avatar_Tartaglia_ElementalBurst_01_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ElementalBurst_01_Hit", + "abilityName": "Avatar_Tartaglia_ElementalBurst_01_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ElementalBurst_01_BS", + "abilityName": "Avatar_Tartaglia_ElementalBurst_01_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ElementalBurst_02_Spine", + "abilityName": "Avatar_Tartaglia_ElementalBurst_02_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ElementalBurst_02_Hit", + "abilityName": "Avatar_Tartaglia_ElementalBurst_02_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ElementalBurst_02_BS", + "abilityName": "Avatar_Tartaglia_ElementalBurst_02_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_Spine_Loop", + "abilityName": "Avatar_Tartaglia_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_Spine", + "abilityName": "Avatar_Tartaglia_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_02_Spine", + "abilityName": "Avatar_Tartaglia_02_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tartaglia_ThousandWithers", + "abilityName": "Avatar_Tartaglia_ThousandWithers", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Tighnari.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Tighnari.json new file mode 100644 index 0000000..08f8586 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Tighnari.json @@ -0,0 +1,194 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Tighnari_PressShoot", + "abilityName": "Avatar_Tighnari_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_AimPressShoot", + "abilityName": "Avatar_Tighnari_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ShootAimingArrow_Charge", + "abilityName": "Avatar_Tighnari_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ShootArrow_Aiming", + "abilityName": "Avatar_Tighnari_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_PermanentSkill_1P", + "abilityName": "Avatar_Tighnari_PermanentSkill_1P", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_PermanentSkill_1", + "abilityName": "Avatar_Tighnari_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ShootArrow_01", + "abilityName": "Avatar_Tighnari_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ShootArrow_02", + "abilityName": "Avatar_Tighnari_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ShootArrow_03", + "abilityName": "Avatar_Tighnari_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ShootArrow_03_01", + "abilityName": "Avatar_Tighnari_ShootArrow_03_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ShootArrow_04", + "abilityName": "Avatar_Tighnari_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementalArt", + "abilityName": "Avatar_Tighnari_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementalBurst", + "abilityName": "Avatar_Tighnari_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Tighnari_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementalBurst_BulletTrigger", + "abilityName": "Avatar_Tighnari_ElementalBurst_BulletTrigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementalBurst_Bullet_Damage1", + "abilityName": "Avatar_Tighnari_ElementalBurst_Bullet_Damage1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementalBurst_Bullet_Damage2", + "abilityName": "Avatar_Tighnari_ElementalBurst_Bullet_Damage2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_PermanentSkill_2", + "abilityName": "Avatar_Tighnari_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_FallingAnthem", + "abilityName": "Avatar_Tighnari_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_Radar_Collectables_Sumeru", + "abilityName": "Avatar_Tighnari_Radar_Collectables_Sumeru", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari", + "abilityName": "Avatar_Tighnari", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_SetGadget", + "abilityName": "Avatar_Tighnari_SetGadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_TeamConfig_01BS", + "abilityName": "Avatar_Tighnari_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_TeamConfig_01Loop", + "abilityName": "Avatar_Tighnari_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_TeamConfig_01AS", + "abilityName": "Avatar_Tighnari_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementalBurst_Spine", + "abilityName": "Avatar_Tighnari_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_Spine", + "abilityName": "Avatar_Tighnari_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementalBurst_BS", + "abilityName": "Avatar_Tighnari_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementBurst_01", + "abilityName": "Avatar_Tighnari_ElementBurst_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementBurst_05", + "abilityName": "Avatar_Tighnari_ElementBurst_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementBurst_02", + "abilityName": "Avatar_Tighnari_ElementBurst_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementBurst_06", + "abilityName": "Avatar_Tighnari_ElementBurst_06", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementBurst_03", + "abilityName": "Avatar_Tighnari_ElementBurst_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementBurst_07", + "abilityName": "Avatar_Tighnari_ElementBurst_07", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementBurst_04", + "abilityName": "Avatar_Tighnari_ElementBurst_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementBurst_08", + "abilityName": "Avatar_Tighnari_ElementBurst_08", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_ElementalBurst_Hit", + "abilityName": "Avatar_Tighnari_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tighnari_Spine_Loop", + "abilityName": "Avatar_Tighnari_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Tohma.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Tohma.json new file mode 100644 index 0000000..6b3ec97 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Tohma.json @@ -0,0 +1,114 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Tohma_ExtraAttack", + "abilityName": "Avatar_Tohma_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_ExtraAttack_CreateBullet", + "abilityName": "Avatar_Tohma_ExtraAttack_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_ExtraAttack_Bullet", + "abilityName": "Avatar_Tohma_ExtraAttack_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_ElementalArt_Handler", + "abilityName": "Avatar_Tohma_ElementalArt_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_HasTeamShield", + "abilityName": "Avatar_Tohma_HasTeamShield", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_Has_ELementalBurstBuff", + "abilityName": "Avatar_Tohma_Has_ELementalBurstBuff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_ElementalArt_Strike", + "abilityName": "Avatar_Tohma_ElementalArt_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_ElementalBurst_Start", + "abilityName": "Avatar_Tohma_ElementalBurst_Start", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_ElementalBurst_Buff_Handler", + "abilityName": "Avatar_Tohma_ElementalBurst_Buff_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_ElementalBurstPos", + "abilityName": "Avatar_Tohma_ElementalBurstPos", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_ElementalBurstDir", + "abilityName": "Avatar_Tohma_ElementalBurstDir", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_ElementalBurst_TriggerAttack", + "abilityName": "Avatar_Tohma_ElementalBurst_TriggerAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_NormalAttack_DamageHandler", + "abilityName": "Avatar_Tohma_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_FallingAnthem", + "abilityName": "Avatar_Tohma_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma", + "abilityName": "Avatar_Tohma", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_Skill_ElementalArt", + "abilityName": "Avatar_Tohma_Skill_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_Skill_ElementalArt_AS", + "abilityName": "Avatar_Tohma_Skill_ElementalArt_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_Skill_ElementalBurst", + "abilityName": "Avatar_Tohma_Skill_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_TeamConfig_01BS", + "abilityName": "Avatar_Tohma_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_TeamConfig_01Loop", + "abilityName": "Avatar_Tohma_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_TeamConfig_01AS", + "abilityName": "Avatar_Tohma_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Tohma_Skill_ElementalBurst_AS", + "abilityName": "Avatar_Tohma_Skill_ElementalBurst_AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Venti.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Venti.json new file mode 100644 index 0000000..3a00424 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Venti.json @@ -0,0 +1,194 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Venti_WindBlade_Test", + "abilityName": "Avatar_Venti_WindBlade_Test", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_WindBlade", + "abilityName": "Avatar_Venti_WindBlade", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_Arrow_FX", + "abilityName": "Avatar_Venti_Arrow_FX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_PressShoot", + "abilityName": "Avatar_Venti_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_AimPressShoot", + "abilityName": "Avatar_Venti_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ShootArrow_01", + "abilityName": "Avatar_Venti_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ShootArrow_02", + "abilityName": "Avatar_Venti_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ShootArrow_03", + "abilityName": "Avatar_Venti_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ShootArrow_04", + "abilityName": "Avatar_Venti_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ShootArrow_05", + "abilityName": "Avatar_Venti_ShootArrow_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ShootArrow_06", + "abilityName": "Avatar_Venti_ShootArrow_06", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ShootArrow_Aiming", + "abilityName": "Avatar_Venti_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ShootArrow_Enchanted_Wind", + "abilityName": "Avatar_Venti_ShootArrow_Enchanted_Wind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ShootArrow_Enchanted_WithoutWind", + "abilityName": "Avatar_Venti_ShootArrow_Enchanted_WithoutWind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ShootAimingArrow_Charge", + "abilityName": "Avatar_Venti_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ChangeMainSkill", + "abilityName": "Avatar_Venti_ChangeMainSkill", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_Hurricane", + "abilityName": "Avatar_Venti_Hurricane", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_Hurricane_Mix", + "abilityName": "Avatar_Venti_Hurricane_Mix", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_Hurricane_Dissipate", + "abilityName": "Avatar_Venti_Hurricane_Dissipate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_Hurricane_DropBall", + "abilityName": "Avatar_Venti_Hurricane_DropBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_FlyChampion", + "abilityName": "Avatar_Venti_FlyChampion", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_FlyStamina_Reduction", + "abilityName": "Avatar_Venti_FlyStamina_Reduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_Talnet_ShootArrow_Enchanted_Wind", + "abilityName": "Avatar_Venti_Talnet_ShootArrow_Enchanted_Wind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_Talnet_ShootArrow_Enchanted_WithoutWind", + "abilityName": "Avatar_Venti_Talnet_ShootArrow_Enchanted_WithoutWind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_WindField", + "abilityName": "Avatar_Venti_WindField", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_FallingAnthem", + "abilityName": "Avatar_Venti_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti", + "abilityName": "Avatar_Venti", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_Talnet_ShootArrow_Enchanted_Wind4Avatar_Venti_Talnet_ShootArrow_Enchanted_WithoutWind", + "abilityName": "Avatar_Venti_Talnet_ShootArrow_Enchanted_Wind4Avatar_Venti_Talnet_ShootArrow_Enchanted_WithoutWind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_TeamConfig_01BS", + "abilityName": "Avatar_Venti_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_TeamConfig_01Loop", + "abilityName": "Avatar_Venti_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_TeamConfig_01AS", + "abilityName": "Avatar_Venti_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ElementalBurst_Spine", + "abilityName": "Avatar_Venti_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ElementalBurst_BS", + "abilityName": "Avatar_Venti_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ElementalBurst", + "abilityName": "Avatar_Venti_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ElementBurst", + "abilityName": "Avatar_Venti_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_ElementalBurst_Hit", + "abilityName": "Avatar_Venti_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_Spine_Loop", + "abilityName": "Avatar_Venti_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Venti_FlyStamina_Reduction_", + "abilityName": "Avatar_Venti_FlyStamina_Reduction_", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Wanderer.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Wanderer.json new file mode 100644 index 0000000..831c98f --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Wanderer.json @@ -0,0 +1,569 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Wanderer_ElementalArt_HoverAir_Handler", + "abilityName": "Avatar_Wanderer_ElementalArt_HoverAir_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ExtraAttack", + "abilityName": "Avatar_Wanderer_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ExtraAttack_Charge", + "abilityName": "Avatar_Wanderer_ExtraAttack_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ExtraAttack_Charge_HasTarget", + "abilityName": "Avatar_Wanderer_ExtraAttack_Charge_HasTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ExtraAttack_Charge_NoTarget", + "abilityName": "Avatar_Wanderer_ExtraAttack_Charge_NoTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ExtraAttack_Initiate", + "abilityName": "Avatar_Wanderer_ExtraAttack_Initiate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ExtraAttack_Air_Charge", + "abilityName": "Avatar_Wanderer_ExtraAttack_Air_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ExtraAttack_Air_Charge_HasTarget", + "abilityName": "Avatar_Wanderer_ExtraAttack_Air_Charge_HasTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ExtraAttack_Air_Charge_NoTarget", + "abilityName": "Avatar_Wanderer_ExtraAttack_Air_Charge_NoTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ExtraAttack_Air_Initiate", + "abilityName": "Avatar_Wanderer_ExtraAttack_Air_Initiate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAir_Flag", + "abilityName": "Avatar_Wanderer_HoverAir_Flag", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HatVisible_Flag", + "abilityName": "Avatar_Wanderer_HatVisible_Flag", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HatVisible_Hide_Handler", + "abilityName": "Avatar_Wanderer_HatVisible_Hide_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HatVisible_SetGV", + "abilityName": "Avatar_Wanderer_HatVisible_SetGV", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Attack01", + "abilityName": "Avatar_Wanderer_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Attack02", + "abilityName": "Avatar_Wanderer_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Attack03", + "abilityName": "Avatar_Wanderer_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_Bullet_1", + "abilityName": "Avatar_Wanderer_NormalAttack_Bullet_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_01_Bullet_VFX", + "abilityName": "Avatar_Wanderer_NormalAttack_01_Bullet_VFX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_01_Bullet_AngularVelocity_Timer", + "abilityName": "Avatar_Wanderer_NormalAttack_01_Bullet_AngularVelocity_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_01_Bullet_AngularVelocity6Avatar_Wanderer_NormalAttack_01_Bullet_AngularVelocity", + "abilityName": "Avatar_Wanderer_NormalAttack_01_Bullet_AngularVelocity6Avatar_Wanderer_NormalAttack_01_Bullet_AngularVelocity", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_Bullet_2", + "abilityName": "Avatar_Wanderer_NormalAttack_Bullet_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_02_Bullet_VFX", + "abilityName": "Avatar_Wanderer_NormalAttack_02_Bullet_VFX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_02_Bullet_AngularVelocity_Timer", + "abilityName": "Avatar_Wanderer_NormalAttack_02_Bullet_AngularVelocity_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_02_Bullet_AngularVelocity6Avatar_Wanderer_NormalAttack_02_Bullet_AngularVelocity", + "abilityName": "Avatar_Wanderer_NormalAttack_02_Bullet_AngularVelocity6Avatar_Wanderer_NormalAttack_02_Bullet_AngularVelocity", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_Bullet_3", + "abilityName": "Avatar_Wanderer_NormalAttack_Bullet_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_03_Bullet_VFX", + "abilityName": "Avatar_Wanderer_NormalAttack_03_Bullet_VFX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_03_Bullet_AngularVelocity_Timer", + "abilityName": "Avatar_Wanderer_NormalAttack_03_Bullet_AngularVelocity_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_03_Bullet_AngularVelocity6Avatar_Wanderer_NormalAttack_03_Bullet_AngularVelocity", + "abilityName": "Avatar_Wanderer_NormalAttack_03_Bullet_AngularVelocity6Avatar_Wanderer_NormalAttack_03_Bullet_AngularVelocity", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_Bullet_4", + "abilityName": "Avatar_Wanderer_NormalAttack_Bullet_4", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_04_Bullet_VFX", + "abilityName": "Avatar_Wanderer_NormalAttack_04_Bullet_VFX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_04_Bullet_AngularVelocity_Timer", + "abilityName": "Avatar_Wanderer_NormalAttack_04_Bullet_AngularVelocity_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_NormalAttack_04_Bullet_AngularVelocity6Avatar_Wanderer_NormalAttack_04_Bullet_AngularVelocity", + "abilityName": "Avatar_Wanderer_NormalAttack_04_Bullet_AngularVelocity6Avatar_Wanderer_NormalAttack_04_Bullet_AngularVelocity", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Launch", + "abilityName": "Avatar_Wanderer_ElementalArt_Launch", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_HoverAir_", + "abilityName": "Avatar_Wanderer_ElementalArt_HoverAir_", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Ring_Handler", + "abilityName": "Avatar_Wanderer_ElementalArt_Ring_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Kasa_Ring_Idle", + "abilityName": "Avatar_Wanderer_Kasa_Ring_Idle", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Kasa_Ring_Move", + "abilityName": "Avatar_Wanderer_Kasa_Ring_Move", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Kasa_Ring_Dash", + "abilityName": "Avatar_Wanderer_Kasa_Ring_Dash", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Kasa_Ring_DashHold", + "abilityName": "Avatar_Wanderer_Kasa_Ring_DashHold", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Kasa_Ring_Recovery", + "abilityName": "Avatar_Wanderer_Kasa_Ring_Recovery", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAir_Mark", + "abilityName": "Avatar_Wanderer_HoverAir_Mark", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Ring", + "abilityName": "Avatar_Wanderer_ElementalArt_Ring", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_HoverAir", + "abilityName": "Avatar_Wanderer_ElementalArt_HoverAir", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_HoverAir_Remover", + "abilityName": "Avatar_Wanderer_ElementalArt_HoverAir_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Constellation_6_Handler", + "abilityName": "Avatar_Wanderer_Constellation_6_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Constellation_6_Count", + "abilityName": "Avatar_Wanderer_Constellation_6_Count", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Constellation_6_Buff", + "abilityName": "Avatar_Wanderer_Constellation_6_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_HoverAir_Dash", + "abilityName": "Avatar_Wanderer_ElementalArt_HoverAir_Dash", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_HoverAir_Up", + "abilityName": "Avatar_Wanderer_ElementalArt_HoverAir_Up", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Recovery", + "abilityName": "Avatar_Wanderer_ElementalArt_Recovery", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HitFallToGround_Visible_Handler", + "abilityName": "Avatar_Wanderer_HitFallToGround_Visible_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Recovery_Handler", + "abilityName": "Avatar_Wanderer_Recovery_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Recovery_AddEndure", + "abilityName": "Avatar_Wanderer_Recovery_AddEndure", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_HoverAir_Shoot", + "abilityName": "Avatar_Wanderer_ElementalArt_HoverAir_Shoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_HoverAir_Shoot_1", + "abilityName": "Avatar_Wanderer_ElementalArt_HoverAir_Shoot_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_HoverAir_Shoot_2", + "abilityName": "Avatar_Wanderer_ElementalArt_HoverAir_Shoot_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_HoverAir_Shoot_3", + "abilityName": "Avatar_Wanderer_ElementalArt_HoverAir_Shoot_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Bullet_1", + "abilityName": "Avatar_Wanderer_ElementalArt_Bullet_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAttack_01_Bullet_VFX", + "abilityName": "Avatar_Wanderer_HoverAttack_01_Bullet_VFX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAttack_01_Bullet_AngularVelocity_Timer", + "abilityName": "Avatar_Wanderer_HoverAttack_01_Bullet_AngularVelocity_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAttack_01_Bullet_AngularVelocity5Avatar_Wanderer_HoverAttack_01_Bullet_AngularVelocity", + "abilityName": "Avatar_Wanderer_HoverAttack_01_Bullet_AngularVelocity5Avatar_Wanderer_HoverAttack_01_Bullet_AngularVelocity", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Bullet_2", + "abilityName": "Avatar_Wanderer_ElementalArt_Bullet_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAttack_02_Bullet_VFX", + "abilityName": "Avatar_Wanderer_HoverAttack_02_Bullet_VFX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAttack_02_Bullet_AngularVelocity_Timer", + "abilityName": "Avatar_Wanderer_HoverAttack_02_Bullet_AngularVelocity_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAttack_02_Bullet_AngularVelocity5Avatar_Wanderer_HoverAttack_02_Bullet_AngularVelocity", + "abilityName": "Avatar_Wanderer_HoverAttack_02_Bullet_AngularVelocity5Avatar_Wanderer_HoverAttack_02_Bullet_AngularVelocity", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Bullet_3", + "abilityName": "Avatar_Wanderer_ElementalArt_Bullet_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAttack_03_Bullet_VFX", + "abilityName": "Avatar_Wanderer_HoverAttack_03_Bullet_VFX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAttack_03_Bullet_AngularVelocity_Timer", + "abilityName": "Avatar_Wanderer_HoverAttack_03_Bullet_AngularVelocity_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAttack_03_Bullet_AngularVelocity5Avatar_Wanderer_HoverAttack_03_Bullet_AngularVelocity", + "abilityName": "Avatar_Wanderer_HoverAttack_03_Bullet_AngularVelocity5Avatar_Wanderer_HoverAttack_03_Bullet_AngularVelocity", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Bullet_4", + "abilityName": "Avatar_Wanderer_ElementalArt_Bullet_4", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAttack_04_Bullet_VFX", + "abilityName": "Avatar_Wanderer_HoverAttack_04_Bullet_VFX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAttack_04_Bullet_AngularVelocity_Timer", + "abilityName": "Avatar_Wanderer_HoverAttack_04_Bullet_AngularVelocity_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_HoverAttack_04_Bullet_AngularVelocity5Avatar_Wanderer_HoverAttack_04_Bullet_AngularVelocity", + "abilityName": "Avatar_Wanderer_HoverAttack_04_Bullet_AngularVelocity5Avatar_Wanderer_HoverAttack_04_Bullet_AngularVelocity", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Bullet_1_Extra", + "abilityName": "Avatar_Wanderer_ElementalArt_Bullet_1_Extra", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Bullet_2_Extra", + "abilityName": "Avatar_Wanderer_ElementalArt_Bullet_2_Extra", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Bullet_3_Extra", + "abilityName": "Avatar_Wanderer_ElementalArt_Bullet_3_Extra", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Bullet_4_Extra", + "abilityName": "Avatar_Wanderer_ElementalArt_Bullet_4_Extra", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalBurst", + "abilityName": "Avatar_Wanderer_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalBurst_Emotion", + "abilityName": "Avatar_Wanderer_ElementalBurst_Emotion", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalBurst_SkinControl", + "abilityName": "Avatar_Wanderer_ElementalBurst_SkinControl", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalBurst_Invincible", + "abilityName": "Avatar_Wanderer_ElementalBurst_Invincible", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalBurst_FogFX01", + "abilityName": "Avatar_Wanderer_ElementalBurst_FogFX01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalBurst_Bullet", + "abilityName": "Avatar_Wanderer_ElementalBurst_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_PermanentSkill_1", + "abilityName": "Avatar_Wanderer_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_ResetMixTypey", + "abilityName": "Avatar_Wanderer_ElementalArt_ResetMixTypey", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_ResetMixType", + "abilityName": "Avatar_Wanderer_ElementalArt_ResetMixType", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_PermanentSkill_2", + "abilityName": "Avatar_Wanderer_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_PermanentSkill_2_HasTarget", + "abilityName": "Avatar_Wanderer_PermanentSkill_2_HasTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_PermanentSkill_2_NoTarget", + "abilityName": "Avatar_Wanderer_PermanentSkill_2_NoTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_PermanentSkill_2_RandomCheck", + "abilityName": "Avatar_Wanderer_PermanentSkill_2_RandomCheck", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Bullet_HoverDash", + "abilityName": "Avatar_Wanderer_ElementalArt_Bullet_HoverDash", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Bullet_Extra_Trail", + "abilityName": "Avatar_Wanderer_ElementalArt_Bullet_Extra_Trail", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Bullet_Extra_Core", + "abilityName": "Avatar_Wanderer_ElementalArt_Bullet_Extra_Core", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Bullet_Extra_Hit", + "abilityName": "Avatar_Wanderer_ElementalArt_Bullet_Extra_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_FallingAnthem", + "abilityName": "Avatar_Wanderer_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_FallAnthem_BS_Wind", + "abilityName": "Avatar_Wanderer_FallAnthem_BS_Wind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_FallAnthem_Self_Wind", + "abilityName": "Avatar_Wanderer_FallAnthem_Self_Wind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_FallAnthem_Strike_01_Wind", + "abilityName": "Avatar_Wanderer_FallAnthem_Strike_01_Wind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_FallAnthem_Strike_02_Wind", + "abilityName": "Avatar_Wanderer_FallAnthem_Strike_02_Wind", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer", + "abilityName": "Avatar_Wanderer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_TeamConfig_01BS", + "abilityName": "Avatar_Wanderer_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_TeamConfig_01Loop", + "abilityName": "Avatar_Wanderer_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_TeamConfig_01AS", + "abilityName": "Avatar_Wanderer_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalArt_Bullet_HoverDash_Trigger5Avatar_Wanderer_ElementalArt_Bullet_HoverDash_Trigger", + "abilityName": "Avatar_Wanderer_ElementalArt_Bullet_HoverDash_Trigger5Avatar_Wanderer_ElementalArt_Bullet_HoverDash_Trigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalBurst_Spine", + "abilityName": "Avatar_Wanderer_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalBurst_Spine_Foot", + "abilityName": "Avatar_Wanderer_ElementalBurst_Spine_Foot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Spine", + "abilityName": "Avatar_Wanderer_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_02_Spine", + "abilityName": "Avatar_Wanderer_02_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalBurst_BS", + "abilityName": "Avatar_Wanderer_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_ElementalBurst_Hit", + "abilityName": "Avatar_Wanderer_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Spine_Loop_Hand", + "abilityName": "Avatar_Wanderer_Spine_Loop_Hand", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wanderer_Spine_Loop", + "abilityName": "Avatar_Wanderer_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Wriothesley.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Wriothesley.json new file mode 100644 index 0000000..1374037 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Wriothesley.json @@ -0,0 +1,264 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Wriothesley_ExtraAttack", + "abilityName": "Avatar_Wriothesley_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ExtraAttack_Strike", + "abilityName": "Avatar_Wriothesley_ExtraAttack_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_NormalAttack_Damage_Handler", + "abilityName": "Avatar_Wriothesley_NormalAttack_Damage_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_AttackSpeed_Buff", + "abilityName": "Avatar_Wriothesley_AttackSpeed_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_AttackSpeed_Handler", + "abilityName": "Avatar_Wriothesley_AttackSpeed_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_AttackSpeed_Buff_Self_Handler0Avatar_Wriothesley_AttackSpeed_Buff_Team_Handler", + "abilityName": "Avatar_Wriothesley_AttackSpeed_Buff_Self_Handler0Avatar_Wriothesley_AttackSpeed_Buff_Team_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_AttackSpeed_Buff_Self_Timer", + "abilityName": "Avatar_Wriothesley_AttackSpeed_Buff_Self_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_AttackSpeed_Buff_Team_Timer", + "abilityName": "Avatar_Wriothesley_AttackSpeed_Buff_Team_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_AttackSpeed_Buff_Self_Handler", + "abilityName": "Avatar_Wriothesley_AttackSpeed_Buff_Self_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_AttackSpeed_Buff_Self0Avatar_Wriothesley_AttackSpeed_Buff_Team_Handler", + "abilityName": "Avatar_Wriothesley_AttackSpeed_Buff_Self0Avatar_Wriothesley_AttackSpeed_Buff_Team_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_AttackSpeed_Buff_Team", + "abilityName": "Avatar_Wriothesley_AttackSpeed_Buff_Team", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_AttackSpeed_Buff_Self", + "abilityName": "Avatar_Wriothesley_AttackSpeed_Buff_Self", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ElementalArt_Buff", + "abilityName": "Avatar_Wriothesley_ElementalArt_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ElementalArt_Buff_Handler", + "abilityName": "Avatar_Wriothesley_ElementalArt_Buff_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_NormalAttack_Buff_Handler", + "abilityName": "Avatar_Wriothesley_NormalAttack_Buff_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ElementalArt_LoseHP", + "abilityName": "Avatar_Wriothesley_ElementalArt_LoseHP", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ElementalArt_GenerateEnergy", + "abilityName": "Avatar_Wriothesley_ElementalArt_GenerateEnergy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ExtraAttack_Buff_CD_Handler", + "abilityName": "Avatar_Wriothesley_ExtraAttack_Buff_CD_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ExtraAttack_Buff_Predicate", + "abilityName": "Avatar_Wriothesley_ExtraAttack_Buff_Predicate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ExtraAttack_Buff_CD", + "abilityName": "Avatar_Wriothesley_ExtraAttack_Buff_CD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ExtraAttack_Buff_Trigger", + "abilityName": "Avatar_Wriothesley_ExtraAttack_Buff_Trigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ExtraAttack_Buff_Handler", + "abilityName": "Avatar_Wriothesley_ExtraAttack_Buff_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ExtraAttack_Buff_HealHP", + "abilityName": "Avatar_Wriothesley_ExtraAttack_Buff_HealHP", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ElementalArt_Buff_HandlerM", + "abilityName": "Avatar_Wriothesley_ElementalArt_Buff_HandlerM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ElementalBurst_Cast", + "abilityName": "Avatar_Wriothesley_ElementalBurst_Cast", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Wriothesley_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ElementalBurst_Bullet", + "abilityName": "Avatar_Wriothesley_ElementalBurst_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ElementalBurst_Arkhe_CD_Handler2Avatar_Wriothesley_ElementalBurst_Arkhe_CD_Handler", + "abilityName": "Avatar_Wriothesley_ElementalBurst_Arkhe_CD_Handler2Avatar_Wriothesley_ElementalBurst_Arkhe_CD_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_FallingAnthem", + "abilityName": "Avatar_Wriothesley_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_Handler3", + "abilityName": "Avatar_Wriothesley_Gauntlet_Handler3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_L_Handler", + "abilityName": "Avatar_Wriothesley_Gauntlet_L_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_R_Handler", + "abilityName": "Avatar_Wriothesley_Gauntlet_R_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_L_Dissolve", + "abilityName": "Avatar_Wriothesley_Gauntlet_L_Dissolve", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_R_Dissolve", + "abilityName": "Avatar_Wriothesley_Gauntlet_R_Dissolve", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_L_Enable", + "abilityName": "Avatar_Wriothesley_Gauntlet_L_Enable", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_R_Enable", + "abilityName": "Avatar_Wriothesley_Gauntlet_R_Enable", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_ElementalBurst_Dissolveff", + "abilityName": "Avatar_Wriothesley_Gauntlet_ElementalBurst_Dissolveff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_Handler_VFX", + "abilityName": "Avatar_Wriothesley_Gauntlet_Handler_VFX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_Initialize_2", + "abilityName": "Avatar_Wriothesley_Gauntlet_Initialize_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_L_Disable", + "abilityName": "Avatar_Wriothesley_Gauntlet_L_Disable", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_R_Disable", + "abilityName": "Avatar_Wriothesley_Gauntlet_R_Disable", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_L_Disabler", + "abilityName": "Avatar_Wriothesley_Gauntlet_L_Disabler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_R_Disabler", + "abilityName": "Avatar_Wriothesley_Gauntlet_R_Disabler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_ElementalBurst_Dissolve", + "abilityName": "Avatar_Wriothesley_Gauntlet_ElementalBurst_Dissolve", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_Initialize", + "abilityName": "Avatar_Wriothesley_Gauntlet_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley", + "abilityName": "Avatar_Wriothesley", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_TeamConfig_01BS", + "abilityName": "Avatar_Wriothesley_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_TeamConfig_01Loop", + "abilityName": "Avatar_Wriothesley_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_TeamConfig_01AS", + "abilityName": "Avatar_Wriothesley_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_Gauntlet_Handler", + "abilityName": "Avatar_Wriothesley_Gauntlet_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ExtraAttack_Strike0Wriothesley_ExtraAttack_Constellation_6_CritRate", + "abilityName": "Avatar_Wriothesley_ExtraAttack_Strike0Wriothesley_ExtraAttack_Constellation_6_CritRate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Wriothesley_ExtraAttack_Strike0Wriothesley_ExtraAttack_Constellation_6_CritHurt", + "abilityName": "Avatar_Wriothesley_ExtraAttack_Strike0Wriothesley_ExtraAttack_Constellation_6_CritHurt", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xiangling.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xiangling.json new file mode 100644 index 0000000..b11c016 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xiangling.json @@ -0,0 +1,169 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Xiangling_ExtraAttack_Damage", + "abilityName": "Avatar_Xiangling_ExtraAttack_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_ExtraAttack", + "abilityName": "Avatar_Xiangling_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_ExtraAttack_CreateBullet", + "abilityName": "Avatar_Xiangling_ExtraAttack_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_ExtraAttack_Bullet", + "abilityName": "Avatar_Xiangling_ExtraAttack_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_Eff_Attack_04", + "abilityName": "Avatar_Xiangling_Eff_Attack_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_PandaBornEffect", + "abilityName": "Avatar_Xiangling_PandaBornEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_PandaBornEffect_Run", + "abilityName": "Avatar_Xiangling_PandaBornEffect_Run", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_PandaFire", + "abilityName": "Avatar_Xiangling_PandaFire", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_PandaFire_Run", + "abilityName": "Avatar_Xiangling_PandaFire_Run", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_PandaFireAim", + "abilityName": "Avatar_Xiangling_PandaFireAim", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_PandaFire_Effect", + "abilityName": "Avatar_Xiangling_PandaFire_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_PandaFire_Attack", + "abilityName": "Avatar_Xiangling_PandaFire_Attack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_PandaPepper", + "abilityName": "Avatar_Xiangling_PandaPepper", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_FireCircleSkillStart", + "abilityName": "Avatar_Xiangling_FireCircleSkillStart", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_FireCircle01", + "abilityName": "Avatar_Xiangling_FireCircle01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_FireCircle02", + "abilityName": "Avatar_Xiangling_FireCircle02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_FireCircle03", + "abilityName": "Avatar_Xiangling_FireCircle03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_FireCircle", + "abilityName": "Avatar_Xiangling_FireCircle", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_NormalAttackDamage", + "abilityName": "Avatar_Xiangling_NormalAttackDamage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_FallingAnthem", + "abilityName": "Avatar_Xiangling_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling", + "abilityName": "Avatar_Xiangling", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_TeamConfig_01BS", + "abilityName": "Avatar_Xiangling_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_TeamConfig_01Loop", + "abilityName": "Avatar_Xiangling_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_TeamConfig_01AS", + "abilityName": "Avatar_Xiangling_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_ElementalBurst_Spine", + "abilityName": "Avatar_Xiangling_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_ElementalBurst_BS", + "abilityName": "Avatar_Xiangling_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_ElementalBurst", + "abilityName": "Avatar_Xiangling_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_ElementBurst", + "abilityName": "Avatar_Xiangling_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_ElementalBurst_Hit", + "abilityName": "Avatar_Xiangling_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_elementalBurst_Normal", + "abilityName": "Avatar_Xiangling_elementalBurst_Normal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_Spine_Loop", + "abilityName": "Avatar_Xiangling_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_Spine_Loop_BG", + "abilityName": "Avatar_Xiangling_Spine_Loop_BG", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiangling_Spine", + "abilityName": "Avatar_Xiangling_Spine", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xiao.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xiao.json new file mode 100644 index 0000000..f90ccc7 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xiao.json @@ -0,0 +1,134 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Xiao_ExtraAttack", + "abilityName": "Avatar_Xiao_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_DevilDash_Handler", + "abilityName": "Avatar_Xiao_DevilDash_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_DevilDash_Bullet", + "abilityName": "Avatar_Xiao_DevilDash_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_CloseCollider", + "abilityName": "Avatar_Xiao_CloseCollider", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_FallingAnthem", + "abilityName": "Avatar_Xiao_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_HowlingSoul_CameraController", + "abilityName": "Avatar_Xiao_HowlingSoul_CameraController", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_HowlingSoul", + "abilityName": "Avatar_Xiao_HowlingSoul", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_NormalAttack_DamageHandler", + "abilityName": "Avatar_Xiao_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_CoreSkill", + "abilityName": "Avatar_Xiao_CoreSkill", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_FallingDamageReduction", + "abilityName": "Avatar_Xiao_FallingDamageReduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_ClimbStamina_Reduction", + "abilityName": "Avatar_Xiao_ClimbStamina_Reduction", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_QuestAbility_XiaoTriggerElementalBurst", + "abilityName": "Avatar_QuestAbility_XiaoTriggerElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao", + "abilityName": "Avatar_Xiao", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_Skill_DevilDash", + "abilityName": "Avatar_Xiao_Skill_DevilDash", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_Skill_DevilDash_AS", + "abilityName": "Avatar_Xiao_Skill_DevilDash_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_Skill_DevilDashAir", + "abilityName": "Avatar_Xiao_Skill_DevilDashAir", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_Skill_DevilDashAir_AS", + "abilityName": "Avatar_Xiao_Skill_DevilDashAir_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_TeamConfig_01BS", + "abilityName": "Avatar_Xiao_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_TeamConfig_01Loop", + "abilityName": "Avatar_Xiao_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_TeamConfig_01AS", + "abilityName": "Avatar_Xiao_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_ElementalBurst_Spine", + "abilityName": "Avatar_Xiao_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_ElementalBurst_BS", + "abilityName": "Avatar_Xiao_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_ElementalBurst_Hit", + "abilityName": "Avatar_Xiao_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_Spine_Loop", + "abilityName": "Avatar_Xiao_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_Spine", + "abilityName": "Avatar_Xiao_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xiao_02_Spine", + "abilityName": "Avatar_Xiao_02_Spine", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xingqiu.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xingqiu.json new file mode 100644 index 0000000..812ca6e --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xingqiu.json @@ -0,0 +1,189 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Xingqiu_ExtraAttack", + "abilityName": "Avatar_Xingqiu_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_Spoondrift", + "abilityName": "Avatar_Xingqiu_Spoondrift", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_PhantomShield", + "abilityName": "Avatar_Xingqiu_PhantomShield", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_Minazuki", + "abilityName": "Avatar_Xingqiu_Minazuki", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_Minazuki_Attack01", + "abilityName": "Avatar_Xingqiu_Minazuki_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_Minazuki_Attack02", + "abilityName": "Avatar_Xingqiu_Minazuki_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_Minazuki_Attack03", + "abilityName": "Avatar_Xingqiu_Minazuki_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_PhantomBurst_GainEnergy", + "abilityName": "Avatar_Xingqiu_PhantomBurst_GainEnergy", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_PhantomBurst_Debuff", + "abilityName": "Avatar_Xingqiu_PhantomBurst_Debuff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_DamageHandler", + "abilityName": "Avatar_Xingqiu_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_FallingAnthem", + "abilityName": "Avatar_Xingqiu_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu", + "abilityName": "Avatar_Xingqiu", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_Skill_ElmentalArt_01", + "abilityName": "Avatar_Xingqiu_Skill_ElmentalArt_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_Skill_ElmentalArt_01_AS", + "abilityName": "Avatar_Xingqiu_Skill_ElmentalArt_01_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_Skill_ElmentalBurst", + "abilityName": "Avatar_Xingqiu_Skill_ElmentalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_Skill_ElmentalBurst_AS", + "abilityName": "Avatar_Xingqiu_Skill_ElmentalBurst_AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_TeamConfig_01BS", + "abilityName": "Avatar_Xingqiu_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_TeamConfig_01Loop", + "abilityName": "Avatar_Xingqiu_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_TeamConfig_01AS", + "abilityName": "Avatar_Xingqiu_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementalBurst_Spine", + "abilityName": "Avatar_Xingqiu_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementalBurst_BS", + "abilityName": "Avatar_Xingqiu_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementalBurst", + "abilityName": "Avatar_Xingqiu_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementBurst_01", + "abilityName": "Avatar_Xingqiu_ElementBurst_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementBurst_06", + "abilityName": "Avatar_Xingqiu_ElementBurst_06", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementBurst_02", + "abilityName": "Avatar_Xingqiu_ElementBurst_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementBurst_07", + "abilityName": "Avatar_Xingqiu_ElementBurst_07", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementBurst_03", + "abilityName": "Avatar_Xingqiu_ElementBurst_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementBurst_08", + "abilityName": "Avatar_Xingqiu_ElementBurst_08", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementBurst_04", + "abilityName": "Avatar_Xingqiu_ElementBurst_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementBurst_09", + "abilityName": "Avatar_Xingqiu_ElementBurst_09", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementBurst_05", + "abilityName": "Avatar_Xingqiu_ElementBurst_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementBurst_10", + "abilityName": "Avatar_Xingqiu_ElementBurst_10", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_ElementalBurst_Hit", + "abilityName": "Avatar_Xingqiu_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_elementalBurst_normal", + "abilityName": "Avatar_Xingqiu_elementalBurst_normal", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_elementalBurst_buff", + "abilityName": "Avatar_Xingqiu_elementalBurst_buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_Spine_Loop", + "abilityName": "Avatar_Xingqiu_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xingqiu_Spine", + "abilityName": "Avatar_Xingqiu_Spine", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xinyan.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xinyan.json new file mode 100644 index 0000000..3245e11 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Xinyan.json @@ -0,0 +1,99 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Xinyan_ExtraAttack", + "abilityName": "Avatar_Xinyan_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_ElementalArt_Hit", + "abilityName": "Avatar_Xinyan_ElementalArt_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_ElementalArt_Shield_1", + "abilityName": "Avatar_Xinyan_ElementalArt_Shield_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_ElementalArt_Shield_2", + "abilityName": "Avatar_Xinyan_ElementalArt_Shield_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_ElementalArt_Shield_3", + "abilityName": "Avatar_Xinyan_ElementalArt_Shield_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_ElementalArt", + "abilityName": "Avatar_Xinyan_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_ElementalArt_Shield_3_Explosion", + "abilityName": "Avatar_Xinyan_ElementalArt_Shield_3_Explosion", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_ElementalBurst_Initiate", + "abilityName": "Avatar_Xinyan_ElementalBurst_Initiate", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_ElementalBurst_Hit", + "abilityName": "Avatar_Xinyan_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_ElementalBurst_Effect", + "abilityName": "Avatar_Xinyan_ElementalBurst_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_ElementalBurst_Fire", + "abilityName": "Avatar_Xinyan_ElementalBurst_Fire", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_ElementalBurst_CameraExit", + "abilityName": "Avatar_Xinyan_ElementalBurst_CameraExit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_FallingAnthem", + "abilityName": "Avatar_Xinyan_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_NormalAttack_DamageHandler", + "abilityName": "Avatar_Xinyan_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan", + "abilityName": "Avatar_Xinyan", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_TeamConfig_01BS", + "abilityName": "Avatar_Xinyan_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_TeamConfig_01Loop", + "abilityName": "Avatar_Xinyan_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Xinyan_TeamConfig_01AS", + "abilityName": "Avatar_Xinyan_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_PlayGuitar01_Xinyan", + "abilityName": "Avatar_PlayGuitar01_Xinyan", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yae.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yae.json new file mode 100644 index 0000000..0589344 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yae.json @@ -0,0 +1,224 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Yae_ExtraAttack", + "abilityName": "Avatar_Yae_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ExtraAttack_TriggerBullet", + "abilityName": "Avatar_Yae_ExtraAttack_TriggerBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ExtraAttack_Damage_1", + "abilityName": "Avatar_Yae_ExtraAttack_Damage_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ExtraAttack_Damage_2", + "abilityName": "Avatar_Yae_ExtraAttack_Damage_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ExtraAttack_Damage_3", + "abilityName": "Avatar_Yae_ExtraAttack_Damage_3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ExtraAttack_Damage_4", + "abilityName": "Avatar_Yae_ExtraAttack_Damage_4", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ExtraAttack_Damage_5", + "abilityName": "Avatar_Yae_ExtraAttack_Damage_5", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_Attack_Hit", + "abilityName": "Avatar_Yae_Attack_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_Attack01", + "abilityName": "Avatar_Yae_Attack01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_Attack02", + "abilityName": "Avatar_Yae_Attack02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_Attack03", + "abilityName": "Avatar_Yae_Attack03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_Attack01_Damage", + "abilityName": "Avatar_Yae_Attack01_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_Attack02_Damage", + "abilityName": "Avatar_Yae_Attack02_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_Attack03_Damage", + "abilityName": "Avatar_Yae_Attack03_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalArt_ElderBrain", + "abilityName": "Avatar_Yae_ElementalArt_ElderBrain", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalArt", + "abilityName": "Avatar_Yae_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalArt_Foxtail", + "abilityName": "Avatar_Yae_ElementalArt_Foxtail", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalArt_Retreat_Foxtail", + "abilityName": "Avatar_Yae_ElementalArt_Retreat_Foxtail", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalArt_Foxtail_Remover", + "abilityName": "Avatar_Yae_ElementalArt_Foxtail_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalArt_Air", + "abilityName": "Avatar_Yae_ElementalArt_Air", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_FoxTower_ThunderFall_Level1", + "abilityName": "Avatar_Yae_FoxTower_ThunderFall_Level1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_FoxTower_ThunderFall_Level2", + "abilityName": "Avatar_Yae_FoxTower_ThunderFall_Level2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_FoxTower_ThunderFall_Level3", + "abilityName": "Avatar_Yae_FoxTower_ThunderFall_Level3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_FoxTower_ThunderFall_Level4", + "abilityName": "Avatar_Yae_FoxTower_ThunderFall_Level4", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalBurst_CameraController", + "abilityName": "Avatar_Yae_ElementalBurst_CameraController", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalBurst_PostEffect", + "abilityName": "Avatar_Yae_ElementalBurst_PostEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Yae_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalBurst_Mark_Tower", + "abilityName": "Avatar_Yae_ElementalBurst_Mark_Tower", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalBurst_Clear_Tower", + "abilityName": "Avatar_Yae_ElementalBurst_Clear_Tower", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_PermanentSkill_1", + "abilityName": "Avatar_Yae_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_PermanentSkill_2", + "abilityName": "Avatar_Yae_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_Constellation_6", + "abilityName": "Avatar_Yae_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_FallingAnthem_Foxtail", + "abilityName": "Avatar_Yae_FallingAnthem_Foxtail", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_FallingAnthem", + "abilityName": "Avatar_Yae_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae", + "abilityName": "Avatar_Yae", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_TeamConfig_01BS", + "abilityName": "Avatar_Yae_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_TeamConfig_01Loop", + "abilityName": "Avatar_Yae_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_TeamConfig_01AS", + "abilityName": "Avatar_Yae_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalBurst_Spine", + "abilityName": "Avatar_Yae_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalBurst_BS", + "abilityName": "Avatar_Yae_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalBurst_Hit", + "abilityName": "Avatar_Yae_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_ElementalBurst_Buff", + "abilityName": "Avatar_Yae_ElementalBurst_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yae_Spine_Loop", + "abilityName": "Avatar_Yae_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_YaeMiko", + "abilityName": "Avatar_YaeMiko", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yaoyao.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yaoyao.json new file mode 100644 index 0000000..bd6c35f --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yaoyao.json @@ -0,0 +1,209 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Yaoyao_ExtraAttack", + "abilityName": "Avatar_Yaoyao_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ExtraAttack_CreateBullet", + "abilityName": "Avatar_Yaoyao_ExtraAttack_CreateBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ExtraAttack_Bullet", + "abilityName": "Avatar_Yaoyao_ExtraAttack_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalArt", + "abilityName": "Avatar_Yaoyao_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalArt_CreateRabbit", + "abilityName": "Avatar_Yaoyao_ElementalArt_CreateRabbit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalArt_CreateRabbitM", + "abilityName": "Avatar_Yaoyao_ElementalArt_CreateRabbitM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalArt_CreateGadget", + "abilityName": "Avatar_Yaoyao_ElementalArt_CreateGadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst", + "abilityName": "Avatar_Yaoyao_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst_StrikeL7", + "abilityName": "Avatar_Yaoyao_ElementalBurst_StrikeL7", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst_Strike", + "abilityName": "Avatar_Yaoyao_ElementalBurst_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst_CreateGadget", + "abilityName": "Avatar_Yaoyao_ElementalBurst_CreateGadget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_NormalAttack_DamageHandler", + "abilityName": "Avatar_Yaoyao_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_FallingAnthem", + "abilityName": "Avatar_Yaoyao_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_Turnip_Bullet", + "abilityName": "Avatar_Yaoyao_Turnip_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_Turnip", + "abilityName": "Avatar_Yaoyao_Turnip", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_Golden_Turnip_Bullet", + "abilityName": "Avatar_Yaoyao_Golden_Turnip_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_Golden_Turnip", + "abilityName": "Avatar_Yaoyao_Golden_Turnip", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_Turnip_Bullet_Parabola", + "abilityName": "Avatar_Yaoyao_Turnip_Bullet_Parabola", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalArt_Rabbit", + "abilityName": "Avatar_Yaoyao_ElementalArt_Rabbit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalArt_Rabbit_Throw", + "abilityName": "Avatar_Yaoyao_ElementalArt_Rabbit_Throw", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalArt_CreateGadgeth", + "abilityName": "Avatar_Yaoyao_ElementalArt_CreateGadgeth", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalArt_Rabbit_Throw_Speed_Fix", + "abilityName": "Avatar_Yaoyao_ElementalArt_Rabbit_Throw_Speed_Fix", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst_Rabbit", + "abilityName": "Avatar_Yaoyao_ElementalBurst_Rabbit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst_Rabbit_Throw_Pre", + "abilityName": "Avatar_Yaoyao_ElementalBurst_Rabbit_Throw_Pre", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst_Rabbit_Throw_Pre_BulletTrigger", + "abilityName": "Avatar_Yaoyao_ElementalBurst_Rabbit_Throw_Pre_BulletTrigger", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst_CreateGadgeth", + "abilityName": "Avatar_Yaoyao_ElementalBurst_CreateGadgeth", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst_Rabbit_Throw", + "abilityName": "Avatar_Yaoyao_ElementalBurst_Rabbit_Throw", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_PermanentSkill_1", + "abilityName": "Avatar_Yaoyao_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_PermanentSkill_2", + "abilityName": "Avatar_Yaoyao_PermanentSkill_2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao", + "abilityName": "Avatar_Yaoyao", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalArt_Rabbit_Throw1Avatar_Yaoyao_ElementalArt_Rabbit_Throw_Speed_Fix", + "abilityName": "Avatar_Yaoyao_ElementalArt_Rabbit_Throw1Avatar_Yaoyao_ElementalArt_Rabbit_Throw_Speed_Fix", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_TeamConfig_01BS", + "abilityName": "Avatar_Yaoyao_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_TeamConfig_01Loop", + "abilityName": "Avatar_Yaoyao_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_TeamConfig_01AS", + "abilityName": "Avatar_Yaoyao_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst_Spine", + "abilityName": "Avatar_Yaoyao_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst_BS_Rabbit", + "abilityName": "Avatar_Yaoyao_ElementalBurst_BS_Rabbit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst_BS", + "abilityName": "Avatar_Yaoyao_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementBurst", + "abilityName": "Avatar_Yaoyao_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst_Hit", + "abilityName": "Avatar_Yaoyao_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_ElementalBurst_Buff", + "abilityName": "Avatar_Yaoyao_ElementalBurst_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yaoyao_Spine_Loop", + "abilityName": "Avatar_Yaoyao_Spine_Loop", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yelan.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yelan.json new file mode 100644 index 0000000..fcc89aa --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yelan.json @@ -0,0 +1,474 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Activity_CharAmusement_Yelan_ResetCD", + "abilityName": "Avatar_Activity_CharAmusement_Yelan_ResetCD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Activity_CharAmusement_Yelan_ResetCD_Delay1Avatar_Activity_CharAmusement_Yelan_ResetCD_Delay", + "abilityName": "Avatar_Activity_CharAmusement_Yelan_ResetCD_Delay1Avatar_Activity_CharAmusement_Yelan_ResetCD_Delay", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_PressShoot", + "abilityName": "Avatar_Yelan_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_AimPressShoot", + "abilityName": "Avatar_Yelan_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShootAimingArrow_Charge", + "abilityName": "Avatar_Yelan_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShootArrow_01", + "abilityName": "Avatar_Yelan_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShootArrow_02", + "abilityName": "Avatar_Yelan_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShootArrow_03", + "abilityName": "Avatar_Yelan_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShootArrow_04", + "abilityName": "Avatar_Yelan_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShootArrow_05", + "abilityName": "Avatar_Yelan_ShootArrow_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShootArrow_06", + "abilityName": "Avatar_Yelan_ShootArrow_06", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShootArrow_Aiming", + "abilityName": "Avatar_Yelan_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShootArrow_Bullet", + "abilityName": "Avatar_Yelan_ShootArrow_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShootArrow_Bullet_Last", + "abilityName": "Avatar_Yelan_ShootArrow_Bullet_Last", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShootArrow_Enchanted_WithOutWater", + "abilityName": "Avatar_Yelan_ShootArrow_Enchanted_WithOutWater", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShootArrow_Enchanted_WithWater", + "abilityName": "Avatar_Yelan_ShootArrow_Enchanted_WithWater", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_SneakArrow", + "abilityName": "Avatar_Yelan_SneakArrow", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_Sneak_Shoot", + "abilityName": "Avatar_Yelan_Sneak_Shoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalArt_Check", + "abilityName": "Avatar_Yelan_ElementalArt_Check", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_Initialize", + "abilityName": "Avatar_Yelan_QuietStep_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_Effect", + "abilityName": "Avatar_Yelan_QuietStep_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_Effect_Line", + "abilityName": "Avatar_Yelan_QuietStep_Effect_Line", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_Effect_Line_Remover", + "abilityName": "Avatar_Yelan_QuietStep_Effect_Line_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_Weather", + "abilityName": "Avatar_Yelan_QuietStep_Weather", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_MaxTimer", + "abilityName": "Avatar_Yelan_QuietStep_MaxTimer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_TurndDirection_Add", + "abilityName": "Avatar_Yelan_QuietStep_TurndDirection_Add", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_TurndDirection_Remove", + "abilityName": "Avatar_Yelan_QuietStep_TurndDirection_Remove", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_TurndDirection", + "abilityName": "Avatar_Yelan_QuietStep_TurndDirection", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_StrikeEndEffect", + "abilityName": "Avatar_Yelan_QuietStep_StrikeEndEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_StopEndEffect", + "abilityName": "Avatar_Yelan_QuietStep_StopEndEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_LineStrike_Remover", + "abilityName": "Avatar_Yelan_QuietStep_LineStrike_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalArt_DropBall_Handler", + "abilityName": "Avatar_Yelan_ElementalArt_DropBall_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_Effect_Line_Handler_DelayM", + "abilityName": "Avatar_Yelan_QuietStep_Effect_Line_Handler_DelayM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_Effect_Line_Handler", + "abilityName": "Avatar_Yelan_QuietStep_Effect_Line_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_Effect_Line_Handler_Delay", + "abilityName": "Avatar_Yelan_QuietStep_Effect_Line_Handler_Delay", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_LineStrike", + "abilityName": "Avatar_Yelan_QuietStep_LineStrike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalArt_ScreenEffect", + "abilityName": "Avatar_Yelan_ElementalArt_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_SwitchJumpSprint", + "abilityName": "Avatar_Yelan_QuietStep_SwitchJumpSprint", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalArt_TriggerCollision", + "abilityName": "Avatar_Yelan_ElementalArt_TriggerCollision", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_TriggerConstellation", + "abilityName": "Avatar_Yelan_QuietStep_TriggerConstellation", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_TriggerBullet", + "abilityName": "Avatar_Yelan_QuietStep_TriggerBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_FireBomb", + "abilityName": "Avatar_Yelan_QuietStep_FireBomb", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_TriggerConstellationM", + "abilityName": "Avatar_Yelan_QuietStep_TriggerConstellationM", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_CollisionDetect", + "abilityName": "Avatar_Yelan_QuietStep_CollisionDetect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_ResetSneak", + "abilityName": "Avatar_Yelan_QuietStep_ResetSneak", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_QuietStep_TimeBomb_OnMonster", + "abilityName": "Avatar_Yelan_QuietStep_TimeBomb_OnMonster", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalArt_QuietStep_Bullet", + "abilityName": "Avatar_Yelan_ElementalArt_QuietStep_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst", + "abilityName": "Avatar_Yelan_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Initialize", + "abilityName": "Avatar_Yelan_ElementalBurst_Initialize", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Camera_Effect", + "abilityName": "Avatar_Yelan_ElementalBurst_Camera_Effect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Camera_Handler", + "abilityName": "Avatar_Yelan_ElementalBurst_Camera_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_EmotionControl", + "abilityName": "Avatar_Yelan_ElementalBurst_EmotionControl", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Camera_PushTarget", + "abilityName": "Avatar_Yelan_ElementalBurst_Camera_PushTarget", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Invincible", + "abilityName": "Avatar_Yelan_ElementalBurst_Invincible", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_WeatherChange", + "abilityName": "Avatar_Yelan_ElementalBurst_WeatherChange", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Camera_DungeonEffect", + "abilityName": "Avatar_Yelan_ElementalBurst_Camera_DungeonEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_CameraBlur", + "abilityName": "Avatar_Yelan_ElementalBurst_CameraBlur", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_CreateDice", + "abilityName": "Avatar_Yelan_ElementalBurst_CreateDice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Strike_Damage", + "abilityName": "Avatar_Yelan_ElementalBurst_Strike_Damage", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_PostEffect", + "abilityName": "Avatar_Yelan_ElementalBurst_PostEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_ScreenEffect", + "abilityName": "Avatar_Yelan_ElementalBurst_ScreenEffect", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShareElementalArt_Handler", + "abilityName": "Avatar_Yelan_ShareElementalArt_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ShareElementalArt_TriggerDice", + "abilityName": "Avatar_Yelan_ShareElementalArt_TriggerDice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Dice_TriggerBullet_Extra", + "abilityName": "Avatar_Yelan_ElementalBurst_Dice_TriggerBullet_Extra", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_PostEffectJ", + "abilityName": "Avatar_Yelan_ElementalBurst_PostEffectJ", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_Constellation_6", + "abilityName": "Avatar_Yelan_Constellation_6", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Dice", + "abilityName": "Avatar_Yelan_ElementalBurst_Dice", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_PermanentSkill_2_Handler", + "abilityName": "Avatar_Yelan_PermanentSkill_2_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_PermanentSkill_2_Buff_OnTeam", + "abilityName": "Avatar_Yelan_PermanentSkill_2_Buff_OnTeam", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_PermanentSkill_2_Buff", + "abilityName": "Avatar_Yelan_PermanentSkill_2_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Dice_TriggerBullet", + "abilityName": "Avatar_Yelan_ElementalBurst_Dice_TriggerBullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Dice_Bullet_01", + "abilityName": "Avatar_Yelan_ElementalBurst_Dice_Bullet_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_FallingAnthem", + "abilityName": "Avatar_Yelan_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_PermanentSkill_1", + "abilityName": "Avatar_Yelan_PermanentSkill_1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_PermanentSkill_1_Handler", + "abilityName": "Avatar_Yelan_PermanentSkill_1_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_PermanentSkill_1_Buff", + "abilityName": "Avatar_Yelan_PermanentSkill_1_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_PermanentSkill_1_Buff_Lv1", + "abilityName": "Avatar_Yelan_PermanentSkill_1_Buff_Lv1", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_PermanentSkill_1_Buff_Lv2", + "abilityName": "Avatar_Yelan_PermanentSkill_1_Buff_Lv2", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_PermanentSkill_1_Buff_Lv3", + "abilityName": "Avatar_Yelan_PermanentSkill_1_Buff_Lv3", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_PermanentSkill_1_Buff_Lv4", + "abilityName": "Avatar_Yelan_PermanentSkill_1_Buff_Lv4", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Dice_Bullet_Extra", + "abilityName": "Avatar_Yelan_ElementalBurst_Dice_Bullet_Extra", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_Constellatin_4_Handler", + "abilityName": "Avatar_Yelan_Constellatin_4_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_Constellatin_4_Timer", + "abilityName": "Avatar_Yelan_Constellatin_4_Timer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_Constellation_6_BuffTimer", + "abilityName": "Avatar_Yelan_Constellation_6_BuffTimer", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_Constellation_6_StateHandler", + "abilityName": "Avatar_Yelan_Constellation_6_StateHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_Constellation_6_State", + "abilityName": "Avatar_Yelan_Constellation_6_State", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_SneakArrow_Extra_Before", + "abilityName": "Avatar_Yelan_SneakArrow_Extra_Before", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_SneakArrow_Extra_After", + "abilityName": "Avatar_Yelan_SneakArrow_Extra_After", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan", + "abilityName": "Avatar_Yelan", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Dice_TriggerBullet4Avatar_Yelan_ElementalBurst_Dice_TriggerBullet_Extra", + "abilityName": "Avatar_Yelan_ElementalBurst_Dice_TriggerBullet4Avatar_Yelan_ElementalBurst_Dice_TriggerBullet_Extra", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_TeamConfig_01BS", + "abilityName": "Avatar_Yelan_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_TeamConfig_01Loop", + "abilityName": "Avatar_Yelan_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_TeamConfig_01AS", + "abilityName": "Avatar_Yelan_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yelan_ElementalBurst_Dice_TriggerBullet_Extra4Avatar_Yelan_ElementalBurst_Dice_TriggerBullet_Extra", + "abilityName": "Avatar_Yelan_ElementalBurst_Dice_TriggerBullet_Extra4Avatar_Yelan_ElementalBurst_Dice_TriggerBullet_Extra", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yoimiya.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yoimiya.json new file mode 100644 index 0000000..c5603ba --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yoimiya.json @@ -0,0 +1,239 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Yoimiya_PressShoot", + "abilityName": "Avatar_Yoimiya_PressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_AimPressShoot", + "abilityName": "Avatar_Yoimiya_AimPressShoot", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ShootArrow_01", + "abilityName": "Avatar_Yoimiya_ShootArrow_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_FireShoot_State", + "abilityName": "Avatar_Yoimiya_FireShoot_State", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ShootArrow_01_01", + "abilityName": "Avatar_Yoimiya_ShootArrow_01_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ShootArrow_02", + "abilityName": "Avatar_Yoimiya_ShootArrow_02", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ShootArrow_03", + "abilityName": "Avatar_Yoimiya_ShootArrow_03", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ShootArrow_04", + "abilityName": "Avatar_Yoimiya_ShootArrow_04", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ShootArrow_04_01", + "abilityName": "Avatar_Yoimiya_ShootArrow_04_01", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ShootArrow_05", + "abilityName": "Avatar_Yoimiya_ShootArrow_05", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ShootAimingArrow_Charge", + "abilityName": "Avatar_Yoimiya_ShootAimingArrow_Charge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ShootArrow_Aiming", + "abilityName": "Avatar_Yoimiya_ShootArrow_Aiming", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalArt_DropBall", + "abilityName": "Avatar_Yoimiya_ElementalArt_DropBall", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalArt", + "abilityName": "Avatar_Yoimiya_ElementalArt", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_Stack_Num", + "abilityName": "Avatar_Yoimiya_Stack_Num", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_Camera", + "abilityName": "Avatar_Yoimiya_ElementalBurst_Camera", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst", + "abilityName": "Avatar_Yoimiya_ElementalBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_SetTag", + "abilityName": "Avatar_Yoimiya_ElementalBurst_SetTag", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_MonsterInTag", + "abilityName": "Avatar_Yoimiya_ElementalBurst_MonsterInTag", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_Count", + "abilityName": "Avatar_Yoimiya_ElementalBurst_Count", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_Tag", + "abilityName": "Avatar_Yoimiya_ElementalBurst_Tag", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_TimeCount", + "abilityName": "Avatar_Yoimiya_ElementalBurst_TimeCount", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_EffectDone", + "abilityName": "Avatar_Yoimiya_ElementalBurst_EffectDone", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_InTriggerCD", + "abilityName": "Avatar_Yoimiya_ElementalBurst_InTriggerCD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_BombAttackCD", + "abilityName": "Avatar_Yoimiya_ElementalBurst_BombAttackCD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_BombAttackEvent", + "abilityName": "Avatar_Yoimiya_ElementalBurst_BombAttackEvent", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_WhenMonsterOnKill", + "abilityName": "Avatar_Yoimiya_ElementalBurst_WhenMonsterOnKill", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_Tag1UNIQUE_Avatar_Yoimiya_ElementalBurst_BombAttackCD", + "abilityName": "Avatar_Yoimiya_ElementalBurst_Tag1UNIQUE_Avatar_Yoimiya_ElementalBurst_BombAttackCD", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_TagJ", + "abilityName": "Avatar_Yoimiya_ElementalBurst_TagJ", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_FallingAnthem", + "abilityName": "Avatar_Yoimiya_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya", + "abilityName": "Avatar_Yoimiya", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_TeamConfig_01BS", + "abilityName": "Avatar_Yoimiya_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_TeamConfig_01Loop", + "abilityName": "Avatar_Yoimiya_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_TeamConfig_01AS", + "abilityName": "Avatar_Yoimiya_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "AvatarItem_Yoimiya_Turquoise", + "abilityName": "AvatarItem_Yoimiya_Turquoise", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_Spine", + "abilityName": "Avatar_Yoimiya_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementBurst", + "abilityName": "Avatar_Yoimiya_ElementBurst", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_BS", + "abilityName": "Avatar_Yoimiya_ElementalBurst_BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_Hit", + "abilityName": "Avatar_Yoimiya_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_Hit_Buff", + "abilityName": "Avatar_Yoimiya_ElementalBurst_Hit_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_Spine_Loop", + "abilityName": "Avatar_Yoimiya_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_Spine", + "abilityName": "Avatar_Yoimiya_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_Spine_Loop_BG", + "abilityName": "Avatar_Yoimiya_Spine_Loop_BG", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yoimiya_ElementalBurst_Spine_Star", + "abilityName": "Avatar_Yoimiya_ElementalBurst_Spine_Star", + "abilityOverride": "" + }, + { + "abilityID": "AvatarItem_Yoimiya_Turquoise_01_TurquoiseShine", + "abilityName": "AvatarItem_Yoimiya_Turquoise_01_TurquoiseShine", + "abilityOverride": "" + }, + { + "abilityID": "AvatarItem_Yoimiya_Turquoise_01_Outside", + "abilityName": "AvatarItem_Yoimiya_Turquoise_01_Outside", + "abilityOverride": "" + }, + { + "abilityID": "AvatarItem_Yoimiya_Turquoise_01_Inside", + "abilityName": "AvatarItem_Yoimiya_Turquoise_01_Inside", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yunjin.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yunjin.json new file mode 100644 index 0000000..e594dc3 --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Yunjin.json @@ -0,0 +1,119 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Yunjin_NormalAttack_DamageHandler", + "abilityName": "Avatar_Yunjin_NormalAttack_DamageHandler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_ExtraAttack", + "abilityName": "Avatar_Yunjin_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_ExtraAttack_Cast", + "abilityName": "Avatar_Yunjin_ExtraAttack_Cast", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_ExtraAttack_Bullet", + "abilityName": "Avatar_Yunjin_ExtraAttack_Bullet", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_FallingAnthem", + "abilityName": "Avatar_Yunjin_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_ElementalArt_Handler", + "abilityName": "Avatar_Yunjin_ElementalArt_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_ElementalArt_Remover", + "abilityName": "Avatar_Yunjin_ElementalArt_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_Kaoqi", + "abilityName": "Avatar_Yunjin_Kaoqi", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_Kaoqi_Reset", + "abilityName": "Avatar_Yunjin_Kaoqi_Reset", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_Kaoqi_Remover", + "abilityName": "Avatar_Yunjin_Kaoqi_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_ElementalArt_Strike", + "abilityName": "Avatar_Yunjin_ElementalArt_Strike", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_ElementalArt_Strike_VFX", + "abilityName": "Avatar_Yunjin_ElementalArt_Strike_VFX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_ElementalArt_Strike_Weather", + "abilityName": "Avatar_Yunjin_ElementalArt_Strike_Weather", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_ElementalBurst_Cast", + "abilityName": "Avatar_Yunjin_ElementalBurst_Cast", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_ElementalBurst_Buff_Handler", + "abilityName": "Avatar_Yunjin_ElementalBurst_Buff_Handler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_ElementalBurst_Buff", + "abilityName": "Avatar_Yunjin_ElementalBurst_Buff", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_ElementalBurst_Reset", + "abilityName": "Avatar_Yunjin_ElementalBurst_Reset", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_ElementalBurst_Buff_VFX", + "abilityName": "Avatar_Yunjin_ElementalBurst_Buff_VFX", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_Buff_VFX_Remover", + "abilityName": "Avatar_Yunjin_Buff_VFX_Remover", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin", + "abilityName": "Avatar_Yunjin", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_TeamConfig_01BS", + "abilityName": "Avatar_Yunjin_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_TeamConfig_01Loop", + "abilityName": "Avatar_Yunjin_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Yunjin_TeamConfig_01AS", + "abilityName": "Avatar_Yunjin_TeamConfig_01AS", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Zhongli.json b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Zhongli.json new file mode 100644 index 0000000..eea546e --- /dev/null +++ b/NahidaImpact.Common/assets/binout/avatar/ConfigAvatar_Zhongli.json @@ -0,0 +1,94 @@ +{ + "abilities": [ + { + "abilityID": "Avatar_Zhongli_ExtraAttack", + "abilityName": "Avatar_Zhongli_ExtraAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_PillarOrShield_HoldCharge", + "abilityName": "Avatar_Zhongli_PillarOrShield_HoldCharge", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_SetHairEmissionScaler", + "abilityName": "Avatar_Zhongli_SetHairEmissionScaler", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_PrimoPillar", + "abilityName": "Avatar_Zhongli_PrimoPillar", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_RockShield", + "abilityName": "Avatar_Zhongli_RockShield", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_GeoOrder", + "abilityName": "Avatar_Zhongli_GeoOrder", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_RockFever", + "abilityName": "Avatar_Zhongli_RockFever", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_NormalAttack", + "abilityName": "Avatar_Zhongli_NormalAttack", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_FallingAnthem", + "abilityName": "Avatar_Zhongli_FallingAnthem", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli", + "abilityName": "Avatar_Zhongli", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_TeamConfig_01BS", + "abilityName": "Avatar_Zhongli_TeamConfig_01BS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_TeamConfig_01Loop", + "abilityName": "Avatar_Zhongli_TeamConfig_01Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_TeamConfig_01AS", + "abilityName": "Avatar_Zhongli_TeamConfig_01AS", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_ElementalBurst_Spine", + "abilityName": "Avatar_Zhongli_ElementalBurst_Spine", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_ElementalBurst_Hit", + "abilityName": "Avatar_Zhongli_ElementalBurst_Hit", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_Spine_Loop", + "abilityName": "Avatar_Zhongli_Spine_Loop", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_Spine_Loop_Cloud", + "abilityName": "Avatar_Zhongli_Spine_Loop_Cloud", + "abilityOverride": "" + }, + { + "abilityID": "Avatar_Zhongli_Sub_Spine", + "abilityName": "Avatar_Zhongli_Sub_Spine", + "abilityOverride": "" + } + ] +} \ No newline at end of file diff --git a/NahidaImpact.Common/assets/excel/AvatarExcelConfigData.json b/NahidaImpact.Common/assets/excel/AvatarExcelConfigData.json new file mode 100644 index 0000000..5fcb30c --- /dev/null +++ b/NahidaImpact.Common/assets/excel/AvatarExcelConfigData.json @@ -0,0 +1,6978 @@ +[ + { + "attackBase": 5.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [ + 900011, + 900013, + 900015 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 67993194395036856, + "controllerPathHashSuffix": 31925045831370702, + "controllerPathRemoteHashSuffix": 51066636618558810, + "coopPicNameHashSuffix": 12079677100145829, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 8.0, + "descTextMapHash": 1731825193, + "featureTagGroupId": 10000001, + "gachaCardNameHashSuffix": 67325049465262287, + "gachaImageNameHashSuffix": 64425982164741827, + "hpBase": 166.0, + "iconName": "UI_AvatarIcon_Kate", + "id": 10000001, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 1731825193, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 55136124680407829, + "nameTextMapHash": 1857915418, + "prefabPathHashSuffix": 4729135519363573, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 38333527116904810, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Kate", + "skillDepotId": 101, + "staminaRecoverSpeed": 25.0, + "sus2": 48054748594336654, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 37586259490057407, + "attackBase": 26.62660026550293, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [ + 900021, + 900023, + 900025 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 29750952775514445, + "controllerPathHashSuffix": 10481317711184430, + "controllerPathRemoteHashSuffix": 27392606648342357, + "coopPicNameHashSuffix": 26289165543991019, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 61.0265998840332, + "descTextMapHash": 3703438153, + "featureTagGroupId": 10000002, + "gachaCardNameHashSuffix": 65003405011446227, + "gachaImageNameHashSuffix": 1814941436481979, + "hpBase": 1000.9860229492188, + "iconName": "UI_AvatarIcon_Ayaka", + "id": 10000002, + "imageName": "AvatarImage_Forward_Ayaka", + "infoDesc": 3703438153, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 63914156148086446, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 10744411933528157, + "nameTextMapHash": 1006042610, + "prefabPathHashSuffix": 57624638487017099, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 59454437435635448, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Ayaka", + "skillDepotId": 201, + "staminaRecoverSpeed": 25.0, + "sus2": 40320947422027908, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 23264276287511081, + "attackBase": 18.6200008392334, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 3, + "avatarPromoteRewardIdList": [ + 900031, + 900033, + 900035 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 61672267365925266, + "controllerPathHashSuffix": 53654500955750258, + "controllerPathRemoteHashSuffix": 32978720839070425, + "coopPicNameHashSuffix": 38236531943509897, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 59.83000183105469, + "descTextMapHash": 2215890689, + "featureTagGroupId": 10000003, + "gachaCardNameHashSuffix": 17340147289864998, + "gachaImageNameHashSuffix": 1058948451911271, + "hpBase": 1143.9840087890625, + "iconName": "UI_AvatarIcon_Qin", + "id": 10000003, + "imageName": "AvatarImage_Forward_Qin", + "infoDesc": 2215890689, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 60016550768591920, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 34703781099415905, + "nameTextMapHash": 3221566250, + "prefabPathHashSuffix": 28088385793817621, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 35160856317600406, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Qin", + "skillDepotId": 301, + "staminaRecoverSpeed": 25.0, + "sus2": 45993404325253442, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 44625665225343027, + "attackBase": 17.808000564575195, + "avatarPromoteId": 12, + "avatarPromoteRewardIdList": [ + 900041, + 900043, + 900045 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [ + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508 + ], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 13383278528739272, + "controllerPathHashSuffix": 67990429820005776, + "controllerPathRemoteHashSuffix": 67998805597939105, + "coopPicNameHashSuffix": 8063451862365749, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 57.224998474121094, + "descTextMapHash": 1204666377, + "featureTagGroupId": 10000005, + "gachaCardNameHashSuffix": 32488295342263905, + "gachaImageNameHashSuffix": 26194120514597975, + "hpBase": 911.791015625, + "iconName": "UI_AvatarIcon_PlayerBoy", + "id": 10000005, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 1204666377, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 14608035605869221, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 61067059128597498, + "nameTextMapHash": 1533656818, + "prefabPathHashSuffix": 22462465405445373, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 70809297694408876, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_PlayerBoy", + "skillDepotId": 501, + "staminaRecoverSpeed": 25.0, + "sus2": 27058246392752221, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 52490081346670258, + "attackBase": 19.410720825195312, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 4, + "avatarPromoteRewardIdList": [ + 900051, + 900053, + 900055 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 3199372562900809, + "controllerPathHashSuffix": 48577681241205214, + "controllerPathRemoteHashSuffix": 42761088285288451, + "coopPicNameHashSuffix": 19975736133798087, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 48.069000244140625, + "descTextMapHash": 1387136209, + "featureTagGroupId": 10000006, + "gachaCardNameHashSuffix": 24416828757338715, + "gachaImageNameHashSuffix": 39289452589804909, + "hpBase": 802.3760986328125, + "iconName": "UI_AvatarIcon_Lisa", + "id": 10000006, + "imageName": "AvatarImage_Forward_Lisa", + "infoDesc": 1387136209, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 188013948855021, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 63224086081781506, + "nameTextMapHash": 3344622722, + "prefabPathHashSuffix": 34775716490008848, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 8535564099549497, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Lisa", + "skillDepotId": 601, + "staminaRecoverSpeed": 25.0, + "sus2": 49284560419708108, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 30842113957440995, + "attackBase": 17.808000564575195, + "avatarPromoteId": 12, + "avatarPromoteRewardIdList": [ + 900041, + 900043, + 900045 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [ + 701, + 702, + 703, + 704, + 705, + 706, + 707, + 708 + ], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 54221268921681145, + "controllerPathHashSuffix": 12416350102524079, + "controllerPathRemoteHashSuffix": 24898322031678616, + "coopPicNameHashSuffix": 5045455510201004, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 57.224998474121094, + "descTextMapHash": 4261991457, + "featureTagGroupId": 10000007, + "gachaCardNameHashSuffix": 2237732668697872, + "gachaImageNameHashSuffix": 1173333778840641, + "hpBase": 911.791015625, + "iconName": "UI_AvatarIcon_PlayerGirl", + "id": 10000007, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 4261991457, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 49568657561956636, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 14355509100224805, + "nameTextMapHash": 3816664530, + "prefabPathHashSuffix": 44995531660349586, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 50398996291630039, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_PlayerGirl", + "skillDepotId": 701, + "staminaRecoverSpeed": 25.0, + "sus2": 63955032245690167, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 15258407521967203, + "attackBase": 13.355999946594238, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 14, + "avatarPromoteRewardIdList": [ + 900061, + 900063, + 900065 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 10394159936229226, + "controllerPathHashSuffix": 67131178205010242, + "controllerPathRemoteHashSuffix": 67770814987800289, + "coopPicNameHashSuffix": 50158293335157311, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 56.080501556396484, + "descTextMapHash": 1566920073, + "featureTagGroupId": 10000014, + "gachaCardNameHashSuffix": 45913353403136913, + "gachaImageNameHashSuffix": 31814185058597875, + "hpBase": 820.6118774414062, + "iconName": "UI_AvatarIcon_Barbara", + "id": 10000014, + "imageName": "AvatarImage_Forward_Barbara", + "infoDesc": 1566920073, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 58231159407731119, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 49275936119924959, + "nameTextMapHash": 3775299170, + "prefabPathHashSuffix": 9877182645380618, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 8387207851265062, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Barbara", + "skillDepotId": 1401, + "staminaRecoverSpeed": 25.0, + "sus2": 26620946874056788, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 66215477942073589, + "attackBase": 18.698400497436523, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 15, + "avatarPromoteRewardIdList": [ + 900071, + 900073, + 900075 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_MALE", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 63007350652895025, + "controllerPathHashSuffix": 20720829920718380, + "controllerPathRemoteHashSuffix": 41231330786233421, + "coopPicNameHashSuffix": 45434992700586722, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 66.38099670410156, + "descTextMapHash": 783578577, + "featureTagGroupId": 10000015, + "gachaCardNameHashSuffix": 3491449406289574, + "gachaImageNameHashSuffix": 62643934460303460, + "hpBase": 975.6163940429688, + "iconName": "UI_AvatarIcon_Kaeya", + "id": 10000015, + "imageName": "AvatarImage_Forward_Qin", + "infoDesc": 783578577, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 15046296002080769, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 35722281200448464, + "nameTextMapHash": 4119663210, + "prefabPathHashSuffix": 4873479393824556, + "prefabPathRagdollHashSuffix": 69125965490831506, + "prefabPathRemoteHashSuffix": 34971172025407716, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 44689199583546995, + "sideIconName": "UI_AvatarIcon_Side_Kaeya", + "skillDepotId": 1501, + "staminaRecoverSpeed": 25.0, + "sus2": 8495729732976220, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 21748010646299129, + "attackBase": 26.06800079345703, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 16, + "avatarPromoteRewardIdList": [ + 900081, + 900083, + 900085 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_MALE", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 31821148526733024, + "controllerPathHashSuffix": 44625155045306852, + "controllerPathRemoteHashSuffix": 6880576258158376, + "coopPicNameHashSuffix": 6862583061892051, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 61.0265998840332, + "descTextMapHash": 2413312897, + "featureTagGroupId": 10000016, + "gachaCardNameHashSuffix": 67401174416576776, + "gachaImageNameHashSuffix": 495486962927556, + "hpBase": 1010.5192260742188, + "iconName": "UI_AvatarIcon_Diluc", + "id": 10000016, + "imageName": "AvatarImage_Forward_Diluc", + "infoDesc": 2413312897, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 58240550837326454, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 44218883974830672, + "nameTextMapHash": 3608180322, + "prefabPathHashSuffix": 47412781750660915, + "prefabPathRagdollHashSuffix": 69125965490831506, + "prefabPathRemoteHashSuffix": 4216492936342423, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 44689199583546995, + "sideIconName": "UI_AvatarIcon_Side_Diluc", + "skillDepotId": 1601, + "staminaRecoverSpeed": 25.0, + "sus2": 24408953241489423, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 65097177661216778, + "attackBase": 19.58880043029785, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 20, + "avatarPromoteRewardIdList": [ + 900091, + 900093, + 900095 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 16200384224295442, + "controllerPathHashSuffix": 33629350941214564, + "controllerPathRemoteHashSuffix": 20448356556368992, + "coopPicNameHashSuffix": 71705496519551928, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 62.9474983215332, + "descTextMapHash": 3901895113, + "featureTagGroupId": 10000020, + "gachaCardNameHashSuffix": 38256149591356395, + "gachaImageNameHashSuffix": 48977896792575350, + "hpBase": 1002.9700927734375, + "iconName": "UI_AvatarIcon_Razor", + "id": 10000020, + "imageName": "AvatarImage_Forward_Qin", + "infoDesc": 3901895113, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 10384179725348804, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 56211296096927830, + "nameTextMapHash": 4160147242, + "prefabPathHashSuffix": 44315004257837616, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 27814281682905743, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Razor", + "skillDepotId": 2001, + "staminaRecoverSpeed": 25.0, + "sus2": 49643630083604521, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 6432421957120109, + "attackBase": 18.698400497436523, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 21, + "avatarPromoteRewardIdList": [ + 900101, + 900103, + 900105 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 43616678842210213, + "controllerPathHashSuffix": 5310977256323425, + "controllerPathRemoteHashSuffix": 42081331251873186, + "coopPicNameHashSuffix": 11648177938659346, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 50.358001708984375, + "descTextMapHash": 3898061993, + "featureTagGroupId": 10000021, + "gachaCardNameHashSuffix": 16440683144765141, + "gachaImageNameHashSuffix": 54176313983837348, + "hpBase": 793.2581787109375, + "iconName": "UI_AvatarIcon_Ambor", + "id": 10000021, + "imageName": "AvatarImage_Forward_Ambor", + "infoDesc": 3898061993, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 24317511667745306, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 4194109828463941, + "nameTextMapHash": 1966438658, + "prefabPathHashSuffix": 46869931188902037, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 52319115143806373, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Ambor", + "skillDepotId": 2101, + "staminaRecoverSpeed": 25.0, + "sus2": 56650876020255509, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 32971882206531143, + "attackBase": 20.48200035095215, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 22, + "avatarPromoteRewardIdList": [ + 900111, + 900113, + 900115 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 19443443006926429, + "controllerPathHashSuffix": 17716338645585000, + "controllerPathRemoteHashSuffix": 23446666760204235, + "coopPicNameHashSuffix": 48110201312531130, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 52.052101135253906, + "descTextMapHash": 4137166409, + "featureTagGroupId": 10000022, + "gachaCardNameHashSuffix": 10871662789297867, + "gachaImageNameHashSuffix": 54546373515007127, + "hpBase": 819.855224609375, + "iconName": "UI_AvatarIcon_Venti", + "id": 10000022, + "imageName": "AvatarImage_Forward_Venti", + "infoDesc": 4137166409, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 9408188408756386, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 54230430319150174, + "nameTextMapHash": 2466140362, + "prefabPathHashSuffix": 32463664539220042, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 57715650157100650, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Venti", + "skillDepotId": 2201, + "staminaRecoverSpeed": 25.0, + "sus2": 15625304908172568, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 45920683878379005, + "attackBase": 18.876480102539062, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 23, + "avatarPromoteRewardIdList": [ + 900121, + 900123, + 900125 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 3816740328479746, + "controllerPathHashSuffix": 67256853231090966, + "controllerPathRemoteHashSuffix": 23003191225164392, + "coopPicNameHashSuffix": 53440327001162157, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 56.080501556396484, + "descTextMapHash": 2058084377, + "featureTagGroupId": 10000023, + "gachaCardNameHashSuffix": 49446897114936339, + "gachaImageNameHashSuffix": 33817351123789477, + "hpBase": 911.791015625, + "iconName": "UI_AvatarIcon_Xiangling", + "id": 10000023, + "imageName": "AvatarImage_Forward_Xiangling", + "infoDesc": 2058084377, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 62181421986790477, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 53222219423014270, + "nameTextMapHash": 1130996346, + "prefabPathHashSuffix": 14359347824811046, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 3792859130466051, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Xiangling", + "skillDepotId": 2301, + "staminaRecoverSpeed": 25.0, + "sus2": 14994198666208809, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 59925700168999361, + "attackBase": 18.876480102539062, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 24, + "avatarPromoteRewardIdList": [ + 900131, + 900133, + 900135 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 29545113761628818, + "controllerPathHashSuffix": 376641566499084, + "controllerPathRemoteHashSuffix": 4944869963549275, + "coopPicNameHashSuffix": 40563784465460171, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 54.36375045776367, + "descTextMapHash": 2910785993, + "featureTagGroupId": 10000024, + "gachaCardNameHashSuffix": 61571577178584653, + "gachaImageNameHashSuffix": 70921118593670741, + "hpBase": 1094.149169921875, + "iconName": "UI_AvatarIcon_Beidou", + "id": 10000024, + "imageName": "AvatarImage_Forward_Beidou", + "infoDesc": 2910785993, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51922278462929565, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 13764496340184223, + "nameTextMapHash": 2646367730, + "prefabPathHashSuffix": 30416206508044436, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 6659157137131756, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Beidou", + "skillDepotId": 2401, + "staminaRecoverSpeed": 25.0, + "sus2": 8008859883252079, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 528261845237054, + "attackBase": 16.917600631713867, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 25, + "avatarPromoteRewardIdList": [ + 900141, + 900143, + 900145 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 1673986470126541, + "controllerPathHashSuffix": 8669642003896132, + "controllerPathRemoteHashSuffix": 9674772600281975, + "coopPicNameHashSuffix": 57114468927989662, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 63.51974868774414, + "descTextMapHash": 3660176857, + "featureTagGroupId": 10000025, + "gachaCardNameHashSuffix": 55617337537335202, + "gachaImageNameHashSuffix": 54339597555237266, + "hpBase": 857.0835571289062, + "iconName": "UI_AvatarIcon_Xingqiu", + "id": 10000025, + "imageName": "AvatarImage_Forward_Xingqiu", + "infoDesc": 3660176857, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 67867281073217556, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 26055241024474980, + "nameTextMapHash": 4197635682, + "prefabPathHashSuffix": 5342587295070358, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 17015116518881514, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Xingqiu", + "skillDepotId": 2501, + "staminaRecoverSpeed": 25.0, + "sus2": 41207367550303847, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 10924488166847306, + "attackBase": 27.185199737548828, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 26, + "avatarPromoteRewardIdList": [ + 900151, + 900153, + 900155 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 40871637160292133, + "controllerPathHashSuffix": 5279640043054520, + "controllerPathRemoteHashSuffix": 56864332815763025, + "coopPicNameHashSuffix": 611813323718468, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 62.223201751708984, + "descTextMapHash": 2789047073, + "featureTagGroupId": 10000026, + "gachaCardNameHashSuffix": 4031602458543164, + "gachaImageNameHashSuffix": 70121741080803867, + "hpBase": 991.4528198242188, + "iconName": "UI_AvatarIcon_Xiao", + "id": 10000026, + "imageName": "AvatarImage_Forward_Xiao", + "infoDesc": 2789047073, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 36610126763193057, + "manekinMotionConfig": 106, + "manekinPathHashSuffix": 24015640456027919, + "nameTextMapHash": 1021947690, + "prefabPathHashSuffix": 24035487814926473, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 63851420641411065, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Xiao", + "skillDepotId": 2601, + "staminaRecoverSpeed": 25.0, + "sus2": 37402532464346046, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 31492020451023039, + "attackBase": 17.808000564575195, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 27, + "avatarPromoteRewardIdList": [ + 900161, + 900163, + 900165 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 67246291688339866, + "controllerPathHashSuffix": 47483443822182181, + "controllerPathRemoteHashSuffix": 31110937851516617, + "coopPicNameHashSuffix": 6373219962271805, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 48.069000244140625, + "descTextMapHash": 2174640361, + "featureTagGroupId": 10000027, + "gachaCardNameHashSuffix": 5746591691470561, + "gachaImageNameHashSuffix": 44802598630502902, + "hpBase": 820.6118774414062, + "iconName": "UI_AvatarIcon_Ningguang", + "id": 10000027, + "imageName": "AvatarImage_Forward_Lisa", + "infoDesc": 2174640361, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 38403349820008422, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 70243595918247789, + "nameTextMapHash": 4127888970, + "prefabPathHashSuffix": 44953941820941238, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 47819141919130558, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Ningguang", + "skillDepotId": 2701, + "staminaRecoverSpeed": 25.0, + "sus2": 7474280422247739, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 13889313662228327, + "attackBase": 24.20599937438965, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 29, + "avatarPromoteRewardIdList": [ + 900171, + 900173, + 900175 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LOLI", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 34218053528216797, + "controllerPathHashSuffix": 36911268966884242, + "controllerPathRemoteHashSuffix": 172514394571745, + "coopPicNameHashSuffix": 55167067734202848, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 47.86399841308594, + "descTextMapHash": 2313554193, + "featureTagGroupId": 10000029, + "gachaCardNameHashSuffix": 42834723514634811, + "gachaImageNameHashSuffix": 43209797225244112, + "hpBase": 800.788818359375, + "iconName": "UI_AvatarIcon_Klee", + "id": 10000029, + "imageName": "AvatarImage_Forward_Klee", + "infoDesc": 2313554193, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 15333351275342238, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 11681899097060511, + "nameTextMapHash": 3339083250, + "prefabPathHashSuffix": 43285034988275796, + "prefabPathRagdollHashSuffix": 58123400587505344, + "prefabPathRemoteHashSuffix": 43065485306752619, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 47538393428685098, + "sideIconName": "UI_AvatarIcon_Side_Klee", + "skillDepotId": 2901, + "staminaRecoverSpeed": 25.0, + "sus2": 14604717556856125, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 13719838641055449, + "attackBase": 19.551000595092773, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 30, + "avatarPromoteRewardIdList": [ + 900181, + 900183, + 900185 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_MALE", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 8189796438664362, + "controllerPathHashSuffix": 17191515452038642, + "controllerPathRemoteHashSuffix": 22807089757215909, + "coopPicNameHashSuffix": 49607994055078028, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 57.436798095703125, + "descTextMapHash": 2898546105, + "featureTagGroupId": 10000030, + "gachaCardNameHashSuffix": 27968743716226304, + "gachaImageNameHashSuffix": 39543137957564065, + "hpBase": 1143.9840087890625, + "iconName": "UI_AvatarIcon_Zhongli", + "id": 10000030, + "imageName": "AvatarImage_Forward_Diluc", + "infoDesc": 2898546105, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 17199790401423074, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 24885700087709796, + "nameTextMapHash": 3862787418, + "prefabPathHashSuffix": 27995279496376124, + "prefabPathRagdollHashSuffix": 69125965490831506, + "prefabPathRemoteHashSuffix": 35178784289944086, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 44689199583546995, + "sideIconName": "UI_AvatarIcon_Side_Zhongli", + "skillDepotId": 3001, + "staminaRecoverSpeed": 25.0, + "sus2": 57832392292535288, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 41758764700506483, + "attackBase": 20.47920036315918, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 31, + "avatarPromoteRewardIdList": [ + 900191, + 900193, + 900195 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 19982185161598016, + "controllerPathHashSuffix": 47310652924819412, + "controllerPathRemoteHashSuffix": 46297921910866133, + "coopPicNameHashSuffix": 49498257552787928, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 49.78575134277344, + "descTextMapHash": 1695621873, + "featureTagGroupId": 10000031, + "gachaCardNameHashSuffix": 71530043446044261, + "gachaImageNameHashSuffix": 17114964723339001, + "hpBase": 770.46337890625, + "iconName": "UI_AvatarIcon_Fischl", + "id": 10000031, + "imageName": "AvatarImage_Forward_Fischl", + "infoDesc": 1695621873, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 71796304225112944, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 25720399749759274, + "nameTextMapHash": 3277782506, + "prefabPathHashSuffix": 37762464602789932, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 62167866612148455, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Fischl", + "skillDepotId": 3101, + "staminaRecoverSpeed": 25.0, + "sus2": 18894998704607918, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 71973666028814382, + "attackBase": 16.02720069885254, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 32, + "avatarPromoteRewardIdList": [ + 900201, + 900203, + 900205 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 13458219780893542, + "controllerPathHashSuffix": 44409046041637866, + "controllerPathRemoteHashSuffix": 45476234543138119, + "coopPicNameHashSuffix": 43398932330820513, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 64.66425323486328, + "descTextMapHash": 3696214329, + "featureTagGroupId": 10000032, + "gachaCardNameHashSuffix": 41855536820057669, + "gachaImageNameHashSuffix": 67437644341376943, + "hpBase": 1039.4417724609375, + "iconName": "UI_AvatarIcon_Bennett", + "id": 10000032, + "imageName": "AvatarImage_Forward_Bennett", + "infoDesc": 3696214329, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 72050863458483641, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 38919111604700447, + "nameTextMapHash": 968893378, + "prefabPathHashSuffix": 12815615982935695, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 23261231501756705, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Bennett", + "skillDepotId": 3201, + "staminaRecoverSpeed": 25.0, + "sus2": 55042918888309107, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 64894346273983933, + "attackBase": 23.461200714111328, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 33, + "avatarPromoteRewardIdList": [ + 900211, + 900213, + 900215 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_MALE", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 21065096112180909, + "controllerPathHashSuffix": 35895252042618892, + "controllerPathRemoteHashSuffix": 30978846546545629, + "coopPicNameHashSuffix": 61833775822127357, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 63.4197998046875, + "descTextMapHash": 1915755417, + "featureTagGroupId": 10000033, + "gachaCardNameHashSuffix": 49530897473930409, + "gachaImageNameHashSuffix": 39747399055818976, + "hpBase": 1020.0524291992188, + "iconName": "UI_AvatarIcon_Tartaglia", + "id": 10000033, + "imageName": "AvatarImage_Forward_Tartaglia", + "infoDesc": 1915755417, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 32566765252010587, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 2577560858786911, + "nameTextMapHash": 3847143266, + "prefabPathHashSuffix": 417767213356437, + "prefabPathRagdollHashSuffix": 69125965490831506, + "prefabPathRemoteHashSuffix": 30092816527280062, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 44689199583546995, + "sideIconName": "UI_AvatarIcon_Side_Tartaglia", + "skillDepotId": 3301, + "staminaRecoverSpeed": 25.0, + "sus2": 66343613398574628, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 32186609503794943, + "attackBase": 16.02720069885254, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 34, + "avatarPromoteRewardIdList": [ + 900221, + 900223, + 900225 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 22515614773599372, + "controllerPathHashSuffix": 1781057693406310, + "controllerPathRemoteHashSuffix": 19553049617824904, + "coopPicNameHashSuffix": 69018849188974899, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 66.9532470703125, + "descTextMapHash": 1136975897, + "featureTagGroupId": 10000034, + "gachaCardNameHashSuffix": 7216333160797346, + "gachaImageNameHashSuffix": 7268194596507953, + "hpBase": 1012.0880126953125, + "iconName": "UI_AvatarIcon_Noel", + "id": 10000034, + "imageName": "AvatarImage_Forward_Noel", + "infoDesc": 1136975897, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 42137241133076684, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 44763276791365983, + "nameTextMapHash": 1921418842, + "prefabPathHashSuffix": 24699451555960668, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 71516227783405562, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Noel", + "skillDepotId": 3401, + "staminaRecoverSpeed": 25.0, + "sus2": 24768126479181811, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 63424757581039671, + "attackBase": 22.3439998626709, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 35, + "avatarPromoteRewardIdList": [ + 900231, + 900233, + 900235 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LOLI", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 888886955831067, + "controllerPathHashSuffix": 70139524778006043, + "controllerPathRemoteHashSuffix": 42671377569239230, + "coopPicNameHashSuffix": 14387630223620815, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 71.7959976196289, + "descTextMapHash": 3128332321, + "featureTagGroupId": 10000035, + "gachaCardNameHashSuffix": 59482148473171790, + "gachaImageNameHashSuffix": 2320478083981607, + "hpBase": 962.8532104492188, + "iconName": "UI_AvatarIcon_Qiqi", + "id": 10000035, + "imageName": "AvatarImage_Forward_Qin", + "infoDesc": 3128332321, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 21103396321503871, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 61864003452999403, + "nameTextMapHash": 168956722, + "prefabPathHashSuffix": 42880077393031947, + "prefabPathRagdollHashSuffix": 12381997878214711, + "prefabPathRemoteHashSuffix": 34809203104559891, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 47538393428685098, + "sideIconName": "UI_AvatarIcon_Side_Qiqi", + "skillDepotId": 3501, + "staminaRecoverSpeed": 25.0, + "sus2": 54767824078054506, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 46848351571939843, + "attackBase": 18.698400497436523, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 36, + "avatarPromoteRewardIdList": [ + 900241, + 900243, + 900245 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 19154515614013404, + "controllerPathHashSuffix": 2018865034796379, + "controllerPathRemoteHashSuffix": 50838074252691357, + "coopPicNameHashSuffix": 44103868572484714, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 54.36375045776367, + "descTextMapHash": 572700337, + "featureTagGroupId": 10000036, + "gachaCardNameHashSuffix": 2280192104911768, + "gachaImageNameHashSuffix": 47125267983039294, + "hpBase": 920.908935546875, + "iconName": "UI_AvatarIcon_Chongyun", + "id": 10000036, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 572700337, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 70798572856700460, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 41379525357015452, + "nameTextMapHash": 2876340530, + "prefabPathHashSuffix": 47222167689903383, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 41679268336972438, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Chongyun", + "skillDepotId": 3601, + "staminaRecoverSpeed": 25.0, + "sus2": 53023268642133745, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 12242543327825791, + "attackBase": 26.06800079345703, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 37, + "avatarPromoteRewardIdList": [ + 900251, + 900253, + 900255 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 20586702263389536, + "controllerPathHashSuffix": 28084181829633200, + "controllerPathRemoteHashSuffix": 20133305245405827, + "coopPicNameHashSuffix": 40087786419158941, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 49.06060028076172, + "descTextMapHash": 313187777, + "featureTagGroupId": 10000037, + "gachaCardNameHashSuffix": 60531139811218888, + "gachaImageNameHashSuffix": 14676624608780081, + "hpBase": 762.656005859375, + "iconName": "UI_AvatarIcon_Ganyu", + "id": 10000037, + "imageName": "AvatarImage_Forward_Fischl", + "infoDesc": 313187777, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 32263514169199902, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 18277245107644069, + "nameTextMapHash": 2679781122, + "prefabPathHashSuffix": 46702521270259908, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 1694711068794541, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Ganyu", + "skillDepotId": 3701, + "staminaRecoverSpeed": 25.0, + "sus2": 3101491740743512, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 9795925303062769, + "attackBase": 19.551000595092773, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 38, + "avatarPromoteRewardIdList": [ + 900261, + 900263, + 900265 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 24498890298247219, + "controllerPathHashSuffix": 1792025443311836, + "controllerPathRemoteHashSuffix": 2220806724804688, + "coopPicNameHashSuffix": 2280966329777689, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 68.2061996459961, + "descTextMapHash": 3544652497, + "featureTagGroupId": 10000038, + "gachaCardNameHashSuffix": 52407065023904882, + "gachaImageNameHashSuffix": 26645928747796850, + "hpBase": 1029.5855712890625, + "iconName": "UI_AvatarIcon_Albedo", + "id": 10000038, + "imageName": "AvatarImage_Forward_Albedo", + "infoDesc": 3544652497, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 54058067477631116, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 8071328102994596, + "nameTextMapHash": 4108620722, + "prefabPathHashSuffix": 10011941771373859, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 11025142292305546, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Albedo", + "skillDepotId": 3801, + "staminaRecoverSpeed": 25.0, + "sus2": 15823697077465659, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 30002845491934090, + "attackBase": 17.808000564575195, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 39, + "avatarPromoteRewardIdList": [ + 900271, + 900273, + 900275 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LOLI", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 3231895744017760, + "controllerPathHashSuffix": 25150228432339770, + "controllerPathRemoteHashSuffix": 69371559472418473, + "coopPicNameHashSuffix": 10950397577022607, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 50.358001708984375, + "descTextMapHash": 3149724857, + "featureTagGroupId": 10000039, + "gachaCardNameHashSuffix": 10865805694499342, + "gachaImageNameHashSuffix": 24441290062101016, + "hpBase": 802.3760986328125, + "iconName": "UI_AvatarIcon_Diona", + "id": 10000039, + "imageName": "AvatarImage_Forward_Diona", + "infoDesc": 3149724857, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 7853015972120703, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 13786782354610188, + "nameTextMapHash": 1468367538, + "prefabPathHashSuffix": 22027636368802546, + "prefabPathRagdollHashSuffix": 12381997878214711, + "prefabPathRemoteHashSuffix": 65410629155625777, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 47538393428685098, + "sideIconName": "UI_AvatarIcon_Side_Diona", + "skillDepotId": 3901, + "staminaRecoverSpeed": 25.0, + "sus2": 7036607745426034, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 53543966099476347, + "attackBase": 22.3439998626709, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 41, + "avatarPromoteRewardIdList": [ + 900281, + 900283, + 900285 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 52161817562944965, + "controllerPathHashSuffix": 61535905243362162, + "controllerPathRemoteHashSuffix": 4421842511154225, + "coopPicNameHashSuffix": 65393023597415793, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 50.855499267578125, + "descTextMapHash": 506249649, + "featureTagGroupId": 10000041, + "gachaCardNameHashSuffix": 71577307003612054, + "gachaImageNameHashSuffix": 67661387539395219, + "hpBase": 810.322021484375, + "iconName": "UI_AvatarIcon_Mona", + "id": 10000041, + "imageName": "AvatarImage_Forward_Mona", + "infoDesc": 506249649, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 34266971006286276, + "manekinMotionConfig": 106, + "manekinPathHashSuffix": 15717558822010441, + "nameTextMapHash": 1113306282, + "prefabPathHashSuffix": 48617088078880981, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 70183195846741975, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Mona", + "skillDepotId": 4101, + "staminaRecoverSpeed": 25.0, + "sus2": 4776949034669630, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 20007120403299767, + "attackBase": 25.136999130249023, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 42, + "avatarPromoteRewardIdList": [ + 900291, + 900293, + 900295 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 53783538838312405, + "controllerPathHashSuffix": 12416350102524079, + "controllerPathRemoteHashSuffix": 26055060758198288, + "coopPicNameHashSuffix": 66712676582815637, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 62.223201751708984, + "descTextMapHash": 2249961857, + "featureTagGroupId": 10000042, + "gachaCardNameHashSuffix": 13988550244942878, + "gachaImageNameHashSuffix": 29277478669678425, + "hpBase": 1020.0524291992188, + "iconName": "UI_AvatarIcon_Keqing", + "id": 10000042, + "imageName": "AvatarImage_Forward_Keqing", + "infoDesc": 2249961857, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 58231020244449418, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 38370457317491599, + "nameTextMapHash": 1864015138, + "prefabPathHashSuffix": 41658809662486818, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 23419624369495015, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Keqing", + "skillDepotId": 4201, + "staminaRecoverSpeed": 25.0, + "sus2": 63955032245690167, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 63799243175669728, + "attackBase": 14.246399879455566, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 43, + "avatarPromoteRewardIdList": [ + 900301, + 900303, + 900305 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 22087021631628268, + "controllerPathHashSuffix": 15526604860786504, + "controllerPathRemoteHashSuffix": 1880448574864987, + "coopPicNameHashSuffix": 71240916145790443, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 58.941749572753906, + "descTextMapHash": 4249311673, + "featureTagGroupId": 10000043, + "gachaCardNameHashSuffix": 19986039646427573, + "gachaImageNameHashSuffix": 35779443067891613, + "hpBase": 775.0223388671875, + "iconName": "UI_AvatarIcon_Sucrose", + "id": 10000043, + "imageName": "AvatarImage_Forward_Sucrose", + "infoDesc": 4249311673, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 41629484382965801, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 54090696259133443, + "nameTextMapHash": 1053433018, + "prefabPathHashSuffix": 65167501008151532, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 17705433980902798, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Sucrose", + "skillDepotId": 4301, + "staminaRecoverSpeed": 25.0, + "sus2": 31450449342930286, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 1658671323840144, + "attackBase": 20.835359573364258, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 44, + "avatarPromoteRewardIdList": [ + 900311, + 900313, + 900315 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 4006557509487748, + "controllerPathHashSuffix": 26843427291679410, + "controllerPathRemoteHashSuffix": 11194524541718808, + "coopPicNameHashSuffix": 37613208561827049, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 66.9532470703125, + "descTextMapHash": 2430683361, + "featureTagGroupId": 10000044, + "gachaCardNameHashSuffix": 10431995544991778, + "gachaImageNameHashSuffix": 21387477197555285, + "hpBase": 939.1447143554688, + "iconName": "UI_AvatarIcon_Xinyan", + "id": 10000044, + "imageName": "AvatarImage_Forward_Xinyan", + "infoDesc": 2430683361, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 38481791436746842, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 72022398788641274, + "nameTextMapHash": 4273845410, + "prefabPathHashSuffix": 56115881198930356, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 59019966635599302, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Xinyan", + "skillDepotId": 4401, + "staminaRecoverSpeed": 25.0, + "sus2": 32894917793894119, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 67509527995430521, + "attackBase": 20.12303924560547, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 45, + "avatarPromoteRewardIdList": [ + 900321, + 900323, + 900325 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 53131180340648163, + "controllerPathHashSuffix": 60224036651407988, + "controllerPathRemoteHashSuffix": 28356285094364614, + "coopPicNameHashSuffix": 22464311227604623, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 59.513999938964844, + "descTextMapHash": 1025256649, + "featureTagGroupId": 10000045, + "gachaCardNameHashSuffix": 20588185401240524, + "gachaImageNameHashSuffix": 30522069816582260, + "hpBase": 1030.3238525390625, + "iconName": "UI_AvatarIcon_Rosaria", + "id": 10000045, + "imageName": "AvatarImage_Forward_Rosaria", + "infoDesc": 1025256649, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 6846158217882137, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 69356258804744471, + "nameTextMapHash": 4260733330, + "prefabPathHashSuffix": 19737351553885405, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 30155316588230123, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Rosaria", + "skillDepotId": 4501, + "staminaRecoverSpeed": 25.0, + "sus2": 58593596814712370, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 51325013703818405, + "attackBase": 8.285900115966797, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 46, + "avatarPromoteRewardIdList": [ + 900331, + 900333, + 900335 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 11194888182686654, + "controllerPathHashSuffix": 71662487909780009, + "controllerPathRemoteHashSuffix": 43081719924505610, + "coopPicNameHashSuffix": 25372205290156122, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 68.2061996459961, + "descTextMapHash": 223073489, + "featureTagGroupId": 10000046, + "gachaCardNameHashSuffix": 7058728386438376, + "gachaImageNameHashSuffix": 4715635661920505, + "hpBase": 1210.7164306640625, + "iconName": "UI_AvatarIcon_Hutao", + "id": 10000046, + "imageName": "AvatarImage_Forward_Hutao", + "infoDesc": 223073489, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 44814963339948164, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 20938221158846202, + "nameTextMapHash": 1940919994, + "prefabPathHashSuffix": 70476148743107607, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 23822253181270044, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Hutao", + "skillDepotId": 4601, + "staminaRecoverSpeed": 25.0, + "sus2": 5506720550357097, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 43846655236992503, + "attackBase": 23.08880043029785, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 47, + "avatarPromoteRewardIdList": [ + 900341, + 900343, + 900345 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 47426194264597195, + "controllerPathHashSuffix": 19638346585721422, + "controllerPathRemoteHashSuffix": 5534107556599501, + "coopPicNameHashSuffix": 40107205026266325, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 62.82149887084961, + "descTextMapHash": 174508593, + "featureTagGroupId": 10000047, + "gachaCardNameHashSuffix": 19698890058246947, + "gachaImageNameHashSuffix": 2284615411338034, + "hpBase": 1039.1187744140625, + "iconName": "UI_AvatarIcon_Kazuha", + "id": 10000047, + "imageName": "AvatarImage_Forward_Kazuha", + "infoDesc": 174508593, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 14731369573779768, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 17777503318328495, + "nameTextMapHash": 88505754, + "prefabPathHashSuffix": 38977007912560943, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 60030356958444267, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Kazuha", + "skillDepotId": 4701, + "staminaRecoverSpeed": 25.0, + "sus2": 11312229336730971, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 9935292241800919, + "attackBase": 20.12303924560547, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 48, + "avatarPromoteRewardIdList": [ + 900351, + 900353, + 900355 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 24085249138405381, + "controllerPathHashSuffix": 16432065307303008, + "controllerPathRemoteHashSuffix": 10346358482575327, + "coopPicNameHashSuffix": 65878288186824910, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 49.2135009765625, + "descTextMapHash": 1827440433, + "featureTagGroupId": 10000048, + "gachaCardNameHashSuffix": 67264408195335079, + "gachaImageNameHashSuffix": 31357034275666242, + "hpBase": 784.1402587890625, + "iconName": "UI_AvatarIcon_Feiyan", + "id": 10000048, + "imageName": "AvatarImage_Forward_Feiyan", + "infoDesc": 1827440433, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 70724002172807981, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 25135373674784709, + "nameTextMapHash": 697277554, + "prefabPathHashSuffix": 4009953622786098, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 44543661752936764, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Feiyan", + "skillDepotId": 4801, + "staminaRecoverSpeed": 25.0, + "sus2": 14899561664498916, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 34231573984513949, + "attackBase": 25.136999130249023, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 49, + "avatarPromoteRewardIdList": [ + 900361, + 900363, + 900365 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 30774025030637157, + "controllerPathHashSuffix": 54490978630138197, + "controllerPathRemoteHashSuffix": 50136734298451220, + "coopPicNameHashSuffix": 44318985393388117, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 47.86399841308594, + "descTextMapHash": 1813152017, + "featureTagGroupId": 10000049, + "gachaCardNameHashSuffix": 49023507692874429, + "gachaImageNameHashSuffix": 15895688907251922, + "hpBase": 791.255615234375, + "iconName": "UI_AvatarIcon_Yoimiya", + "id": 10000049, + "imageName": "AvatarImage_Forward_Yoimiya", + "infoDesc": 1813152017, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 53366301512471609, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 23773225050858901, + "nameTextMapHash": 2504399314, + "prefabPathHashSuffix": 63971970477101517, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 173084889334166, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Yoimiya", + "skillDepotId": 4901, + "staminaRecoverSpeed": 25.0, + "sus2": 1353696840772887, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 44911236670160418, + "attackBase": 16.917600631713867, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 50, + "avatarPromoteRewardIdList": [ + 900371, + 900373, + 900375 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_MALE", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 52559090966008846, + "controllerPathHashSuffix": 13003018487513551, + "controllerPathRemoteHashSuffix": 36647493383767306, + "coopPicNameHashSuffix": 15650745975754148, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 62.9474983215332, + "descTextMapHash": 3062484009, + "featureTagGroupId": 10000050, + "gachaCardNameHashSuffix": 35570205593745184, + "gachaImageNameHashSuffix": 53584253427504898, + "hpBase": 866.2014770507812, + "iconName": "UI_AvatarIcon_Tohma", + "id": 10000050, + "imageName": "AvatarImage_Forward_Tohma", + "infoDesc": 3062484009, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 60104752074543265, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 39725816755842136, + "nameTextMapHash": 3555115602, + "prefabPathHashSuffix": 23943456747611599, + "prefabPathRagdollHashSuffix": 69125965490831506, + "prefabPathRemoteHashSuffix": 15418930598474087, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 44689199583546995, + "sideIconName": "UI_AvatarIcon_Side_Tohma", + "skillDepotId": 5001, + "staminaRecoverSpeed": 25.0, + "sus2": 54557583508205187, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 12591855305686003, + "attackBase": 26.62660026550293, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 51, + "avatarPromoteRewardIdList": [ + 900381, + 900383, + 900385 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 35234222296913357, + "controllerPathHashSuffix": 47017942792144709, + "controllerPathRemoteHashSuffix": 64927400881012168, + "coopPicNameHashSuffix": 4220446586011208, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 58.45391082763672, + "descTextMapHash": 490802649, + "featureTagGroupId": 10000051, + "gachaCardNameHashSuffix": 36548040977799534, + "gachaImageNameHashSuffix": 68453648416930486, + "hpBase": 1029.5855712890625, + "iconName": "UI_AvatarIcon_Eula", + "id": 10000051, + "imageName": "AvatarImage_Forward_Eula", + "infoDesc": 490802649, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 56887130854870504, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 30576985118832533, + "nameTextMapHash": 3717667418, + "prefabPathHashSuffix": 34539627090156692, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 30989807470153350, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Eula", + "skillDepotId": 5101, + "staminaRecoverSpeed": 25.0, + "sus2": 23092937084025093, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 65520092829190316, + "attackBase": 26.254199981689453, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 52, + "avatarPromoteRewardIdList": [ + 900401, + 900403, + 900405 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 42624755433541288, + "controllerPathHashSuffix": 63096398878964443, + "controllerPathRemoteHashSuffix": 21539691419062143, + "coopPicNameHashSuffix": 27232118059498199, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 61.445411682128906, + "descTextMapHash": 553307289, + "featureTagGroupId": 10000052, + "gachaCardNameHashSuffix": 26132200168511315, + "gachaImageNameHashSuffix": 66841636084590893, + "hpBase": 1004.7992553710938, + "iconName": "UI_AvatarIcon_Shougun", + "id": 10000052, + "imageName": "AvatarImage_Forward_Shougun", + "infoDesc": 553307289, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 46840202741247940, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 56663301525058101, + "nameTextMapHash": 3024507506, + "prefabPathHashSuffix": 53790971495656883, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 25599337640736116, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Shougun", + "skillDepotId": 5201, + "staminaRecoverSpeed": 25.0, + "sus2": 46489995536984143, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 19843083991973948, + "attackBase": 20.47920036315918, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 53, + "avatarPromoteRewardIdList": [ + 900391, + 900393, + 900395 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LOLI", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 51673558231736075, + "controllerPathHashSuffix": 63556748206457334, + "controllerPathRemoteHashSuffix": 65917081766789859, + "coopPicNameHashSuffix": 50983763406945867, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 62.43247604370117, + "descTextMapHash": 3029516969, + "featureTagGroupId": 10000053, + "gachaCardNameHashSuffix": 6842199147064060, + "gachaImageNameHashSuffix": 12318251835160409, + "hpBase": 993.8521728515625, + "iconName": "UI_AvatarIcon_Sayu", + "id": 10000053, + "imageName": "AvatarImage_Forward_Sayu", + "infoDesc": 3029516969, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 42227626436875638, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 20234876941667621, + "nameTextMapHash": 2388785242, + "prefabPathHashSuffix": 69110441157490995, + "prefabPathRagdollHashSuffix": 12381997878214711, + "prefabPathRemoteHashSuffix": 52965196649775419, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 47538393428685098, + "sideIconName": "UI_AvatarIcon_Side_Sayu", + "skillDepotId": 5301, + "staminaRecoverSpeed": 25.0, + "sus": 37295368538913710, + "sus2": 23710961733014766, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 25955310826649227, + "attackBase": 18.247600555419922, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 54, + "avatarPromoteRewardIdList": [ + 900421, + 900423, + 900425 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 11713792659703375, + "controllerPathHashSuffix": 38526939101824414, + "controllerPathRemoteHashSuffix": 69237184916411890, + "coopPicNameHashSuffix": 16919684248201438, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 51.1546516418457, + "descTextMapHash": 505027577, + "featureTagGroupId": 10000054, + "gachaCardNameHashSuffix": 58797961658071713, + "gachaImageNameHashSuffix": 15614054451763355, + "hpBase": 1048.6519775390625, + "iconName": "UI_AvatarIcon_Kokomi", + "id": 10000054, + "imageName": "AvatarImage_Forward_Kokomi", + "infoDesc": 505027577, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 11997593508218957, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 59067685385549476, + "nameTextMapHash": 3914045794, + "prefabPathHashSuffix": 70202536191603521, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 44516399313701247, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Kokomi", + "skillDepotId": 5401, + "staminaRecoverSpeed": 25.0, + "sus2": 68449363807632884, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 33916490879459572, + "attackBase": 15.31488037109375, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 55, + "avatarPromoteRewardIdList": [ + 900451, + 900453, + 900455 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 71089723336209886, + "controllerPathHashSuffix": 52244626238837774, + "controllerPathRemoteHashSuffix": 37045724950808877, + "coopPicNameHashSuffix": 63299309501043811, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 54.36375045776367, + "descTextMapHash": 2692321673, + "featureTagGroupId": 10000055, + "gachaCardNameHashSuffix": 61995069685559144, + "gachaImageNameHashSuffix": 43193546684931624, + "hpBase": 802.3760986328125, + "iconName": "UI_AvatarIcon_Gorou", + "id": 10000055, + "imageName": "AvatarImage_Forward_Gorou", + "infoDesc": 2692321673, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 33315853617070447, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 53435427624379084, + "nameTextMapHash": 3400133546, + "prefabPathHashSuffix": 60508531846457759, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 25401772739059923, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Gorou", + "skillDepotId": 5501, + "staminaRecoverSpeed": 25.0, + "sus2": 16820751499687951, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 63927937012626056, + "attackBase": 16.383359909057617, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 56, + "avatarPromoteRewardIdList": [ + 900411, + 900413, + 900415 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 50987469428553042, + "controllerPathHashSuffix": 41612033516582399, + "controllerPathRemoteHashSuffix": 37474551912818907, + "coopPicNameHashSuffix": 11627710289712832, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 52.64699935913086, + "descTextMapHash": 148777793, + "featureTagGroupId": 10000056, + "gachaCardNameHashSuffix": 5585664422267788, + "gachaImageNameHashSuffix": 61430401226981711, + "hpBase": 802.3760986328125, + "iconName": "UI_AvatarIcon_Sara", + "id": 10000056, + "imageName": "AvatarImage_Forward_Sara", + "infoDesc": 148777793, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 17455717915957354, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 44330895406622779, + "nameTextMapHash": 1483922610, + "prefabPathHashSuffix": 19138628013166600, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 45130107112839915, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Sara", + "skillDepotId": 5601, + "staminaRecoverSpeed": 25.0, + "sus2": 45033729963212391, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 29331841099941549, + "attackBase": 17.68899917602539, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 57, + "avatarPromoteRewardIdList": [ + 900441, + 900443, + 900445 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_MALE", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 12497953253359203, + "controllerPathHashSuffix": 6034934281520578, + "controllerPathRemoteHashSuffix": 26322537225391621, + "coopPicNameHashSuffix": 52810912686917042, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 74.66783905029297, + "descTextMapHash": 3512498385, + "featureTagGroupId": 10000057, + "gachaCardNameHashSuffix": 59279924797517419, + "gachaImageNameHashSuffix": 67857441140592586, + "hpBase": 1000.9860229492188, + "iconName": "UI_AvatarIcon_Itto", + "id": 10000057, + "imageName": "AvatarImage_Forward_Itto", + "infoDesc": 3512498385, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 49214590960598445, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 52085010385127613, + "nameTextMapHash": 3068316954, + "prefabPathHashSuffix": 12144898852558423, + "prefabPathRagdollHashSuffix": 69125965490831506, + "prefabPathRemoteHashSuffix": 18328858493239545, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 44689199583546995, + "sideIconName": "UI_AvatarIcon_Side_Itto", + "skillDepotId": 5701, + "staminaRecoverSpeed": 25.0, + "sus2": 24563132238915810, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 37827955735091958, + "attackBase": 26.440399169921875, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 58, + "avatarPromoteRewardIdList": [ + 900481, + 900483, + 900485 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 60709890741154682, + "controllerPathHashSuffix": 36391916234976517, + "controllerPathRemoteHashSuffix": 9168506761581807, + "coopPicNameHashSuffix": 6689249057719280, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 44.274200439453125, + "descTextMapHash": 1170085417, + "featureTagGroupId": 10000058, + "gachaCardNameHashSuffix": 20161751847509155, + "gachaImageNameHashSuffix": 21963705799370569, + "hpBase": 807.4620361328125, + "iconName": "UI_AvatarIcon_Yae", + "id": 10000058, + "imageName": "AvatarImage_Forward_Yae", + "infoDesc": 1170085417, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 6304875960715594, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 64043467842382130, + "nameTextMapHash": 2713453234, + "prefabPathHashSuffix": 31873589346299602, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 67749847971978406, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Yae", + "skillDepotId": 5801, + "staminaRecoverSpeed": 25.0, + "sus2": 37559368195480191, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 41689773545424503, + "attackBase": 18.876480102539062, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 59, + "avatarPromoteRewardIdList": [ + 900521, + 900523, + 900525 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 4114597402232592, + "controllerPathHashSuffix": 57891874937580998, + "controllerPathRemoteHashSuffix": 67125266558119912, + "coopPicNameHashSuffix": 15185146321376970, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 57.33945083618164, + "descTextMapHash": 3971624201, + "featureTagGroupId": 10000059, + "gachaCardNameHashSuffix": 60237042332356779, + "gachaImageNameHashSuffix": 35172397304007523, + "hpBase": 893.55517578125, + "iconName": "UI_AvatarIcon_Heizo", + "id": 10000059, + "imageName": "AvatarImage_Forward_Heizo", + "infoDesc": 3971624201, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 28019988660415380, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 22901015600797048, + "nameTextMapHash": 646032090, + "prefabPathHashSuffix": 6506996508727517, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 41204341248457072, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Heizo", + "skillDepotId": 5901, + "staminaRecoverSpeed": 25.0, + "sus2": 43491423922078173, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 22862513319809597, + "attackBase": 18.992399215698242, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 60, + "avatarPromoteRewardIdList": [ + 900501, + 900503, + 900505 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 2525466945005867, + "controllerPathHashSuffix": 35664028565237688, + "controllerPathRemoteHashSuffix": 10569174430784172, + "coopPicNameHashSuffix": 60600431748745174, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 42.658790588378906, + "descTextMapHash": 2689854257, + "featureTagGroupId": 10000060, + "gachaCardNameHashSuffix": 33661587357722127, + "gachaImageNameHashSuffix": 68376885918690775, + "hpBase": 1124.9176025390625, + "iconName": "UI_AvatarIcon_Yelan", + "id": 10000060, + "imageName": "AvatarImage_Forward_Yelan", + "infoDesc": 2689854257, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 14392029451614046, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 12896065333070175, + "nameTextMapHash": 2848374378, + "prefabPathHashSuffix": 37963859527964259, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 28230714446227794, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Yelan", + "skillDepotId": 6001, + "staminaRecoverSpeed": 25.0, + "sus2": 62963128410257794, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 33327582967990193, + "attackBase": 18.698400497436523, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 61, + "avatarPromoteRewardIdList": [ + 900691, + 900693, + 900695 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 68494577595931545, + "controllerPathHashSuffix": 15409471311948475, + "controllerPathRemoteHashSuffix": 36442982477967870, + "coopPicNameHashSuffix": 55674454609680122, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 45.779998779296875, + "descTextMapHash": 3108007489, + "featureTagGroupId": 10000061, + "gachaCardNameHashSuffix": 43690428823990913, + "gachaImageNameHashSuffix": 35521925735318226, + "hpBase": 1021.2059326171875, + "iconName": "UI_AvatarIcon_Momoka", + "id": 10000061, + "imageName": "AvatarImage_Forward_Momoka", + "infoDesc": 3108007489, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 35117895497260476, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 5925168471707986, + "nameTextMapHash": 1456643042, + "prefabPathHashSuffix": 45513571354098713, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 9343297704536489, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Momoka", + "skillDepotId": 6101, + "staminaRecoverSpeed": 25.0, + "sus2": 7616955116913518, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 57109166966669895, + "attackBase": 18.210359573364258, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 62, + "avatarPromoteRewardIdList": [ + 900431, + 900433, + 900435 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 42008566566260843, + "controllerPathHashSuffix": 5127146514448497, + "controllerPathRemoteHashSuffix": 31325766123445425, + "coopPicNameHashSuffix": 39159556148641688, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 52.65039825439453, + "descTextMapHash": 2468599457, + "featureTagGroupId": 10000062, + "gachaCardNameHashSuffix": 1125746417280931, + "gachaImageNameHashSuffix": 69314598937424811, + "hpBase": 848.4547729492188, + "iconName": "UI_AvatarIcon_Aloy", + "id": 10000062, + "imageName": "AvatarImage_Forward_Aloy", + "infoDesc": 2468599457, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 36551572141888856, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 69800413746500478, + "nameTextMapHash": 3689108098, + "prefabPathHashSuffix": 6033126892624703, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 10275591553238494, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE_SP", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Aloy", + "skillDepotId": 6201, + "staminaRecoverSpeed": 25.0, + "sus2": 2751157909975534, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 29137246692370707, + "attackBase": 23.64739990234375, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 63, + "avatarPromoteRewardIdList": [ + 900461, + 900463, + 900465 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 16570437878343003, + "controllerPathHashSuffix": 53827865146910722, + "controllerPathRemoteHashSuffix": 67988738443674937, + "coopPicNameHashSuffix": 42244020122096881, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 64.61640167236328, + "descTextMapHash": 373064729, + "featureTagGroupId": 10000063, + "gachaCardNameHashSuffix": 23585581436885651, + "gachaImageNameHashSuffix": 53168679852632708, + "hpBase": 1011.4725341796875, + "iconName": "UI_AvatarIcon_Shenhe", + "id": 10000063, + "imageName": "AvatarImage_Forward_Shenhe", + "infoDesc": 373064729, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 69014543677821785, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 7785684905715412, + "nameTextMapHash": 334242634, + "prefabPathHashSuffix": 4004763566688259, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 36995765379726258, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Shenhe", + "skillDepotId": 6301, + "staminaRecoverSpeed": 25.0, + "sus2": 17369584518555421, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 24119154129100093, + "attackBase": 16.02720069885254, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 64, + "avatarPromoteRewardIdList": [ + 900471, + 900473, + 900475 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 68878240295010917, + "controllerPathHashSuffix": 6912336961287236, + "controllerPathRemoteHashSuffix": 55792259298597060, + "coopPicNameHashSuffix": 7635273496148199, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 61.574100494384766, + "descTextMapHash": 4037633993, + "featureTagGroupId": 10000064, + "gachaCardNameHashSuffix": 19929398367543264, + "gachaImageNameHashSuffix": 707480368625422, + "hpBase": 893.55517578125, + "iconName": "UI_AvatarIcon_Yunjin", + "id": 10000064, + "imageName": "AvatarImage_Forward_Yunjin", + "infoDesc": 4037633993, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 68348095950424252, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 47090978846904145, + "nameTextMapHash": 655825874, + "prefabPathHashSuffix": 49066682390724309, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 25302019694464850, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Yunjin", + "skillDepotId": 6401, + "staminaRecoverSpeed": 25.0, + "sus2": 1714901831498747, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 68738542996283151, + "attackBase": 17.808000564575195, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 65, + "avatarPromoteRewardIdList": [ + 900511, + 900513, + 900515 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 22964036922333814, + "controllerPathHashSuffix": 25890798040075272, + "controllerPathRemoteHashSuffix": 7925499058421192, + "coopPicNameHashSuffix": 3601945174890309, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 62.9474983215332, + "descTextMapHash": 738455441, + "featureTagGroupId": 10000065, + "gachaCardNameHashSuffix": 57441002501318311, + "gachaImageNameHashSuffix": 10983330622159113, + "hpBase": 1030.3238525390625, + "iconName": "UI_AvatarIcon_Shinobu", + "id": 10000065, + "imageName": "AvatarImage_Forward_Shinobu", + "infoDesc": 738455441, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 41681757250499107, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 17766154816220128, + "nameTextMapHash": 1940821986, + "prefabPathHashSuffix": 22790412635966420, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 13980832109550954, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Shinobu", + "skillDepotId": 6501, + "staminaRecoverSpeed": 25.0, + "sus2": 45440781812016321, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 6468907785444183, + "attackBase": 23.274999618530273, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 66, + "avatarPromoteRewardIdList": [ + 900491, + 900493, + 900495 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_MALE", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 68958337937986499, + "controllerPathHashSuffix": 15840912238626339, + "controllerPathRemoteHashSuffix": 59193330925441066, + "coopPicNameHashSuffix": 42011376483093054, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 59.83000183105469, + "descTextMapHash": 2887592185, + "featureTagGroupId": 10000066, + "gachaCardNameHashSuffix": 27779911138219516, + "gachaImageNameHashSuffix": 18504459652097554, + "hpBase": 1067.7183837890625, + "iconName": "UI_AvatarIcon_Ayato", + "id": 10000066, + "imageName": "AvatarImage_Forward_Ayato", + "infoDesc": 2887592185, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 22189646281054736, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 5314325765590661, + "nameTextMapHash": 1588620330, + "prefabPathHashSuffix": 42275246386464037, + "prefabPathRagdollHashSuffix": 69125965490831506, + "prefabPathRemoteHashSuffix": 42380206932594171, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 44689199583546995, + "sideIconName": "UI_AvatarIcon_Side_Ayato", + "skillDepotId": 6601, + "staminaRecoverSpeed": 25.0, + "sus2": 8294153425102529, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 30228945486713907, + "attackBase": 16.739519119262695, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 67, + "avatarPromoteRewardIdList": [ + 900551, + 900553, + 900555 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 27286480194752576, + "controllerPathHashSuffix": 50800100963599197, + "controllerPathRemoteHashSuffix": 70153179165152723, + "coopPicNameHashSuffix": 67717450047066883, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 50.358001708984375, + "descTextMapHash": 2491093329, + "featureTagGroupId": 10000067, + "gachaCardNameHashSuffix": 29420238251562499, + "gachaImageNameHashSuffix": 45537369564510395, + "hpBase": 820.6118774414062, + "iconName": "UI_AvatarIcon_Collei", + "id": 10000067, + "imageName": "AvatarImage_Forward_Collei", + "infoDesc": 2491093329, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 18133643192548129, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 14746644365375077, + "nameTextMapHash": 2948362178, + "prefabPathHashSuffix": 66561881293164911, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 26858586349049991, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Collei", + "skillDepotId": 6701, + "staminaRecoverSpeed": 25.0, + "sus2": 62354350866012292, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 39339915370949032, + "attackBase": 18.698400497436523, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 68, + "avatarPromoteRewardIdList": [ + 900531, + 900533, + 900535 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LOLI", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 51418365371803076, + "controllerPathHashSuffix": 68922699755886329, + "controllerPathRemoteHashSuffix": 40186747684547345, + "coopPicNameHashSuffix": 8590643418349188, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 60.65850067138672, + "descTextMapHash": 71570297, + "featureTagGroupId": 10000068, + "gachaCardNameHashSuffix": 5644715274227901, + "gachaImageNameHashSuffix": 21953658375594792, + "hpBase": 1039.4417724609375, + "iconName": "UI_AvatarIcon_Dori", + "id": 10000068, + "imageName": "AvatarImage_Forward_Dori", + "infoDesc": 71570297, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 25353451160530908, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 15818636183692823, + "nameTextMapHash": 388272194, + "prefabPathHashSuffix": 19424498462858949, + "prefabPathRagdollHashSuffix": 12381997878214711, + "prefabPathRemoteHashSuffix": 67362241866666371, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 47538393428685098, + "sideIconName": "UI_AvatarIcon_Side_Dori", + "skillDepotId": 6801, + "staminaRecoverSpeed": 25.0, + "sus": 48387722231455563, + "sus2": 52558851565810538, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 71476632592413108, + "attackBase": 20.854400634765625, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 69, + "avatarPromoteRewardIdList": [ + 900541, + 900543, + 900545 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 45664108426274863, + "controllerPathHashSuffix": 42909427290390210, + "controllerPathRemoteHashSuffix": 15154114644492366, + "coopPicNameHashSuffix": 42889331357864335, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 49.06060028076172, + "descTextMapHash": 2793013657, + "featureTagGroupId": 10000069, + "gachaCardNameHashSuffix": 48438236063640589, + "gachaImageNameHashSuffix": 40680610396182977, + "hpBase": 844.6415405273438, + "iconName": "UI_AvatarIcon_Tighnari", + "id": 10000069, + "imageName": "AvatarImage_Forward_Tighnari", + "infoDesc": 2793013657, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 54470733474513442, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 60225513178621500, + "nameTextMapHash": 2506955778, + "prefabPathHashSuffix": 68884458322179780, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 57723621117320236, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Tighnari", + "skillDepotId": 6901, + "staminaRecoverSpeed": 25.0, + "sus2": 67955542505134219, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 33846393104470550, + "attackBase": 17.875200271606445, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 70, + "avatarPromoteRewardIdList": [ + 900581, + 900583, + 900585 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 13349412426038113, + "controllerPathHashSuffix": 3730429053663527, + "controllerPathRemoteHashSuffix": 31616917990003293, + "coopPicNameHashSuffix": 51615159153732103, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 56.718841552734375, + "descTextMapHash": 3126933153, + "featureTagGroupId": 10000070, + "gachaCardNameHashSuffix": 49777377746549771, + "gachaImageNameHashSuffix": 24935601841826482, + "hpBase": 1182.1168212890625, + "iconName": "UI_AvatarIcon_Nilou", + "id": 10000070, + "imageName": "AvatarImage_Forward_Nilou", + "infoDesc": 3126933153, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 12230448294687738, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 51892697214006789, + "nameTextMapHash": 3850149970, + "prefabPathHashSuffix": 57435222662537876, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 55726107393077272, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Nilou", + "skillDepotId": 7001, + "staminaRecoverSpeed": 25.0, + "sus2": 9502963892448576, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 50839639545497614, + "attackBase": 24.76460075378418, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 71, + "avatarPromoteRewardIdList": [ + 900561, + 900563, + 900565 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 55136119718012873, + "controllerPathHashSuffix": 48407491664426367, + "controllerPathRemoteHashSuffix": 71070615763435434, + "coopPicNameHashSuffix": 57457133887131232, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 66.88993835449219, + "descTextMapHash": 2253913929, + "featureTagGroupId": 10000071, + "gachaCardNameHashSuffix": 47227101296264014, + "gachaImageNameHashSuffix": 44348277494699001, + "hpBase": 972.3864135742188, + "iconName": "UI_AvatarIcon_Cyno", + "id": 10000071, + "imageName": "AvatarImage_Forward_Cyno", + "infoDesc": 2253913929, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 32185849284875828, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 66409627877065264, + "nameTextMapHash": 1049891906, + "prefabPathHashSuffix": 55114788152474647, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 22118067160298416, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Cyno", + "skillDepotId": 7101, + "staminaRecoverSpeed": 25.0, + "sus2": 67020043674975189, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 34730867356754930, + "attackBase": 17.808000564575195, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 72, + "avatarPromoteRewardIdList": [ + 900571, + 900573, + 900575 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 71767698318409327, + "controllerPathHashSuffix": 22695679904076139, + "controllerPathRemoteHashSuffix": 4384256527013432, + "coopPicNameHashSuffix": 4990263551942624, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 57.224998474121094, + "descTextMapHash": 369426969, + "featureTagGroupId": 10000072, + "gachaCardNameHashSuffix": 7206932127214961, + "gachaImageNameHashSuffix": 57623208141483309, + "hpBase": 911.791015625, + "iconName": "UI_AvatarIcon_Candace", + "id": 10000072, + "imageName": "AvatarImage_Forward_Candace", + "infoDesc": 369426969, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 54472966588740204, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 62925401507701790, + "nameTextMapHash": 3092975658, + "prefabPathHashSuffix": 61973632850278676, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 70947888468284719, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Candace", + "skillDepotId": 7201, + "staminaRecoverSpeed": 25.0, + "sus2": 37175968968029680, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 4181805254321007, + "attackBase": 23.274999618530273, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 73, + "avatarPromoteRewardIdList": [ + 900601, + 900603, + 900605 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LOLI", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 6144786061544801, + "controllerPathHashSuffix": 492644298579749, + "controllerPathRemoteHashSuffix": 15964692845042684, + "coopPicNameHashSuffix": 32384208430461693, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 49.06060028076172, + "descTextMapHash": 2629071729, + "featureTagGroupId": 10000073, + "gachaCardNameHashSuffix": 10520901361897215, + "gachaImageNameHashSuffix": 20314770495238046, + "hpBase": 806.5087280273438, + "iconName": "UI_AvatarIcon_Nahida", + "id": 10000073, + "imageName": "AvatarImage_Forward_Nahida", + "infoDesc": 2629071729, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 67428749875638754, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 65720461983330943, + "nameTextMapHash": 712501082, + "prefabPathHashSuffix": 8162970734530542, + "prefabPathRagdollHashSuffix": 12381997878214711, + "prefabPathRemoteHashSuffix": 68284558519294988, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 47538393428685098, + "sideIconName": "UI_AvatarIcon_Side_Nahida", + "skillDepotId": 7301, + "staminaRecoverSpeed": 25.0, + "sus2": 55198324725333653, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 63697247316327090, + "attackBase": 18.164159774780273, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 74, + "avatarPromoteRewardIdList": [ + 900591, + 900593, + 900595 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 47200682749781142, + "controllerPathHashSuffix": 15505372380013507, + "controllerPathRemoteHashSuffix": 54501114528414354, + "coopPicNameHashSuffix": 17550679168385993, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 54.93600082397461, + "descTextMapHash": 2729249993, + "featureTagGroupId": 10000074, + "gachaCardNameHashSuffix": 21623135743197407, + "gachaImageNameHashSuffix": 15022362863974317, + "hpBase": 930.0267944335938, + "iconName": "UI_AvatarIcon_Layla", + "id": 10000074, + "imageName": "AvatarImage_Forward_Layla", + "infoDesc": 2729249993, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 61339913636611372, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 67819718073869132, + "nameTextMapHash": 2889777514, + "prefabPathHashSuffix": 44955528039764019, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 48067107303612227, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Layla", + "skillDepotId": 7401, + "staminaRecoverSpeed": 25.0, + "sus2": 3933597077945492, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 69346097803858839, + "attackBase": 25.5093994140625, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 75, + "avatarPromoteRewardIdList": [ + 900621, + 900623, + 900625 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 56470594988064471, + "controllerPathHashSuffix": 11699712908999195, + "controllerPathRemoteHashSuffix": 12577006465490299, + "coopPicNameHashSuffix": 41006144665349581, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 47.26570129394531, + "descTextMapHash": 431267537, + "featureTagGroupId": 10000075, + "gachaCardNameHashSuffix": 3190652008933649, + "gachaImageNameHashSuffix": 43588526880889681, + "hpBase": 791.255615234375, + "iconName": "UI_AvatarIcon_Wanderer", + "id": 10000075, + "imageName": "AvatarImage_Forward_Wanderer", + "infoDesc": 431267537, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 50519889968418010, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 67817838245587235, + "nameTextMapHash": 3230559562, + "prefabPathHashSuffix": 4827591580725170, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 42116874840764147, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Wanderer", + "skillDepotId": 7501, + "staminaRecoverSpeed": 25.0, + "sus2": 48917119416860286, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 28611343896650108, + "attackBase": 16.472400665283203, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 76, + "avatarPromoteRewardIdList": [ + 900611, + 900613, + 900615 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 53542763285816291, + "controllerPathHashSuffix": 35308282616891375, + "controllerPathRemoteHashSuffix": 3224008619692659, + "coopPicNameHashSuffix": 35384656770851346, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 52.64699935913086, + "descTextMapHash": 4013065569, + "featureTagGroupId": 10000076, + "gachaCardNameHashSuffix": 12132458970070896, + "gachaImageNameHashSuffix": 48320860020389563, + "hpBase": 802.3760986328125, + "iconName": "UI_AvatarIcon_Faruzan", + "id": 10000076, + "imageName": "AvatarImage_Forward_Faruzan", + "infoDesc": 4013065569, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 50892824650172546, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 7726574155869852, + "nameTextMapHash": 2387711994, + "prefabPathHashSuffix": 67619447508824393, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 70815331999588105, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Faruzan", + "skillDepotId": 7601, + "staminaRecoverSpeed": 25.0, + "sus2": 58405621555154284, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 607567575438664, + "attackBase": 17.808000564575195, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 77, + "avatarPromoteRewardIdList": [ + 900631, + 900633, + 900635 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LOLI", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 29109211029257972, + "controllerPathHashSuffix": 12542623081545695, + "controllerPathRemoteHashSuffix": 15990112379514400, + "coopPicNameHashSuffix": 17683929332252168, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 62.9474983215332, + "descTextMapHash": 1595771809, + "featureTagGroupId": 10000077, + "gachaCardNameHashSuffix": 37391560278377499, + "gachaImageNameHashSuffix": 42612604399012742, + "hpBase": 1030.3238525390625, + "iconName": "UI_AvatarIcon_Yaoyao", + "id": 10000077, + "imageName": "AvatarImage_Forward_Yaoyao", + "infoDesc": 1595771809, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 59992348958650129, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 46304404866590057, + "nameTextMapHash": 1732418482, + "prefabPathHashSuffix": 33433006048989983, + "prefabPathRagdollHashSuffix": 20465433773312795, + "prefabPathRemoteHashSuffix": 57324210317700359, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 47538393428685098, + "sideIconName": "UI_AvatarIcon_Side_Yaoyao", + "skillDepotId": 7701, + "staminaRecoverSpeed": 25.0, + "sus2": 47201207413626407, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 46294635157138942, + "attackBase": 24.392200469970703, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 78, + "avatarPromoteRewardIdList": [ + 900641, + 900643, + 900645 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_MALE", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 53423963306168503, + "controllerPathHashSuffix": 41617144842062591, + "controllerPathRemoteHashSuffix": 69116286304691170, + "coopPicNameHashSuffix": 36170677839175114, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 60.847110748291016, + "descTextMapHash": 2584161865, + "featureTagGroupId": 10000078, + "gachaCardNameHashSuffix": 62248224976845339, + "gachaImageNameHashSuffix": 24588025715340443, + "hpBase": 1039.1187744140625, + "iconName": "UI_AvatarIcon_Alhatham", + "id": 10000078, + "imageName": "AvatarImage_Forward_Alhatham", + "infoDesc": 2584161865, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 44263216545131574, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 48736905349345485, + "nameTextMapHash": 4002157418, + "prefabPathHashSuffix": 38273843189942716, + "prefabPathRagdollHashSuffix": 69125965490831506, + "prefabPathRemoteHashSuffix": 4129252018530729, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 44689199583546995, + "sideIconName": "UI_AvatarIcon_Side_Alhatham", + "skillDepotId": 7801, + "staminaRecoverSpeed": 25.0, + "sus2": 64268139773402876, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 44073754289158485, + "attackBase": 20.66819953918457, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 79, + "avatarPromoteRewardIdList": [ + 900651, + 900653, + 900655 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 8777635032950941, + "controllerPathHashSuffix": 36634057997623268, + "controllerPathRemoteHashSuffix": 19803296039489447, + "coopPicNameHashSuffix": 25275642726186831, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 48.88111114501953, + "descTextMapHash": 1894790521, + "featureTagGroupId": 10000079, + "gachaCardNameHashSuffix": 58859124030426712, + "gachaImageNameHashSuffix": 35859133032388923, + "hpBase": 1220.2496337890625, + "iconName": "UI_AvatarIcon_Dehya", + "id": 10000079, + "imageName": "AvatarImage_Forward_Dehya", + "infoDesc": 1894790521, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 6004385753582703, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 71509204012433324, + "nameTextMapHash": 2360533154, + "prefabPathHashSuffix": 55335704208096092, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 27422635081873701, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Dehya", + "skillDepotId": 7901, + "staminaRecoverSpeed": 25.0, + "sus2": 42611724495787142, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 41966123148329538, + "attackBase": 18.698400497436523, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 80, + "avatarPromoteRewardIdList": [ + 900661, + 900663, + 900665 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 66297104006064411, + "controllerPathHashSuffix": 4948406871788361, + "controllerPathRemoteHashSuffix": 19766185622299361, + "coopPicNameHashSuffix": 8616470332023629, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 59.80012512207031, + "descTextMapHash": 3487590873, + "featureTagGroupId": 10000080, + "gachaCardNameHashSuffix": 19441068259486206, + "gachaImageNameHashSuffix": 45613132951255548, + "hpBase": 1048.5596923828125, + "iconName": "UI_AvatarIcon_Mika", + "id": 10000080, + "imageName": "AvatarImage_Forward_Mika", + "infoDesc": 3487590873, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51533922798546183, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 2337496907582489, + "nameTextMapHash": 231911858, + "prefabPathHashSuffix": 32984532398816815, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 52716384299131656, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Mika", + "skillDepotId": 8001, + "staminaRecoverSpeed": 25.0, + "sus2": 9521297607850432, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 24501394123421897, + "attackBase": 19.58880043029785, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 81, + "avatarPromoteRewardIdList": [ + 900671, + 900673, + 900675 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_MALE", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 54135651825175827, + "controllerPathHashSuffix": 24588382604127233, + "controllerPathRemoteHashSuffix": 32053874931423504, + "coopPicNameHashSuffix": 6689028192768596, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 62.9474983215332, + "descTextMapHash": 2545348585, + "featureTagGroupId": 10000081, + "gachaCardNameHashSuffix": 22031610670021829, + "gachaImageNameHashSuffix": 11018904965660776, + "hpBase": 1002.9700927734375, + "iconName": "UI_AvatarIcon_Kaveh", + "id": 10000081, + "imageName": "AvatarImage_Forward_Kaveh", + "infoDesc": 2545348585, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 18809101106623960, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 42273629025436922, + "nameTextMapHash": 466355514, + "prefabPathHashSuffix": 60662505610439837, + "prefabPathRagdollHashSuffix": 69125965490831506, + "prefabPathRemoteHashSuffix": 4453544572510605, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 44689199583546995, + "sideIconName": "UI_AvatarIcon_Side_Kaveh", + "skillDepotId": 8101, + "staminaRecoverSpeed": 25.0, + "sus2": 5955028170653739, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 53568963759883417, + "attackBase": 14.989100456237793, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 82, + "avatarPromoteRewardIdList": [ + 900681, + 900683, + 900685 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_MALE", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 43624966953591459, + "controllerPathHashSuffix": 15489794420498673, + "controllerPathRemoteHashSuffix": 26094119412058683, + "coopPicNameHashSuffix": 15146814780910843, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 38.88949966430664, + "descTextMapHash": 3312539857, + "featureTagGroupId": 10000082, + "gachaCardNameHashSuffix": 44785126450998780, + "gachaImageNameHashSuffix": 39800470129303012, + "hpBase": 1039.1187744140625, + "iconName": "UI_AvatarIcon_Baizhuer", + "id": 10000082, + "imageName": "AvatarImage_Forward_Baizhuer", + "infoDesc": 3312539857, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 18232255076946368, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 47388051588314715, + "nameTextMapHash": 2984815066, + "prefabPathHashSuffix": 3788883342153007, + "prefabPathRagdollHashSuffix": 69125965490831506, + "prefabPathRemoteHashSuffix": 50958862561645681, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 44689199583546995, + "sideIconName": "UI_AvatarIcon_Side_Baizhuer", + "skillDepotId": 8201, + "staminaRecoverSpeed": 25.0, + "sus2": 13836492147038544, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 11443457338122777, + "attackBase": 19.410720825195312, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 83, + "avatarPromoteRewardIdList": [ + 900701, + 900703, + 900705 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 70506552387056099, + "controllerPathHashSuffix": 33176720593872020, + "controllerPathRemoteHashSuffix": 37007658916907786, + "coopPicNameHashSuffix": 45844657316466878, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 59.68567657470703, + "descTextMapHash": 3450878153, + "featureTagGroupId": 10000083, + "gachaCardNameHashSuffix": 69742097842457538, + "gachaImageNameHashSuffix": 67137931760593647, + "hpBase": 1039.4417724609375, + "iconName": "UI_AvatarIcon_Linette", + "id": 10000083, + "imageName": "AvatarImage_Forward_Linette", + "infoDesc": 3450878153, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 40299102094122167, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 32103230411984852, + "nameTextMapHash": 1225226258, + "prefabPathHashSuffix": 43087257426962145, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 19798374651687455, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Linette", + "skillDepotId": 8301, + "staminaRecoverSpeed": 25.0, + "sus2": 62262762423737911, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 37444011919080740, + "attackBase": 24.76460075378418, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 84, + "avatarPromoteRewardIdList": [ + 900711, + 900713, + 900715 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 64854675410231961, + "controllerPathHashSuffix": 27841560771004947, + "controllerPathRemoteHashSuffix": 42974577320284066, + "coopPicNameHashSuffix": 42447716173924625, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 41.88100051879883, + "descTextMapHash": 3225015385, + "featureTagGroupId": 10000084, + "gachaCardNameHashSuffix": 71208138056789608, + "gachaImageNameHashSuffix": 56691635274583356, + "hpBase": 857.9879760742188, + "iconName": "UI_AvatarIcon_Liney", + "id": 10000084, + "imageName": "AvatarImage_Forward_Liney", + "infoDesc": 3225015385, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 13232635685888655, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 5969257570440086, + "nameTextMapHash": 2472444970, + "prefabPathHashSuffix": 71886518290567287, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 57323722431968489, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Liney", + "skillDepotId": 8401, + "staminaRecoverSpeed": 25.0, + "sus2": 27683716770919215, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_BOW" + }, + { + "animatorConfigPathHash": 68358123463354068, + "attackBase": 21.369600296020508, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 85, + "avatarPromoteRewardIdList": [ + 900721, + 900723, + 900725 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 23013840584669564, + "controllerPathHashSuffix": 15914260649080443, + "controllerPathRemoteHashSuffix": 52737571146597390, + "coopPicNameHashSuffix": 56136480663131597, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 59.39955139160156, + "descTextMapHash": 2838709961, + "featureTagGroupId": 10000085, + "gachaCardNameHashSuffix": 36501731533760571, + "gachaImageNameHashSuffix": 40101844813273056, + "hpBase": 1012.0880126953125, + "iconName": "UI_AvatarIcon_Freminet", + "id": 10000085, + "imageName": "AvatarImage_Forward_Freminet", + "infoDesc": 2838709961, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 32407848865344725, + "manekinMotionConfig": 106, + "manekinPathHashSuffix": 51543138738245716, + "nameTextMapHash": 4201964354, + "prefabPathHashSuffix": 59967884630536574, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 6592919622774867, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Freminet", + "skillDepotId": 8501, + "staminaRecoverSpeed": 25.0, + "sus2": 59970026893786326, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 39878068240436134, + "attackBase": 24.20599937438965, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 86, + "avatarPromoteRewardIdList": [ + 900731, + 900733, + 900735 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_MALE", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 33083520223334526, + "controllerPathHashSuffix": 18430026735703139, + "controllerPathRemoteHashSuffix": 56498527641762935, + "coopPicNameHashSuffix": 8477484797914346, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 59.411190032958984, + "descTextMapHash": 3963795561, + "featureTagGroupId": 10000086, + "gachaCardNameHashSuffix": 40312759387313777, + "gachaImageNameHashSuffix": 68931303156367602, + "hpBase": 1058.1851806640625, + "iconName": "UI_AvatarIcon_Wriothesley", + "id": 10000086, + "imageName": "AvatarImage_Forward_Wriothesley", + "infoDesc": 3963795561, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 33938060557906715, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 10894429736584811, + "nameTextMapHash": 370151050, + "prefabPathHashSuffix": 21863527238341233, + "prefabPathRagdollHashSuffix": 69125965490831506, + "prefabPathRemoteHashSuffix": 35972161770368472, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 44689199583546995, + "sideIconName": "UI_AvatarIcon_Side_Wriothesley", + "skillDepotId": 8601, + "staminaRecoverSpeed": 25.0, + "sus2": 4207318801814855, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 51577163246222126, + "attackBase": 16.218019485473633, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 87, + "avatarPromoteRewardIdList": [ + 900741, + 900743, + 900745 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_MALE", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 66442380031132777, + "controllerPathHashSuffix": 64071251295059254, + "controllerPathRemoteHashSuffix": 1436207423948812, + "coopPicNameHashSuffix": 38177332441848055, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 44.872501373291016, + "descTextMapHash": 3918027945, + "featureTagGroupId": 10000087, + "gachaCardNameHashSuffix": 39916103576016707, + "gachaImageNameHashSuffix": 50891721552921657, + "hpBase": 1143.9840087890625, + "iconName": "UI_AvatarIcon_Neuvillette", + "id": 10000087, + "imageName": "AvatarImage_Forward_Neuvillette", + "infoDesc": 3918027945, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 27419131766399049, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 7880958117541587, + "nameTextMapHash": 1504902330, + "prefabPathHashSuffix": 6904748118634798, + "prefabPathRagdollHashSuffix": 69125965490831506, + "prefabPathRemoteHashSuffix": 8261792748832598, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 44689199583546995, + "sideIconName": "UI_AvatarIcon_Side_Neuvillette", + "skillDepotId": 8701, + "staminaRecoverSpeed": 25.0, + "sus2": 58930822433351977, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 18887080459883944, + "attackBase": 14.513520240783691, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 88, + "avatarPromoteRewardIdList": [ + 900751, + 900753, + 900755 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 50622791896302564, + "controllerPathHashSuffix": 10028239714346923, + "controllerPathRemoteHashSuffix": 54299632646537985, + "coopPicNameHashSuffix": 30501818093253511, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 45.779998779296875, + "descTextMapHash": 3090032161, + "featureTagGroupId": 10000088, + "gachaCardNameHashSuffix": 53986262234119320, + "gachaImageNameHashSuffix": 33805205104421468, + "hpBase": 902.673095703125, + "iconName": "UI_AvatarIcon_Charlotte", + "id": 10000088, + "imageName": "AvatarImage_Forward_Charlotte", + "infoDesc": 3090032161, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 36597164233231329, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 33856603498598250, + "nameTextMapHash": 3831162130, + "prefabPathHashSuffix": 63412514484014527, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 53018286116825656, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Charlotte", + "skillDepotId": 8801, + "staminaRecoverSpeed": 25.0, + "sus2": 4926175986034677, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "animatorConfigPathHash": 30207149798304915, + "attackBase": 18.992399215698242, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 89, + "avatarPromoteRewardIdList": [ + 900761, + 900763, + 900765 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 57479630179699646, + "controllerPathHashSuffix": 62513056510359816, + "controllerPathRemoteHashSuffix": 8883967862012887, + "coopPicNameHashSuffix": 22782347502641923, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 54.146148681640625, + "descTextMapHash": 2843800569, + "featureTagGroupId": 10000089, + "gachaCardNameHashSuffix": 40449570605507073, + "gachaImageNameHashSuffix": 65801788171102939, + "hpBase": 1191.6500244140625, + "iconName": "UI_AvatarIcon_Furina", + "id": 10000089, + "imageName": "AvatarImage_Forward_Furina", + "infoDesc": 2843800569, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 29119113590246869, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 42596027627476788, + "nameTextMapHash": 2180900234, + "prefabPathHashSuffix": 41921412820673367, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 66261346186247, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Furina", + "skillDepotId": 8901, + "staminaRecoverSpeed": 25.0, + "sus2": 4157642950043403, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "animatorConfigPathHash": 14053803150037308, + "attackBase": 16.205280303955078, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 90, + "avatarPromoteRewardIdList": [ + 900771, + 900773, + 900775 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 61752550343446219, + "controllerPathHashSuffix": 30315690193281387, + "controllerPathRemoteHashSuffix": 67681335529686466, + "coopPicNameHashSuffix": 13596568330138882, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 50.701351165771484, + "descTextMapHash": 3743936161, + "featureTagGroupId": 10000090, + "gachaCardNameHashSuffix": 11644834827563301, + "gachaImageNameHashSuffix": 28615258405131594, + "hpBase": 1002.9700927734375, + "iconName": "UI_AvatarIcon_Chevreuse", + "id": 10000090, + "imageName": "AvatarImage_Forward_Chevreuse", + "infoDesc": 3743936161, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 875149233002815, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 45792742100180655, + "nameTextMapHash": 540313842, + "prefabPathHashSuffix": 56689321339140115, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 43588030945274560, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Chevreuse", + "skillDepotId": 9001, + "staminaRecoverSpeed": 25.0, + "sus2": 7639528277983555, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_POLE" + }, + { + "animatorConfigPathHash": 33206495296079627, + "attackBase": 27.371400833129883, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 91, + "avatarPromoteRewardIdList": [ + 900781, + 900783, + 900785 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 70140968053116563, + "controllerPathHashSuffix": 22053619469519520, + "controllerPathRemoteHashSuffix": 8727469306755785, + "coopPicNameHashSuffix": 41716598511053836, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 61.74456024169922, + "descTextMapHash": 251470345, + "featureTagGroupId": 10000091, + "gachaCardNameHashSuffix": 54819655111158106, + "gachaImageNameHashSuffix": 44322377930129816, + "hpBase": 984.779541015625, + "iconName": "UI_AvatarIcon_Navia", + "id": 10000091, + "imageName": "AvatarImage_Forward_Navia", + "infoDesc": 251470345, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 33975348526323799, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 1729575110561430, + "nameTextMapHash": 2877588578, + "prefabPathHashSuffix": 21545301106097749, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 51129867469108970, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Navia", + "skillDepotId": 9101, + "staminaRecoverSpeed": 25.0, + "sus2": 65024100546489953, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 39933759152588996, + "attackBase": 25.2873592376709, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 92, + "avatarPromoteRewardIdList": [ + 900791, + 900793, + 900795 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 66685689917817669, + "controllerPathHashSuffix": 71143576037850306, + "controllerPathRemoteHashSuffix": 49512329633220836, + "coopPicNameHashSuffix": 35262943584920509, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 58.941749572753906, + "descTextMapHash": 669926801, + "featureTagGroupId": 10000092, + "gachaCardNameHashSuffix": 14444663081178883, + "gachaImageNameHashSuffix": 47113749703849640, + "hpBase": 957.3805541992188, + "iconName": "UI_AvatarIcon_Gaming", + "id": 10000092, + "imageName": "AvatarImage_Forward_Gaming", + "infoDesc": 669926801, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 11028645502293227, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 66253171644652451, + "nameTextMapHash": 2822240322, + "prefabPathHashSuffix": 54409103753088014, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 35263472151012768, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Gaming", + "skillDepotId": 9201, + "staminaRecoverSpeed": 25.0, + "sus2": 45141798046624837, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CLAYMORE" + }, + { + "animatorConfigPathHash": 34626468922327122, + "attackBase": 26.06800079345703, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 93, + "avatarPromoteRewardIdList": [ + 900801, + 900803, + 900805 + ], + "avatarPromoteRewardLevelList": [ + 1, + 3, + 5 + ], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 32494745480219828, + "controllerPathHashSuffix": 33340271862881225, + "controllerPathRemoteHashSuffix": 26029622627991760, + "coopPicNameHashSuffix": 62759491225337842, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 44.57334899902344, + "descTextMapHash": 1611204721, + "featureTagGroupId": 10000093, + "gachaCardNameHashSuffix": 35732545827436187, + "gachaImageNameHashSuffix": 56098151317181248, + "hpBase": 810.322021484375, + "iconName": "UI_AvatarIcon_Liuyun", + "id": 10000093, + "imageName": "AvatarImage_Forward_Liuyun", + "infoDesc": 1611204721, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 62290473269993640, + "manekinMotionConfig": 103, + "manekinPathHashSuffix": 15250814277948256, + "nameTextMapHash": 3648220770, + "prefabPathHashSuffix": 1026074262658751, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 53750159059776581, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Liuyun", + "skillDepotId": 9301, + "staminaRecoverSpeed": 25.0, + "sus2": 71488901954377634, + "useType": "AVATAR_FORMAL", + "weaponType": "WEAPON_CATALYST" + }, + { + "attackBase": 99999.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 61672267365925266, + "controllerPathHashSuffix": 31925045831370702, + "controllerPathRemoteHashSuffix": 51066636618558810, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 99999.0, + "descTextMapHash": 1029005921, + "featureTagGroupId": 10000001, + "hpBase": 99999.0, + "iconName": "UI_AvatarIcon_Side_Ambor", + "id": 11000008, + "imageName": "AvatarImage_Forward_Ambor", + "infoDesc": 1029005921, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 34703781099415905, + "nameTextMapHash": 3525263658, + "prefabPathHashSuffix": 4729135519363573, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 38333527116904810, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Ambor", + "skillDepotId": 8011, + "staminaRecoverSpeed": 25.0, + "sus2": 48054748594336654, + "useType": "AVATAR_ABANDON", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 99999.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 3618601654559369, + "controllerPathHashSuffix": 47627508575917610, + "controllerPathRemoteHashSuffix": 56948908368685679, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 99999.0, + "descTextMapHash": 1835561441, + "featureTagGroupId": 10000001, + "hpBase": 99999.0, + "iconName": "UI_AvatarIcon_Side_Kate", + "id": 11000009, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 1835561441, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 55136124680407829, + "nameTextMapHash": 3719770402, + "prefabPathHashSuffix": 50405489677491353, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 10725930342216161, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Kate", + "skillDepotId": 9011, + "staminaRecoverSpeed": 25.0, + "sus2": 62997278649543547, + "useType": "AVATAR_ABANDON", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 99999.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 3618601654559369, + "controllerPathHashSuffix": 46672224606096422, + "controllerPathRemoteHashSuffix": 61251852993006870, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 99999.0, + "descTextMapHash": 786373081, + "featureTagGroupId": 10000001, + "hpBase": 99999.0, + "iconName": "UI_AvatarIcon_Side_Kate", + "id": 11000010, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 786373081, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 55136124680407829, + "nameTextMapHash": 2646377570, + "prefabPathHashSuffix": 5189199440940448, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 22565691467417466, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Kate", + "skillDepotId": 10011, + "staminaRecoverSpeed": 25.0, + "sus2": 41150436161678426, + "useType": "AVATAR_ABANDON", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 99999.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 9308403171398750, + "controllerPathHashSuffix": 27486918322845718, + "controllerPathRemoteHashSuffix": 1632562252579889, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 99999.0, + "descTextMapHash": 840788129, + "featureTagGroupId": 10000001, + "hpBase": 99999.0, + "iconName": "UI_AvatarIcon_Side_Kate", + "id": 11000011, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 840788129, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 64143048752815855, + "nameTextMapHash": 3630849682, + "prefabPathHashSuffix": 21297691110381278, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 53725032450677420, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Kate", + "skillDepotId": 501, + "staminaRecoverSpeed": 25.0, + "sus2": 19067321717231189, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 99999.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 9998434569876205, + "controllerPathHashSuffix": 29209364363328890, + "controllerPathRemoteHashSuffix": 44261656086156992, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 99999.0, + "descTextMapHash": 1567121545, + "featureTagGroupId": 10000001, + "hpBase": 99999.0, + "iconName": "UI_AvatarIcon_Side_Kate", + "id": 11000013, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 1567121545, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 55136124680407829, + "nameTextMapHash": 1904921362, + "prefabPathHashSuffix": 393569443568098, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 30789870529931385, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Kate", + "skillDepotId": 13011, + "staminaRecoverSpeed": 25.0, + "sus2": 22649031354796341, + "useType": "AVATAR_SYNC_TEST", + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 99999.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_MALE", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 63007350652895025, + "controllerPathHashSuffix": 38230416671460683, + "controllerPathRemoteHashSuffix": 6657684595157210, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 99999.0, + "descTextMapHash": 1479741705, + "featureTagGroupId": 10000001, + "hpBase": 99999.0, + "iconName": "UI_AvatarIcon_Qin", + "id": 11000017, + "imageName": "AvatarImage_Forward_Qin", + "infoDesc": 1479741705, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 35722281200448464, + "nameTextMapHash": 2161552122, + "prefabPathHashSuffix": 30039205407139176, + "prefabPathRagdollHashSuffix": 69125965490831506, + "prefabPathRemoteHashSuffix": 40476433775639229, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 44689199583546995, + "sideIconName": "UI_AvatarIcon_Side_Qin", + "skillDepotId": 1501, + "staminaRecoverSpeed": 25.0, + "sus2": 37396099180908356, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 99999.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 61672267365925266, + "controllerPathHashSuffix": 39351142476504418, + "controllerPathRemoteHashSuffix": 24285732946487685, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 99999.0, + "descTextMapHash": 1273592169, + "featureTagGroupId": 10000001, + "hpBase": 99999.0, + "iconName": "UI_AvatarIcon_Qin", + "id": 11000018, + "imageName": "AvatarImage_Forward_Qin", + "infoDesc": 1273592169, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 35722281200448464, + "nameTextMapHash": 281153370, + "prefabPathHashSuffix": 68567642565017084, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 21201923700454912, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Qin", + "skillDepotId": 1501, + "staminaRecoverSpeed": 25.0, + "sus2": 16354110707850064, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 99999.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 29750952775514445, + "controllerPathHashSuffix": 19507850982114029, + "controllerPathRemoteHashSuffix": 23747448963754595, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 99999.0, + "descTextMapHash": 2403736705, + "featureTagGroupId": 10000001, + "hpBase": 99999.0, + "iconName": "UI_AvatarIcon_Qin", + "id": 11000019, + "imageName": "AvatarImage_Forward_Qin", + "infoDesc": 2403736705, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 35722281200448464, + "nameTextMapHash": 556091050, + "prefabPathHashSuffix": 48987911330726811, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 61807387178185867, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Qin", + "skillDepotId": 1501, + "staminaRecoverSpeed": 25.0, + "sus2": 34029778952996721, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 8.199999809265137, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 42562243270306819, + "controllerPathHashSuffix": 49279722664046923, + "controllerPathRemoteHashSuffix": 30618362370638013, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 9.5, + "descTextMapHash": 1967235985, + "featureTagGroupId": 10000001, + "hpBase": 208.60000610351562, + "iconName": "UI_AvatarIcon_Razor", + "id": 11000025, + "imageName": "AvatarImage_Forward_Qin", + "infoDesc": 1967235985, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 25151998798607576, + "nameTextMapHash": 2454769378, + "prefabPathHashSuffix": 7522963087879874, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 6418277175316904, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_Razor", + "skillDepotId": 25011, + "staminaRecoverSpeed": 25.0, + "sus2": 34913750204797075, + "weaponType": "WEAPON_BOW" + }, + { + "attackBase": 99999.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_LOLI", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 29750952775514445, + "controllerPathHashSuffix": 25058489009461763, + "controllerPathRemoteHashSuffix": 45539200796971881, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 99999.0, + "descTextMapHash": 2705898529, + "featureTagGroupId": 10000001, + "hpBase": 99999.0, + "iconName": "UI_AvatarIcon_Qin", + "id": 11000026, + "imageName": "AvatarImage_Forward_Qin", + "infoDesc": 2705898529, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 3085676105004949, + "nameTextMapHash": 2413150418, + "prefabPathHashSuffix": 59692398934378033, + "prefabPathRagdollHashSuffix": 12381997878214711, + "prefabPathRemoteHashSuffix": 15798380426569524, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 47538393428685098, + "sideIconName": "UI_AvatarIcon_Side_Qin", + "skillDepotId": 1501, + "staminaRecoverSpeed": 25.0, + "sus2": 57388575238600814, + "weaponType": "WEAPON_CATALYST" + }, + { + "attackBase": 5.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 67993194395036856, + "controllerPathHashSuffix": 31925045831370702, + "controllerPathRemoteHashSuffix": 51066636618558810, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 8.0, + "descTextMapHash": 1177707113, + "featureTagGroupId": 10000001, + "hpBase": 166.0, + "iconName": "UI_AvatarIcon_Kate", + "id": 11000027, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 1177707113, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 55136124680407829, + "nameTextMapHash": 2402432058, + "prefabPathHashSuffix": 4729135519363573, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 38333527116904810, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Kate", + "skillDepotId": 101, + "staminaRecoverSpeed": 25.0, + "sus2": 48054748594336654, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 6.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 3047675947237184, + "controllerPathHashSuffix": 64712241954046138, + "controllerPathRemoteHashSuffix": 34344629332988016, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 10.399999618530273, + "descTextMapHash": 2023269409, + "featureTagGroupId": 10000001, + "hpBase": 185.0, + "iconName": "UI_AvatarIcon_Ayaka", + "id": 11000028, + "imageName": "AvatarImage_Forward_Ayaka", + "infoDesc": 2023269409, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 10744411933528157, + "nameTextMapHash": 3413685882, + "prefabPathHashSuffix": 24468520101419227, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 55250510550392886, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Ayaka", + "skillDepotId": 28011, + "staminaRecoverSpeed": 25.0, + "sus2": 63198039451805441, + "weaponType": "WEAPON_POLE" + }, + { + "attackBase": 5.599999904632568, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 29750952775514445, + "controllerPathHashSuffix": 63285038237684228, + "controllerPathRemoteHashSuffix": 2844509837551507, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 10.5, + "descTextMapHash": 1576784713, + "featureTagGroupId": 10000001, + "hpBase": 189.5, + "iconName": "UI_AvatarIcon_Qin", + "id": 11000030, + "imageName": "AvatarImage_Forward_Qin", + "infoDesc": 1576784713, + "initialWeapon": 12101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 34703781099415905, + "nameTextMapHash": 2955554858, + "prefabPathHashSuffix": 29284841965879061, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 11621264847991923, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Qin", + "skillDepotId": 30011, + "staminaRecoverSpeed": 25.0, + "sus2": 42853692550145176, + "weaponType": "WEAPON_CLAYMORE" + }, + { + "attackBase": 5.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 67993194395036856, + "controllerPathHashSuffix": 31925045831370702, + "controllerPathRemoteHashSuffix": 51066636618558810, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 8.0, + "descTextMapHash": 1902343241, + "featureTagGroupId": 10000001, + "hpBase": 166.0, + "iconName": "UI_AvatarIcon_Kate", + "id": 11000031, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 1902343241, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 55136124680407829, + "nameTextMapHash": 2536892626, + "prefabPathHashSuffix": 4729135519363573, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 38333527116904810, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Kate", + "skillDepotId": 101, + "staminaRecoverSpeed": 25.0, + "sus2": 48054748594336654, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 5.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 67993194395036856, + "controllerPathHashSuffix": 31925045831370702, + "controllerPathRemoteHashSuffix": 51066636618558810, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 8.0, + "descTextMapHash": 1364029553, + "featureTagGroupId": 10000001, + "hpBase": 166.0, + "iconName": "UI_AvatarIcon_Kate", + "id": 11000032, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 1364029553, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 55136124680407829, + "nameTextMapHash": 1807340018, + "prefabPathHashSuffix": 4729135519363573, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 38333527116904810, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Kate", + "skillDepotId": 101, + "staminaRecoverSpeed": 25.0, + "sus2": 48054748594336654, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 5.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 67993194395036856, + "controllerPathHashSuffix": 31925045831370702, + "controllerPathRemoteHashSuffix": 51066636618558810, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 8.0, + "descTextMapHash": 1091572897, + "featureTagGroupId": 10000001, + "hpBase": 166.0, + "iconName": "UI_AvatarIcon_Kate", + "id": 11000033, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 1091572897, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 55136124680407829, + "nameTextMapHash": 3912257050, + "prefabPathHashSuffix": 4729135519363573, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 38333527116904810, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Kate", + "skillDepotId": 101, + "staminaRecoverSpeed": 25.0, + "sus2": 48054748594336654, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 5.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 67993194395036856, + "controllerPathHashSuffix": 31925045831370702, + "controllerPathRemoteHashSuffix": 51066636618558810, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 8.0, + "descTextMapHash": 2042656601, + "featureTagGroupId": 10000001, + "hpBase": 166.0, + "iconName": "UI_AvatarIcon_Kate", + "id": 11000034, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 2042656601, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 55136124680407829, + "nameTextMapHash": 934545010, + "prefabPathHashSuffix": 4729135519363573, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 38333527116904810, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Kate", + "skillDepotId": 101, + "staminaRecoverSpeed": 25.0, + "sus2": 48054748594336654, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 6.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_LADY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 31821148526733024, + "controllerPathHashSuffix": 45744632695510901, + "controllerPathRemoteHashSuffix": 66440805074576541, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 10.399999618530273, + "descTextMapHash": 287638449, + "featureTagGroupId": 10000001, + "hpBase": 185.0, + "iconName": "UI_AvatarIcon_Xiangling", + "id": 11000035, + "imageName": "AvatarImage_Forward_Xiangling", + "infoDesc": 287638449, + "initialWeapon": 13101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 53222219423014270, + "nameTextMapHash": 1030006682, + "prefabPathHashSuffix": 10909423127502327, + "prefabPathRagdollHashSuffix": 42534290417828051, + "prefabPathRemoteHashSuffix": 23883907598085684, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 69282460592306296, + "sideIconName": "UI_AvatarIcon_Side_Xiangling", + "skillDepotId": 101, + "staminaRecoverSpeed": 25.0, + "sus2": 28861861250018647, + "weaponType": "WEAPON_POLE" + }, + { + "attackBase": 5.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 67993194395036856, + "controllerPathHashSuffix": 31925045831370702, + "controllerPathRemoteHashSuffix": 51066636618558810, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 8.0, + "descTextMapHash": 1059199361, + "featureTagGroupId": 10000001, + "hpBase": 166.0, + "iconName": "UI_AvatarIcon_Kate", + "id": 11000036, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 1059199361, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 55136124680407829, + "nameTextMapHash": 2849814274, + "prefabPathHashSuffix": 4729135519363573, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 38333527116904810, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Kate", + "skillDepotId": 101, + "staminaRecoverSpeed": 25.0, + "sus2": 48054748594336654, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 5.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 59543618328776858, + "controllerPathHashSuffix": 67855213607414062, + "controllerPathRemoteHashSuffix": 5761029866009395, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 11.0, + "descTextMapHash": 675318753, + "featureTagGroupId": 10000001, + "hpBase": 191.0, + "iconName": "UI_AvatarIcon_PlayerBoy", + "id": 11000037, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 675318753, + "initialWeapon": 15101, + "isRangeAttack": true, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 35523032050408816, + "nameTextMapHash": 2151605170, + "prefabPathHashSuffix": 55473383172635747, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 37462734419737349, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_PlayerBoy", + "skillDepotId": 37011, + "staminaRecoverSpeed": 25.0, + "sus2": 26174177468261742, + "weaponType": "WEAPON_BOW" + }, + { + "attackBase": 5.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 67993194395036856, + "controllerPathHashSuffix": 31925045831370702, + "controllerPathRemoteHashSuffix": 51066636618558810, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 8.0, + "descTextMapHash": 254244673, + "featureTagGroupId": 10000001, + "hpBase": 166.0, + "iconName": "UI_AvatarIcon_Kate", + "id": 11000038, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 254244673, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 55136124680407829, + "nameTextMapHash": 3973360514, + "prefabPathHashSuffix": 4729135519363573, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 38333527116904810, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Kate", + "skillDepotId": 101, + "staminaRecoverSpeed": 25.0, + "sus2": 48054748594336654, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 5.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 67993194395036856, + "controllerPathHashSuffix": 31925045831370702, + "controllerPathRemoteHashSuffix": 51066636618558810, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 8.0, + "descTextMapHash": 1995767489, + "featureTagGroupId": 10000001, + "hpBase": 166.0, + "iconName": "UI_AvatarIcon_Kate", + "id": 11000039, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 1995767489, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 55136124680407829, + "nameTextMapHash": 1823283130, + "prefabPathHashSuffix": 4729135519363573, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 38333527116904810, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_Kate", + "skillDepotId": 101, + "staminaRecoverSpeed": 25.0, + "sus2": 48054748594336654, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 17.63520050048828, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_GIRL", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 54221268921681145, + "controllerPathHashSuffix": 57046369777178771, + "controllerPathRemoteHashSuffix": 27641845635530333, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 15.975500106811523, + "descTextMapHash": 3504508073, + "featureTagGroupId": 10000001, + "hpBase": 441.9454040527344, + "iconName": "UI_AvatarIcon_PlayerGirl", + "id": 11000040, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 3504508073, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 49568657561956636, + "manekinMotionConfig": 104, + "manekinPathHashSuffix": 14355509100224805, + "nameTextMapHash": 1811000906, + "prefabPathHashSuffix": 67288539402383475, + "prefabPathRagdollHashSuffix": 54135498342059543, + "prefabPathRemoteHashSuffix": 22742062142732528, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S5", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S5", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_ORANGE", + "scriptDataPathHashSuffix": 53206626330453730, + "sideIconName": "UI_AvatarIcon_Side_PlayerGirl", + "skillDepotId": 701, + "staminaRecoverSpeed": 25.0, + "sus2": 11173696918316934, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 17.63520050048828, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 51026465958420952, + "controllerPathHashSuffix": 44795176679094917, + "controllerPathRemoteHashSuffix": 38885040096197984, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 15.975500106811523, + "descTextMapHash": 3428611249, + "featureTagGroupId": 10000001, + "hpBase": 441.9454040527344, + "iconName": "UI_AvatarIcon_PlayerBoy", + "id": 11000041, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 3428611249, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 104, + "manekinPathHashSuffix": 34720494028453975, + "nameTextMapHash": 4198235314, + "prefabPathHashSuffix": 11071674793257469, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 17877135529834519, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_PlayerBoy", + "skillDepotId": 501, + "staminaRecoverSpeed": 25.0, + "sus2": 68383554775964542, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 17.63520050048828, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_BOY", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 51026465958420952, + "controllerPathHashSuffix": 44795176679094917, + "controllerPathRemoteHashSuffix": 38885040096197984, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 15.975500106811523, + "descTextMapHash": 1912123953, + "featureTagGroupId": 10000001, + "hpBase": 441.9454040527344, + "iconName": "UI_AvatarIcon_PlayerBoy", + "id": 11000042, + "imageName": "AvatarImage_Forward_Kate", + "infoDesc": 1912123953, + "initialWeapon": 11101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 104, + "manekinPathHashSuffix": 41379525357015452, + "nameTextMapHash": 1272638962, + "prefabPathHashSuffix": 11071674793257469, + "prefabPathRagdollHashSuffix": 63561486643060887, + "prefabPathRemoteHashSuffix": 17877135529834519, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 41921077364201276, + "sideIconName": "UI_AvatarIcon_Side_PlayerBoy", + "skillDepotId": 38001, + "staminaRecoverSpeed": 25.0, + "sus2": 68383554775964542, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 99999.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_LOLI", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 29750952775514445, + "controllerPathHashSuffix": 63556748206457334, + "controllerPathRemoteHashSuffix": 65917081766789859, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 99999.0, + "descTextMapHash": 811756225, + "featureTagGroupId": 10000001, + "hpBase": 99999.0, + "iconName": "UI_AvatarIcon_Qin", + "id": 11000043, + "imageName": "AvatarImage_Forward_Qin", + "infoDesc": 811756225, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 20234876941667621, + "nameTextMapHash": 1786994050, + "prefabPathHashSuffix": 69110441157490995, + "prefabPathRagdollHashSuffix": 12381997878214711, + "prefabPathRemoteHashSuffix": 52965196649775419, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 47538393428685098, + "sideIconName": "UI_AvatarIcon_Side_Qin", + "skillDepotId": 1501, + "staminaRecoverSpeed": 25.0, + "sus2": 23710961733014766, + "weaponType": "WEAPON_CLAYMORE" + }, + { + "attackBase": 99999.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_LOLI", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 29750952775514445, + "controllerPathHashSuffix": 70139524778006043, + "controllerPathRemoteHashSuffix": 42671377569239230, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 99999.0, + "descTextMapHash": 3385550169, + "featureTagGroupId": 10000001, + "hpBase": 99999.0, + "iconName": "UI_AvatarIcon_Qin", + "id": 11000044, + "imageName": "AvatarImage_Forward_Qin", + "infoDesc": 3385550169, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 61864003452999403, + "nameTextMapHash": 1732288986, + "prefabPathHashSuffix": 42880077393031947, + "prefabPathRagdollHashSuffix": 12381997878214711, + "prefabPathRemoteHashSuffix": 34809203104559891, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 47538393428685098, + "sideIconName": "UI_AvatarIcon_Side_Qin", + "skillDepotId": 1501, + "staminaRecoverSpeed": 25.0, + "sus2": 54767824078054506, + "weaponType": "WEAPON_SWORD_ONE_HAND" + }, + { + "attackBase": 99999.0, + "avatarIdentityType": "AVATAR_IDENTITY_NORMAL", + "avatarPromoteId": 2, + "avatarPromoteRewardIdList": [], + "avatarPromoteRewardLevelList": [], + "bodyType": "BODY_LOLI", + "candSkillDepotIds": [], + "chargeEfficiency": 1.0, + "combatConfigHashSuffix": 29750952775514445, + "controllerPathHashSuffix": 25150228432339770, + "controllerPathRemoteHashSuffix": 69371559472418473, + "critical": 0.05000000074505806, + "criticalHurt": 0.5, + "cutsceneShow": "", + "defenseBase": 99999.0, + "descTextMapHash": 3033564529, + "featureTagGroupId": 10000001, + "hpBase": 99999.0, + "iconName": "UI_AvatarIcon_Qin", + "id": 11000045, + "imageName": "AvatarImage_Forward_Qin", + "infoDesc": 3033564529, + "initialWeapon": 14101, + "lodPatternName": "", + "manekinJsonConfigHashSuffix": 51388847060193563, + "manekinMotionConfig": 100, + "manekinPathHashSuffix": 13786782354610188, + "nameTextMapHash": 1907871458, + "prefabPathHashSuffix": 22027636368802546, + "prefabPathRagdollHashSuffix": 12381997878214711, + "prefabPathRemoteHashSuffix": 65410629155625777, + "propGrowCurves": [ + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_HP" + }, + { + "growCurve": "GROW_CURVE_ATTACK_S4", + "type": "FIGHT_PROP_BASE_ATTACK" + }, + { + "growCurve": "GROW_CURVE_HP_S4", + "type": "FIGHT_PROP_BASE_DEFENSE" + } + ], + "qualityType": "QUALITY_PURPLE", + "scriptDataPathHashSuffix": 47538393428685098, + "sideIconName": "UI_AvatarIcon_Side_Qin", + "skillDepotId": 1501, + "staminaRecoverSpeed": 25.0, + "sus2": 7036607745426034, + "weaponType": "WEAPON_BOW" + } +] \ No newline at end of file diff --git a/NahidaImpact.Common/assets/security/client_public_key.der b/NahidaImpact.Common/assets/security/client_public_key.der new file mode 100644 index 0000000000000000000000000000000000000000..dc86f8e270fec81d1b5438e3f2622def9471e1e9 GIT binary patch literal 294 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 literal 0 HcmV?d00001 diff --git a/NahidaImpact.Gameserver/Controllers/AccountController.cs b/NahidaImpact.Gameserver/Controllers/AccountController.cs new file mode 100644 index 0000000..f216383 --- /dev/null +++ b/NahidaImpact.Gameserver/Controllers/AccountController.cs @@ -0,0 +1,152 @@ +using NahidaImpact.Common.Constants; +using NahidaImpact.Common.Security; +using NahidaImpact.Gameserver.Controllers.Attributes; +using NahidaImpact.Gameserver.Controllers.Result; +using NahidaImpact.Gameserver.Game; +using NahidaImpact.Gameserver.Game.Avatar; +using NahidaImpact.Gameserver.Game.Scene; +using NahidaImpact.Gameserver.Network.Session; +using NahidaImpact.Protocol; + +namespace NahidaImpact.Gameserver.Controllers; + +[NetController] +internal class AccountController : ControllerBase +{ + [NetCommand(CmdType.GetPlayerTokenReq)] + public ValueTask OnGetPlayerTokenReq() + { + return ValueTask.FromResult(Response(CmdType.GetPlayerTokenRsp, new GetPlayerTokenRsp + { + ServerRandKey = "CfO2d7eEYha5bJRXdCfoiemPNAtXDpyNTQ3ObeTt5a7SSHz6GAEO1WPiTQ7fR6OG8LqhVN3ZTxH9Bnkc09BnCxud+kn0+PiGv1PTOuWK0LkQQ1xmg89zA9IHS+OJd1yKT2BBmJf4sN61gi+WtT7aFwRlzku3kGCk6p2wiPo2enE7UwCFi/GiD4vq/m3hNZiKBjitAvheaqbSLjMpBax+c8HXoY5G09ap1PjEnUQPIK0xZRRQKpnrWcCyP4j8N3WwYYQGDW+OYOJjBvJdv+D6XSdEi+4IsZASYVpu9V8UZ570Cakbc+IjUm0UZJXghcR7izIjKtoNHf2Fmc26DEp1Jw==", +Sign = "mMx/Klovbzq1QxQvVgm30nYhj0jDOykyo9aparyWRNz3ACxV/2gIdLpyM/SMerWMTcx26NapQ9HsKK7BRK7Yx+nMR0O83BkBlxfl+NEarYr6kj9lBKAxZYXTXFRYA4sRynvwa/MOPmGwYMNl6aVvMohhvrsTopsRvIuGFtnCVL2wBfbxcNnbVfP5k+DxPuQnxa/vi+ju8TogW2R+r0p9zQ5NJe1oaYe4xYbyhefFVv11FA/JQHwMHLEyrEdPqTzdN75CUmE09yLuAoeJzoJ1vwwjwfcH9dMDPxsewNJBGiylVHYf56kF4HypNkYNjtxbghgLBaHg0ZoeYHTOJ7YUTQ==", + Uid = 1337, + CountryCode = "RU", + PlatformType = 3 + })); + } + + [NetCommand(CmdType.PingReq)] + public ValueTask OnPingReq() + { + return ValueTask.FromResult(Response(CmdType.PingRsp, new PingRsp + { + //ServerTime = (uint)DateTimeOffset.Now.ToUnixTimeSeconds() + })); + } + + [NetCommand(CmdType.PlayerLoginReq)] + public async ValueTask OnPlayerLoginReq(NetSession session, Player player, SceneManager sceneManager) + { + player.InitDefaultPlayer(); + + await session.NotifyAsync(CmdType.PlayerDataNotify, new PlayerDataNotify + { + NickName = player.Name, + PropMap = + { + {PlayerProp.PROP_PLAYER_LEVEL, new() { Type = PlayerProp.PROP_PLAYER_LEVEL, Ival = 5 } }, + {PlayerProp.PROP_IS_FLYABLE, new() { Type = PlayerProp.PROP_IS_FLYABLE, Ival = 1 } }, + {PlayerProp.PROP_MAX_STAMINA, new() { Type = PlayerProp.PROP_MAX_STAMINA, Ival = 10000 } }, + {PlayerProp.PROP_CUR_PERSIST_STAMINA, new() { Type = PlayerProp.PROP_CUR_PERSIST_STAMINA, Ival = 10000 } }, + {PlayerProp.PROP_IS_TRANSFERABLE, new() { Type = PlayerProp.PROP_IS_TRANSFERABLE, Ival = 1 } }, + {PlayerProp.PROP_IS_SPRING_AUTO_USE, new() { Type = PlayerProp.PROP_IS_SPRING_AUTO_USE, Ival = 1 } }, + {PlayerProp.PROP_SPRING_AUTO_USE_PERCENT, new() { Type = PlayerProp.PROP_SPRING_AUTO_USE_PERCENT, Ival = 50 } } + } + }); + + AvatarDataNotify avatarDataNotify = new() + { + CurAvatarTeamId = player.CurTeamIndex, + ChooseAvatarGuid = 228 + }; + + foreach (GameAvatar gameAvatar in player.Avatars) + { + avatarDataNotify.AvatarList.Add(gameAvatar.AsAvatarInfo()); + } + + foreach (GameAvatarTeam team in player.AvatarTeams) + { + AvatarTeam avatarTeam = new(); + avatarTeam.AvatarGuidList.AddRange(team.AvatarGuidList); + + avatarDataNotify.AvatarTeamMap.Add(team.Index, avatarTeam); + } + + await session.NotifyAsync(CmdType.AvatarDataNotify, avatarDataNotify); + + await session.NotifyAsync(CmdType.OpenStateUpdateNotify, new OpenStateUpdateNotify + { + OpenStateMap = + { + {1, 1}, + {2, 1}, + {3, 1}, + {4, 1}, + {5, 1}, + {6, 1}, + {7, 0}, + {8, 1}, + {10, 1}, + {11, 1}, + {12, 1}, + {13, 1}, + {14, 1}, + {15, 1}, + {27, 1}, + {28, 1}, + {29, 1}, + {30, 1}, + {31, 1}, + {32, 1}, + {33, 1}, + {37, 1}, + {38, 1}, + {45, 1}, + {47, 1}, + {53, 1}, + {54, 1}, + {55, 1}, + {59, 1}, + {62, 1}, + {65, 1}, + {900, 1}, + {901, 1}, + {902, 1}, + {903, 1}, + {1001, 1}, + {1002, 1}, + {1003, 1}, + {1004, 1}, + {1005, 1}, + {1007, 1}, + {1008, 1}, + {1009, 1}, + {1010, 1}, + {1100, 1}, + {1103, 1}, + {1300, 1}, + {1401, 1}, + {1403, 1}, + {1700, 1}, + {2100, 1}, + {2101, 1}, + {2103, 1}, + {2400, 1}, + {3701, 1}, + {3702, 1}, + {4100, 1 } + } + }); + + await sceneManager.EnterSceneAsync(3); + + return Response(CmdType.PlayerLoginRsp, new PlayerLoginRsp + { + CountryCode = "RU", + GameBiz = "hk4e_global", + ResVersionConfig = new() + }); + } +} diff --git a/NahidaImpact.Gameserver/Controllers/Attributes/NetCommandAttribute.cs b/NahidaImpact.Gameserver/Controllers/Attributes/NetCommandAttribute.cs new file mode 100644 index 0000000..6436d65 --- /dev/null +++ b/NahidaImpact.Gameserver/Controllers/Attributes/NetCommandAttribute.cs @@ -0,0 +1,9 @@ +using NahidaImpact.Protocol; + +namespace NahidaImpact.Gameserver.Controllers.Attributes; + +[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] +internal class NetCommandAttribute(CmdType cmdType) : Attribute +{ + public CmdType CmdType { get; } = cmdType; +} diff --git a/NahidaImpact.Gameserver/Controllers/Attributes/NetControllerAttribute.cs b/NahidaImpact.Gameserver/Controllers/Attributes/NetControllerAttribute.cs new file mode 100644 index 0000000..49120bd --- /dev/null +++ b/NahidaImpact.Gameserver/Controllers/Attributes/NetControllerAttribute.cs @@ -0,0 +1,6 @@ +namespace NahidaImpact.Gameserver.Controllers.Attributes; + +[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] +internal class NetControllerAttribute : Attribute +{ +} diff --git a/NahidaImpact.Gameserver/Controllers/AvatarController.cs b/NahidaImpact.Gameserver/Controllers/AvatarController.cs new file mode 100644 index 0000000..4957ba9 --- /dev/null +++ b/NahidaImpact.Gameserver/Controllers/AvatarController.cs @@ -0,0 +1,35 @@ +using NahidaImpact.Gameserver.Controllers.Attributes; +using NahidaImpact.Gameserver.Controllers.Result; +using NahidaImpact.Gameserver.Game.Scene; +using NahidaImpact.Gameserver.Network.Session; +using NahidaImpact.Protocol; + +namespace NahidaImpact.Gameserver.Controllers; + +[NetController] +internal class AvatarController : ControllerBase +{ + [NetCommand(CmdType.SetUpAvatarTeamReq)] + public async ValueTask OnSetUpAvatarTeamReq(NetSession session, SceneManager sceneManager) + { + SetUpAvatarTeamReq request = Packet!.DecodeBody(); + + AvatarTeam newTeam = new(); + newTeam.AvatarGuidList.AddRange(request.AvatarTeamGuidList); + await session.NotifyAsync(CmdType.AvatarTeamUpdateNotify, new AvatarTeamUpdateNotify + { + AvatarTeamMap = { { request.TeamId, newTeam } } + }); + + await sceneManager.ChangeTeamAvatarsAsync(request.AvatarTeamGuidList.ToArray()); + + SetUpAvatarTeamRsp response = new() + { + CurAvatarGuid = request.CurAvatarGuid, + TeamId = request.TeamId, + }; + response.AvatarTeamGuidList.AddRange(request.AvatarTeamGuidList); + + return Response(CmdType.SetUpAvatarTeamRsp, response); + } +} diff --git a/NahidaImpact.Gameserver/Controllers/ControllerBase.cs b/NahidaImpact.Gameserver/Controllers/ControllerBase.cs new file mode 100644 index 0000000..33f94d8 --- /dev/null +++ b/NahidaImpact.Gameserver/Controllers/ControllerBase.cs @@ -0,0 +1,25 @@ +using NahidaImpact.Gameserver.Controllers.Result; +using NahidaImpact.Gameserver.Network; +using NahidaImpact.Protocol; +using Google.Protobuf; + +namespace NahidaImpact.Gameserver.Controllers; +internal abstract class ControllerBase +{ + public NetPacket? Packet { get; set; } + + protected IResult Ok() + { + return new SinglePacketResult(null); + } + + protected IResult Response(CmdType cmdType, TMessage message) where TMessage : IMessage + { + return new SinglePacketResult(new() + { + CmdType = cmdType, + Head = Memory.Empty, + Body = message.ToByteArray() + }); + } +} diff --git a/NahidaImpact.Gameserver/Controllers/Dispatching/NetCommandDispatcher.cs b/NahidaImpact.Gameserver/Controllers/Dispatching/NetCommandDispatcher.cs new file mode 100644 index 0000000..b339821 --- /dev/null +++ b/NahidaImpact.Gameserver/Controllers/Dispatching/NetCommandDispatcher.cs @@ -0,0 +1,99 @@ +using System.Collections.Immutable; +using System.Linq.Expressions; +using System.Reflection; +using NahidaImpact.Gameserver.Controllers.Attributes; +using NahidaImpact.Gameserver.Controllers.Result; +using NahidaImpact.Gameserver.Network; +using NahidaImpact.Protocol; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace NahidaImpact.Gameserver.Controllers.Dispatching; +internal class NetCommandDispatcher(IServiceProvider serviceProvider, ILogger logger) +{ + private static readonly ImmutableDictionary>> _handlers; + private readonly IServiceProvider _serviceProvider = serviceProvider; + private readonly ILogger _logger = logger; + + static NetCommandDispatcher() + { + _handlers = InitializeHandlers(); + } + + public async ValueTask InvokeHandler(NetPacket packet) + { + ArgumentNullException.ThrowIfNull(packet, nameof(packet)); + + if (_handlers.TryGetValue(packet.CmdType, out Func>? handler)) + { + return await handler(_serviceProvider, packet); + } + + _logger.LogWarning("No handler defined for command of type {cmdType}", packet.CmdType); + return null; + } + + private static ImmutableDictionary>> InitializeHandlers() + { + ImmutableDictionary>>.Builder builder + = ImmutableDictionary.CreateBuilder>>(); + + IEnumerable types = Assembly.GetExecutingAssembly().GetTypes() + .Where(type => type.GetCustomAttribute() != null); + + foreach (Type type in types) + { + IEnumerable methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public) + .Where(method => method.GetCustomAttribute() != null); + + foreach (MethodInfo method in methods) + { + NetCommandAttribute attribute = method.GetCustomAttribute()!; + if (builder.TryGetKey(attribute.CmdType, out _)) + throw new Exception($"Handler for command {attribute.CmdType} defined twice!"); + + builder[attribute.CmdType] = CreateHandlerDelegate(type, method); + } + } + + return builder.ToImmutable(); + } + + private static Func> CreateHandlerDelegate(Type controllerType, MethodInfo method) + { + ParameterExpression serviceProviderParameter = Expression.Parameter(typeof(IServiceProvider), "serviceProvider"); + ParameterExpression netPacketParameter = Expression.Parameter(typeof(NetPacket), "packet"); + + ConstantExpression controllerTypeConstant = Expression.Constant(controllerType); + ParameterExpression controllerVariable = Expression.Variable(controllerType, "controller"); + PropertyInfo packetProperty = typeof(ControllerBase).GetProperty("Packet")!; + + MethodInfo createInstanceMethod = typeof(ActivatorUtilities).GetMethod("CreateInstance", [typeof(IServiceProvider), typeof(Type), typeof(object[])])!; + + List expressionBlock = + [ + Expression.Assign(controllerVariable, Expression.Convert( + Expression.Call(null, createInstanceMethod, serviceProviderParameter, controllerTypeConstant, Expression.Constant(Array.Empty())), + controllerType)), + Expression.Assign(Expression.Property(controllerVariable, packetProperty), netPacketParameter) + ]; + + List parameterExpressions = []; + foreach (ParameterInfo parameter in method.GetParameters()) + { + MethodInfo getServiceMethod = typeof(ServiceProviderServiceExtensions) + .GetMethod("GetRequiredService", [typeof(IServiceProvider)])! + .MakeGenericMethod(parameter.ParameterType); + + parameterExpressions.Add(Expression.Call(getServiceMethod, serviceProviderParameter)); + } + + expressionBlock.Add(Expression.Call(controllerVariable, method, parameterExpressions)); + + return Expression.Lambda>>( + Expression.Block(new[] { controllerVariable }, expressionBlock), + serviceProviderParameter, + netPacketParameter) + .Compile(); + } +} diff --git a/NahidaImpact.Gameserver/Controllers/Result/IResult.cs b/NahidaImpact.Gameserver/Controllers/Result/IResult.cs new file mode 100644 index 0000000..0bae983 --- /dev/null +++ b/NahidaImpact.Gameserver/Controllers/Result/IResult.cs @@ -0,0 +1,8 @@ +using System.Diagnostics.CodeAnalysis; +using NahidaImpact.Gameserver.Network; + +namespace NahidaImpact.Gameserver.Controllers.Result; +internal interface IResult +{ + bool NextPacket([MaybeNullWhen(false)] out NetPacket packet); +} diff --git a/NahidaImpact.Gameserver/Controllers/Result/SinglePacketResult.cs b/NahidaImpact.Gameserver/Controllers/Result/SinglePacketResult.cs new file mode 100644 index 0000000..3ffc83f --- /dev/null +++ b/NahidaImpact.Gameserver/Controllers/Result/SinglePacketResult.cs @@ -0,0 +1,16 @@ +using System.Diagnostics.CodeAnalysis; +using NahidaImpact.Gameserver.Network; + +namespace NahidaImpact.Gameserver.Controllers.Result; +internal class SinglePacketResult(NetPacket? packet) : IResult +{ + private NetPacket? _packet = packet; + + public bool NextPacket([MaybeNullWhen(false)] out NetPacket packet) + { + packet = _packet; + _packet = null; + + return packet != null; + } +} diff --git a/NahidaImpact.Gameserver/Controllers/SceneController.cs b/NahidaImpact.Gameserver/Controllers/SceneController.cs new file mode 100644 index 0000000..0a00101 --- /dev/null +++ b/NahidaImpact.Gameserver/Controllers/SceneController.cs @@ -0,0 +1,57 @@ +using NahidaImpact.Gameserver.Controllers.Attributes; +using NahidaImpact.Gameserver.Controllers.Result; +using NahidaImpact.Gameserver.Game.Scene; +using NahidaImpact.Protocol; + +namespace NahidaImpact.Gameserver.Controllers; + +[NetController] +internal class SceneController : ControllerBase +{ + // TODO: Scene management, Entity management!!! + public const uint WeaponEntityId = 100663300; + + [NetCommand(CmdType.PostEnterSceneReq)] + public async ValueTask OnPostEnterSceneReq(SceneManager sceneManager) + { + await sceneManager.OnEnterStateChanged(SceneEnterState.PostEnter); + + return Response(CmdType.PostEnterSceneRsp, new PostEnterSceneRsp + { + EnterSceneToken = sceneManager.EnterToken + }); + } + + [NetCommand(CmdType.EnterSceneDoneReq)] + public async ValueTask OnEnterSceneDoneReq(SceneManager sceneManager) + { + await sceneManager.OnEnterStateChanged(SceneEnterState.EnterDone); + + return Response(CmdType.EnterSceneDoneRsp, new EnterSceneDoneRsp + { + EnterSceneToken = sceneManager.EnterToken + }); + } + + [NetCommand(CmdType.SceneInitFinishReq)] + public async ValueTask OnSceneInitFinishReq(SceneManager sceneManager) + { + await sceneManager.OnEnterStateChanged(SceneEnterState.InitFinished); + + return Response(CmdType.SceneInitFinishRsp, new SceneInitFinishRsp + { + EnterSceneToken = sceneManager.EnterToken + }); + } + + [NetCommand(CmdType.EnterSceneReadyReq)] + public async ValueTask OnEnterSceneReadyReq(SceneManager sceneManager) + { + await sceneManager.OnEnterStateChanged(SceneEnterState.ReadyToEnter); + + return Response(CmdType.EnterSceneReadyRsp, new EnterSceneReadyRsp + { + EnterSceneToken = sceneManager.EnterToken + }); + } +} diff --git a/NahidaImpact.Gameserver/Game/Avatar/GameAvatar.cs b/NahidaImpact.Gameserver/Game/Avatar/GameAvatar.cs new file mode 100644 index 0000000..bffd4af --- /dev/null +++ b/NahidaImpact.Gameserver/Game/Avatar/GameAvatar.cs @@ -0,0 +1,135 @@ +using NahidaImpact.Common.Constants; +using NahidaImpact.Common.Data.Excel; +using NahidaImpact.Protocol; + +namespace NahidaImpact.Gameserver.Game.Avatar; +internal class GameAvatar +{ + public const ulong WeaponGuid = 2281337; + + public ulong Guid { get; set; } + + public uint AvatarId { get; set; } + public uint SkillDepotId { get; set; } + public uint WearingFlycloakId { get; set; } + public uint BornTime { get; set; } + + public uint WeaponId { get; set; } // TODO: Weapon class! + + // Properties + public List Properties; + public List FightProperties; + + public GameAvatar() + { + Properties = []; + FightProperties = []; + } + + public void InitDefaultProps(AvatarExcel avatarExcel) + { + Properties.Clear(); + FightProperties.Clear(); + + SetProp(PlayerProp.PROP_LEVEL, 1); + SetProp(PlayerProp.PROP_EXP, 0); + SetProp(PlayerProp.PROP_BREAK_LEVEL, 0); + + float baseHp = (float)avatarExcel.HpBase; + float baseAttack = (float)avatarExcel.AttackBase; + float baseDefense = (float)avatarExcel.DefenseBase; + + SetFightProp(FightProp.FIGHT_PROP_BASE_HP, baseHp); + SetFightProp(FightProp.FIGHT_PROP_CUR_HP, baseHp); + SetFightProp(FightProp.FIGHT_PROP_MAX_HP, baseHp); + + SetFightProp(FightProp.FIGHT_PROP_BASE_ATTACK, baseAttack); + SetFightProp(FightProp.FIGHT_PROP_CUR_ATTACK, baseAttack); + + SetFightProp(FightProp.FIGHT_PROP_BASE_DEFENSE, baseDefense); + SetFightProp(FightProp.FIGHT_PROP_CUR_DEFENSE, baseDefense); + + SetFightProp(FightProp.FIGHT_PROP_CHARGE_EFFICIENCY, (float)avatarExcel.ChargeEfficiency); + SetFightProp(FightProp.FIGHT_PROP_CRITICAL_HURT, (float)avatarExcel.CriticalHurt); + SetFightProp(FightProp.FIGHT_PROP_CRITICAL, (float)avatarExcel.Critical); + + SetFightProp(FightProp.FIGHT_PROP_CUR_FIRE_ENERGY, 100); + SetFightProp(FightProp.FIGHT_PROP_CUR_ELEC_ENERGY, 100); + SetFightProp(FightProp.FIGHT_PROP_CUR_WATER_ENERGY, 100); + SetFightProp(FightProp.FIGHT_PROP_CUR_GRASS_ENERGY, 100); + SetFightProp(FightProp.FIGHT_PROP_CUR_WIND_ENERGY, 100); + SetFightProp(FightProp.FIGHT_PROP_CUR_ICE_ENERGY, 100); + SetFightProp(FightProp.FIGHT_PROP_CUR_ROCK_ENERGY, 100); + SetFightProp(FightProp.FIGHT_PROP_MAX_FIRE_ENERGY, 100); + SetFightProp(FightProp.FIGHT_PROP_MAX_ELEC_ENERGY, 100); + SetFightProp(FightProp.FIGHT_PROP_MAX_WATER_ENERGY, 100); + SetFightProp(FightProp.FIGHT_PROP_MAX_GRASS_ENERGY, 100); + SetFightProp(FightProp.FIGHT_PROP_MAX_WIND_ENERGY, 100); + SetFightProp(FightProp.FIGHT_PROP_MAX_ICE_ENERGY, 100); + SetFightProp(FightProp.FIGHT_PROP_MAX_ROCK_ENERGY, 100); + } + + public void SetProp(uint propType, uint value) + { + PropValue? prop = Properties.Find(p => p.Type == propType); + if (prop != null) + { + prop.Ival = value; + return; + } + + Properties.Add(new PropValue { Type = propType, Ival = value }); + } + + public void SetProp(uint propType, float value) + { + PropValue? prop = Properties.Find(p => p.Type == propType); + if (prop != null) + { + prop.Fval = value; + return; + } + + Properties.Add(new PropValue { Type = propType, Fval = value }); + } + + public void SetFightProp(uint propType, float value) + { + FightPropPair? fightPropPair = FightProperties.Find(pair => pair.PropType == propType); + if (fightPropPair != null) + { + fightPropPair.PropValue = value; + return; + } + + FightProperties.Add(new FightPropPair { PropType = propType, PropValue = value }); + } + + public AvatarInfo AsAvatarInfo() + { + AvatarInfo info = new() + { + Guid = Guid, + AvatarId = AvatarId, + SkillDepotId = SkillDepotId, + LifeState = 1, + AvatarType = 1, + WearingFlycloakId = WearingFlycloakId, + BornTime = BornTime, + FetterInfo = new() { ExpLevel = 1 }, + EquipGuidList = { WeaponGuid } // no weapon classes for now + }; + + foreach (PropValue prop in Properties) + { + info.PropMap.Add(prop.Type, prop); + } + + foreach (FightPropPair pair in FightProperties) + { + info.FightPropMap.Add(pair.PropType, pair.PropValue); + } + + return info; + } +} diff --git a/NahidaImpact.Gameserver/Game/Avatar/GameAvatarTeam.cs b/NahidaImpact.Gameserver/Game/Avatar/GameAvatarTeam.cs new file mode 100644 index 0000000..78648ec --- /dev/null +++ b/NahidaImpact.Gameserver/Game/Avatar/GameAvatarTeam.cs @@ -0,0 +1,11 @@ +namespace NahidaImpact.Gameserver.Game.Avatar; +internal class GameAvatarTeam +{ + public uint Index { get; set; } + public List AvatarGuidList { get; set; } + + public GameAvatarTeam() + { + AvatarGuidList = []; + } +} diff --git a/NahidaImpact.Gameserver/Game/Entity/AvatarEntity.cs b/NahidaImpact.Gameserver/Game/Entity/AvatarEntity.cs new file mode 100644 index 0000000..43fe47b --- /dev/null +++ b/NahidaImpact.Gameserver/Game/Entity/AvatarEntity.cs @@ -0,0 +1,99 @@ +using NahidaImpact.Common.Constants; +using NahidaImpact.Common.Data.Binout; +using NahidaImpact.Common.Data.Binout.Ability; +using NahidaImpact.Common.Extensions; +using NahidaImpact.Gameserver.Controllers; +using NahidaImpact.Gameserver.Game.Avatar; +using NahidaImpact.Protocol; + +namespace NahidaImpact.Gameserver.Game.Entity; +internal class AvatarEntity : SceneEntity +{ + public override ProtEntityType EntityType => ProtEntityType.Avatar; + + public uint Uid { get; } + public GameAvatar GameAvatar { get; } + + public AvatarEntity(GameAvatar gameAvatar, uint uid, uint entityId) : base(entityId) + { + Uid = uid; + GameAvatar = gameAvatar; + Properties = gameAvatar.Properties; + FightProperties = gameAvatar.FightProperties; + } + + public AbilityControlBlock BuildAbilityControlBlock(BinDataCollection binData) + { + AbilityControlBlock abilityControlBlock = new(); + AvatarConfig avatarConfig = binData.GetAvatarConfig(GameAvatar.AvatarId); + + uint defaultOverrideHash = "Default".GetStableHash(); + foreach (string abilityName in AvatarConstants.CommonAbilities) + { + abilityControlBlock.AbilityEmbryoList.Add(new AbilityEmbryo + { + AbilityId = (uint)(abilityControlBlock.AbilityEmbryoList.Count + 1), + AbilityNameHash = abilityName.GetStableHash(), + AbilityOverrideNameHash = defaultOverrideHash + }); + } + + foreach (AbilityData ability in avatarConfig.Abilities) + { + abilityControlBlock.AbilityEmbryoList.Add(new AbilityEmbryo + { + AbilityId = (uint)(abilityControlBlock.AbilityEmbryoList.Count + 1), + AbilityNameHash = ability.AbilityName.GetStableHash(), + AbilityOverrideNameHash = ability.GetAbilityOverride().GetStableHash() + }); + } + + return abilityControlBlock; + } + + public override SceneEntityInfo AsInfo() + { + SceneEntityInfo info = base.AsInfo(); + + info.Avatar = new() + { + Uid = Uid, + AvatarId = GameAvatar.AvatarId, + Guid = GameAvatar.Guid, + PeerId = 1, + EquipIdList = { GameAvatar.WeaponId }, + SkillDepotId = GameAvatar.SkillDepotId, + Weapon = new SceneWeaponInfo + { + EntityId = SceneController.WeaponEntityId, + GadgetId = 50000000 + GameAvatar.WeaponId, + ItemId = GameAvatar.WeaponId, + Guid = GameAvatar.WeaponGuid, + Level = 1, + PromoteLevel = 0, + AbilityInfo = new() + }, + CoreProudSkillLevel = 0, + InherentProudSkillList = { 832301 }, + SkillLevelMap = + { + { 10832, 1 }, + { 10835, 1 }, + { 10831, 1 } + }, + ProudSkillExtraLevelMap = + { + { 8331, 0 }, + { 8332, 0 }, + { 8339, 0 } + }, + TeamResonanceList = { 10301 }, + WearingFlycloakId = GameAvatar.WearingFlycloakId, + BornTime = GameAvatar.BornTime, + CostumeId = 0, + AnimHash = 0 + }; + + return info; + } +} diff --git a/NahidaImpact.Gameserver/Game/Entity/EntityManager.cs b/NahidaImpact.Gameserver/Game/Entity/EntityManager.cs new file mode 100644 index 0000000..f4a9476 --- /dev/null +++ b/NahidaImpact.Gameserver/Game/Entity/EntityManager.cs @@ -0,0 +1,20 @@ +using NahidaImpact.Gameserver.Game.Entity.Listener; +using NahidaImpact.Protocol; + +namespace NahidaImpact.Gameserver.Game.Entity; +internal class EntityManager(IEntityEventListener listener) +{ + private readonly List _entities = []; + private readonly IEntityEventListener _listener = listener; + + public async ValueTask SpawnEntityAsync(SceneEntity entity, VisionType visionType) + { + _entities.Add(entity); + await _listener.OnEntitySpawned(entity, visionType); + } + + public void Reset() + { + _entities.Clear(); + } +} diff --git a/NahidaImpact.Gameserver/Game/Entity/Factory/EntityFactory.cs b/NahidaImpact.Gameserver/Game/Entity/Factory/EntityFactory.cs new file mode 100644 index 0000000..ed46456 --- /dev/null +++ b/NahidaImpact.Gameserver/Game/Entity/Factory/EntityFactory.cs @@ -0,0 +1,12 @@ +using NahidaImpact.Gameserver.Game.Avatar; + +namespace NahidaImpact.Gameserver.Game.Entity.Factory; +internal class EntityFactory +{ + private uint _entityIdSeed; + + public AvatarEntity CreateAvatar(GameAvatar gameAvatar, uint belongUid) + { + return new(gameAvatar, belongUid, ++_entityIdSeed); + } +} diff --git a/NahidaImpact.Gameserver/Game/Entity/Listener/IEntityEventListener.cs b/NahidaImpact.Gameserver/Game/Entity/Listener/IEntityEventListener.cs new file mode 100644 index 0000000..9506898 --- /dev/null +++ b/NahidaImpact.Gameserver/Game/Entity/Listener/IEntityEventListener.cs @@ -0,0 +1,7 @@ +using NahidaImpact.Protocol; + +namespace NahidaImpact.Gameserver.Game.Entity.Listener; +internal interface IEntityEventListener +{ + ValueTask OnEntitySpawned(SceneEntity entity, VisionType visionType); +} diff --git a/NahidaImpact.Gameserver/Game/Entity/SceneEntity.cs b/NahidaImpact.Gameserver/Game/Entity/SceneEntity.cs new file mode 100644 index 0000000..685854c --- /dev/null +++ b/NahidaImpact.Gameserver/Game/Entity/SceneEntity.cs @@ -0,0 +1,69 @@ +using NahidaImpact.Protocol; + +namespace NahidaImpact.Gameserver.Game.Entity; +internal abstract class SceneEntity +{ + public abstract ProtEntityType EntityType { get; } + + public uint EntityId { get; } + public MotionInfo MotionInfo { get; set; } + public List Properties { get; set; } + public List FightProperties { get; set; } + + public SceneEntity(uint entityId) + { + EntityId = ((uint)EntityType << 24) + entityId; + + MotionInfo = new() { Pos = new(), Rot = new(), Speed = new() }; + Properties = []; + FightProperties = []; + } + + public void SetPosition(float x, float y, float z) + { + MotionInfo.Pos.X = x; + MotionInfo.Pos.Y = y; + MotionInfo.Pos.Z = z; + } + + public void SetRotation(float x, float y, float z) + { + MotionInfo.Rot.X = x; + MotionInfo.Rot.Y = y; + MotionInfo.Rot.Z = z; + } + + public virtual SceneEntityInfo AsInfo() + { + SceneEntityInfo info = new() + { + EntityType = EntityType, + EntityId = EntityId, + MotionInfo = MotionInfo, + LifeState = 1, + EntityClientData = new(), + EntityAuthorityInfo = new EntityAuthorityInfo + { + AbilityInfo = new(), + AiInfo = new() + { + IsAiOpen = true, + BornPos = new() + }, + BornPos = new(), + ClientExtraInfo = new(), + RendererChangedInfo = new() + }, + AnimatorParaList = { new AnimatorParameterValueInfoPair() } + }; + + foreach (PropValue prop in Properties) + { + info.PropList.Add(new PropPair { Type = prop.Type, PropValue = prop }); + } + + info.FightPropList.AddRange(FightProperties); + + return info; + } +} diff --git a/NahidaImpact.Gameserver/Game/Player.cs b/NahidaImpact.Gameserver/Game/Player.cs new file mode 100644 index 0000000..0c2da5c --- /dev/null +++ b/NahidaImpact.Gameserver/Game/Player.cs @@ -0,0 +1,72 @@ +using System.Diagnostics.CodeAnalysis; +using NahidaImpact.Common.Data.Excel; +using NahidaImpact.Gameserver.Game.Avatar; + +namespace NahidaImpact.Gameserver.Game; +internal class Player(ExcelTableCollection excelTables) +{ + private static readonly uint[] AvatarBlackList = [10000001, 10000007]; // kate and traveler + + public uint Uid { get; set; } + public uint GuidSeed { get; set; } + public string Name { get; set; } = "Traveler"; + + public List Avatars { get; set; } = []; + public List AvatarTeams { get; set; } = []; + public uint CurTeamIndex { get; set; } + + private readonly ExcelTableCollection _excelTables = excelTables; + + public void InitDefaultPlayer() + { + // We don't have database atm, so let's init default player state for every session. + + Uid = 1337; + Name = "ReversedRooms"; + + UnlockAllAvatars(); + + _ = TryGetAvatar(10000073, out GameAvatar? avatar); + AvatarTeams.Add(new() + { + AvatarGuidList = [avatar!.Guid], + Index = 1 + }); + CurTeamIndex = 1; + } + + public GameAvatarTeam GetCurrentTeam() + => AvatarTeams.Find(team => team.Index == CurTeamIndex)!; + + public bool TryGetAvatar(uint avatarId, [MaybeNullWhen(false)] out GameAvatar avatar) + => (avatar = Avatars.Find(a => a.AvatarId == avatarId)) != null; + + private void UnlockAllAvatars() + { + ExcelTable avatarTable = _excelTables.GetTable(ExcelType.Avatar); + for (int i = 0; i < avatarTable.Count; i++) + { + AvatarExcel avatarExcel = avatarTable.GetItemAt(i); + if (AvatarBlackList.Contains(avatarExcel.Id) || avatarExcel.Id >= 11000000) continue; + + uint currentTimestamp = (uint)DateTimeOffset.Now.ToUnixTimeSeconds(); + GameAvatar avatar = new() + { + AvatarId = avatarExcel.Id, + SkillDepotId = avatarExcel.SkillDepotId, + WeaponId = avatarExcel.InitialWeapon, + BornTime = currentTimestamp, + Guid = NextGuid(), + WearingFlycloakId = 140001 + }; + + avatar.InitDefaultProps(avatarExcel); + Avatars.Add(avatar); + } + } + + public ulong NextGuid() + { + return ((ulong)Uid << 32) + (++GuidSeed); + } +} diff --git a/NahidaImpact.Gameserver/Game/Scene/SceneEnterState.cs b/NahidaImpact.Gameserver/Game/Scene/SceneEnterState.cs new file mode 100644 index 0000000..1069531 --- /dev/null +++ b/NahidaImpact.Gameserver/Game/Scene/SceneEnterState.cs @@ -0,0 +1,12 @@ +namespace NahidaImpact.Gameserver.Game.Scene; +internal enum SceneEnterState +{ + None = -1, + EnterRequested, + ReadyToEnter, + InitFinished, + EnterDone, + PostEnter, + + Complete +} diff --git a/NahidaImpact.Gameserver/Game/Scene/SceneManager.cs b/NahidaImpact.Gameserver/Game/Scene/SceneManager.cs new file mode 100644 index 0000000..1bf5514 --- /dev/null +++ b/NahidaImpact.Gameserver/Game/Scene/SceneManager.cs @@ -0,0 +1,209 @@ +using System.Numerics; +using NahidaImpact.Common.Data.Binout; +using NahidaImpact.Gameserver.Controllers; +using NahidaImpact.Gameserver.Game.Avatar; +using NahidaImpact.Gameserver.Game.Entity; +using NahidaImpact.Gameserver.Game.Entity.Factory; +using NahidaImpact.Gameserver.Network.Session; +using NahidaImpact.Protocol; + +namespace NahidaImpact.Gameserver.Game.Scene; +internal class SceneManager(NetSession session, Player player, EntityManager entityManager, EntityFactory entityFactory, BinDataCollection binData) +{ + public uint EnterToken { get; private set; } + + private readonly BinDataCollection _binData = binData; + + private readonly NetSession _session = session; + private readonly Player _player = player; + private readonly EntityManager _entityManager = entityManager; + private readonly EntityFactory _entityFactory = entityFactory; + + private readonly List _teamAvatars = []; + + private uint _enterTokenSeed; + private uint _sceneId; + private ulong _beginTime; + + private SceneEnterState _enterState; + + public async ValueTask OnEnterStateChanged(SceneEnterState changedToState) + { + if (_enterState is SceneEnterState.None or SceneEnterState.Complete) + throw new InvalidOperationException($"SceneManager::OnEnterStateChanged called when enter state is {_enterState}!"); + + if (_enterState > changedToState) + throw new ArgumentException($"SceneManager::OnEnterStateChanged - requested state is less than current! (curr={_enterState}, req={changedToState})"); + + if (_enterState + 1 != changedToState) + throw new ArgumentException($"SceneManager::OnEnterStateChanged - trying to skip enter state! (curr={_enterState}, req={changedToState})"); + + _enterState = changedToState; + switch (_enterState) + { + case SceneEnterState.ReadyToEnter: + await OnReadyToEnterScene(); + break; + case SceneEnterState.InitFinished: + await OnSceneInitFinished(); + break; + case SceneEnterState.EnterDone: + await OnEnterDone(); + break; + case SceneEnterState.PostEnter: + await OnPostEnter(); + break; + } + + if (_enterState == SceneEnterState.PostEnter) + _enterState = SceneEnterState.Complete; + } + + public async ValueTask ChangeTeamAvatarsAsync(ulong[] guidList) + { + _teamAvatars.Clear(); + + foreach (ulong guid in guidList) + { + GameAvatar gameAvatar = _player.Avatars.Find(avatar => avatar.Guid == guid)!; // currently only first one + + AvatarEntity avatarEntity = _entityFactory.CreateAvatar(gameAvatar, _player.Uid); + avatarEntity.SetPosition(2336.789f, 249.98896f, -751.3081f); + + _teamAvatars.Add(avatarEntity); + } + + await SendSceneTeamUpdate(); + await _entityManager.SpawnEntityAsync(_teamAvatars[0], VisionType.Born); + } + + private async ValueTask OnEnterDone() + { + await _entityManager.SpawnEntityAsync(_teamAvatars[0], VisionType.Born); + } + + private async ValueTask OnSceneInitFinished() + { + GameAvatarTeam avatarTeam = _player.GetCurrentTeam(); + + foreach (ulong guid in avatarTeam.AvatarGuidList) + { + GameAvatar gameAvatar = _player.Avatars.Find(avatar => avatar.Guid == guid)!; + + AvatarEntity avatarEntity = _entityFactory.CreateAvatar(gameAvatar, _player.Uid); + avatarEntity.SetPosition(2336.789f, 249.98896f, -751.3081f); + + _teamAvatars.Add(avatarEntity); + } + + await SendEnterSceneInfo(); + await SendSceneTeamUpdate(); + } + + private async ValueTask OnReadyToEnterScene() + { + await _session.NotifyAsync(CmdType.EnterScenePeerNotify, new EnterScenePeerNotify + { + DestSceneId = _sceneId, + EnterSceneToken = EnterToken, + HostPeerId = 1, // TODO: Scene peers + PeerId = 1 + }); + } + + private ValueTask OnPostEnter() + { + return ValueTask.CompletedTask; + } + + public async ValueTask EnterSceneAsync(uint sceneId) + { + if (_beginTime != 0) ResetState(); + + _beginTime = (ulong)DateTimeOffset.Now.ToUnixTimeSeconds(); + _sceneId = sceneId; + EnterToken = ++_enterTokenSeed; + + _enterState = SceneEnterState.EnterRequested; + await _session.NotifyAsync(CmdType.PlayerEnterSceneNotify, new PlayerEnterSceneNotify + { + SceneBeginTime = _beginTime, + SceneId = _sceneId, + SceneTransaction = CreateTransaction(_sceneId, _player.Uid, _beginTime), + Pos = new() + { + X = 2191.16357421875f, + Y = 214.65115356445312f, + Z = -1120.633056640625f + }, + TargetUid = _player.Uid, + EnterSceneToken = EnterToken, + PrevPos = new(), + Type = EnterType.Self + }); + } + + private async ValueTask SendSceneTeamUpdate() + { + SceneTeamUpdateNotify sceneTeamUpdate = new(); + foreach (AvatarEntity avatar in _teamAvatars) + { + sceneTeamUpdate.SceneTeamAvatarList.Add(new SceneTeamAvatar + { + SceneEntityInfo = avatar.AsInfo(), + WeaponEntityId = SceneController.WeaponEntityId, + PlayerUid = _player.Uid, + WeaponGuid = GameAvatar.WeaponGuid, + EntityId = avatar.EntityId, + AvatarGuid = avatar.GameAvatar.Guid, + AbilityControlBlock = avatar.BuildAbilityControlBlock(_binData), + SceneId = _sceneId + }); + } + + await _session.NotifyAsync(CmdType.SceneTeamUpdateNotify, sceneTeamUpdate); + } + + private async ValueTask SendEnterSceneInfo() + { + PlayerEnterSceneInfoNotify enterSceneInfo = new() + { + CurAvatarEntityId = _teamAvatars[0].EntityId, + EnterSceneToken = EnterToken, + MpLevelEntityInfo = new MPLevelEntityInfo + { + EntityId = 184549377, + AbilityInfo = new AbilitySyncStateInfo(), + AuthorityPeerId = 1 + }, + TeamEnterInfo = new TeamEnterSceneInfo + { + TeamEntityId = 150994946, + AbilityControlBlock = new AbilityControlBlock(), + TeamAbilityInfo = new AbilitySyncStateInfo() + } + }; + + foreach (AvatarEntity avatar in _teamAvatars) + { + enterSceneInfo.AvatarEnterInfo.Add(new AvatarEnterSceneInfo + { + AvatarGuid = avatar.GameAvatar.Guid, + AvatarEntityId = avatar.EntityId, + WeaponEntityId = SceneController.WeaponEntityId, + WeaponGuid = GameAvatar.WeaponGuid + }); + } + + await _session.NotifyAsync(CmdType.PlayerEnterSceneInfoNotify, enterSceneInfo); + } + + private void ResetState() + { + _teamAvatars.Clear(); + _entityManager.Reset(); + } + + private static string CreateTransaction(uint sceneId, uint playerUid, ulong beginTime) + => string.Format("{0}-{1}-{2}-13830", sceneId, playerUid, beginTime); +} diff --git a/NahidaImpact.Gameserver/GameServer.cs b/NahidaImpact.Gameserver/GameServer.cs new file mode 100644 index 0000000..a073408 --- /dev/null +++ b/NahidaImpact.Gameserver/GameServer.cs @@ -0,0 +1,28 @@ +using NahidaImpact.Common.Data.Binout; +using NahidaImpact.Common.Data.Excel; +using NahidaImpact.Gameserver.Network; +using Microsoft.Extensions.Hosting; + +namespace NahidaImpact.Gameserver; +internal class GameServer : IHostedService +{ + private readonly IGateway _gateway; + + public GameServer(IGateway gateway, ExcelTableCollection excelTables, BinDataCollection binDataCollection) + { + _ = excelTables; + _ = binDataCollection; + + _gateway = gateway; + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + await _gateway.Start(); + } + + public async Task StopAsync(CancellationToken cancellationToken) + { + await _gateway.Stop(); + } +} diff --git a/NahidaImpact.Gameserver/NahidaImpact.Gameserver.csproj b/NahidaImpact.Gameserver/NahidaImpact.Gameserver.csproj new file mode 100644 index 0000000..5b00f7a --- /dev/null +++ b/NahidaImpact.Gameserver/NahidaImpact.Gameserver.csproj @@ -0,0 +1,26 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/NahidaImpact.Gameserver/Network/IGateway.cs b/NahidaImpact.Gameserver/Network/IGateway.cs new file mode 100644 index 0000000..e12ad41 --- /dev/null +++ b/NahidaImpact.Gameserver/Network/IGateway.cs @@ -0,0 +1,6 @@ +namespace NahidaImpact.Gameserver.Network; +internal interface IGateway +{ + Task Start(); + Task Stop(); +} diff --git a/NahidaImpact.Gameserver/Network/INetworkUnit.cs b/NahidaImpact.Gameserver/Network/INetworkUnit.cs new file mode 100644 index 0000000..836804c --- /dev/null +++ b/NahidaImpact.Gameserver/Network/INetworkUnit.cs @@ -0,0 +1,10 @@ +using System.Net; + +namespace NahidaImpact.Gameserver.Network; +internal interface INetworkUnit : IDisposable +{ + IPEndPoint RemoteEndPoint { get; } + + ValueTask ReceiveAsync(Memory buffer, CancellationToken cancellationToken); + ValueTask SendAsync(Memory buffer, CancellationToken cancellationToken); +} diff --git a/NahidaImpact.Gameserver/Network/Kcp/KcpGateway.cs b/NahidaImpact.Gameserver/Network/Kcp/KcpGateway.cs new file mode 100644 index 0000000..5e97d51 --- /dev/null +++ b/NahidaImpact.Gameserver/Network/Kcp/KcpGateway.cs @@ -0,0 +1,85 @@ +using System.Buffers; +using System.Net; +using System.Net.Sockets; +using NahidaImpact.Gameserver.Options; +using NahidaImpact.Kcp; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace NahidaImpact.Gameserver.Network.Kcp; +internal sealed class KcpGateway(ILogger logger, IOptions options, NetSessionManager sessionManager) : IGateway +{ + private readonly Random _random = new(); + private readonly ILogger _logger = logger; + private readonly IOptions _options = options; + private readonly NetSessionManager _sessionManager = sessionManager; + + private uint _sessionCounter; + private IKcpTransport? _transport; + + public Task Start() + { + IPEndPoint bindEndPoint = _options.Value.EndPoint; + + _transport = KcpSocketTransport.CreateMultiplexConnection(new(bindEndPoint), 1400); + _transport.SetCallbacks(20, HandleKcpHandshake); + _transport.Start(); + + _logger.LogInformation("KCP Gateway is up at {endPoint}", bindEndPoint); + return Task.CompletedTask; + } + + private async ValueTask HandleKcpHandshake(UdpReceiveResult receiveResult) + { + KcpHandshake handshake = KcpHandshake.ReadFrom(receiveResult.Buffer); + + switch ((handshake.Head, handshake.Tail)) + { + case (KcpHandshake.StartConversationHead, KcpHandshake.StartConversationTail): + await OnStartConversationRequest(receiveResult.RemoteEndPoint); + break; + } + } + + private async ValueTask OnStartConversationRequest(IPEndPoint clientEndPoint) + { + uint convId = Interlocked.Increment(ref _sessionCounter); + uint token = (uint)_random.Next(); + + long convId64 = (long)convId << 32 | token; + KcpConversation conversation = _transport!.Connection.CreateConversation(convId64, clientEndPoint); + _ = _sessionManager.RunSessionAsync(convId64, new KcpNetworkUnit(conversation, clientEndPoint)); + + await SendConversationCreatedPacket(clientEndPoint, convId, token); + } + + private async ValueTask SendConversationCreatedPacket(IPEndPoint clientEndPoint, uint convId, uint token) + { + KcpHandshake handshakeResponse = new() + { + Head = KcpHandshake.ConversationCreatedHead, + Param1 = convId, + Param2 = token, + Data = 1234567890, + Tail = KcpHandshake.ConversationCreatedTail + }; + + byte[] buffer = ArrayPool.Shared.Rent(20); + try + { + Memory bufferMemory = buffer.AsMemory(); + + handshakeResponse.WriteTo(buffer); + await _transport!.SendPacketAsync(bufferMemory[..20], clientEndPoint, CancellationToken.None); + } + finally + { + ArrayPool.Shared.Return(buffer); + } + } + + public Task Stop() + { + return Task.CompletedTask; + } +} diff --git a/NahidaImpact.Gameserver/Network/Kcp/KcpHandshake.cs b/NahidaImpact.Gameserver/Network/Kcp/KcpHandshake.cs new file mode 100644 index 0000000..d98b0b8 --- /dev/null +++ b/NahidaImpact.Gameserver/Network/Kcp/KcpHandshake.cs @@ -0,0 +1,39 @@ +using System.Buffers.Binary; + +namespace NahidaImpact.Gameserver.Network.Kcp; + +internal struct KcpHandshake +{ + public const uint StartConversationHead = 0xFF; + public const uint StartConversationTail = 0xFFFFFFFF; + + public const uint ConversationCreatedHead = 0x00000145; + public const uint ConversationCreatedTail = 0x14514545; + + public const uint ConversationEndHead = 0x194; + public const uint ConversationEndTail = 0x19419494; + + public uint Head { get; set; } + public uint Param1 { get; set; } + public uint Param2 { get; set; } + public uint Data { get; set; } + public uint Tail { get; set; } + + public readonly void WriteTo(Span buffer) + { + BinaryPrimitives.WriteUInt32BigEndian(buffer[0..4], Head); + BinaryPrimitives.WriteUInt32LittleEndian(buffer[4..8], Param1); + BinaryPrimitives.WriteUInt32LittleEndian(buffer[8..12], Param2); + BinaryPrimitives.WriteUInt32BigEndian(buffer[12..16], Data); + BinaryPrimitives.WriteUInt32BigEndian(buffer[16..20], Tail); + } + + public static KcpHandshake ReadFrom(ReadOnlySpan buffer) => new() + { + Head = BinaryPrimitives.ReadUInt32BigEndian(buffer[0..4]), + Param1 = BinaryPrimitives.ReadUInt32LittleEndian(buffer[4..8]), + Param2 = BinaryPrimitives.ReadUInt32LittleEndian(buffer[8..12]), + Data = BinaryPrimitives.ReadUInt32BigEndian(buffer[12..16]), + Tail = BinaryPrimitives.ReadUInt32BigEndian(buffer[16..20]) + }; +} diff --git a/NahidaImpact.Gameserver/Network/Kcp/KcpNetworkUnit.cs b/NahidaImpact.Gameserver/Network/Kcp/KcpNetworkUnit.cs new file mode 100644 index 0000000..b0a8875 --- /dev/null +++ b/NahidaImpact.Gameserver/Network/Kcp/KcpNetworkUnit.cs @@ -0,0 +1,29 @@ +using System.Net; +using NahidaImpact.Kcp; + +namespace NahidaImpact.Gameserver.Network.Kcp; +internal class KcpNetworkUnit(KcpConversation conversation, IPEndPoint remoteEndPoint) : INetworkUnit +{ + public IPEndPoint RemoteEndPoint { get; } = remoteEndPoint; + + private readonly KcpConversation _conversation = conversation; + + public async ValueTask ReceiveAsync(Memory buffer, CancellationToken cancellationToken) + { + KcpConversationReceiveResult result = await _conversation.ReceiveAsync(buffer, cancellationToken); + if (result.TransportClosed) + return -1; + + return result.BytesReceived; + } + + public async ValueTask SendAsync(Memory buffer, CancellationToken cancellationToken) + { + await _conversation.SendAsync(buffer, cancellationToken); + } + + public void Dispose() + { + _conversation.Dispose(); + } +} diff --git a/NahidaImpact.Gameserver/Network/Kcp/KcpSession.cs b/NahidaImpact.Gameserver/Network/Kcp/KcpSession.cs new file mode 100644 index 0000000..ffc578e --- /dev/null +++ b/NahidaImpact.Gameserver/Network/Kcp/KcpSession.cs @@ -0,0 +1,41 @@ +using NahidaImpact.Gameserver.Controllers.Dispatching; +using NahidaImpact.Gameserver.Network.Session; +using Microsoft.Extensions.Logging; + +namespace NahidaImpact.Gameserver.Network.Kcp; +internal class KcpSession(ILogger logger, NetSessionManager sessionManager, NetCommandDispatcher commandDispatcher) : NetSession(logger, sessionManager, commandDispatcher) +{ + private const int MaxPacketSize = 32768; + private const int ReadTimeout = 30; + private const int WriteTimeout = 30; + + private readonly byte[] _recvBuffer = GC.AllocateUninitializedArray(MaxPacketSize); + private readonly byte[] _sendBuffer = GC.AllocateUninitializedArray(MaxPacketSize); + + public override async ValueTask RunAsync() + { + Memory buffer = _recvBuffer.AsMemory(); + + while (true) + { + int readAmount = await ReadWithTimeoutAsync(buffer, ReadTimeout); + if (readAmount <= 0) + break; + + //MhySecurity.Xor(buffer[..readAmount].Span, EncryptionKey); + int consumedBytes = await ConsumePacketsAsync(buffer[..readAmount]); + if (consumedBytes == -1) + break; + } + } + + public override async ValueTask SendAsync(NetPacket packet) + { + Memory buffer = _sendBuffer.AsMemory(); + + int length = packet.EncodeTo(buffer); + //MhySecurity.Xor(buffer[..length].Span, EncryptionKey); + + await WriteWithTimeoutAsync(buffer[..length], WriteTimeout); + } +} diff --git a/NahidaImpact.Gameserver/Network/NetPacket.cs b/NahidaImpact.Gameserver/Network/NetPacket.cs new file mode 100644 index 0000000..d7ebb7e --- /dev/null +++ b/NahidaImpact.Gameserver/Network/NetPacket.cs @@ -0,0 +1,67 @@ +using System.Buffers.Binary; +using NahidaImpact.Protocol; +using Google.Protobuf; + +namespace NahidaImpact.Gameserver.Network; +internal class NetPacket +{ + private const ushort HeadMagic = 0x4567; + private const ushort TailMagic = 0x89AB; + + public CmdType CmdType { get; set; } + public Memory Head { get; set; } + public Memory Body { get; set; } + + public TBody DecodeBody() where TBody : IMessage, new() + { + return new MessageParser(() => new()).ParseFrom(Body.Span); + } + + public int EncodeTo(Memory buffer) + { + Span span = buffer.Span; + + BinaryPrimitives.WriteUInt16BigEndian(span[0..2], HeadMagic); + BinaryPrimitives.WriteUInt16BigEndian(span[2..4], (ushort)CmdType); + BinaryPrimitives.WriteUInt16BigEndian(span[4..6], (ushort)Head.Length); + BinaryPrimitives.WriteInt32BigEndian(span[6..10], Body.Length); + Head.CopyTo(buffer[10..]); + Body.CopyTo(buffer[(10 + Head.Length)..]); + BinaryPrimitives.WriteUInt16BigEndian(span[(10 + Head.Length + Body.Length)..], TailMagic); + + return 12 + Head.Length + Body.Length; + } + + public static (NetPacket?, int) DecodeFrom(Memory data) + { + ReadOnlySpan span = data.Span; + + ushort headMagic = BinaryPrimitives.ReadUInt16BigEndian(span[0..2]); + if (headMagic != HeadMagic) + return (null, 0); + + ushort cmdType = BinaryPrimitives.ReadUInt16BigEndian(span[2..4]); + + int headLength = BinaryPrimitives.ReadUInt16BigEndian(span[4..6]); + int bodyLength = BinaryPrimitives.ReadInt32BigEndian(span[6..10]); + + if (data.Length < 12 + headLength + bodyLength) + return (null, 0); + + Memory head = data.Slice(10, headLength); + Memory body = data.Slice(10 + headLength, bodyLength); + + ushort tailMagic = BinaryPrimitives.ReadUInt16BigEndian(span[(10 + headLength + bodyLength)..]); + if (tailMagic != TailMagic) + return (null, 0); + + NetPacket netPacket = new() + { + CmdType = (CmdType)cmdType, + Head = head, + Body = body + }; + + return (netPacket, 12 + headLength + bodyLength); + } +} diff --git a/NahidaImpact.Gameserver/Network/NetSessionManager.cs b/NahidaImpact.Gameserver/Network/NetSessionManager.cs new file mode 100644 index 0000000..a89f16c --- /dev/null +++ b/NahidaImpact.Gameserver/Network/NetSessionManager.cs @@ -0,0 +1,49 @@ +using System.Collections.Concurrent; +using NahidaImpact.Gameserver.Network.Session; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace NahidaImpact.Gameserver.Network; +internal class NetSessionManager(ILogger logger, IServiceScopeFactory serviceScopeFactory) +{ + private readonly ConcurrentDictionary _sessions = new(); + private readonly ILogger _logger = logger; + private readonly IServiceScopeFactory _serviceScopeFactory = serviceScopeFactory; + + public async Task RunSessionAsync(long sessionId, INetworkUnit networkUnit) + { + await using AsyncServiceScope serviceScope = _serviceScopeFactory.CreateAsyncScope(); + NetSession session = serviceScope.ServiceProvider.GetRequiredService(); + + try + { + session.Establish(sessionId, networkUnit); + await session.RunAsync(); + } + catch (OperationCanceledException) + { + // OperationCanceled + } + catch (Exception exception) + { + _logger.LogError("Exception occurred during handling a session, trace: {exception}", exception); + } + } + + public void Add(NetSession session) + { + _sessions[session.SessionId] = session; + _logger.LogInformation("New connection from {endPoint}", session.EndPoint); + } + + public bool TryRemove(NetSession session) + { + bool removed = _sessions.TryRemove(session.SessionId, out _); + if (removed) + { + _logger.LogInformation("Client from {endPoint} disconnected", session.EndPoint); + } + + return removed; + } +} diff --git a/NahidaImpact.Gameserver/Network/Session/NetSession.cs b/NahidaImpact.Gameserver/Network/Session/NetSession.cs new file mode 100644 index 0000000..7e7d9ea --- /dev/null +++ b/NahidaImpact.Gameserver/Network/Session/NetSession.cs @@ -0,0 +1,100 @@ +using System.Net; +using NahidaImpact.Common.Security; +using NahidaImpact.Gameserver.Controllers.Dispatching; +using NahidaImpact.Gameserver.Controllers.Result; +using NahidaImpact.Protocol; +using Google.Protobuf; +using Microsoft.Extensions.Logging; + +namespace NahidaImpact.Gameserver.Network.Session; +internal abstract class NetSession(ILogger logger, NetSessionManager sessionManager, NetCommandDispatcher commandDispatcher) : IDisposable +{ + public IPEndPoint EndPoint => _networkUnit!.RemoteEndPoint; + + public long SessionId { get; private set; } + private INetworkUnit? _networkUnit; + + private readonly ILogger _logger = logger; + private readonly NetSessionManager _sessionManager = sessionManager; + private readonly NetCommandDispatcher _commandDispatcher = commandDispatcher; + + protected byte[] EncryptionKey { get; private set; } = MhySecurity.InitialKey; + + public abstract ValueTask RunAsync(); + public abstract ValueTask SendAsync(NetPacket packet); + + public void Establish(long sessionId, INetworkUnit networkUnit) + { + SessionId = sessionId; + _networkUnit = networkUnit; + + _sessionManager.Add(this); + } + + public async Task NotifyAsync(CmdType cmdType, TNotify notify) where TNotify : IMessage + { + await SendAsync(new() + { + CmdType = cmdType, + Head = Memory.Empty, + Body = notify.ToByteArray() + }); + } + + protected async ValueTask ConsumePacketsAsync(Memory buffer) + { + if (buffer.Length < 12) + return 0; + + int consumed = 0; + do + { + (NetPacket? packet, int bytesConsumed) = NetPacket.DecodeFrom(buffer[consumed..]); + consumed += bytesConsumed; + + if (packet == null) + return consumed; + + IResult? result = await _commandDispatcher.InvokeHandler(packet); + if (result != null) + { + while (result.NextPacket(out NetPacket? serverPacket)) + { + await SendAsync(serverPacket); + + if (serverPacket.CmdType == CmdType.GetPlayerTokenRsp) + { + InitializeEncryption(1337); // hardcoded MT seed with patch + } + } + + _logger.LogInformation("Successfully handled command of type {cmdType}", packet.CmdType); + } + } while (buffer.Length - consumed >= 12); + + return consumed; + } + + private void InitializeEncryption(ulong seed) + { + EncryptionKey = MhySecurity.GenerateSecretKey(seed); + } + + protected async ValueTask ReadWithTimeoutAsync(Memory buffer, int timeoutSeconds) + { + using CancellationTokenSource cancellationTokenSource = new(TimeSpan.FromSeconds(timeoutSeconds)); + return await _networkUnit!.ReceiveAsync(buffer, cancellationTokenSource.Token); + } + + protected async ValueTask WriteWithTimeoutAsync(Memory buffer, int timeoutSeconds) + { + using CancellationTokenSource cancellationTokenSource = new(TimeSpan.FromSeconds(timeoutSeconds)); + await _networkUnit!.SendAsync(buffer, cancellationTokenSource.Token); + } + + public virtual void Dispose() + { + _networkUnit?.Dispose(); + _ = _sessionManager.TryRemove(this); + } +} diff --git a/NahidaImpact.Gameserver/Network/Session/SessionEntityEventListener.cs b/NahidaImpact.Gameserver/Network/Session/SessionEntityEventListener.cs new file mode 100644 index 0000000..b541099 --- /dev/null +++ b/NahidaImpact.Gameserver/Network/Session/SessionEntityEventListener.cs @@ -0,0 +1,18 @@ +using NahidaImpact.Gameserver.Game.Entity; +using NahidaImpact.Gameserver.Game.Entity.Listener; +using NahidaImpact.Protocol; + +namespace NahidaImpact.Gameserver.Network.Session; +internal class SessionEntityEventListener(NetSession session) : IEntityEventListener +{ + private readonly NetSession _session = session; + + public async ValueTask OnEntitySpawned(SceneEntity entity, VisionType visionType) + { + await _session.NotifyAsync(CmdType.SceneEntityAppearNotify, new SceneEntityAppearNotify + { + AppearType = visionType, + EntityList = { entity.AsInfo() } + }); + } +} diff --git a/NahidaImpact.Gameserver/Options/GatewayOptions.cs b/NahidaImpact.Gameserver/Options/GatewayOptions.cs new file mode 100644 index 0000000..08bf0a2 --- /dev/null +++ b/NahidaImpact.Gameserver/Options/GatewayOptions.cs @@ -0,0 +1,12 @@ +using System.Net; + +namespace NahidaImpact.Gameserver.Options; +internal record GatewayOptions +{ + public const string Section = "Gateway"; + + public required string Host { get; set; } + public required int Port { get; set; } + + public IPEndPoint EndPoint => new(IPAddress.Parse(Host), Port); +} diff --git a/NahidaImpact.Gameserver/Program.cs b/NahidaImpact.Gameserver/Program.cs new file mode 100644 index 0000000..6790982 --- /dev/null +++ b/NahidaImpact.Gameserver/Program.cs @@ -0,0 +1,54 @@ +using NahidaImpact.Common.Data; +using NahidaImpact.Common.Data.Binout; +using NahidaImpact.Common.Data.Excel; +using NahidaImpact.Common.Data.Provider; +using NahidaImpact.Gameserver; +using NahidaImpact.Gameserver.Controllers.Dispatching; +using NahidaImpact.Gameserver.Game; +using NahidaImpact.Gameserver.Game.Entity; +using NahidaImpact.Gameserver.Game.Entity.Factory; +using NahidaImpact.Gameserver.Game.Entity.Listener; +using NahidaImpact.Gameserver.Game.Scene; +using NahidaImpact.Gameserver.Network; +using NahidaImpact.Gameserver.Network.Kcp; +using NahidaImpact.Gameserver.Network.Session; +using NahidaImpact.Gameserver.Options; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +Console.Title = "NahidaImpact | Game Server [Experimental] (4.3.50)"; + +Console.WriteLine(" ddxocc:;lc:o \r\n lllooddocc;',ll:::llcdxxo:,l\r\n dllllooxO0KXXXKK00OOkkkko::;ccclc:olc\r\n llodkO0KK00K00KXXXKK0KKXNNNKx::ldOkxx:;ld\r\n l:coxxO0XXK00KK0kOKXXKOO0000KXXxodddxkkdcdocld\r\n oclxOOOKXK0KKXNXK0KNXXXXXKKXNXKKOxdooxxoddcdKOl:o\r\n dc:d000KXK0KXNNNXKKNNNNKOKNNX0KNNNOxdc:lxxdko:o00d:l\r\n dccxOOXNXKKXNNNNK0KNNNNNK0KXNNX0KN0kkdc,:oloOx:ldx0xccd\r\n xdco000NNXXNWWNWNKk0NNNNNNXXKXNNNXK0kxocc:::ccodlclox0Olcd\r\n xd:l0KKNNKXWMMMMWKxONWNNNNNNNKKNNNNKkxoclc::::cccll:;lkOOlcd\r\n d::k0KNX0XWMWWWN0xxKMMWWWWWWWXXWWNNNXK0kxddd::ldxooxc,coxOlcd\r\n xl:dkOKX0KWWNNNN0OxxXWWWWWWWMMNXWWXKXK0XNX0kOd:cxK0oodl:;:xOccd\r\n dclxk0X0KNNNNNNK0KddXNNXNNNWWWNKXNXO00dOXN0oodxocodddc;clccxkcc\r\n o;oO0X00NNNNNXKKX0dxKNNXXNNNNNX00N0x0XkdOKkko,::',cdkl'',,;ckx:l\r\n c;o0KKKNNNNNX0KKOxkxkXNKKXNNNNN0OKklxKkdoodOx;'..':xOxl;'..,oOd:o\r\n xolc;'l0KKXNNNXK0KKxkKNKOXN0OKNNNNN0xxdox0Kkkkllddc;'';dKKkdol:;:x0dcd\r\n dl:cl;;x0XNNNXXKKKOx0NMWXkOXKxOXNNNNKxod00O000XKdclddlcclONXkooooookkll\r\n ::dkxox0XXKK0OO0OdccddddddxkKOd0NNNNXkoO0Oxolldoddxkoddood0XNOoccloldlcd\r\n ;ck0xdOKKOO0KX0dolc'...',,,;oxxll0NNNXkkOc'';,...'okxokK0Oxx0NXxcccox0kcl\r\n :oxkdkNN0k0XXNXxc'.;:''dK0c'oK0xodOKXN0kd',xKO:.;:,'lx0NNX0odXN0l:ldxKKll\r\n :cc:oKN0coKXXNKo..:x:,cd0k:,xWWWNKOkO00Ox;,d0xl,,xl..c0NNXKl:ONXolxdkKKol\r\n ::;dXXl'dX0KNNKdcxKdo0OOkooKWWMWMWWNXXXKdokOO0do0OllONNKK0o;dXXxkOxOX0ll\r\n xd:oX0xdkKKOOXNX00XKO0K000KWMWWWWWWWWWWWX00KK0OOXX0KNKOkK0xxx00xOOkKXd:o\r\n d::xk0kx0KKkxkOOOO0K0KKXNWWWWWWWWWWWWWWWNXKKKK0OkOkxdxKXkk0xdddxk0XO\r\n ccc:dOXX0dllx0XNXXNNNWWWWWWWWWWWWWWWNNNXXXXKklldOXNOlloldkOO0Kk:\r\n xxl;cxKNKOocd0NNNNNWWWWWWNXXXNWWWWWWNNNNNKxclOKNXOookxdkKKK0d;\r\n xd:;coOXNKx;;ok0XNWWWWWWN000XWWWWWWNX0ko;,oKNXKx:,cxxddO0xl:\r\n o:clok0XN0l;,;lodxkO0XXXXXXXKOkxool:';cOXX0xllc;ldddddc,\r\n oc:looxkOOd:;;,...':codxdoc:,...,,,:dOkxdlldl:dOkl; Game Server\r\n xolccllll:,';oolll;',:::,';cllod:',:llldxxd:ckdl"); +Console.CursorTop = 0; +Console.CursorVisible = false; + +HostApplicationBuilder builder = Host.CreateApplicationBuilder(); +builder.Logging.ClearProviders(); + +builder.Services.Configure(builder.Configuration.GetSection(GatewayOptions.Section)); + +// Resources +builder.Services.UseLocalAssets(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + +// Game Logic +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); + +// Logic Listeners +builder.Services.AddScoped(); + +// Network +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + +builder.Services.AddHostedService(); + +await builder.Build().RunAsync(); \ No newline at end of file diff --git a/NahidaImpact.Gameserver/appsettings.json b/NahidaImpact.Gameserver/appsettings.json new file mode 100644 index 0000000..9a3c8dc --- /dev/null +++ b/NahidaImpact.Gameserver/appsettings.json @@ -0,0 +1,6 @@ +{ + "Gateway": { + "Host": "0.0.0.0", + "Port": 22101 + } +} \ No newline at end of file diff --git a/NahidaImpact.Kcp/ArrayMemoryOwner.cs b/NahidaImpact.Kcp/ArrayMemoryOwner.cs new file mode 100644 index 0000000..b7c4531 --- /dev/null +++ b/NahidaImpact.Kcp/ArrayMemoryOwner.cs @@ -0,0 +1,22 @@ +#if !NEED_POH_SHIM + +using System.Buffers; + +namespace NahidaImpact.Kcp +{ + internal sealed class ArrayMemoryOwner : IMemoryOwner + { + private readonly byte[] _buffer; + + public ArrayMemoryOwner(byte[] buffer) + { + _buffer = buffer ?? throw new ArgumentNullException(nameof(buffer)); + } + + public Memory Memory => _buffer; + + public void Dispose() { } + } +} + +#endif diff --git a/NahidaImpact.Kcp/AsyncAutoResetEvent.cs b/NahidaImpact.Kcp/AsyncAutoResetEvent.cs new file mode 100644 index 0000000..09e86bb --- /dev/null +++ b/NahidaImpact.Kcp/AsyncAutoResetEvent.cs @@ -0,0 +1,117 @@ +using System.Diagnostics; +using System.Threading.Tasks.Sources; + +namespace NahidaImpact.Kcp +{ + internal class AsyncAutoResetEvent : IValueTaskSource + { + private ManualResetValueTaskSourceCore _rvtsc; + private SpinLock _lock; + private bool _isSet; + private bool _activeWait; + private bool _signaled; + + private T? _value; + + public AsyncAutoResetEvent() + { + _rvtsc = new ManualResetValueTaskSourceCore() + { + RunContinuationsAsynchronously = true + }; + _lock = new SpinLock(); + } + + T IValueTaskSource.GetResult(short token) + { + try + { + return _rvtsc.GetResult(token); + } + finally + { + _rvtsc.Reset(); + + bool lockTaken = false; + try + { + _lock.Enter(ref lockTaken); + + _activeWait = false; + _signaled = false; + } + finally + { + if (lockTaken) + { + _lock.Exit(); + } + } + } + } + + ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) => _rvtsc.GetStatus(token); + void IValueTaskSource.OnCompleted(Action continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) + => _rvtsc.OnCompleted(continuation, state, token, flags); + + public ValueTask WaitAsync() + { + bool lockTaken = false; + try + { + _lock.Enter(ref lockTaken); + + if (_activeWait) + { + return new ValueTask(Task.FromException(new InvalidOperationException("Another thread is already waiting."))); + } + if (_isSet) + { + _isSet = false; + T value = _value!; + _value = default; + return new ValueTask(value); + } + + _activeWait = true; + Debug.Assert(!_signaled); + + return new ValueTask(this, _rvtsc.Version); + } + finally + { + if (lockTaken) + { + _lock.Exit(); + } + } + } + + public void Set(T value) + { + bool lockTaken = false; + try + { + _lock.Enter(ref lockTaken); + + if (_activeWait && !_signaled) + { + _signaled = true; + _rvtsc.SetResult(value); + return; + } + + _isSet = true; + _value = value; + } + finally + { + if (lockTaken) + { + _lock.Exit(); + } + } + } + } + +} diff --git a/NahidaImpact.Kcp/DefaultArrayPoolBufferAllocator.cs b/NahidaImpact.Kcp/DefaultArrayPoolBufferAllocator.cs new file mode 100644 index 0000000..dbdbf14 --- /dev/null +++ b/NahidaImpact.Kcp/DefaultArrayPoolBufferAllocator.cs @@ -0,0 +1,13 @@ +namespace NahidaImpact.Kcp +{ + internal sealed class DefaultArrayPoolBufferAllocator : IKcpBufferPool + { + public static DefaultArrayPoolBufferAllocator Default { get; } = new DefaultArrayPoolBufferAllocator(); + + public KcpRentedBuffer Rent(KcpBufferPoolRentOptions options) + { + return KcpRentedBuffer.FromSharedArrayPool(options.Size); + } + } + +} diff --git a/NahidaImpact.Kcp/IKcpBufferPool.cs b/NahidaImpact.Kcp/IKcpBufferPool.cs new file mode 100644 index 0000000..2ec183a --- /dev/null +++ b/NahidaImpact.Kcp/IKcpBufferPool.cs @@ -0,0 +1,15 @@ +namespace NahidaImpact.Kcp +{ + /// + /// The buffer pool to rent buffers from. + /// + public interface IKcpBufferPool + { + /// + /// Rent a buffer using the specified options. + /// + /// The options used to rent this buffer. + /// + KcpRentedBuffer Rent(KcpBufferPoolRentOptions options); + } +} diff --git a/NahidaImpact.Kcp/IKcpConversation.cs b/NahidaImpact.Kcp/IKcpConversation.cs new file mode 100644 index 0000000..1c052c4 --- /dev/null +++ b/NahidaImpact.Kcp/IKcpConversation.cs @@ -0,0 +1,23 @@ +using System.Net.Sockets; + +namespace NahidaImpact.Kcp +{ + /// + /// A conversation or a channel over the transport. + /// + public interface IKcpConversation : IDisposable + { + /// + /// Put message into the receive queue of the channel. + /// + /// The packet content with the optional conversation ID. This buffer should not contain space for pre-buffer and post-buffer. + /// The token to cancel this operation. + /// A that completes when the packet is put into the receive queue. + ValueTask InputPakcetAsync(UdpReceiveResult packet, CancellationToken cancellationToken); + + /// + /// Mark the underlying transport as closed. Abort all active send or receive operations. + /// + void SetTransportClosed(); + } +} diff --git a/NahidaImpact.Kcp/IKcpConversationUpdateNotificationSource.cs b/NahidaImpact.Kcp/IKcpConversationUpdateNotificationSource.cs new file mode 100644 index 0000000..c8a9c53 --- /dev/null +++ b/NahidaImpact.Kcp/IKcpConversationUpdateNotificationSource.cs @@ -0,0 +1,8 @@ +namespace NahidaImpact.Kcp +{ + internal interface IKcpConversationUpdateNotificationSource + { + ReadOnlyMemory Packet { get; } + void Release(); + } +} diff --git a/NahidaImpact.Kcp/IKcpExceptionProducer.cs b/NahidaImpact.Kcp/IKcpExceptionProducer.cs new file mode 100644 index 0000000..48de214 --- /dev/null +++ b/NahidaImpact.Kcp/IKcpExceptionProducer.cs @@ -0,0 +1,16 @@ +namespace NahidaImpact.Kcp +{ + /// + /// An instance that can produce exceptions in background jobs. + /// + /// The type of the instance. + public interface IKcpExceptionProducer + { + /// + /// Set the handler to invoke when exception is thrown. Return true in the handler to ignore the error and continue running. Return false in the handler to abort the operation. + /// + /// The exception handler. + /// The state object to pass into the exception handler. + void SetExceptionHandler(Func handler, object state); + } +} diff --git a/NahidaImpact.Kcp/IKcpMultiplexConnection.cs b/NahidaImpact.Kcp/IKcpMultiplexConnection.cs new file mode 100644 index 0000000..c32e645 --- /dev/null +++ b/NahidaImpact.Kcp/IKcpMultiplexConnection.cs @@ -0,0 +1,57 @@ +using System.Net; + +namespace NahidaImpact.Kcp +{ + /// + /// Multiplex many channels or conversations over the same transport. + /// + public interface IKcpMultiplexConnection : IDisposable + { + /// + /// Determine whether the multiplex connection contains a conversation with the specified id. + /// + /// The conversation ID. + /// True if the multiplex connection contains the specified conversation. Otherwise false. + bool Contains(long id); + + /// + /// Create a raw channel with the specified conversation ID. + /// + /// The conversation ID. + /// The remote endpoint + /// The options of the . + /// The raw channel created. + /// The current instance is disposed. + /// Another channel or conversation with the same ID was already registered. + KcpRawChannel CreateRawChannel(long id, IPEndPoint remoteEndpoint, KcpRawChannelOptions options = null); + + /// + /// Create a conversation with the specified conversation ID. + /// + /// The conversation ID. + /// The remote endpoint + /// The options of the . + /// The KCP conversation created. + /// The current instance is disposed. + /// Another channel or conversation with the same ID was already registered. + KcpConversation CreateConversation(long id, IPEndPoint remoteEndpoint, KcpConversationOptions options = null); + + /// + /// Register a conversation or channel with the specified conversation ID and user state. + /// + /// The conversation or channel to register. + /// The conversation ID. + /// is not provided. + /// The current instance is disposed. + /// Another channel or conversation with the same ID was already registered. + void RegisterConversation(IKcpConversation conversation, long id); + + + /// + /// Unregister a conversation or channel with the specified conversation ID. + /// + /// The conversation ID. + /// The conversation unregistered. Returns null when the conversation with the specified ID is not found. + IKcpConversation UnregisterConversation(long id); + } +} diff --git a/NahidaImpact.Kcp/IKcpMultiplexConnectionOfT.cs b/NahidaImpact.Kcp/IKcpMultiplexConnectionOfT.cs new file mode 100644 index 0000000..64ebc61 --- /dev/null +++ b/NahidaImpact.Kcp/IKcpMultiplexConnectionOfT.cs @@ -0,0 +1,53 @@ +using System.Net; + +namespace NahidaImpact.Kcp +{ + /// + /// Multiplex many channels or conversations over the same transport. + /// + public interface IKcpMultiplexConnection : IKcpMultiplexConnection + { + /// + /// Create a raw channel with the specified conversation ID. + /// + /// The conversation ID. + /// The remote Endpoint + /// The user state of this channel. + /// The options of the . + /// The raw channel created. + /// The current instance is disposed. + /// Another channel or conversation with the same ID was already registered. + KcpRawChannel CreateRawChannel(long id, IPEndPoint remoteEndpoint, T state, KcpRawChannelOptions options = null); + + /// + /// Create a conversation with the specified conversation ID. + /// + /// The conversation ID. + /// The remote Endpoint + /// The user state of this conversation. + /// The options of the . + /// The KCP conversation created. + /// The current instance is disposed. + /// Another channel or conversation with the same ID was already registered. + KcpConversation CreateConversation(long id, IPEndPoint remoteEndpoint, T state, KcpConversationOptions options = null); + + /// + /// Register a conversation or channel with the specified conversation ID and user state. + /// + /// The conversation or channel to register. + /// The conversation ID. + /// The user state + /// is not provided. + /// The current instance is disposed. + /// Another channel or conversation with the same ID was already registered. + void RegisterConversation(IKcpConversation conversation, long id, T? state); + + /// + /// Unregister a conversation or channel with the specified conversation ID. + /// + /// The conversation ID. + /// The user state. + /// The conversation unregistered with the user state. Returns default when the conversation with the specified ID is not found. + IKcpConversation UnregisterConversation(long id, out T? state); + } +} diff --git a/NahidaImpact.Kcp/IKcpTransport.cs b/NahidaImpact.Kcp/IKcpTransport.cs new file mode 100644 index 0000000..ba0ad71 --- /dev/null +++ b/NahidaImpact.Kcp/IKcpTransport.cs @@ -0,0 +1,22 @@ +using System.Net; +using System.Net.Sockets; + +namespace NahidaImpact.Kcp +{ + /// + /// A transport to send and receive packets. + /// + public interface IKcpTransport + { + /// + /// Send a packet into the transport. + /// + /// The content of the packet. + /// The remote endpoint + /// A token to cancel this operation. + /// A that completes when the packet is sent. + ValueTask SendPacketAsync(Memory packet, IPEndPoint remoteEndpoint, CancellationToken cancellationToken); + + void SetCallbacks(int handshakeSize, Func handshakeHandler); + } +} diff --git a/NahidaImpact.Kcp/IKcpTransportOfT.cs b/NahidaImpact.Kcp/IKcpTransportOfT.cs new file mode 100644 index 0000000..13de8fb --- /dev/null +++ b/NahidaImpact.Kcp/IKcpTransportOfT.cs @@ -0,0 +1,22 @@ +namespace NahidaImpact.Kcp +{ + /// + /// A transport instance for upper-level connections. + /// + /// The type of the upper-level connection. + public interface IKcpTransport : IKcpTransport, IKcpExceptionProducer>, IDisposable + { + /// + /// Get the upper-level connection instace. If Start is not called or the transport is closed, will be thrown. + /// + /// Start is not called or the transport is closed. + T Connection { get; } + + /// + /// Create the upper-level connection and start pumping packets from the socket to the upper-level connection. + /// + /// The current instance is disposed. + /// has been called before. + void Start(); + } +} diff --git a/NahidaImpact.Kcp/KcpAcknowledgeList.cs b/NahidaImpact.Kcp/KcpAcknowledgeList.cs new file mode 100644 index 0000000..4be9644 --- /dev/null +++ b/NahidaImpact.Kcp/KcpAcknowledgeList.cs @@ -0,0 +1,104 @@ +using System.Runtime.CompilerServices; + +namespace NahidaImpact.Kcp +{ + internal sealed class KcpAcknowledgeList + { + private readonly KcpSendQueue _sendQueue; + private (uint SerialNumber, uint Timestamp)[] _array; + private int _count; + private SpinLock _lock; + + public KcpAcknowledgeList(KcpSendQueue sendQueue, int windowSize) + { + _array = new (uint SerialNumber, uint Timestamp)[windowSize]; + _count = 0; + _lock = new SpinLock(); + _sendQueue = sendQueue; + } + + public bool TryGetAt(int index, out uint serialNumber, out uint timestamp) + { + bool lockTaken = false; + try + { + _lock.Enter(ref lockTaken); + + if ((uint)index >= (uint)_count) + { + serialNumber = default; + timestamp = default; + return false; + } + + (serialNumber, timestamp) = _array[index]; + return true; + } + finally + { + if (lockTaken) + { + _lock.Exit(); + } + } + } + + public void Clear() + { + bool lockTaken = false; + try + { + _lock.Enter(ref lockTaken); + + _count = 0; + } + finally + { + if (lockTaken) + { + _lock.Exit(); + } + } + _sendQueue.NotifyAckListChanged(false); + } + + public void Add(uint serialNumber, uint timestamp) + { + bool lockTaken = false; + try + { + _lock.Enter(ref lockTaken); + + EnsureCapacity(); + _array[_count++] = (serialNumber, timestamp); + } + finally + { + if (lockTaken) + { + _lock.Exit(); + } + } + _sendQueue.NotifyAckListChanged(true); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void EnsureCapacity() + { + if (_count == _array.Length) + { + Expand(); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void Expand() + { + int capacity = _count + 1; + capacity = Math.Max(capacity + capacity / 2, 16); + var newArray = new (uint SerialNumber, uint Timestamp)[capacity]; + _array.AsSpan(0, _count).CopyTo(newArray); + _array = newArray; + } + } +} diff --git a/NahidaImpact.Kcp/KcpBuffer.cs b/NahidaImpact.Kcp/KcpBuffer.cs new file mode 100644 index 0000000..af6f17b --- /dev/null +++ b/NahidaImpact.Kcp/KcpBuffer.cs @@ -0,0 +1,59 @@ +using System.Diagnostics; + +namespace NahidaImpact.Kcp +{ + internal readonly struct KcpBuffer + { + private readonly object _owner; + private readonly Memory _memory; + private readonly int _length; + + public ReadOnlyMemory DataRegion => _memory.Slice(0, _length); + + public int Length => _length; + + private KcpBuffer(object owner, Memory memory, int length) + { + _owner = owner; + _memory = memory; + _length = length; + } + + public static KcpBuffer CreateFromSpan(KcpRentedBuffer buffer, ReadOnlySpan dataSource) + { + Memory memory = buffer.Memory; + if (dataSource.Length > memory.Length) + { + ThrowRentedBufferTooSmall(); + } + dataSource.CopyTo(memory.Span); + return new KcpBuffer(buffer.Owner, memory, dataSource.Length); + } + + public KcpBuffer AppendData(ReadOnlySpan data) + { + if (_length + data.Length > _memory.Length) + { + ThrowRentedBufferTooSmall(); + } + data.CopyTo(_memory.Span.Slice(_length)); + return new KcpBuffer(_owner, _memory, _length + data.Length); + } + + public KcpBuffer Consume(int length) + { + Debug.Assert((uint)length <= (uint)_length); + return new KcpBuffer(_owner, _memory.Slice(length), _length - length); + } + + public void Release() + { + new KcpRentedBuffer(_owner, _memory).Dispose(); + } + + private static void ThrowRentedBufferTooSmall() + { + throw new InvalidOperationException("The rented buffer is not large enough to hold the data."); + } + } +} diff --git a/NahidaImpact.Kcp/KcpBufferPoolRentOptions.cs b/NahidaImpact.Kcp/KcpBufferPoolRentOptions.cs new file mode 100644 index 0000000..9ce2f14 --- /dev/null +++ b/NahidaImpact.Kcp/KcpBufferPoolRentOptions.cs @@ -0,0 +1,41 @@ +namespace NahidaImpact.Kcp +{ + /// + /// The options to use when renting buffers from the pool. + /// + public readonly struct KcpBufferPoolRentOptions : IEquatable + { + private readonly int _size; + private readonly bool _isOutbound; + + /// + /// The minimum size of the buffer. + /// + public int Size => _size; + + /// + /// True if the buffer may be passed to the outside of KcpSharp. False if the buffer is only used internally in KcpSharp. + /// + public bool IsOutbound => _isOutbound; + + /// + /// Create a with the specified parameters. + /// + /// The minimum size of the buffer. + /// True if the buffer may be passed to the outside of KcpSharp. False if the buffer is only used internally in KcpSharp. + public KcpBufferPoolRentOptions(int size, bool isOutbound) + { + _size = size; + _isOutbound = isOutbound; + } + + /// + public bool Equals(KcpBufferPoolRentOptions other) => _size == other._size && _isOutbound == other.IsOutbound; + + /// + public override bool Equals(object obj) => obj is KcpBufferPoolRentOptions other && Equals(other); + + /// + public override int GetHashCode() => HashCode.Combine(_size, _isOutbound); + } +} diff --git a/NahidaImpact.Kcp/KcpCommand.cs b/NahidaImpact.Kcp/KcpCommand.cs new file mode 100644 index 0000000..1de6d77 --- /dev/null +++ b/NahidaImpact.Kcp/KcpCommand.cs @@ -0,0 +1,10 @@ +namespace NahidaImpact.Kcp +{ + internal enum KcpCommand : byte + { + Push = 81, + Ack = 82, + WindowProbe = 83, + WindowSize = 84 + } +} diff --git a/NahidaImpact.Kcp/KcpConversation.FlushAsyncMethodBuilder.cs b/NahidaImpact.Kcp/KcpConversation.FlushAsyncMethodBuilder.cs new file mode 100644 index 0000000..6104692 --- /dev/null +++ b/NahidaImpact.Kcp/KcpConversation.FlushAsyncMethodBuilder.cs @@ -0,0 +1,275 @@ +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; +using System.Threading.Tasks.Sources; + +namespace NahidaImpact.Kcp +{ + partial class KcpConversation + { +#if NET6_0_OR_GREATER + [ThreadStatic] + private static KcpConversation? s_currentObject; + private object? _flushStateMachine; + + struct KcpFlushAsyncMethodBuilder + { + private readonly KcpConversation _conversation; + private StateMachineBox? _task; + + private static readonly StateMachineBox s_syncSuccessSentinel = new SyncSuccessSentinelStateMachineBox(); + + public KcpFlushAsyncMethodBuilder(KcpConversation conversation) + { + _conversation = conversation; + _task = null; + } + + public static KcpFlushAsyncMethodBuilder Create() + { + KcpConversation? conversation = s_currentObject; + Debug.Assert(conversation is not null); + s_currentObject = null; + + return new KcpFlushAsyncMethodBuilder(conversation); + } + +#pragma warning disable CA1822 // Mark members as static + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Start(ref TStateMachine stateMachine) + where TStateMachine : IAsyncStateMachine +#pragma warning restore CA1822 // Mark members as static + { + Debug.Assert(stateMachine is not null); + + stateMachine.MoveNext(); + } + + public ValueTask Task + { + get + { + if (ReferenceEquals(_task, s_syncSuccessSentinel)) + { + return default; + } + StateMachineBox stateMachineBox = _task ??= CreateWeaklyTypedStateMachineBox(); + return new ValueTask(stateMachineBox, stateMachineBox.Version); + } + } + +#pragma warning disable CA1822 // Mark members as static + public void SetStateMachine(IAsyncStateMachine stateMachine) +#pragma warning restore CA1822 // Mark members as static + { + Debug.Fail("SetStateMachine should not be used."); + } + + public void SetResult() + { + if (_task == null) + { + _task = s_syncSuccessSentinel; + } + else + { + _task.SetResult(); + } + } + + public void SetException(Exception exception) + { + SetException(exception, ref _task); + } + + private static void SetException(Exception exception, ref StateMachineBox? boxFieldRef) + { + if (exception == null) + { + throw new ArgumentNullException(nameof(exception)); + } + (boxFieldRef ??= CreateWeaklyTypedStateMachineBox()).SetException(exception); + } + + public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : INotifyCompletion + where TStateMachine : IAsyncStateMachine + { + AwaitOnCompleted(ref awaiter, ref stateMachine, ref _task, _conversation); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : ICriticalNotifyCompletion + where TStateMachine : IAsyncStateMachine + { + AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine, ref _task, _conversation); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine, ref StateMachineBox? boxRef, KcpConversation conversation) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine + { + StateMachineBox stateMachineBox = GetStateMachineBox(ref stateMachine, ref boxRef, conversation); + AwaitUnsafeOnCompleted(ref awaiter, stateMachineBox); + } + + private static void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine, ref StateMachineBox? box, KcpConversation conversation) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine + { + try + { + awaiter.OnCompleted(GetStateMachineBox(ref stateMachine, ref box, conversation).MoveNextAction); + } + catch (Exception exception) + { + var edi = ExceptionDispatchInfo.Capture(exception); + ThreadPool.QueueUserWorkItem(static state => ((ExceptionDispatchInfo)state!).Throw(), edi); + } + } + + private static void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, StateMachineBox box) where TAwaiter : ICriticalNotifyCompletion + { + try + { + awaiter.UnsafeOnCompleted(box.MoveNextAction); + } + catch (Exception exception) + { + var edi = ExceptionDispatchInfo.Capture(exception); + ThreadPool.QueueUserWorkItem(static state => ((ExceptionDispatchInfo)state!).Throw(), edi); + } + } + + + private static StateMachineBox CreateWeaklyTypedStateMachineBox() + { + return new StateMachineBox(null); + } + + private static StateMachineBox GetStateMachineBox(ref TStateMachine stateMachine, ref StateMachineBox? boxFieldRef, KcpConversation conversation) where TStateMachine : IAsyncStateMachine + { + StateMachineBox? stateMachineBox = boxFieldRef as StateMachineBox; + if (stateMachineBox != null) + { + return stateMachineBox; + } + StateMachineBox? stateMachineBox2 = boxFieldRef as StateMachineBox; + if (stateMachineBox2 != null) + { + if (stateMachineBox2.StateMachine == null) + { + Debugger.NotifyOfCrossThreadDependency(); + stateMachineBox2.StateMachine = stateMachine; + } + return stateMachineBox2; + } + Debugger.NotifyOfCrossThreadDependency(); + StateMachineBox stateMachineBox3 = (StateMachineBox)(boxFieldRef = StateMachineBox.GetOrCreateBox(conversation)); + stateMachineBox3.StateMachine = stateMachine; + return stateMachineBox3; + } + + abstract class StateMachineBox : IValueTaskSource + { + protected ManualResetValueTaskSourceCore _mrvtsc; + protected Action? _moveNextAction; + + public virtual Action MoveNextAction => _moveNextAction!; + + public short Version => _mrvtsc.Version; + + public void SetResult() + { + _mrvtsc.SetResult(true); + } + + public void SetException(Exception error) + { + _mrvtsc.SetException(error); + } + + public ValueTaskSourceStatus GetStatus(short token) + { + return _mrvtsc.GetStatus(token); + } + + public void OnCompleted(Action continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) + { + _mrvtsc.OnCompleted(continuation, state, token, flags); + } + + void IValueTaskSource.GetResult(short token) + { + throw new NotSupportedException(); + } + } + + sealed class SyncSuccessSentinelStateMachineBox : StateMachineBox + { + public SyncSuccessSentinelStateMachineBox() + { + SetResult(); + } + } + + + sealed class StateMachineBox : StateMachineBox, IValueTaskSource where TStateMachine : IAsyncStateMachine + { + [MaybeNull] + public TStateMachine StateMachine; + private KcpConversation? _conversation; + + public override Action MoveNextAction => _moveNextAction ??= MoveNext; + + internal StateMachineBox(KcpConversation? conversation) + { + _conversation = conversation; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static StateMachineBox GetOrCreateBox(KcpConversation conversation) + { + if (conversation._flushStateMachine is StateMachineBox stateMachine) + { + stateMachine._conversation = conversation; + conversation._flushStateMachine = null; + return stateMachine; + } + return new StateMachineBox(conversation); + } + + void IValueTaskSource.GetResult(short token) + { + try + { + _mrvtsc.GetResult(token); + } + finally + { + ReturnOrDropBox(); + } + } + + public void MoveNext() + { + if (StateMachine is not null) + { + StateMachine.MoveNext(); + } + } + + private void ReturnOrDropBox() + { + StateMachine = default!; + _mrvtsc.Reset(); + if (_conversation is not null) + { + _conversation._flushStateMachine = this; + _conversation = null; + } + } + } + } +#endif + } +} diff --git a/NahidaImpact.Kcp/KcpConversation.cs b/NahidaImpact.Kcp/KcpConversation.cs new file mode 100644 index 0000000..7279b84 --- /dev/null +++ b/NahidaImpact.Kcp/KcpConversation.cs @@ -0,0 +1,1395 @@ +using System.Buffers.Binary; +using System.Runtime.CompilerServices; +using System.Net; +using System.Net.Sockets; + +#if NEED_LINKEDLIST_SHIM +using LinkedListOfBufferItem = KcpSharp.NetstandardShim.LinkedList; +using LinkedListNodeOfBufferItem = KcpSharp.NetstandardShim.LinkedListNode; +#else +using LinkedListOfBufferItem = System.Collections.Generic.LinkedList; +using LinkedListNodeOfBufferItem = System.Collections.Generic.LinkedListNode; +#endif + +namespace NahidaImpact.Kcp +{ + /// + /// A reliable channel over an unreliable transport implemented in KCP protocol. + /// + public sealed partial class KcpConversation : IKcpConversation, IKcpExceptionProducer + { + private readonly IKcpBufferPool _bufferPool; + private readonly IKcpTransport _transport; + private readonly IPEndPoint _remoteEndPoint; + private readonly ulong? _id; + + private readonly int _mtu; + private readonly int _mss; + private readonly int _preBufferSize; + private readonly int _postBufferSize; + + private uint _snd_una; + private uint _snd_nxt; + private uint _rcv_nxt; + + private uint _ssthresh; + + private int _rx_rttval; + private int _rx_srtt; + private uint _rx_rto; + private uint _rx_minrto; + + private uint _snd_wnd; + private uint _rcv_wnd; + private uint _rmt_wnd; + private uint _cwnd; + private KcpProbeType _probe; + private SpinLock _cwndUpdateLock; + + private uint _interval; + private uint _ts_flush; + + private bool _nodelay; + private uint _ts_probe; + private uint _probe_wait; + + private uint _incr; + + private readonly KcpSendReceiveQueueItemCache _queueItemCache; + private readonly KcpSendQueue _sendQueue; + private readonly KcpReceiveQueue _receiveQueue; + + private readonly LinkedListOfBufferItem _sndBuf = new(); + private readonly LinkedListOfBufferItem _rcvBuf = new(); + private KcpSendReceiveBufferItemCache _cache = KcpSendReceiveBufferItemCache.Create(); + + private readonly KcpAcknowledgeList _ackList; + + private int _fastresend; + private int _fastlimit; + private bool _nocwnd; + private bool _stream; + + private bool _keepAliveEnabled; + private uint _keepAliveInterval; + private uint _keepAliveGracePeriod; + private uint _lastReceiveTick; + private uint _lastSendTick; + + private KcpReceiveWindowNotificationOptions? _receiveWindowNotificationOptions; + private uint _ts_rcv_notify; + private uint _ts_rcv_notify_wait; + + private KcpConversationUpdateActivation? _updateActivation; + private CancellationTokenSource? _updateLoopCts; + private bool _transportClosed; + private bool _disposed; + + private Func? _exceptionHandler; + private object? _exceptionHandlerState; + + private const uint IKCP_RTO_MAX = 60000; + private const int IKCP_THRESH_MIN = 2; + private const uint IKCP_PROBE_INIT = 7000; // 7 secs to probe window size + private const uint IKCP_PROBE_LIMIT = 120000; // up to 120 secs to probe window + + /// + /// Construct a reliable channel using KCP protocol. + /// + /// The remote endpoint + /// The underlying transport. + /// The options of the . + public KcpConversation(IPEndPoint remoteEndpoint, IKcpTransport transport, KcpConversationOptions? options) + : this(remoteEndpoint, transport, null, options) + { } + + /// + /// Construct a reliable channel using KCP protocol. + /// + /// The remote endpoint + /// The underlying transport. + /// The conversation ID. + /// The options of the . + public KcpConversation(IPEndPoint remoteEndpoint, IKcpTransport transport, long conversationId, KcpConversationOptions? options) + : this(remoteEndpoint, transport, (ulong)conversationId, options) + { } + + private KcpConversation(IPEndPoint remoteEndpoint, IKcpTransport transport, ulong? conversationId, KcpConversationOptions? options) + { + _bufferPool = options?.BufferPool ?? DefaultArrayPoolBufferAllocator.Default; + _transport = transport; + _remoteEndPoint = remoteEndpoint; + _id = conversationId; + + if (options is null) + { + _mtu = KcpConversationOptions.MtuDefaultValue; + } + else if (options.Mtu < 50) + { + throw new ArgumentException("MTU must be at least 50.", nameof(options)); + } + else + { + _mtu = options.Mtu; + } + + _preBufferSize = options?.PreBufferSize ?? 0; + _postBufferSize = options?.PostBufferSize ?? 0; + if (_preBufferSize < 0) + { + throw new ArgumentException("PreBufferSize must be a non-negative integer.", nameof(options)); + } + if (_postBufferSize < 0) + { + throw new ArgumentException("PostBufferSize must be a non-negative integer.", nameof(options)); + } + if ((uint)(_preBufferSize + _postBufferSize) >= (uint)(_mtu - KcpGlobalVars.HEADER_LENGTH_WITHOUT_CONVID)) + { + throw new ArgumentException("The sum of PreBufferSize and PostBufferSize is too large. There is not enough space in the packet for the KCP header.", nameof(options)); + } + if (conversationId.HasValue && (uint)(_preBufferSize + _postBufferSize) >= (uint)(_mtu - KcpGlobalVars.HEADER_LENGTH_WITH_CONVID)) + { + throw new ArgumentException("The sum of PreBufferSize and PostBufferSize is too large. There is not enough space in the packet for the KCP header.", nameof(options)); + } + + _mss = conversationId.HasValue ? _mtu - KcpGlobalVars.HEADER_LENGTH_WITH_CONVID : _mtu - KcpGlobalVars.HEADER_LENGTH_WITHOUT_CONVID; + _mss = _mss - _preBufferSize - _postBufferSize; + + _ssthresh = 2; + + _nodelay = options is not null && options.NoDelay; + if (_nodelay) + { + _rx_minrto = 30; + } + else + { + _rx_rto = 200; + _rx_minrto = 100; + } + + _snd_wnd = options is null || options.SendWindow <= 0 ? KcpConversationOptions.SendWindowDefaultValue : (uint)options.SendWindow; + _rcv_wnd = options is null || options.ReceiveWindow <= 0 ? KcpConversationOptions.ReceiveWindowDefaultValue : (uint)options.ReceiveWindow; + _rmt_wnd = options is null || options.RemoteReceiveWindow <= 0 ? KcpConversationOptions.RemoteReceiveWindowDefaultValue : (uint)options.RemoteReceiveWindow; + _rcv_nxt = 0; + + _interval = options is null || options.UpdateInterval < 10 ? KcpConversationOptions.UpdateIntervalDefaultValue : (uint)options.UpdateInterval; + + _fastresend = options is null ? 0 : options.FastResend; + _fastlimit = 5; + _nocwnd = options is not null && options.DisableCongestionControl; + _stream = options is not null && options.StreamMode; + + _updateActivation = new KcpConversationUpdateActivation((int)_interval); + _queueItemCache = new KcpSendReceiveQueueItemCache(); + _sendQueue = new KcpSendQueue(_bufferPool, _updateActivation, _stream, options is null || options.SendQueueSize <= 0 ? KcpConversationOptions.SendQueueSizeDefaultValue : options.SendQueueSize, _mss, _queueItemCache); + _receiveQueue = new KcpReceiveQueue(_stream, options is null || options.ReceiveQueueSize <= 0 ? KcpConversationOptions.ReceiveQueueSizeDefaultValue : options.ReceiveQueueSize, _queueItemCache); + _ackList = new KcpAcknowledgeList(_sendQueue, (int)_snd_wnd); + + _updateLoopCts = new CancellationTokenSource(); + + _ts_flush = GetTimestamp(); + + _lastSendTick = _ts_flush; + _lastReceiveTick = _ts_flush; + KcpKeepAliveOptions? keepAliveOptions = options?.KeepAliveOptions; + if (keepAliveOptions is not null) + { + _keepAliveEnabled = true; + _keepAliveInterval = (uint)keepAliveOptions.SendInterval; + _keepAliveGracePeriod = (uint)keepAliveOptions.GracePeriod; + } + + _receiveWindowNotificationOptions = options?.ReceiveWindowNotificationOptions; + if (_receiveWindowNotificationOptions is not null) + { + _ts_rcv_notify_wait = 0; + _ts_rcv_notify = _ts_flush + (uint)_receiveWindowNotificationOptions.InitialInterval; + } + + RunUpdateOnActivation(); + } + + /// + /// Set the handler to invoke when exception is thrown during flushing packets to the transport. Return true in the handler to ignore the error and continue running. Return false in the handler to abort the operation and mark the transport as closed. + /// + /// The exception handler. + /// The state object to pass into the exception handler. + public void SetExceptionHandler(Func handler, object? state) + { + if (handler is null) + { + throw new ArgumentNullException(nameof(handler)); + } + + _exceptionHandler = handler; + _exceptionHandlerState = state; + } + + /// + /// Get the ID of the current conversation. + /// + public long? ConversationId => (long?)_id; + + /// + /// Get whether the transport is marked as closed. + /// + public bool TransportClosed => _transportClosed; + + /// + /// Get whether the conversation is in stream mode. + /// + public bool StreamMode => _stream; + + /// + /// Get the available byte count and available segment count in the send queue. + /// + /// The available byte count in the send queue. + /// The available segment count in the send queue. + /// True if the transport is not closed. Otherwise false. + public bool TryGetSendQueueAvailableSpace(out int byteCount, out int segmentCount) + => _sendQueue.TryGetAvailableSpace(out byteCount, out segmentCount); + + /// + /// Try to put message into the send queue. + /// + /// The content of the message. + /// True if the message is put into the send queue. False if the message is too large to fit in the send queue, or the transport is closed. + /// The size of the message is larger than 256 * mtu, thus it can not be correctly fragmented and sent. This exception is never thrown in stream mode. + /// The send or flush operation is initiated concurrently. + public bool TrySend(ReadOnlySpan buffer) + => _sendQueue.TrySend(buffer, false, out _); + + /// + /// Try to put message into the send queue. + /// + /// The content of the message. + /// Whether partial sending is allowed in stream mode. This must not be true in non-stream mode. + /// The number of bytes put into the send queue. This is always the same as the size of the unless is set to true. + /// True if the message is put into the send queue. False if the message is too large to fit in the send queue, or the transport is closed. + /// is set to true in non-stream mode. Or the size of the message is larger than 256 * mtu, thus it can not be correctly fragmented and sent. This exception is never thrown in stream mode. + /// The send or flush operation is initiated concurrently. + public bool TrySend(ReadOnlySpan buffer, bool allowPartialSend, out int bytesWritten) + => _sendQueue.TrySend(buffer, allowPartialSend, out bytesWritten); + + /// + /// Wait until the send queue contains at least bytes of free space, and also available segments. + /// + /// The number of bytes in the available space. + /// The count of segments in the available space. + /// The token to cancel this operation. + /// or is larger than the total space of the send queue. + /// The is fired before send operation is completed. Or is called before this operation is completed. + /// A that completes when there is enough space in the send queue. The result of the task is false when the transport is closed. + public ValueTask WaitForSendQueueAvailableSpaceAsync(int minimumBytes, int minimumSegments, CancellationToken cancellationToken = default) + => _sendQueue.WaitForAvailableSpaceAsync(minimumBytes, minimumSegments, cancellationToken); + + /// + /// Put message into the send queue. + /// + /// The content of the message. + /// The token to cancel this operation. + /// The size of the message is larger than 256 * mtu, thus it can not be correctly fragmented and sent. This exception is never thrown in stream mode. + /// The is fired before send operation is completed. Or is called before this operation is completed. + /// The send or flush operation is initiated concurrently. + /// A that completes when the entire message is put into the queue. The result of the task is false when the transport is closed. + public ValueTask SendAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) + => _sendQueue.SendAsync(buffer, cancellationToken); + + internal ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken) + => _sendQueue.WriteAsync(buffer, cancellationToken); + + /// + /// Cancel the current send operation or flush operation. + /// + /// True if the current operation is canceled. False if there is no active send operation. + public bool CancelPendingSend() + => _sendQueue.CancelPendingOperation(null, default); + + /// + /// Cancel the current send operation or flush operation. + /// + /// The inner exception of the thrown by the method or method. + /// The in the thrown by the method or method. + /// True if the current operation is canceled. False if there is no active send operation. + public bool CancelPendingSend(Exception? innerException, CancellationToken cancellationToken) + => _sendQueue.CancelPendingOperation(innerException, cancellationToken); + + /// + /// Gets the count of bytes not yet sent to the remote host or not acknowledged by the remote host. + /// + public long UnflushedBytes => _sendQueue.GetUnflushedBytes(); + + /// + /// Wait until all messages are sent and acknowledged by the remote host, as well as all the acknowledgements are sent. + /// + /// The token to cancel this operation. + /// The is fired before send operation is completed. Or is called before this operation is completed. + /// The send or flush operation is initiated concurrently. + /// The instance is disposed. + /// A that completes when the all messages are sent and acknowledged. The result of the task is false when the transport is closed. + public ValueTask FlushAsync(CancellationToken cancellationToken = default) + => _sendQueue.FlushAsync(cancellationToken); + + internal ValueTask FlushForStreamAsync(CancellationToken cancellationToken) + => _sendQueue.FlushForStreamAsync(cancellationToken); + +#if !NET6_0_OR_GREATER + private ValueTask FlushCoreAsync(CancellationToken cancellationToken) + => new ValueTask(FlushCore2Async(cancellationToken)); + + private async Task FlushCore2Async(CancellationToken cancellationToken) +#else + private ValueTask FlushCoreAsync(CancellationToken cancellationToken) + { + s_currentObject = this; + return FlushCore2Async(cancellationToken); + } + + [AsyncMethodBuilder(typeof(KcpFlushAsyncMethodBuilder))] + private async ValueTask FlushCore2Async(CancellationToken cancellationToken) +#endif + { + int preBufferSize = _preBufferSize; + int postBufferSize = _postBufferSize; + int packetHeaderSize = _id.HasValue ? KcpGlobalVars.HEADER_LENGTH_WITH_CONVID : KcpGlobalVars.HEADER_LENGTH_WITHOUT_CONVID; + int sizeLimitBeforePostBuffer = _mtu - _postBufferSize; + bool anyPacketSent = false; + + ushort windowSize = (ushort)GetUnusedReceiveWindow(); + uint unacknowledged = _rcv_nxt; + + using KcpRentedBuffer bufferOwner = _bufferPool.Rent(new KcpBufferPoolRentOptions(_mtu + (_mtu - preBufferSize - postBufferSize), true)); + Memory buffer = bufferOwner.Memory; + int size = preBufferSize; + buffer.Span.Slice(0, size).Clear(); + + // flush acknowledges + { + int index = 0; + while (_ackList.TryGetAt(index++, out uint serialNumber, out uint timestamp)) + { + if ((size + packetHeaderSize) > sizeLimitBeforePostBuffer) + { + buffer.Span.Slice(size, postBufferSize).Clear(); + await _transport.SendPacketAsync(buffer.Slice(0, size + postBufferSize), _remoteEndPoint, cancellationToken).ConfigureAwait(false); + _lastSendTick = GetTimestamp(); + size = preBufferSize; + buffer.Span.Slice(0, size).Clear(); + anyPacketSent = true; + } + var header = new KcpPacketHeader(KcpCommand.Ack, 0, windowSize, timestamp, serialNumber, unacknowledged); + header.EncodeHeader(_id, 0, buffer.Span.Slice(size), out int bytesWritten); + size += bytesWritten; + } + } + + uint current = GetTimestamp(); + + // calculate window size + uint cwnd = Math.Min(_snd_wnd, _rmt_wnd); + if (!_nocwnd) + { + cwnd = Math.Min(_cwnd, cwnd); + } + + // move data from snd_queue to snd_buf + while (TimeDiff(_snd_nxt, _snd_una + cwnd) < 0) + { + if (!_sendQueue.TryDequeue(out KcpBuffer data, out byte fragment)) + { + break; + } + + lock (_sndBuf) + { + if (_transportClosed) + { + data.Release(); + return; + } + + _sndBuf.AddLast(CreateSendBufferItem(in data, fragment, current, windowSize, (uint)Interlocked.Increment(ref Unsafe.As(ref _snd_nxt)) - 1, unacknowledged, _rx_rto)); + } + } + + // calculate resent + uint resent = _fastresend > 0 ? (uint)_fastresend : 0xffffffff; + uint rtomin = !_nodelay ? (_rx_rto >> 3) : 0; + + // flush data segments + bool lost = false; + bool change = false; + LinkedListNodeOfBufferItem? segmentNode = _sndBuf.First; + while (segmentNode is not null && !_transportClosed) + { + LinkedListNodeOfBufferItem? nextSegmentNode = segmentNode.Next; + + bool needsend = false; + KcpSendSegmentStats stats = segmentNode.ValueRef.Stats; + + if (segmentNode.ValueRef.Stats.TransmitCount == 0) + { + needsend = true; + segmentNode.ValueRef.Stats = new KcpSendSegmentStats(current + segmentNode.ValueRef.Stats.Rto + rtomin, _rx_rto, stats.FastAck, stats.TransmitCount + 1); + } + else if (TimeDiff(current, stats.ResendTimestamp) >= 0) + { + needsend = true; + uint rto = stats.Rto; + if (!_nodelay) + { + rto += Math.Max(stats.Rto, _rx_rto); + } + else + { + uint step = rto; //_nodelay < 2 ? segment.rto : _rx_rto; + rto += step / 2; + } + segmentNode.ValueRef.Stats = new KcpSendSegmentStats(current + rto, rto, stats.FastAck, stats.TransmitCount + 1); + lost = true; + } + else if (stats.FastAck > resent) + { + if (stats.TransmitCount <= _fastlimit || _fastlimit == 0) + { + needsend = true; + segmentNode.ValueRef.Stats = new KcpSendSegmentStats(current, stats.Rto, 0, stats.TransmitCount + 1); + change = true; + } + } + + if (needsend) + { + KcpPacketHeader header = DeplicateHeader(ref segmentNode.ValueRef.Segment, current, windowSize, unacknowledged); + + int need = packetHeaderSize + segmentNode.ValueRef.Data.Length; + if ((size + need) > sizeLimitBeforePostBuffer) + { + buffer.Span.Slice(size, postBufferSize).Clear(); + await _transport.SendPacketAsync(buffer.Slice(0, size + postBufferSize), _remoteEndPoint, cancellationToken).ConfigureAwait(false); + _lastSendTick = GetTimestamp(); + size = preBufferSize; + buffer.Span.Slice(0, size).Clear(); + anyPacketSent = true; + } + + lock (segmentNode) + { + KcpBuffer data = segmentNode.ValueRef.Data; + if (!_transportClosed) + { + header.EncodeHeader(_id, data.Length, buffer.Span.Slice(size), out int bytesWritten); + + size += bytesWritten; + + if (data.Length > 0) + { + data.DataRegion.CopyTo(buffer.Slice(size)); + size += data.Length; + } + } + } + } + + segmentNode = nextSegmentNode; + } + + _ackList.Clear(); + + // probe window size (if remote window size equals zero) + if (_rmt_wnd == 0) + { + if (_probe_wait == 0) + { + _probe_wait = IKCP_PROBE_INIT; + _ts_probe = current + _probe_wait; + } + else + { + if (TimeDiff(current, _ts_probe) >= 0) + { + if (_probe_wait < IKCP_PROBE_INIT) + { + _probe_wait = IKCP_PROBE_INIT; + } + _probe_wait += _probe_wait / 2; + if (_probe_wait > IKCP_PROBE_LIMIT) + { + _probe_wait = IKCP_PROBE_LIMIT; + } + _ts_probe = current + _probe_wait; + _probe |= KcpProbeType.AskSend; + } + } + } + else + { + _ts_probe = 0; + _probe_wait = 0; + } + + // flush window probing command + if ((_probe & KcpProbeType.AskSend) != 0) + { + if ((size + packetHeaderSize) > sizeLimitBeforePostBuffer) + { + buffer.Span.Slice(size, postBufferSize).Clear(); + await _transport.SendPacketAsync(buffer.Slice(0, size + postBufferSize), _remoteEndPoint, cancellationToken).ConfigureAwait(false); + _lastSendTick = GetTimestamp(); + size = preBufferSize; + buffer.Span.Slice(0, size).Clear(); + anyPacketSent = true; + } + var header = new KcpPacketHeader(KcpCommand.WindowProbe, 0, windowSize, 0, 0, unacknowledged); + header.EncodeHeader(_id, 0, buffer.Span.Slice(size), out int bytesWritten); + size += bytesWritten; + } + + // flush window probing response + if (!anyPacketSent && ShouldSendWindowSize(current)) + { + if ((size + packetHeaderSize) > sizeLimitBeforePostBuffer) + { + buffer.Span.Slice(size, postBufferSize).Clear(); + await _transport.SendPacketAsync(buffer.Slice(0, size + postBufferSize), _remoteEndPoint, cancellationToken).ConfigureAwait(false); + _lastSendTick = GetTimestamp(); + size = preBufferSize; + buffer.Span.Slice(0, size).Clear(); + } + var header = new KcpPacketHeader(KcpCommand.WindowSize, 0, windowSize, 0, 0, unacknowledged); + header.EncodeHeader(_id, 0, buffer.Span.Slice(size), out int bytesWritten); + size += bytesWritten; + } + + _probe = KcpProbeType.None; + + // flush remaining segments + if (size > preBufferSize) + { + buffer.Span.Slice(size, postBufferSize).Clear(); + try + { + await _transport.SendPacketAsync(buffer.Slice(0, size + postBufferSize), _remoteEndPoint, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + + } + _lastSendTick = GetTimestamp(); + } + + // update window + bool lockTaken = false; + try + { + _cwndUpdateLock.Enter(ref lockTaken); + + uint updatedCwnd = _cwnd; + uint incr = _incr; + + // update sshthresh + if (change) + { + uint inflight = _snd_nxt - _snd_una; + _ssthresh = Math.Max(inflight / 2, IKCP_THRESH_MIN); + updatedCwnd = _ssthresh + resent; + incr = updatedCwnd * (uint)_mss; + } + + if (lost) + { + _ssthresh = Math.Max(cwnd / 2, IKCP_THRESH_MIN); + updatedCwnd = 1; + incr = (uint)_mss; + } + + if (updatedCwnd < 1) + { + updatedCwnd = 1; + incr = (uint)_mss; + } + + _cwnd = updatedCwnd; + _incr = incr; + } + finally + { + if (lockTaken) + { + _cwndUpdateLock.Exit(); + } + } + + // send keep-alive + if (_keepAliveEnabled) + { + if (TimeDiff(GetTimestamp(), _lastSendTick) > _keepAliveInterval) + { + var header = new KcpPacketHeader(KcpCommand.WindowSize, 0, windowSize, 0, 0, unacknowledged); + header.EncodeHeader(_id, 0, buffer.Span, out int bytesWritten); + await _transport.SendPacketAsync(buffer.Slice(0, bytesWritten), _remoteEndPoint, cancellationToken).ConfigureAwait(false); + _lastSendTick = GetTimestamp(); + } + } + } + + private bool ShouldSendWindowSize(uint current) + { + if ((_probe & KcpProbeType.AskTell) != 0) + { + return true; + } + + KcpReceiveWindowNotificationOptions? options = _receiveWindowNotificationOptions; + if (options is null) + { + return false; + } + + if (TimeDiff(current, _ts_rcv_notify) < 0) + { + return false; + } + + uint inital = (uint)options.InitialInterval; + uint maximum = (uint)options.MaximumInterval; + if (_ts_rcv_notify_wait < inital) + { + _ts_rcv_notify_wait = inital; + } + else if (_ts_rcv_notify_wait >= maximum) + { + _ts_rcv_notify_wait = maximum; + } + else + { + _ts_rcv_notify_wait = Math.Min(maximum, _ts_rcv_notify_wait + _ts_rcv_notify_wait / 2); + } + _ts_rcv_notify = current + _ts_rcv_notify_wait; + + return true; + } + + private LinkedListNodeOfBufferItem CreateSendBufferItem(in KcpBuffer data, byte fragment, uint current, ushort windowSize, uint serialNumber, uint unacknowledged, uint rto) + { + var newseg = new KcpSendReceiveBufferItem + { + Data = data, + Segment = new KcpPacketHeader(KcpCommand.Push, fragment, windowSize, current, serialNumber, unacknowledged), + Stats = new KcpSendSegmentStats(current, rto, 0, 0) + }; + return _cache.Allocate(in newseg); + } + + private static KcpPacketHeader DeplicateHeader(ref KcpPacketHeader header, uint timestamp, ushort windowSize, uint unacknowledged) + { + return new KcpPacketHeader(header.Command, header.Fragment, windowSize, timestamp, header.SerialNumber, unacknowledged); + } + + private uint GetUnusedReceiveWindow() + { + uint count = (uint)_receiveQueue.GetQueueSize(); + if (count < _rcv_wnd) + { + return _rcv_wnd - count; + } + return 0; + } + + private async void RunUpdateOnActivation() + { + CancellationToken cancellationToken = _updateLoopCts?.Token ?? new CancellationToken(true); + KcpConversationUpdateActivation? activation = _updateActivation; + if (activation is null) + { + return; + } + + while (!cancellationToken.IsCancellationRequested) + { + bool update = false; + using (KcpConversationUpdateNotification notification = await activation.WaitAsync(CancellationToken.None).ConfigureAwait(false)) + { + if (_transportClosed) + { + break; + } + + ReadOnlyMemory packet = notification.Packet; + if (!packet.IsEmpty) + { + try + { + update = SetInput(packet.Span); + } + catch (Exception ex) + { + + } + } + + if (_transportClosed) + { + break; + } + + update |= notification.TimerNotification; + } + + try + { + if (update) + { + await UpdateCoreAsync(cancellationToken).ConfigureAwait(false); + } + } + catch (OperationCanceledException) + { + break; + } + catch (Exception ex) + { + if (!HandleFlushException(ex)) + { + break; + } + } + + if (_keepAliveEnabled && TimeDiff(GetTimestamp(), _lastReceiveTick) > _keepAliveGracePeriod) + { + SetTransportClosed(); + } + } + } + + private ValueTask UpdateCoreAsync(CancellationToken cancellationToken) + { + uint current = GetTimestamp(); + long slap = TimeDiff(current, _ts_flush); + if (slap > 10000 || slap < -10000) + { + _ts_flush = current; + slap = 0; + } + + if (slap >= 0 || _nodelay) + { + _ts_flush += _interval; + if (TimeDiff(current, _ts_flush) >= 0) + { + _ts_flush = current + _interval; + } + return FlushCoreAsync(cancellationToken); + } + return default; + } + + private bool HandleFlushException(Exception ex) + { + Func? handler = _exceptionHandler; + object? state = _exceptionHandlerState; + bool result = false; + if (handler is not null) + { + try + { + result = handler.Invoke(ex, this, state); + } + catch + { + result = false; + } + } + + if (!result) + { + SetTransportClosed(); + } + return result; + } + + /// + public ValueTask InputPakcetAsync(UdpReceiveResult packet, CancellationToken cancellationToken = default) + { + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + int packetHeaderSize = _id.HasValue ? KcpGlobalVars.HEADER_LENGTH_WITH_CONVID : KcpGlobalVars.HEADER_LENGTH_WITHOUT_CONVID; + if (packet.Buffer.Length < packetHeaderSize) + { + return default; + } + + ReadOnlySpan packetSpan = packet.Buffer.AsSpan(); + if (_id.HasValue) + { + var conversationId = BinaryPrimitives.ReadUInt64BigEndian(packet.Buffer.AsSpan()); + if (conversationId != _id.GetValueOrDefault()) + { + return default; + } + packetSpan = packetSpan.Slice(8); + } + + uint length = BinaryPrimitives.ReadUInt32LittleEndian(packetSpan.Slice(16)); + if (length > (uint)(packetSpan.Length - 20)) // implicitly checked for (int)length < 0 + { + return default; + } + + KcpConversationUpdateActivation? activation = _updateActivation; + if (activation is null) + { + return default; + } + + return activation.InputPacketAsync(packet.Buffer.AsMemory(), cancellationToken); + } + + private bool SetInput(ReadOnlySpan packet) + { + uint current = GetTimestamp(); + int packetHeaderSize = _id.HasValue ? 28 : 20; + + uint prev_una = _snd_una; + uint maxack = 0, latest_ts = 0; + bool flag = false; + bool mutated = false; + + while (true) + { + if (packet.Length < packetHeaderSize) + { + break; + } + + if (_id.HasValue) + { + if (BinaryPrimitives.ReadUInt64BigEndian(packet) != _id.GetValueOrDefault()) + { + return mutated; + } + packet = packet.Slice(8); + } + + var header = KcpPacketHeader.Parse(packet); + int length = BinaryPrimitives.ReadInt32LittleEndian(packet.Slice(16)); + + packet = packet.Slice(20); + if ((uint)length > (uint)packet.Length) + { + return mutated; + } + + if (header.Command != KcpCommand.Push && + header.Command != KcpCommand.Ack && + header.Command != KcpCommand.WindowProbe && + header.Command != KcpCommand.WindowSize) + { + return mutated; + } + + _lastReceiveTick = current; + _rmt_wnd = header.WindowSize; + mutated = HandleUnacknowledged(header.Unacknowledged) | mutated; + mutated = UpdateSendUnacknowledged() | mutated; + + if (header.Command == KcpCommand.Ack) + { + int rtt = TimeDiff(current, header.Timestamp); + if (rtt >= 0) + { + UpdateRto(rtt); + } + mutated = HandleAck(header.SerialNumber) | mutated; + mutated = UpdateSendUnacknowledged() | mutated; + + if (!flag) + { + flag = true; + maxack = header.SerialNumber; + latest_ts = header.Timestamp; + } + else + { + if (TimeDiff(_snd_nxt, maxack) > 0) + { +#if !IKCP_FASTACK_CONSERVE + maxack = header.SerialNumber; + latest_ts = header.Timestamp; +#else + if (TimeDiff(header.Timestamp, latest_ts) > 0) { + maxack = header.SerialNumber; + latest_ts = header.Timestamp; + } +#endif + } + } + } + else if (header.Command == KcpCommand.Push) + { + if (TimeDiff(header.SerialNumber, _rcv_nxt + _rcv_wnd) < 0) + { + AckPush(header.SerialNumber, header.Timestamp); + if (TimeDiff(header.SerialNumber, _rcv_nxt) >= 0) + { + mutated = HandleData(header, packet.Slice(0, length)) | mutated; + } + + if (_receiveWindowNotificationOptions is not null) + { + if (_ts_rcv_notify_wait != 0) + { + _ts_rcv_notify_wait = 0; + _ts_rcv_notify = current + (uint)_receiveWindowNotificationOptions.InitialInterval; + } + } + } + } + else if (header.Command == KcpCommand.WindowProbe) + { + _probe |= KcpProbeType.AskTell; + } + else if (header.Command == KcpCommand.WindowSize) + { + // do nothing + } + else + { + return mutated; + } + + packet = packet.Slice(length); + } + + if (flag) + { + HandleFastAck(maxack, latest_ts); + } + + if (TimeDiff(_snd_una, prev_una) > 0) + { + bool lockTaken = false; + try + { + _cwndUpdateLock.Enter(ref lockTaken); + + uint cwnd = _cwnd; + uint incr = _incr; + + if (cwnd < _rmt_wnd) + { + uint mss = (uint)_mss; + if (cwnd < _ssthresh) + { + cwnd++; + incr += mss; + } + else + { + if (incr < mss) + { + incr = mss; + } + incr += (mss * mss) / incr + mss / 16; + cwnd = (incr + mss - 1) / (mss > 0 ? mss : 1); + } + if (cwnd > _rmt_wnd) + { + cwnd = _rmt_wnd; + incr = _rmt_wnd * mss; + } + } + + _cwnd = cwnd; + _incr = incr; + } + finally + { + if (lockTaken) + { + _cwndUpdateLock.Exit(); + } + } + } + + return mutated; + } + + private bool HandleUnacknowledged(uint una) + { + bool mutated = false; + lock (_sndBuf) + { + LinkedListNodeOfBufferItem? node = _sndBuf.First; + while (node is not null) + { + LinkedListNodeOfBufferItem? next = node.Next; + + if (TimeDiff(una, node.ValueRef.Segment.SerialNumber) > 0) + { + _sndBuf.Remove(node); + ref KcpBuffer dataRef = ref node.ValueRef.Data; + _sendQueue.SubtractUnflushedBytes(dataRef.Length); + dataRef.Release(); + dataRef = default; + _cache.Return(node); + mutated = true; + } + else + { + break; + } + + node = next; + } + } + return mutated; + } + + private bool UpdateSendUnacknowledged() + { + lock (_sndBuf) + { + LinkedListNodeOfBufferItem? first = _sndBuf.First; + uint snd_una = first is null ? _snd_nxt : first.ValueRef.Segment.SerialNumber; + uint old_snd_una = (uint)Interlocked.Exchange(ref Unsafe.As(ref _snd_una), (int)snd_una); + return snd_una != old_snd_una; + } + } + + private void UpdateRto(int rtt) + { + if (_rx_srtt == 0) + { + _rx_srtt = rtt; + _rx_rttval = rtt / 2; + } + else + { + int delta = rtt - _rx_srtt; + if (delta < 0) + { + delta = -delta; + } + _rx_rttval = (3 * _rx_rttval + delta) / 4; + _rx_srtt = (7 * _rx_srtt + rtt) / 8; + if (_rx_srtt < 1) + { + _rx_srtt = 1; + } + } + int rto = _rx_srtt + Math.Max((int)_interval, 4 * _rx_rttval); +#if NEED_MATH_SHIM + _rx_rto = Math.Min(Math.Max((uint)rto, _rx_minrto), IKCP_RTO_MAX); +#else + _rx_rto = Math.Clamp((uint)rto, _rx_minrto, IKCP_RTO_MAX); +#endif + } + + private bool HandleAck(uint serialNumber) + { + if (TimeDiff(serialNumber, _snd_una) < 0 || TimeDiff(serialNumber, _snd_nxt) >= 0) + { + return false; + } + + lock (_sndBuf) + { + LinkedListNodeOfBufferItem? node = _sndBuf.First; + while (node is not null) + { + LinkedListNodeOfBufferItem? next = node.Next; + + if (serialNumber == node.ValueRef.Segment.SerialNumber) + { + _sndBuf.Remove(node); + ref KcpBuffer dataRef = ref node.ValueRef.Data; + _sendQueue.SubtractUnflushedBytes(dataRef.Length); + dataRef.Release(); + dataRef = default; + _cache.Return(node); + return true; + } + + if (TimeDiff(serialNumber, node.ValueRef.Segment.SerialNumber) < 0) + { + return false; + } + + node = next; + } + } + + return false; + } + + private bool HandleData(KcpPacketHeader header, ReadOnlySpan data) + { + uint serialNumber = header.SerialNumber; + if (TimeDiff(serialNumber, _rcv_nxt + _rcv_wnd) >= 0 || TimeDiff(serialNumber, _rcv_nxt) < 0) + { + return false; + } + + bool mutated = false; + bool repeat = false; + LinkedListNodeOfBufferItem? node; + lock (_rcvBuf) + { + if (_transportClosed) + { + return false; + } + node = _rcvBuf.Last; + while (node is not null) + { + uint nodeSerialNumber = node.ValueRef.Segment.SerialNumber; + if (serialNumber == nodeSerialNumber) + { + repeat = true; + break; + } + if (TimeDiff(serialNumber, nodeSerialNumber) > 0) + { + break; + } + + node = node.Previous; + } + + if (!repeat) + { + KcpRentedBuffer buffer = _bufferPool.Rent(new KcpBufferPoolRentOptions(data.Length, false)); + var item = new KcpSendReceiveBufferItem + { + Data = KcpBuffer.CreateFromSpan(buffer, data), + Segment = header + }; + if (node is null) + { + _rcvBuf.AddFirst(_cache.Allocate(in item)); + } + else + { + _rcvBuf.AddAfter(node, _cache.Allocate(in item)); + } + mutated = true; + } + + // move available data from rcv_buf -> rcv_queue + node = _rcvBuf.First; + while (node is not null) + { + LinkedListNodeOfBufferItem? next = node.Next; + + if (node.ValueRef.Segment.SerialNumber == _rcv_nxt && _receiveQueue.GetQueueSize() < _rcv_wnd) + { + _rcvBuf.Remove(node); + _receiveQueue.Enqueue(node.ValueRef.Data, node.ValueRef.Segment.Fragment); + node.ValueRef.Data = default; + _cache.Return(node); + _rcv_nxt++; + mutated = true; + } + else + { + break; + } + + node = next; + } + } + + return mutated; + } + + private void AckPush(uint serialNumber, uint timestamp) => _ackList.Add(serialNumber, timestamp); + + private void HandleFastAck(uint serialNumber, uint timestamp) + { + if (TimeDiff(serialNumber, _snd_una) < 0 || TimeDiff(serialNumber, _snd_nxt) >= 0) + { + return; + } + + lock (_sndBuf) + { + LinkedListNodeOfBufferItem? node = _sndBuf.First; + while (node is not null) + { + LinkedListNodeOfBufferItem? next = node.Next; + if (TimeDiff(serialNumber, node.ValueRef.Segment.SerialNumber) < 0) + { + break; + } + else if (serialNumber != node.ValueRef.Segment.SerialNumber) + { + ref KcpSendSegmentStats stats = ref node.ValueRef.Stats; +#if !IKCP_FASTACK_CONSERVE + stats = new KcpSendSegmentStats(stats.ResendTimestamp, stats.Rto, stats.FastAck + 1, stats.TransmitCount); +#else + if (TimeDiff(timestamp, node.ValueRef.Segment.Timestamp) >= 0) + { + stats = new KcpSendSegmentStats(stats.ResendTimestamp, stats.Rto, stats.FastAck + 1, stats.TransmitCount); + } +#endif + } + + node = next; + } + } + } + + private static uint GetTimestamp() => (uint)Environment.TickCount; + + private static int TimeDiff(uint later, uint earlier) => (int)(later - earlier); + + /// + /// Get the size of the next available message in the receive queue. + /// + /// The transport state and the size of the next available message. + /// The receive or peek operation is initiated concurrently. + /// True if the receive queue contains at least one message. False if the receive queue is empty or the transport is closed. + public bool TryPeek(out KcpConversationReceiveResult result) + => _receiveQueue.TryPeek(out result); + + /// + /// Remove the next available message in the receive queue and copy its content into . When in stream mode, move as many bytes as possible into . + /// + /// The buffer to receive message. + /// The transport state and the count of bytes moved into . + /// The size of the next available message is larger than the size of . This exception is never thrown in stream mode. + /// The receive or peek operation is initiated concurrently. + /// True if the next available message is moved into . False if the receive queue is empty or the transport is closed. + public bool TryReceive(Span buffer, out KcpConversationReceiveResult result) + => _receiveQueue.TryReceive(buffer, out result); + + /// + /// Wait until the receive queue contains at least one full message, or at least one byte in stream mode. + /// + /// The token to cancel this operation. + /// The is fired before receive operation is completed. + /// The receive or peek operation is initiated concurrently. + /// A that completes when the receive queue contains at least one full message, or at least one byte in stream mode. Its result contains the transport state and the size of the available message. + public ValueTask WaitToReceiveAsync(CancellationToken cancellationToken = default) + => _receiveQueue.WaitToReceiveAsync(cancellationToken); + + /// + /// Wait until the receive queue contains at leat bytes. + /// + /// The minimum bytes in the receive queue. + /// The token to cancel this operation. + /// is a negative integer. + /// The is fired before receive operation is completed. + /// The receive or peek operation is initiated concurrently. + /// A that completes when the receive queue contains at least bytes. The result of the task is false when the transport is closed. + public ValueTask WaitForReceiveQueueAvailableDataAsync(int minimumBytes, CancellationToken cancellationToken = default) + => _receiveQueue.WaitForAvailableDataAsync(minimumBytes, 0, cancellationToken); + + /// + /// Wait until the receive queue contains at leat bytes, and also segments. + /// + /// The minimum bytes in the receive queue. + /// The minimum segments in the receive queue + /// The token to cancel this operation. + /// Any od and is a negative integer. + /// The is fired before receive operation is completed. + /// The receive or peek operation is initiated concurrently. + /// A that completes when the receive queue contains at least bytes. The result of the task is false when the transport is closed. + public ValueTask WaitForReceiveQueueAvailableDataAsync(int minimumBytes, int minimumSegments, CancellationToken cancellationToken = default) + => _receiveQueue.WaitForAvailableDataAsync(minimumBytes, minimumSegments, cancellationToken); + + /// + /// Wait for the next full message to arrive if the receive queue is empty. Remove the next available message in the receive queue and copy its content into . When in stream mode, move as many bytes as possible into . + /// + /// The buffer to receive message. + /// The token to cancel this operation. + /// The size of the next available message is larger than the size of . This exception is never thrown in stream mode. + /// The is fired before send operation is completed. + /// The receive or peek operation is initiated concurrently. + /// A that completes when a full message is moved into or the transport is closed. Its result contains the transport state and the count of bytes written into . + public ValueTask ReceiveAsync(Memory buffer, CancellationToken cancellationToken = default) + => _receiveQueue.ReceiveAsync(buffer, cancellationToken); + + internal ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken) + => _receiveQueue.ReadAsync(buffer, cancellationToken); + + /// + /// Cancel the current receive operation. + /// + /// True if the current operation is canceled. False if there is no active send operation. + public bool CancelPendingReceive() + => _receiveQueue.CancelPendingOperation(null, default); + + /// + /// Cancel the current receive operation. + /// + /// The inner exception of the thrown by the method or method. + /// The in the thrown by the method or method. + /// True if the current operation is canceled. False if there is no active send operation. + public bool CancelPendingReceive(Exception? innerException, CancellationToken cancellationToken) + => _receiveQueue.CancelPendingOperation(innerException, cancellationToken); + + /// + public void SetTransportClosed() + { + _transportClosed = true; + Interlocked.Exchange(ref _updateActivation, null)?.Dispose(); + CancellationTokenSource? updateLoopCts = Interlocked.Exchange(ref _updateLoopCts, null); + if (updateLoopCts is not null) + { + updateLoopCts.Cancel(); + updateLoopCts.Dispose(); + } + + _sendQueue.SetTransportClosed(); + _receiveQueue.SetTransportClosed(); + lock (_sndBuf) + { + LinkedListNodeOfBufferItem? node = _sndBuf.First; + LinkedListNodeOfBufferItem? next = node?.Next; + while (node is not null) + { + lock (node) + { + node.ValueRef.Data.Release(); + node.ValueRef = default; + } + + _sndBuf.Remove(node); + node = next; + next = node?.Next; + } + } + lock (_rcvBuf) + { + LinkedListNodeOfBufferItem? node = _rcvBuf.First; + while (node is not null) + { + node.ValueRef.Data.Release(); + node = node.Next; + } + _rcvBuf.Clear(); + } + _queueItemCache.Clear(); + } + + /// + public void Dispose() + { + bool disposed = _disposed; + _disposed = true; + SetTransportClosed(); + if (!disposed) + { + _sendQueue.Dispose(); + _receiveQueue.Dispose(); + } + } + + } +} diff --git a/NahidaImpact.Kcp/KcpConversationOptions.cs b/NahidaImpact.Kcp/KcpConversationOptions.cs new file mode 100644 index 0000000..53fa33a --- /dev/null +++ b/NahidaImpact.Kcp/KcpConversationOptions.cs @@ -0,0 +1,97 @@ +namespace NahidaImpact.Kcp +{ + /// + /// Options used to control the behaviors of . + /// + public class KcpConversationOptions + { + /// + /// The buffer pool to rent buffer from. + /// + public IKcpBufferPool BufferPool { get; set; } + + /// + /// The maximum packet size that can be transmitted over the underlying transport. + /// + public int Mtu { get; set; } = 1400; + + /// + /// The number of packets in the send window. + /// + public int SendWindow { get; set; } = 32; + + /// + /// The number of packets in the receive window. + /// + public int ReceiveWindow { get; set; } = 128; + + /// + /// The nuber of packets in the receive window of the remote host. + /// + public int RemoteReceiveWindow { get; set; } = 128; + + /// + /// The interval in milliseconds to update the internal state of . + /// + public int UpdateInterval { get; set; } = 100; + + /// + /// Wether no-delay mode is enabled. + /// + public bool NoDelay { get; set; } + + /// + /// The number of ACK packet skipped before a resend is triggered. + /// + public int FastResend { get; set; } + + /// + /// Whether congestion control is disabled. + /// + public bool DisableCongestionControl { get; set; } + + /// + /// Whether stream mode is enabled. + /// + public bool StreamMode { get; set; } + + /// + /// The number of packets in the send queue. + /// + public int SendQueueSize { get; set; } + + /// + /// The number of packets in the receive queue. + /// + public int ReceiveQueueSize { get; set; } + + /// + /// The number of bytes to reserve at the start of buffer passed into the underlying transport. The transport should fill this reserved space. + /// + public int PreBufferSize { get; set; } + + /// + /// The number of bytes to reserve at the end of buffer passed into the underlying transport. The transport should fill this reserved space. + /// + public int PostBufferSize { get; set; } + + /// + /// Options for customized keep-alive functionality. + /// + public KcpKeepAliveOptions KeepAliveOptions { get; set; } + + /// + /// Options for receive window size notification functionality. + /// + public KcpReceiveWindowNotificationOptions ReceiveWindowNotificationOptions { get; set; } + + internal const int MtuDefaultValue = 1400; + internal const uint SendWindowDefaultValue = 32; + internal const uint ReceiveWindowDefaultValue = 128; + internal const uint RemoteReceiveWindowDefaultValue = 128; + internal const uint UpdateIntervalDefaultValue = 100; + + internal const int SendQueueSizeDefaultValue = 32; + internal const int ReceiveQueueSizeDefaultValue = 32; + } +} diff --git a/NahidaImpact.Kcp/KcpConversationReceiveResult.cs b/NahidaImpact.Kcp/KcpConversationReceiveResult.cs new file mode 100644 index 0000000..002d7d8 --- /dev/null +++ b/NahidaImpact.Kcp/KcpConversationReceiveResult.cs @@ -0,0 +1,61 @@ +using System.Globalization; + +namespace NahidaImpact.Kcp +{ + /// + /// The result of a receive or peek operation. + /// + public readonly struct KcpConversationReceiveResult : IEquatable + { + private readonly int _bytesReceived; + private readonly bool _connectionAlive; + + /// + /// The number of bytes received. + /// + public int BytesReceived => _bytesReceived; + + /// + /// Whether the underlying transport is marked as closed. + /// + public bool TransportClosed => !_connectionAlive; + + /// + /// Construct a with the specified number of bytes received. + /// + /// The number of bytes received. + public KcpConversationReceiveResult(int bytesReceived) + { + _bytesReceived = bytesReceived; + _connectionAlive = true; + } + + /// + /// Checks whether the two instance is equal. + /// + /// The one instance. + /// The other instance. + /// Whether the two instance is equal + public static bool operator ==(KcpConversationReceiveResult left, KcpConversationReceiveResult right) => left.Equals(right); + + /// + /// Checks whether the two instance is not equal. + /// + /// The one instance. + /// The other instance. + /// Whether the two instance is not equal + public static bool operator !=(KcpConversationReceiveResult left, KcpConversationReceiveResult right) => !left.Equals(right); + + /// + public bool Equals(KcpConversationReceiveResult other) => BytesReceived == other.BytesReceived && TransportClosed == other.TransportClosed; + + /// + public override bool Equals(object obj) => obj is KcpConversationReceiveResult other && Equals(other); + + /// + public override int GetHashCode() => HashCode.Combine(BytesReceived, TransportClosed); + + /// + public override string ToString() => _connectionAlive ? _bytesReceived.ToString(CultureInfo.InvariantCulture) : "Transport is closed."; + } +} diff --git a/NahidaImpact.Kcp/KcpConversationUpdateActivation.cs b/NahidaImpact.Kcp/KcpConversationUpdateActivation.cs new file mode 100644 index 0000000..4f32f06 --- /dev/null +++ b/NahidaImpact.Kcp/KcpConversationUpdateActivation.cs @@ -0,0 +1,490 @@ +using System.Diagnostics; +using System.Threading.Tasks.Sources; + +namespace NahidaImpact.Kcp +{ + internal sealed class KcpConversationUpdateActivation : IValueTaskSource, IDisposable + { + private readonly Timer _timer; + private ManualResetValueTaskSourceCore _mrvtsc; + + private bool _disposed; + private bool _notificationPending; + private bool _signaled; + private bool _activeWait; + private CancellationToken _cancellationToken; + private CancellationTokenRegistration _cancellationRegistration; + + private readonly WaitList _waitList; + + ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) => _mrvtsc.GetStatus(token); + void IValueTaskSource.OnCompleted(Action continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) => _mrvtsc.OnCompleted(continuation, state, token, flags); + KcpConversationUpdateNotification IValueTaskSource.GetResult(short token) + { + _cancellationRegistration.Dispose(); + + try + { + return _mrvtsc.GetResult(token); + } + finally + { + _mrvtsc.Reset(); + + lock (this) + { + _signaled = false; + _activeWait = false; + _cancellationRegistration = default; + } + } + } + + public KcpConversationUpdateActivation(int interval) + { + _timer = new Timer(state => + { + var reference = (WeakReference)state!; + if (reference.TryGetTarget(out KcpConversationUpdateActivation target)) + { + target.Notify(); + } + }, new WeakReference(this), interval, interval); + _mrvtsc = new ManualResetValueTaskSourceCore { RunContinuationsAsynchronously = true }; + _waitList = new WaitList(this); + } + + public void Notify() + { + if (_disposed) + { + return; + } + lock (this) + { + if (_disposed || _notificationPending) + { + return; + } + if (_activeWait && !_signaled) + { + _signaled = true; + _cancellationToken = default; + _mrvtsc.SetResult(default); + } + else + { + _notificationPending = true; + } + } + } + + private void NotifyPacketReceived() + { + lock (this) + { + if (_disposed) + { + return; + } + if (_activeWait && !_signaled) + { + if (_waitList.Occupy(out KcpConversationUpdateNotification notification)) + { + _signaled = true; + _cancellationToken = default; + bool timerNotification = _notificationPending; + _notificationPending = false; + _mrvtsc.SetResult(notification.WithTimerNotification(timerNotification)); + } + } + } + } + + public ValueTask WaitAsync(CancellationToken cancellationToken) + { + short token; + lock (this) + { + if (_disposed) + { + return default; + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + if (_activeWait) + { + throw new InvalidOperationException(); + } + if (_waitList.Occupy(out KcpConversationUpdateNotification notification)) + { + bool timerNotification = _notificationPending; + _notificationPending = false; + return new ValueTask(notification.WithTimerNotification(timerNotification)); + } + if (_notificationPending) + { + _notificationPending = false; + return default; + } + + _activeWait = true; + Debug.Assert(!_signaled); + _cancellationToken = cancellationToken; + token = _mrvtsc.Version; + } + + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((KcpConversationUpdateActivation)state)!.CancelWaiting(), this); + return new ValueTask(this, token); + } + + private void CancelWaiting() + { + lock (this) + { + if (_activeWait && !_signaled) + { + CancellationToken cancellationToken = _cancellationToken; + _signaled = true; + _cancellationToken = default; + _mrvtsc.SetException(new OperationCanceledException(cancellationToken)); + } + } + } + + public ValueTask InputPacketAsync(ReadOnlyMemory packet, CancellationToken cancellationToken) + { + if (_disposed) + { + return default; + } + return _waitList.InputPacketAsync(packet, cancellationToken); + } + + public void Dispose() + { + lock (this) + { + if (_disposed) + { + return; + } + _disposed = true; + if (_activeWait && !_signaled) + { + _signaled = true; + _cancellationToken = default; + _mrvtsc.SetResult(default); + } + } + _timer.Dispose(); + _waitList.Dispose(); + } + + class WaitList : IValueTaskSource, IKcpConversationUpdateNotificationSource, IDisposable + { + private readonly KcpConversationUpdateActivation _parent; + private LinkedList _list; + private ManualResetValueTaskSourceCore _mrvtsc; + + private bool _available; // activeWait + private bool _occupied; + private bool _signaled; + private bool _disposed; + + private ReadOnlyMemory _packet; + private CancellationToken _cancellationToken; + private CancellationTokenRegistration _cancellationRegistration; + + public ReadOnlyMemory Packet + { + get + { + lock (this) + { + if (_available && _occupied && !_signaled) + { + return _packet; + } + } + return default; + } + } + + ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) => _mrvtsc.GetStatus(token); + void IValueTaskSource.OnCompleted(Action continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) => _mrvtsc.OnCompleted(continuation, state, token, flags); + void IValueTaskSource.GetResult(short token) + { + _cancellationRegistration.Dispose(); + + try + { + _mrvtsc.GetResult(token); + } + finally + { + _mrvtsc.Reset(); + + lock (this) + { + _available = false; + _occupied = false; + _signaled = false; + _cancellationRegistration = default; + } + } + } + + public WaitList(KcpConversationUpdateActivation parent) + { + _parent = parent; + _mrvtsc = new ManualResetValueTaskSourceCore { RunContinuationsAsynchronously = true }; + } + + public ValueTask InputPacketAsync(ReadOnlyMemory packet, CancellationToken cancellationToken) + { + WaitItem waitItem = null; + short token = 0; + lock (this) + { + if (_disposed) + { + return default; + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + if (_available) + { + waitItem = new WaitItem(this, packet, cancellationToken); + _list ??= new LinkedList(); + _list.AddLast(waitItem.Node); + } + else + { + token = _mrvtsc.Version; + + _available = true; + Debug.Assert(!_occupied); + Debug.Assert(!_signaled); + _packet = packet; + _cancellationToken = cancellationToken; + } + } + + ValueTask task; + + if (waitItem is null) + { + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((WaitList)state)!.CancelWaiting(), this); + task = new ValueTask(this, token); + } + else + { + waitItem.RegisterCancellationToken(); + task = new ValueTask(waitItem.Task); + } + + _parent.NotifyPacketReceived(); + + return task; + } + + private void CancelWaiting() + { + lock (this) + { + if (_available && !_occupied && !_signaled) + { + _signaled = true; + CancellationToken cancellationToken = _cancellationToken; + _packet = default; + _cancellationToken = default; + _mrvtsc.SetException(new OperationCanceledException(cancellationToken)); + } + } + } + + public bool Occupy(out KcpConversationUpdateNotification notification) + { + lock (this) + { + if (_disposed) + { + notification = default; + return false; + } + if (_available && !_occupied && !_signaled) + { + _occupied = true; + notification = new KcpConversationUpdateNotification(this, true); + return true; + } + if (_list is null) + { + notification = default; + return false; + } + LinkedListNode node = _list.First; + if (node is not null) + { + _list.Remove(node); + notification = new KcpConversationUpdateNotification(node.Value, true); + return true; + } + } + notification = default; + return false; + } + + public void Release() + { + lock (this) + { + if (_available && _occupied && !_signaled) + { + _signaled = true; + _packet = default; + _cancellationToken = default; + _mrvtsc.SetResult(true); + } + } + } + + internal bool TryRemove(WaitItem item) + { + lock (this) + { + LinkedList list = _list; + if (list is null) + { + return false; + } + LinkedListNode node = item.Node; + if (node.Previous is null && node.Next is null) + { + return false; + } + list.Remove(node); + return true; + } + } + + public void Dispose() + { + if (_disposed) + { + return; + } + lock (this) + { + _disposed = true; + if (_available && !_occupied && !_signaled) + { + _signaled = true; + _packet = default; + _cancellationToken = default; + _mrvtsc.SetResult(false); + } + + LinkedList list = _list; + if (list is not null) + { + _list = null; + + LinkedListNode node = list.First; + LinkedListNode next = node?.Next; + while (node is not null) + { + node.Value.Release(); + + list.Remove(node); + node = next; + next = node?.Next; + } + } + + } + } + + } + + class WaitItem : TaskCompletionSource, IKcpConversationUpdateNotificationSource + { + private readonly WaitList _parent; + private ReadOnlyMemory _packet; + private CancellationToken _cancellationToken; + private CancellationTokenRegistration _cancellationRegistration; + private bool _released; + + public LinkedListNode Node { get; } + + public ReadOnlyMemory Packet + { + get + { + lock (this) + { + if (!_released) + { + return _packet; + } + } + return default; + } + } + + public WaitItem(WaitList parent, ReadOnlyMemory packet, CancellationToken cancellationToken) + { + _parent = parent; + _packet = packet; + _cancellationToken = cancellationToken; + + Node = new LinkedListNode(this); + } + + public void RegisterCancellationToken() + { + _cancellationRegistration = _cancellationToken.UnsafeRegister(state => ((WaitItem)state)!.CancelWaiting(), this); + } + + private void CancelWaiting() + { + CancellationTokenRegistration cancellationRegistration; + if (_parent.TryRemove(this)) + { + CancellationToken cancellationToken; + lock (this) + { + _released = true; + cancellationToken = _cancellationToken; + cancellationRegistration = _cancellationRegistration; + _packet = default; + _cancellationToken = default; + _cancellationRegistration = default; + } + TrySetCanceled(cancellationToken); + } + _cancellationRegistration.Dispose(); + } + + public void Release() + { + CancellationTokenRegistration cancellationRegistration; + lock (this) + { + _released = true; + cancellationRegistration = _cancellationRegistration; + _packet = default; + _cancellationToken = default; + _cancellationRegistration = default; + } + TrySetResult(); + cancellationRegistration.Dispose(); + } + } + } +} diff --git a/NahidaImpact.Kcp/KcpConversationUpdateNotification.cs b/NahidaImpact.Kcp/KcpConversationUpdateNotification.cs new file mode 100644 index 0000000..d15c710 --- /dev/null +++ b/NahidaImpact.Kcp/KcpConversationUpdateNotification.cs @@ -0,0 +1,30 @@ +namespace NahidaImpact.Kcp +{ + internal readonly struct KcpConversationUpdateNotification : IDisposable + { + private readonly IKcpConversationUpdateNotificationSource _source; + private readonly bool _skipTimerNotification; + + public ReadOnlyMemory Packet => _source?.Packet ?? default; + public bool TimerNotification => !_skipTimerNotification; + + public KcpConversationUpdateNotification(IKcpConversationUpdateNotificationSource source, bool skipTimerNotification) + { + _source = source; + _skipTimerNotification = skipTimerNotification; + } + + public KcpConversationUpdateNotification WithTimerNotification(bool timerNotification) + { + return new KcpConversationUpdateNotification(_source, !_skipTimerNotification | timerNotification); + } + + public void Dispose() + { + if (_source is not null) + { + _source.Release(); + } + } + } +} diff --git a/NahidaImpact.Kcp/KcpExceptionProducerExtensions.cs b/NahidaImpact.Kcp/KcpExceptionProducerExtensions.cs new file mode 100644 index 0000000..e7b4c32 --- /dev/null +++ b/NahidaImpact.Kcp/KcpExceptionProducerExtensions.cs @@ -0,0 +1,134 @@ +namespace NahidaImpact.Kcp +{ + /// + /// Helper methods for . + /// + public static class KcpExceptionProducerExtensions + { + /// + /// Set the handler to invoke when exception is thrown. Return true in the handler to ignore the error and continue running. Return false in the handler to abort the operation. + /// + /// The producer instance. + /// The exception handler. + public static void SetExceptionHandler(this IKcpExceptionProducer producer, Func handler) + { + if (producer is null) + { + throw new ArgumentNullException(nameof(producer)); + } + if (handler is null) + { + throw new ArgumentNullException(nameof(handler)); + } + + producer.SetExceptionHandler( + (ex, conv, state) => ((Func)state)!.Invoke(ex, conv), + handler + ); + } + + /// + /// Set the handler to invoke when exception is thrown. Return true in the handler to ignore the error and continue running. Return false in the handler to abort the operation. + /// + /// The producer instance. + /// The exception handler. + public static void SetExceptionHandler(this IKcpExceptionProducer producer, Func handler) + { + if (producer is null) + { + throw new ArgumentNullException(nameof(producer)); + } + if (handler is null) + { + throw new ArgumentNullException(nameof(handler)); + } + + producer.SetExceptionHandler( + (ex, conv, state) => ((Func)state)!.Invoke(ex), + handler + ); + } + + /// + /// Set the handler to invoke when exception is thrown. + /// + /// The producer instance. + /// The exception handler. + /// The state object to pass into the exception handler. + public static void SetExceptionHandler(this IKcpExceptionProducer producer, Action handler, object state) + { + if (producer is null) + { + throw new ArgumentNullException(nameof(producer)); + } + if (handler is null) + { + throw new ArgumentNullException(nameof(handler)); + } + + producer.SetExceptionHandler( + (ex, conv, state) => + { + var tuple = (Tuple, object>)state!; + tuple.Item1.Invoke(ex, conv, tuple.Item2); + return false; + }, + Tuple.Create(handler, state) + ); + } + + /// + /// Set the handler to invoke when exception is thrown. + /// + /// The producer instance. + /// The exception handler. + public static void SetExceptionHandler(this IKcpExceptionProducer producer, Action handler) + { + if (producer is null) + { + throw new ArgumentNullException(nameof(producer)); + } + if (handler is null) + { + throw new ArgumentNullException(nameof(handler)); + } + + producer.SetExceptionHandler( + (ex, conv, state) => + { + var handler = (Action)state!; + handler.Invoke(ex, conv); + return false; + }, + handler + ); + } + + /// + /// Set the handler to invoke when exception is thrown. + /// + /// The producer instance. + /// The exception handler. + public static void SetExceptionHandler(this IKcpExceptionProducer producer, Action handler) + { + if (producer is null) + { + throw new ArgumentNullException(nameof(producer)); + } + if (handler is null) + { + throw new ArgumentNullException(nameof(handler)); + } + + producer.SetExceptionHandler( + (ex, conv, state) => + { + var handler = (Action)state!; + handler.Invoke(ex); + return false; + }, + handler + ); + } + } +} diff --git a/NahidaImpact.Kcp/KcpGlobalVars.cs b/NahidaImpact.Kcp/KcpGlobalVars.cs new file mode 100644 index 0000000..7c8f521 --- /dev/null +++ b/NahidaImpact.Kcp/KcpGlobalVars.cs @@ -0,0 +1,14 @@ +namespace NahidaImpact.Kcp +{ + internal static class KcpGlobalVars + { +#if !CONVID32 + public const ushort CONVID_LENGTH = 8; + public const ushort HEADER_LENGTH_WITH_CONVID = 28; + public const ushort HEADER_LENGTH_WITHOUT_CONVID = 20; +#else + public const ushort HEADER_LENGTH_WITH_CONVID = 24; + public const ushort HEADER_LENGTH_WITHOUT_CONVID = 20; +#endif + } +} diff --git a/NahidaImpact.Kcp/KcpKeepAliveOptions.cs b/NahidaImpact.Kcp/KcpKeepAliveOptions.cs new file mode 100644 index 0000000..95b4694 --- /dev/null +++ b/NahidaImpact.Kcp/KcpKeepAliveOptions.cs @@ -0,0 +1,30 @@ +namespace NahidaImpact.Kcp +{ + /// + /// Options for customized keep-alive functionality. + /// + public sealed class KcpKeepAliveOptions + { + /// + /// Create an instance of option object for customized keep-alive functionality. + /// + /// The minimum interval in milliseconds between sending keep-alive messages. + /// When no packets are received during this period (in milliseconds), the transport is considered to be closed. + public KcpKeepAliveOptions(int sendInterval, int gracePeriod) + { + if (sendInterval <= 0) + { + throw new ArgumentOutOfRangeException(nameof(sendInterval)); + } + if (gracePeriod <= 0) + { + throw new ArgumentOutOfRangeException(nameof(gracePeriod)); + } + SendInterval = sendInterval; + GracePeriod = gracePeriod; + } + + internal int SendInterval { get; } + internal int GracePeriod { get; } + } +} diff --git a/NahidaImpact.Kcp/KcpMultiplexConnection.cs b/NahidaImpact.Kcp/KcpMultiplexConnection.cs new file mode 100644 index 0000000..996674d --- /dev/null +++ b/NahidaImpact.Kcp/KcpMultiplexConnection.cs @@ -0,0 +1,339 @@ +using System.Buffers.Binary; +using System.Collections.Concurrent; +using System.Net; +using System.Net.Sockets; + +namespace NahidaImpact.Kcp +{ + /// + /// Multiplex many channels or conversations over the same transport. + /// + /// The state of the channel. + public sealed class KcpMultiplexConnection : IKcpTransport, IKcpConversation, IKcpMultiplexConnection + { + private readonly IKcpTransport _transport; + + private readonly ConcurrentDictionary _conversations = new(); + private bool _transportClosed; + private bool _disposed; + + private readonly Action _disposeAction; + + /// + /// Construct a multiplexed connection over a transport. + /// + /// The underlying transport. + public KcpMultiplexConnection(IKcpTransport transport) + { + _transport = transport ?? throw new ArgumentNullException(nameof(transport)); + _disposeAction = null; + } + + /// + /// Construct a multiplexed connection over a transport. + /// + /// The underlying transport. + /// The action to invoke when state object is removed. + public KcpMultiplexConnection(IKcpTransport transport, Action disposeAction) + { + _transport = transport ?? throw new ArgumentNullException(nameof(transport)); + _disposeAction = disposeAction; + } + + private void CheckDispose() + { + if (_disposed) + { + ThrowObjectDisposedException(); + } + } + + private static void ThrowObjectDisposedException() + { + throw new ObjectDisposedException(nameof(KcpMultiplexConnection)); + } + + /// + /// Process a newly received packet from the transport. + /// + /// The content of the packet with conversation ID. + /// A token to cancel this operation. + /// A that completes when the packet is handled by the corresponding channel or conversation. + public ValueTask InputPakcetAsync(UdpReceiveResult packet, CancellationToken cancellationToken = default) + { + ReadOnlySpan span = packet.Buffer.AsSpan(); + if (span.Length < KcpGlobalVars.CONVID_LENGTH) + { + return default; + } + if (_transportClosed || _disposed) + { + return default; + } + var id = BinaryPrimitives.ReadInt64BigEndian(span); + if (_conversations.TryGetValue(id, out (IKcpConversation Conversation, T? State) value)) + { + return value.Conversation.InputPakcetAsync(packet, cancellationToken); + } + return default; + } + + /// + /// Determine whether the multiplex connection contains a conversation with the specified id. + /// + /// The conversation ID. + /// True if the multiplex connection contains the specified conversation. Otherwise false. + public bool Contains(long id) + { + CheckDispose(); + return _conversations.ContainsKey(id); + } + + /// + /// Create a raw channel with the specified conversation ID. + /// + /// The conversation ID. + /// The remote Endpoint + /// The options of the . + /// The raw channel created. + /// The current instance is disposed. + /// Another channel or conversation with the same ID was already registered. + public KcpRawChannel CreateRawChannel(long id, IPEndPoint remoteEndpoint, KcpRawChannelOptions options = null) + { + KcpRawChannel channel = new KcpRawChannel(remoteEndpoint, this, id, options); + try + { + RegisterConversation(channel, id, default); + if (_transportClosed) + { + channel.SetTransportClosed(); + } + return Interlocked.Exchange(ref channel, null)!; + } + finally + { + if (channel is not null) + { + channel.Dispose(); + } + } + } + + /// + /// Create a raw channel with the specified conversation ID. + /// + /// The conversation ID. + /// The remote Endpoint + /// The user state of this channel. + /// The options of the . + /// The raw channel created. + /// The current instance is disposed. + /// Another channel or conversation with the same ID was already registered. + public KcpRawChannel CreateRawChannel(long id, IPEndPoint remoteEndpoint, T state, KcpRawChannelOptions options = null) + { + var channel = new KcpRawChannel(remoteEndpoint, this, id, options); + try + { + RegisterConversation(channel, id, state); + if (_transportClosed) + { + channel.SetTransportClosed(); + } + return Interlocked.Exchange(ref channel, null)!; + } + finally + { + if (channel is not null) + { + channel.Dispose(); + } + } + } + + /// + /// Create a conversation with the specified conversation ID. + /// + /// The conversation ID. + /// The remote Endpoint + /// The options of the . + /// The KCP conversation created. + /// The current instance is disposed. + /// Another channel or conversation with the same ID was already registered. + public KcpConversation CreateConversation(long id, IPEndPoint remoteEndpoint, KcpConversationOptions options = null) + { + var conversation = new KcpConversation(remoteEndpoint, this, id, options); + try + { + RegisterConversation(conversation, id, default); + if (_transportClosed) + { + conversation.SetTransportClosed(); + } + return Interlocked.Exchange(ref conversation, null)!; + } + finally + { + if (conversation is not null) + { + conversation.Dispose(); + } + } + } + + /// + /// Create a conversation with the specified conversation ID. + /// + /// The conversation ID. + /// The remote Endpoint + /// The user state of this conversation. + /// The options of the . + /// The KCP conversation created. + /// The current instance is disposed. + /// Another channel or conversation with the same ID was already registered. + public KcpConversation CreateConversation(long id, IPEndPoint remoteEndpoint, T state, KcpConversationOptions options = null) + { + var conversation = new KcpConversation(remoteEndpoint, this, id, options); + try + { + RegisterConversation(conversation, id, state); + if (_transportClosed) + { + conversation.SetTransportClosed(); + } + return Interlocked.Exchange(ref conversation, null)!; + } + finally + { + if (conversation is not null) + { + conversation.Dispose(); + } + } + } + + /// + /// Register a conversation or channel with the specified conversation ID and user state. + /// + /// The conversation or channel to register. + /// The conversation ID. + /// is not provided. + /// The current instance is disposed. + /// Another channel or conversation with the same ID was already registered. + public void RegisterConversation(IKcpConversation conversation, long id) + => RegisterConversation(conversation, id, default); + + /// + /// Register a conversation or channel with the specified conversation ID and user state. + /// + /// The conversation or channel to register. + /// The conversation ID. + /// The user state + /// is not provided. + /// The current instance is disposed. + /// Another channel or conversation with the same ID was already registered. + public void RegisterConversation(IKcpConversation conversation, long id, T? state) + { + if (conversation is null) + { + throw new ArgumentNullException(nameof(conversation)); + } + + CheckDispose(); + (IKcpConversation addedConversation, T? _) = _conversations.GetOrAdd(id, (conversation, state)); + if (!ReferenceEquals(addedConversation, conversation)) + { + throw new InvalidOperationException("Duplicated conversation."); + } + if (_disposed) + { + if (_conversations.TryRemove(id, out (IKcpConversation Conversation, T? State) value) && _disposeAction is not null) + { + _disposeAction.Invoke(value.State); + } + ThrowObjectDisposedException(); + } + } + + /// + /// Unregister a conversation or channel with the specified conversation ID. + /// + /// The conversation ID. + /// The conversation unregistered. Returns null when the conversation with the specified ID is not found. + public IKcpConversation UnregisterConversation(long id) + { + return UnregisterConversation(id, out _); + } + + /// + /// Unregister a conversation or channel with the specified conversation ID. + /// + /// The conversation ID. + /// The user state. + /// The conversation unregistered. Returns null when the conversation with the specified ID is not found. + public IKcpConversation UnregisterConversation(long id, out T? state) + { + if (!_transportClosed && !_disposed && _conversations.TryRemove(id, out (IKcpConversation Conversation, T? State) value)) + { + value.Conversation.SetTransportClosed(); + state = value.State; + if (_disposeAction is not null) + { + _disposeAction.Invoke(state); + } + return value.Conversation; + } + state = default; + return default; + } + + /// + public ValueTask SendPacketAsync(Memory packet, IPEndPoint remoteEndpoint, CancellationToken cancellationToken = default) + { + if (_transportClosed || _disposed) + { + return default; + } + return _transport.SendPacketAsync(packet, remoteEndpoint, cancellationToken); + } + + /// + public void SetTransportClosed() + { + _transportClosed = true; + foreach ((IKcpConversation conversation, T? _) in _conversations.Values) + { + conversation.SetTransportClosed(); + } + } + + /// + public void Dispose() + { + if (_disposed) + { + return; + } + _transportClosed = true; + _disposed = true; + while (!_conversations.IsEmpty) + { + foreach (var id in _conversations.Keys) + { + if (_conversations.TryRemove(id, out (IKcpConversation Conversation, T? State) value)) + { + value.Conversation.Dispose(); + if (_disposeAction is not null) + { + _disposeAction.Invoke(value.State); + } + } + } + } + } + + public void SetCallbacks(int handshakeSize, Func handshakeHandler) + { + throw new NotSupportedException(); + } + } +} diff --git a/NahidaImpact.Kcp/KcpPacketHeader.cs b/NahidaImpact.Kcp/KcpPacketHeader.cs new file mode 100644 index 0000000..de8f062 --- /dev/null +++ b/NahidaImpact.Kcp/KcpPacketHeader.cs @@ -0,0 +1,75 @@ +using System.Buffers.Binary; +using System.Diagnostics; + +namespace NahidaImpact.Kcp +{ + internal readonly struct KcpPacketHeader : IEquatable + { + public KcpPacketHeader(KcpCommand command, byte fragment, ushort windowSize, uint timestamp, uint serialNumber, uint unacknowledged) + { + Command = command; + Fragment = fragment; + WindowSize = windowSize; + Timestamp = timestamp; + SerialNumber = serialNumber; + Unacknowledged = unacknowledged; + } + + internal KcpPacketHeader(byte fragment) + { + Command = 0; + Fragment = fragment; + WindowSize = 0; + Timestamp = 0; + SerialNumber = 0; + Unacknowledged = 0; + } + + public KcpCommand Command { get; } + public byte Fragment { get; } + public ushort WindowSize { get; } + public uint Timestamp { get; } + public uint SerialNumber { get; } + public uint Unacknowledged { get; } + + public bool Equals(KcpPacketHeader other) => Command == other.Command && Fragment == other.Fragment && WindowSize == other.WindowSize && Timestamp == other.Timestamp && SerialNumber == other.SerialNumber && Unacknowledged == other.Unacknowledged; + public override bool Equals(object obj) => obj is KcpPacketHeader other && Equals(other); + public override int GetHashCode() => HashCode.Combine(Command, Fragment, WindowSize, Timestamp, SerialNumber, Unacknowledged); + + public static KcpPacketHeader Parse(ReadOnlySpan buffer) + { + Debug.Assert(buffer.Length >= 16); + return new KcpPacketHeader( + (KcpCommand)buffer[0], + buffer[1], + BinaryPrimitives.ReadUInt16LittleEndian(buffer.Slice(2)), + BinaryPrimitives.ReadUInt32LittleEndian(buffer.Slice(4)), + BinaryPrimitives.ReadUInt32LittleEndian(buffer.Slice(8)), + BinaryPrimitives.ReadUInt32LittleEndian(buffer.Slice(12)) + ); + } + + internal void EncodeHeader(ulong? conversationId, int payloadLength, Span destination, out int bytesWritten) + { + Debug.Assert(destination.Length >= 20); + if (conversationId.HasValue) + { + BinaryPrimitives.WriteUInt64BigEndian(destination, conversationId.GetValueOrDefault()); + destination = destination.Slice(8); + bytesWritten = 28; + } + else + { + bytesWritten = 20; + } + Debug.Assert(destination.Length >= 20); + destination[1] = Fragment; + destination[0] = (byte)Command; + BinaryPrimitives.WriteUInt16LittleEndian(destination.Slice(2), WindowSize); + BinaryPrimitives.WriteUInt32LittleEndian(destination.Slice(4), Timestamp); + BinaryPrimitives.WriteUInt32LittleEndian(destination.Slice(8), SerialNumber); + BinaryPrimitives.WriteUInt32LittleEndian(destination.Slice(12), Unacknowledged); + BinaryPrimitives.WriteUInt32LittleEndian(destination.Slice(16), (uint)payloadLength); + } + } +} diff --git a/NahidaImpact.Kcp/KcpProbeType.cs b/NahidaImpact.Kcp/KcpProbeType.cs new file mode 100644 index 0000000..2b89c9c --- /dev/null +++ b/NahidaImpact.Kcp/KcpProbeType.cs @@ -0,0 +1,10 @@ +namespace NahidaImpact.Kcp +{ + [Flags] + internal enum KcpProbeType + { + None = 0, + AskSend = 1, + AskTell = 2, + } +} diff --git a/NahidaImpact.Kcp/KcpRawChannel.cs b/NahidaImpact.Kcp/KcpRawChannel.cs new file mode 100644 index 0000000..59795b9 --- /dev/null +++ b/NahidaImpact.Kcp/KcpRawChannel.cs @@ -0,0 +1,371 @@ +using System.Buffers.Binary; +using System.Net; +using System.Net.Sockets; + +namespace NahidaImpact.Kcp +{ + /// + /// An unreliable channel with a conversation ID. + /// + public sealed class KcpRawChannel : IKcpConversation, IKcpExceptionProducer + { + private readonly IKcpBufferPool _bufferPool; + private readonly IKcpTransport _transport; + private readonly IPEndPoint _remoteEndPoint; + private readonly ulong? _id; + private readonly int _mtu; + private readonly int _preBufferSize; + private readonly int _postBufferSize; + + private CancellationTokenSource _sendLoopCts; + private readonly KcpRawReceiveQueue _receiveQueue; + private readonly KcpRawSendOperation _sendOperation; + private readonly AsyncAutoResetEvent _sendNotification; + + private Func _exceptionHandler; + private object _exceptionHandlerState; + + /// + /// Construct a unreliable channel with a conversation ID. + /// + /// The remote Endpoint + /// The underlying transport. + /// The options of the . + public KcpRawChannel(IPEndPoint remoteEndPoint, IKcpTransport transport, KcpRawChannelOptions options) + : this(remoteEndPoint, transport, null, options) + { } + + /// + /// Construct a unreliable channel with a conversation ID. + /// + /// The remote Endpoint + /// The underlying transport. + /// The conversation ID. + /// The options of the . + public KcpRawChannel(IPEndPoint remoteEndPoint, IKcpTransport transport, long conversationId, KcpRawChannelOptions options) + : this(remoteEndPoint, transport, (ulong)conversationId, options) + { } + + private KcpRawChannel(IPEndPoint remoteEndPoint, IKcpTransport transport, ulong? conversationId, KcpRawChannelOptions options) + { + _bufferPool = options?.BufferPool ?? DefaultArrayPoolBufferAllocator.Default; + _remoteEndPoint = remoteEndPoint; + _transport = transport; + _id = conversationId; + + if (options is null) + { + _mtu = KcpConversationOptions.MtuDefaultValue; + } + else if (options.Mtu < 50) + { + throw new ArgumentException("MTU must be at least 50.", nameof(options)); + } + else + { + _mtu = options.Mtu; + } + + _preBufferSize = options?.PreBufferSize ?? 0; + _postBufferSize = options?.PostBufferSize ?? 0; + if (_preBufferSize < 0) + { + throw new ArgumentException("PreBufferSize must be a non-negative integer.", nameof(options)); + } + if (_postBufferSize < 0) + { + throw new ArgumentException("PostBufferSize must be a non-negative integer.", nameof(options)); + } + if ((uint)(_preBufferSize + _postBufferSize) >= (uint)_mtu) + { + throw new ArgumentException("The sum of PreBufferSize and PostBufferSize must be less than MTU.", nameof(options)); + } + if (conversationId.HasValue && (uint)(_preBufferSize + _postBufferSize) >= (uint)(_mtu - 4)) + { + throw new ArgumentException("The sum of PreBufferSize and PostBufferSize is too large. There is not enough space in the packet for the conversation ID.", nameof(options)); + } + + int queueSize = options?.ReceiveQueueSize ?? 32; + if (queueSize < 1) + { + throw new ArgumentException("QueueSize must be a positive integer.", nameof(options)); + } + + _sendLoopCts = new CancellationTokenSource(); + _sendNotification = new AsyncAutoResetEvent(); + _receiveQueue = new KcpRawReceiveQueue(_bufferPool, queueSize); + _sendOperation = new KcpRawSendOperation(_sendNotification); + + RunSendLoop(); + } + + /// + /// Set the handler to invoke when exception is thrown during flushing packets to the transport. Return true in the handler to ignore the error and continue running. Return false in the handler to abort the operation and mark the transport as closed. + /// + /// The exception handler. + /// The state object to pass into the exception handler. + public void SetExceptionHandler(Func handler, object state) + { + if (handler is null) + { + throw new ArgumentNullException(nameof(handler)); + } + + _exceptionHandler = handler; + _exceptionHandlerState = state; + } + + /// + /// Get the ID of the current conversation. + /// + public long? ConversationId => (long?)_id; + + /// + /// Get whether the transport is marked as closed. + /// + public bool TransportClosed => _sendLoopCts is null; + + /// + /// Send message to the underlying transport. + /// + /// The content of the message + /// The token to cancel this operation. + /// The size of the message is larger than mtu, thus it can not be sent. + /// The is fired before send operation is completed. + /// The send operation is initiated concurrently. + /// The instance is disposed. + /// A that completes when the entire message is put into the queue. The result of the task is false when the transport is closed. + public ValueTask SendAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) + => _sendOperation.SendAsync(buffer, cancellationToken); + + + /// + /// Cancel the current send operation or flush operation. + /// + /// True if the current operation is canceled. False if there is no active send operation. + public bool CancelPendingSend() + => _sendOperation.CancelPendingOperation(null, default); + + /// + /// Cancel the current send operation or flush operation. + /// + /// The inner exception of the thrown by the method. + /// The in the thrown by the method. + /// True if the current operation is canceled. False if there is no active send operation. + public bool CancelPendingSend(Exception innerException, CancellationToken cancellationToken) + => _sendOperation.CancelPendingOperation(innerException, cancellationToken); + + + private async void RunSendLoop() + { + CancellationToken cancellationToken = _sendLoopCts?.Token ?? new CancellationToken(true); + KcpRawSendOperation sendOperation = _sendOperation; + AsyncAutoResetEvent ev = _sendNotification; + int mss = _mtu - _preBufferSize - _postBufferSize; + if (_id.HasValue) + { + mss -= 8; + } + + try + { + while (!cancellationToken.IsCancellationRequested) + { + int payloadSize = await ev.WaitAsync().ConfigureAwait(false); + if (cancellationToken.IsCancellationRequested) + { + break; + } + + if (payloadSize < 0 || payloadSize > mss) + { + _ = sendOperation.TryConsume(default, out _); + continue; + } + + int overhead = _preBufferSize + _postBufferSize; + if (_id.HasValue) + { + overhead += 8; + } + { + using KcpRentedBuffer owner = _bufferPool.Rent(new KcpBufferPoolRentOptions(payloadSize + overhead, true)); + Memory memory = owner.Memory; + + // Fill the buffer + if (_preBufferSize != 0) + { + memory.Span.Slice(0, _preBufferSize).Clear(); + memory = memory.Slice(_preBufferSize); + } + if (_id.HasValue) + { + BinaryPrimitives.WriteUInt64LittleEndian(memory.Span, _id.GetValueOrDefault()); + memory = memory.Slice(8); + } + if (!sendOperation.TryConsume(memory, out int bytesWritten)) + { + continue; + } + payloadSize = Math.Min(payloadSize, bytesWritten); + memory = memory.Slice(payloadSize); + if (_postBufferSize != 0) + { + memory.Span.Slice(0, _postBufferSize).Clear(); + } + + // Send the buffer + try + { + await _transport.SendPacketAsync(owner.Memory.Slice(0, payloadSize + overhead), _remoteEndPoint, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + if (!HandleFlushException(ex)) + { + break; + } + } + } + } + } + catch (OperationCanceledException) + { + // Do nothing + } + catch (Exception ex) + { + HandleFlushException(ex); + } + } + + + private bool HandleFlushException(Exception ex) + { + Func handler = _exceptionHandler; + object state = _exceptionHandlerState; + bool result = false; + if (handler is not null) + { + try + { + result = handler.Invoke(ex, this, state); + } + catch + { + result = false; + } + } + + if (!result) + { + SetTransportClosed(); + } + return result; + } + + /// + public ValueTask InputPakcetAsync(UdpReceiveResult packet, CancellationToken cancellationToken = default) + { + ReadOnlySpan span = packet.Buffer.AsSpan(); + int overhead = _id.HasValue ? KcpGlobalVars.CONVID_LENGTH : 0; + if (span.Length < overhead || span.Length > _mtu) + { + return default; + } + if (_id.HasValue) + { + if (BinaryPrimitives.ReadUInt64BigEndian(span) != _id.GetValueOrDefault()) + { + return default; + } + span = span.Slice(8); + } + _receiveQueue.Enqueue(span); + return default; + } + + /// + /// Get the size of the next available message in the receive queue. + /// + /// The transport state and the size of the next available message. + /// The receive or peek operation is initiated concurrently. + /// True if the receive queue contains at least one message. False if the receive queue is empty or the transport is closed. + public bool TryPeek(out KcpConversationReceiveResult result) + => _receiveQueue.TryPeek(out result); + + /// + /// Remove the next available message in the receive queue and copy its content into . + /// + /// The buffer to receive message. + /// The transport state and the count of bytes moved into . + /// The size of the next available message is larger than the size of . + /// The receive or peek operation is initiated concurrently. + /// True if the next available message is moved into . False if the receive queue is empty or the transport is closed. + public bool TryReceive(Span buffer, out KcpConversationReceiveResult result) + => _receiveQueue.TryReceive(buffer, out result); + + /// + /// Wait until the receive queue contains at least one message. + /// + /// The token to cancel this operation. + /// The is fired before receive operation is completed. + /// The receive or peek operation is initiated concurrently. + /// A that completes when the receive queue contains at least one full message, or at least one byte in stream mode. Its result contains the transport state and the size of the available message. + public ValueTask WaitToReceiveAsync(CancellationToken cancellationToken) + => _receiveQueue.WaitToReceiveAsync(cancellationToken); + + /// + /// Wait for the next full message to arrive if the receive queue is empty. Remove the next available message in the receive queue and copy its content into . + /// + /// The buffer to receive message. + /// The token to cancel this operation. + /// The size of the next available message is larger than the size of . + /// The is fired before send operation is completed. + /// The receive or peek operation is initiated concurrently. + /// A that completes when a message is moved into or the transport is closed. Its result contains the transport state and the count of bytes written into . + public ValueTask ReceiveAsync(Memory buffer, CancellationToken cancellationToken = default) + => _receiveQueue.ReceiveAsync(buffer, cancellationToken); + + + /// + /// Cancel the current receive operation. + /// + /// True if the current operation is canceled. False if there is no active send operation. + public bool CancelPendingReceive() + => _receiveQueue.CancelPendingOperation(null, default); + + /// + /// Cancel the current send operation or flush operation. + /// + /// The inner exception of the thrown by the method or method. + /// The in the thrown by the method or method. + /// True if the current operation is canceled. False if there is no active send operation. + public bool CancelPendingReceive(Exception innerException, CancellationToken cancellationToken) + => _receiveQueue.CancelPendingOperation(innerException, cancellationToken); + + + /// + public void SetTransportClosed() + { + CancellationTokenSource cts = Interlocked.Exchange(ref _sendLoopCts, null); + if (cts is not null) + { + cts.Cancel(); + cts.Dispose(); + } + + _receiveQueue.SetTransportClosed(); + _sendOperation.SetTransportClosed(); + _sendNotification.Set(0); + } + + /// + public void Dispose() + { + SetTransportClosed(); + _receiveQueue.Dispose(); + _sendOperation.Dispose(); + } + } +} diff --git a/NahidaImpact.Kcp/KcpRawChannelOptions.cs b/NahidaImpact.Kcp/KcpRawChannelOptions.cs new file mode 100644 index 0000000..87a7c04 --- /dev/null +++ b/NahidaImpact.Kcp/KcpRawChannelOptions.cs @@ -0,0 +1,33 @@ +namespace NahidaImpact.Kcp +{ + /// + /// Options used to control the behaviors of . + /// + public sealed class KcpRawChannelOptions + { + /// + /// The buffer pool to rent buffer from. + /// + public IKcpBufferPool BufferPool { get; set; } + + /// + /// The maximum packet size that can be transmitted over the underlying transport. + /// + public int Mtu { get; set; } = 1400; + + /// + /// The number of packets in the receive queue. + /// + public int ReceiveQueueSize { get; set; } = 32; + + /// + /// The number of bytes to reserve at the start of buffer passed into the underlying transport. The transport should fill this reserved space. + /// + public int PreBufferSize { get; set; } + + /// + /// The number of bytes to reserve at the end of buffer passed into the underlying transport. The transport should fill this reserved space. + /// + public int PostBufferSize { get; set; } + } +} diff --git a/NahidaImpact.Kcp/KcpRawReceiveQueue.cs b/NahidaImpact.Kcp/KcpRawReceiveQueue.cs new file mode 100644 index 0000000..e6745f2 --- /dev/null +++ b/NahidaImpact.Kcp/KcpRawReceiveQueue.cs @@ -0,0 +1,356 @@ +using System.Threading.Tasks.Sources; +using System.Diagnostics; +using NahidaImpact.Kcp; + +#if NEED_LINKEDLIST_SHIM +using LinkedListOfQueueItem = KcpSharp.NetstandardShim.LinkedList; +using LinkedListNodeOfQueueItem = KcpSharp.NetstandardShim.LinkedListNode; +#else +using LinkedListOfQueueItem = System.Collections.Generic.LinkedList; +using LinkedListNodeOfQueueItem = System.Collections.Generic.LinkedListNode; +#endif + +namespace NahidaImpact.Kcp +{ + internal sealed class KcpRawReceiveQueue : IValueTaskSource, IDisposable + { + private ManualResetValueTaskSourceCore _mrvtsc; + + private readonly IKcpBufferPool _bufferPool; + private readonly int _capacity; + private readonly LinkedListOfQueueItem _queue; + private readonly LinkedListOfQueueItem _recycled; + + private bool _transportClosed; + private bool _disposed; + + private bool _activeWait; + private bool _signaled; + private bool _bufferProvided; + private Memory _buffer; + private CancellationToken _cancellationToken; + private CancellationTokenRegistration _cancellationRegistration; + + public KcpRawReceiveQueue(IKcpBufferPool bufferPool, int capacity) + { + _bufferPool = bufferPool; + _capacity = capacity; + _queue = new LinkedListOfQueueItem(); + _recycled = new LinkedListOfQueueItem(); + } + + KcpConversationReceiveResult IValueTaskSource.GetResult(short token) + { + _cancellationRegistration.Dispose(); + try + { + return _mrvtsc.GetResult(token); + } + finally + { + _mrvtsc.Reset(); + lock (_queue) + { + _activeWait = false; + _signaled = false; + _cancellationRegistration = default; + } + } + } + + ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) => _mrvtsc.GetStatus(token); + void IValueTaskSource.OnCompleted(Action continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) => _mrvtsc.OnCompleted(continuation, state, token, flags); + + public bool TryPeek(out KcpConversationReceiveResult result) + { + lock (_queue) + { + if (_disposed || _transportClosed) + { + result = default; + return false; + } + if (_activeWait) + { + ThrowHelper.ThrowConcurrentReceiveException(); + } + LinkedListNodeOfQueueItem first = _queue.First; + if (first is null) + { + result = new KcpConversationReceiveResult(0); + return false; + } + + result = new KcpConversationReceiveResult(first.ValueRef.Length); + return true; + } + } + + public ValueTask WaitToReceiveAsync(CancellationToken cancellationToken) + { + short token; + lock (_queue) + { + if (_transportClosed || _disposed) + { + return default; + } + if (_activeWait) + { + return new ValueTask(Task.FromException(ThrowHelper.NewConcurrentReceiveException())); + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + + LinkedListNodeOfQueueItem first = _queue.First; + if (first is not null) + { + return new ValueTask(new KcpConversationReceiveResult(first.ValueRef.Length)); + } + + _activeWait = true; + Debug.Assert(!_signaled); + _bufferProvided = false; + _buffer = default; + _cancellationToken = cancellationToken; + + token = _mrvtsc.Version; + } + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((KcpRawReceiveQueue)state)!.SetCanceled(), this); + + return new ValueTask(this, token); + } + + public bool TryReceive(Span buffer, out KcpConversationReceiveResult result) + { + lock (_queue) + { + if (_disposed || _transportClosed) + { + result = default; + return false; + } + if (_activeWait) + { + ThrowHelper.ThrowConcurrentReceiveException(); + } + LinkedListNodeOfQueueItem first = _queue.First; + if (first is null) + { + result = new KcpConversationReceiveResult(0); + return false; + } + + ref KcpBuffer source = ref first.ValueRef; + if (buffer.Length < source.Length) + { + ThrowHelper.ThrowBufferTooSmall(); + } + + source.DataRegion.Span.CopyTo(buffer); + result = new KcpConversationReceiveResult(source.Length); + + _queue.RemoveFirst(); + source.Release(); + source = default; + _recycled.AddLast(first); + + return true; + } + } + + public ValueTask ReceiveAsync(Memory buffer, CancellationToken cancellationToken = default) + { + short token; + lock (_queue) + { + if (_transportClosed || _disposed) + { + return default; + } + if (_activeWait) + { + return new ValueTask(Task.FromException(ThrowHelper.NewConcurrentReceiveException())); + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + + LinkedListNodeOfQueueItem first = _queue.First; + if (first is not null) + { + ref KcpBuffer source = ref first.ValueRef; + int length = source.Length; + if (buffer.Length < source.Length) + { + return new ValueTask(Task.FromException(ThrowHelper.NewBufferTooSmallForBufferArgument())); + } + _queue.Remove(first); + + source.DataRegion.CopyTo(buffer); + source.Release(); + source = default; + _recycled.AddLast(first); + + return new ValueTask(new KcpConversationReceiveResult(length)); + } + + _activeWait = true; + Debug.Assert(!_signaled); + _bufferProvided = true; + _buffer = buffer; + _cancellationToken = cancellationToken; + + token = _mrvtsc.Version; + } + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((KcpRawReceiveQueue)state)!.SetCanceled(), this); + + return new ValueTask(this, token); + } + + public bool CancelPendingOperation(Exception innerException, CancellationToken cancellationToken) + { + lock (_queue) + { + if (_activeWait && !_signaled) + { + ClearPreviousOperation(); + _mrvtsc.SetException(ThrowHelper.NewOperationCanceledExceptionForCancelPendingReceive(innerException, cancellationToken)); + return true; + } + } + return false; + } + + private void SetCanceled() + { + lock (_queue) + { + if (_activeWait && !_signaled) + { + CancellationToken cancellationToken = _cancellationToken; + ClearPreviousOperation(); + _mrvtsc.SetException(new OperationCanceledException(cancellationToken)); + } + } + } + + private void ClearPreviousOperation() + { + _signaled = true; + _bufferProvided = false; + _buffer = default; + _cancellationToken = default; + } + + public void Enqueue(ReadOnlySpan buffer) + { + lock (_queue) + { + if (_transportClosed || _disposed) + { + return; + } + + int queueSize = _queue.Count; + if (queueSize > 0 || !_activeWait) + { + if (queueSize >= _capacity) + { + return; + } + + KcpRentedBuffer owner = _bufferPool.Rent(new KcpBufferPoolRentOptions(buffer.Length, false)); + _queue.AddLast(AllocateNode(KcpBuffer.CreateFromSpan(owner, buffer))); + return; + } + + if (!_bufferProvided) + { + KcpRentedBuffer owner = _bufferPool.Rent(new KcpBufferPoolRentOptions(buffer.Length, false)); + _queue.AddLast(AllocateNode(KcpBuffer.CreateFromSpan(owner, buffer))); + + ClearPreviousOperation(); + _mrvtsc.SetResult(new KcpConversationReceiveResult(buffer.Length)); + return; + } + + if (buffer.Length > _buffer.Length) + { + KcpRentedBuffer owner = _bufferPool.Rent(new KcpBufferPoolRentOptions(buffer.Length, false)); + _queue.AddLast(AllocateNode(KcpBuffer.CreateFromSpan(owner, buffer))); + + ClearPreviousOperation(); + _mrvtsc.SetException(ThrowHelper.NewBufferTooSmallForBufferArgument()); + return; + } + + buffer.CopyTo(_buffer.Span); + ClearPreviousOperation(); + _mrvtsc.SetResult(new KcpConversationReceiveResult(buffer.Length)); + } + } + + private LinkedListNodeOfQueueItem AllocateNode(KcpBuffer buffer) + { + LinkedListNodeOfQueueItem node = _recycled.First; + if (node is null) + { + node = new LinkedListNodeOfQueueItem(buffer); + } + else + { + node.ValueRef = buffer; + _recycled.Remove(node); + } + return node; + } + + public void SetTransportClosed() + { + lock (_queue) + { + if (_transportClosed || _disposed) + { + return; + } + if (_activeWait && !_signaled) + { + ClearPreviousOperation(); + _mrvtsc.SetResult(default); + } + _recycled.Clear(); + _transportClosed = true; + } + } + + public void Dispose() + { + lock (_queue) + { + if (_disposed) + { + return; + } + if (_activeWait && !_signaled) + { + ClearPreviousOperation(); + _mrvtsc.SetResult(default); + } + LinkedListNodeOfQueueItem node = _queue.First; + while (node is not null) + { + node.ValueRef.Release(); + node = node.Next; + } + _queue.Clear(); + _recycled.Clear(); + _disposed = true; + _transportClosed = true; + } + } + } +} diff --git a/NahidaImpact.Kcp/KcpRawSendOperation.cs b/NahidaImpact.Kcp/KcpRawSendOperation.cs new file mode 100644 index 0000000..42a1009 --- /dev/null +++ b/NahidaImpact.Kcp/KcpRawSendOperation.cs @@ -0,0 +1,182 @@ +using System.Diagnostics; +using System.Threading.Tasks.Sources; + +namespace NahidaImpact.Kcp +{ + internal sealed class KcpRawSendOperation : IValueTaskSource, IDisposable + { + private readonly AsyncAutoResetEvent _notification; + private ManualResetValueTaskSourceCore _mrvtsc; + + private bool _transportClosed; + private bool _disposed; + + private bool _activeWait; + private bool _signaled; + private ReadOnlyMemory _buffer; + private CancellationToken _cancellationToken; + private CancellationTokenRegistration _cancellationRegistration; + + public KcpRawSendOperation(AsyncAutoResetEvent notification) + { + _notification = notification; + + _mrvtsc = new ManualResetValueTaskSourceCore() + { + RunContinuationsAsynchronously = true + }; + } + + bool IValueTaskSource.GetResult(short token) + { + _cancellationRegistration.Dispose(); + try + { + return _mrvtsc.GetResult(token); + } + finally + { + _mrvtsc.Reset(); + lock (this) + { + _activeWait = false; + _signaled = false; + _cancellationRegistration = default; + } + } + } + + ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) => _mrvtsc.GetStatus(token); + void IValueTaskSource.OnCompleted(Action continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) => _mrvtsc.OnCompleted(continuation, state, token, flags); + + public ValueTask SendAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) + { + short token; + lock (this) + { + if (_transportClosed || _disposed) + { + return new ValueTask(false); + } + if (_activeWait) + { + return new ValueTask(Task.FromException(ThrowHelper.NewConcurrentSendException())); + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + + _activeWait = true; + Debug.Assert(!_signaled); + _buffer = buffer; + _cancellationToken = cancellationToken; + token = _mrvtsc.Version; + } + + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((KcpRawSendOperation)state)!.SetCanceled(), this); + + _notification.Set(buffer.Length); + return new ValueTask(this, token); + } + + public bool CancelPendingOperation(Exception innerException, CancellationToken cancellationToken) + { + lock (this) + { + if (_activeWait && !_signaled) + { + ClearPreviousOperation(); + _mrvtsc.SetException(ThrowHelper.NewOperationCanceledExceptionForCancelPendingSend(innerException, cancellationToken)); + return true; + } + } + return false; + } + + private void SetCanceled() + { + lock (this) + { + if (_activeWait && !_signaled) + { + CancellationToken cancellationToken = _cancellationToken; + ClearPreviousOperation(); + _mrvtsc.SetException(new OperationCanceledException(cancellationToken)); + } + } + } + + private void ClearPreviousOperation() + { + _signaled = true; + _buffer = default; + _cancellationToken = default; + } + + public bool TryConsume(Memory buffer, out int bytesWritten) + { + lock (this) + { + if (_transportClosed || _disposed) + { + bytesWritten = 0; + return false; + } + if (!_activeWait) + { + bytesWritten = 0; + return false; + } + ReadOnlyMemory source = _buffer; + if (source.Length > buffer.Length) + { + ClearPreviousOperation(); + _mrvtsc.SetException(ThrowHelper.NewMessageTooLargeForBufferArgument()); + bytesWritten = 0; + return false; + } + source.CopyTo(buffer); + bytesWritten = source.Length; + ClearPreviousOperation(); + _mrvtsc.SetResult(true); + return true; + } + } + + public void SetTransportClosed() + { + lock (this) + { + if (_transportClosed || _disposed) + { + return; + } + if (_activeWait && !_signaled) + { + ClearPreviousOperation(); + _mrvtsc.SetResult(false); + } + _transportClosed = true; + } + } + + public void Dispose() + { + lock (this) + { + if (_disposed) + { + return; + } + if (_activeWait && !_signaled) + { + ClearPreviousOperation(); + _mrvtsc.SetResult(false); + } + _disposed = true; + _transportClosed = true; + } + } + } +} diff --git a/NahidaImpact.Kcp/KcpReceiveQueue.cs b/NahidaImpact.Kcp/KcpReceiveQueue.cs new file mode 100644 index 0000000..0dfaf20 --- /dev/null +++ b/NahidaImpact.Kcp/KcpReceiveQueue.cs @@ -0,0 +1,693 @@ +using System.Threading.Tasks.Sources; +using System.Diagnostics; + +#if NEED_LINKEDLIST_SHIM +using LinkedListOfQueueItem = KcpSharp.NetstandardShim.LinkedList<(KcpSharp.KcpBuffer Data, byte Fragment)>; +using LinkedListNodeOfQueueItem = KcpSharp.NetstandardShim.LinkedListNode<(KcpSharp.KcpBuffer Data, byte Fragment)>; +#else +using LinkedListOfQueueItem = System.Collections.Generic.LinkedList<(NahidaImpact.Kcp.KcpBuffer Data, byte Fragment)>; +using LinkedListNodeOfQueueItem = System.Collections.Generic.LinkedListNode<(NahidaImpact.Kcp.KcpBuffer Data, byte Fragment)>; +#endif + +namespace NahidaImpact.Kcp +{ + internal sealed class KcpReceiveQueue : IValueTaskSource, IValueTaskSource, IValueTaskSource, IDisposable + { + private ManualResetValueTaskSourceCore _mrvtsc; + + private readonly LinkedListOfQueueItem _queue; + private readonly bool _stream; + private readonly int _queueSize; + private readonly KcpSendReceiveQueueItemCache _cache; + private int _completedPacketsCount; + + private bool _transportClosed; + private bool _disposed; + + private bool _activeWait; + private bool _signaled; + private byte _operationMode; // 0-receive 1-wait for message 2-wait for available data + private Memory _buffer; + private int _minimumBytes; + private int _minimumSegments; + private CancellationToken _cancellationToken; + private CancellationTokenRegistration _cancellationRegistration; + + public KcpReceiveQueue(bool stream, int queueSize, KcpSendReceiveQueueItemCache cache) + { + _mrvtsc = new ManualResetValueTaskSourceCore() + { + RunContinuationsAsynchronously = true + }; + _queue = new LinkedListOfQueueItem(); + _stream = stream; + _queueSize = queueSize; + _cache = cache; + } + + public ValueTaskSourceStatus GetStatus(short token) => _mrvtsc.GetStatus(token); + public void OnCompleted(Action continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) + => _mrvtsc.OnCompleted(continuation, state, token, flags); + + KcpConversationReceiveResult IValueTaskSource.GetResult(short token) + { + _cancellationRegistration.Dispose(); + try + { + return _mrvtsc.GetResult(token); + } + finally + { + _mrvtsc.Reset(); + lock (_queue) + { + _activeWait = false; + _signaled = false; + _cancellationRegistration = default; + } + } + } + + int IValueTaskSource.GetResult(short token) + { + _cancellationRegistration.Dispose(); + try + { + return _mrvtsc.GetResult(token).BytesReceived; + } + finally + { + _mrvtsc.Reset(); + lock (_queue) + { + _activeWait = false; + _signaled = false; + _cancellationRegistration = default; + } + } + } + + bool IValueTaskSource.GetResult(short token) + { + _cancellationRegistration.Dispose(); + try + { + return !_mrvtsc.GetResult(token).TransportClosed; + } + finally + { + _mrvtsc.Reset(); + lock (_queue) + { + _activeWait = false; + _signaled = false; + _cancellationRegistration = default; + } + } + } + + public bool TryPeek(out KcpConversationReceiveResult result) + { + lock (_queue) + { + if (_disposed || _transportClosed) + { + result = default; + return false; + } + if (_activeWait) + { + ThrowHelper.ThrowConcurrentReceiveException(); + } + + if (_completedPacketsCount == 0) + { + result = new KcpConversationReceiveResult(0); + return false; + } + + LinkedListNodeOfQueueItem node = _queue.First; + if (node is null) + { + result = new KcpConversationReceiveResult(0); + return false; + } + + if (CalculatePacketSize(node, out int packetSize)) + { + result = new KcpConversationReceiveResult(packetSize); + return true; + } + + result = default; + return false; + } + } + + public ValueTask WaitToReceiveAsync(CancellationToken cancellationToken) + { + short token; + lock (_queue) + { + if (_transportClosed || _disposed) + { + return default; + } + if (_activeWait) + { + return new ValueTask(Task.FromException(ThrowHelper.NewConcurrentReceiveException())); + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + + _operationMode = 1; + _buffer = default; + _minimumBytes = 0; + _minimumSegments = 0; + + token = _mrvtsc.Version; + if (_completedPacketsCount > 0) + { + ConsumePacket(_buffer.Span, out KcpConversationReceiveResult result, out bool bufferTooSmall); + ClearPreviousOperation(false); + if (bufferTooSmall) + { + Debug.Assert(false, "This should never be reached."); + return new ValueTask(Task.FromException(ThrowHelper.NewBufferTooSmallForBufferArgument())); + } + else + { + return new ValueTask(result); + } + } + + _activeWait = true; + Debug.Assert(!_signaled); + _cancellationToken = cancellationToken; + } + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((KcpReceiveQueue)state)!.SetCanceled(), this); + + return new ValueTask(this, token); + } + + public ValueTask WaitForAvailableDataAsync(int minimumBytes, int minimumSegments, CancellationToken cancellationToken) + { + if (minimumBytes < 0) + { + return new ValueTask(Task.FromException(ThrowHelper.NewArgumentOutOfRangeException(nameof(minimumBytes)))); + } + if (minimumSegments < 0) + { + return new ValueTask(Task.FromException(ThrowHelper.NewArgumentOutOfRangeException(nameof(minimumSegments)))); + } + + short token; + lock (_queue) + { + if (_transportClosed || _disposed) + { + return default; + } + if (_activeWait) + { + return new ValueTask(Task.FromException(ThrowHelper.NewConcurrentReceiveException())); + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + + if (CheckQueeuSize(_queue, minimumBytes, minimumSegments, _stream)) + { + return new ValueTask(true); + } + + _activeWait = true; + Debug.Assert(!_signaled); + _operationMode = 2; + _buffer = default; + _minimumBytes = minimumBytes; + _minimumSegments = minimumSegments; + _cancellationToken = cancellationToken; + + token = _mrvtsc.Version; + } + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((KcpReceiveQueue)state)!.SetCanceled(), this); + + return new ValueTask(this, token); + } + + public bool TryReceive(Span buffer, out KcpConversationReceiveResult result) + { + lock (_queue) + { + if (_disposed || _transportClosed) + { + result = default; + return false; + } + if (_activeWait) + { + ThrowHelper.ThrowConcurrentReceiveException(); + } + + if (_completedPacketsCount == 0) + { + result = new KcpConversationReceiveResult(0); + return false; + } + + Debug.Assert(!_signaled); + _operationMode = 0; + + ConsumePacket(buffer, out result, out bool bufferTooSmall); + ClearPreviousOperation(false); + if (bufferTooSmall) + { + ThrowHelper.ThrowBufferTooSmall(); + } + return true; + } + } + + public ValueTask ReceiveAsync(Memory buffer, CancellationToken cancellationToken) + { + short token; + lock (_queue) + { + if (_transportClosed || _disposed) + { + return default; + } + if (_activeWait) + { + return new ValueTask(Task.FromException(ThrowHelper.NewConcurrentReceiveException())); + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + + _operationMode = 0; + _buffer = buffer; + + token = _mrvtsc.Version; + if (_completedPacketsCount > 0) + { + ConsumePacket(_buffer.Span, out KcpConversationReceiveResult result, out bool bufferTooSmall); + ClearPreviousOperation(false); + if (bufferTooSmall) + { + return new ValueTask(Task.FromException(ThrowHelper.NewBufferTooSmallForBufferArgument())); + } + else + { + return new ValueTask(result); + } + } + + _activeWait = true; + Debug.Assert(!_signaled); + _cancellationToken = cancellationToken; + } + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((KcpReceiveQueue)state)!.SetCanceled(), this); + + return new ValueTask(this, token); + } + + public ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken) + { + short token; + lock (_queue) + { + if (_transportClosed || _disposed) + { + return new ValueTask(Task.FromException(ThrowHelper.NewTransportClosedForStreamException())); + } + if (_activeWait) + { + return new ValueTask(Task.FromException(ThrowHelper.NewConcurrentReceiveException())); + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + + _operationMode = 0; + _buffer = buffer; + + token = _mrvtsc.Version; + if (_completedPacketsCount > 0) + { + ConsumePacket(_buffer.Span, out KcpConversationReceiveResult result, out bool bufferTooSmall); + ClearPreviousOperation(false); + if (bufferTooSmall) + { + return new ValueTask(Task.FromException(ThrowHelper.NewBufferTooSmallForBufferArgument())); + } + else + { + return new ValueTask(result.BytesReceived); + } + } + + _activeWait = true; + Debug.Assert(!_signaled); + _cancellationToken = cancellationToken; + } + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((KcpReceiveQueue)state)!.SetCanceled(), this); + + return new ValueTask(this, token); + } + + public bool CancelPendingOperation(Exception innerException, CancellationToken cancellationToken) + { + lock (_queue) + { + if (_activeWait && !_signaled) + { + ClearPreviousOperation(true); + _mrvtsc.SetException(ThrowHelper.NewOperationCanceledExceptionForCancelPendingReceive(innerException, cancellationToken)); + return true; + } + } + return false; + } + + private void SetCanceled() + { + lock (_queue) + { + if (_activeWait && !_signaled) + { + CancellationToken cancellationToken = _cancellationToken; + ClearPreviousOperation(true); + _mrvtsc.SetException(new OperationCanceledException(cancellationToken)); + } + } + } + + private void ClearPreviousOperation(bool signaled) + { + _signaled = signaled; + _operationMode = 0; + _buffer = default; + _minimumBytes = default; + _minimumSegments = default; + _cancellationToken = default; + } + + public void Enqueue(KcpBuffer buffer, byte fragment) + { + lock (_queue) + { + if (_transportClosed || _disposed) + { + return; + } + + if (_stream) + { + if (buffer.Length == 0) + { + return; + } + fragment = 0; + _queue.AddLast(_cache.Rent(buffer, 0)); + } + else + { + LinkedListNodeOfQueueItem lastNode = _queue.Last; + if (lastNode is null || lastNode.ValueRef.Fragment == 0 || lastNode.ValueRef.Fragment - 1 == fragment) + { + _queue.AddLast(_cache.Rent(buffer, fragment)); + } + else + { + fragment = 0; + _queue.AddLast(_cache.Rent(buffer, 0)); + } + } + + if (fragment == 0) + { + _completedPacketsCount++; + if (_activeWait && !_signaled) + { + TryCompleteReceive(); + TryCompleteWaitForData(); + } + } + } + } + + private void TryCompleteReceive() + { + Debug.Assert(_activeWait && !_signaled); + + if (_operationMode <= 1) + { + Debug.Assert(_operationMode == 0 || _operationMode == 1); + ConsumePacket(_buffer.Span, out KcpConversationReceiveResult result, out bool bufferTooSmall); + ClearPreviousOperation(true); + if (bufferTooSmall) + { + _mrvtsc.SetException(ThrowHelper.NewBufferTooSmallForBufferArgument()); + } + else + { + _mrvtsc.SetResult(result); + } + } + } + + private void TryCompleteWaitForData() + { + if (_operationMode == 2) + { + if (CheckQueeuSize(_queue, _minimumBytes, _minimumSegments, _stream)) + { + ClearPreviousOperation(true); + _mrvtsc.SetResult(new KcpConversationReceiveResult(0)); + } + } + } + + private void ConsumePacket(Span buffer, out KcpConversationReceiveResult result, out bool bufferTooSmall) + { + LinkedListNodeOfQueueItem node = _queue.First; + if (node is null) + { + result = default; + bufferTooSmall = false; + return; + } + + // peek + if (_operationMode == 1) + { + if (CalculatePacketSize(node, out int bytesRecevied)) + { + result = new KcpConversationReceiveResult(bytesRecevied); + } + else + { + result = default; + } + bufferTooSmall = false; + return; + } + + Debug.Assert(_operationMode == 0); + + // ensure buffer is big enough + int bytesInPacket = 0; + if (!_stream) + { + while (node is not null) + { + bytesInPacket += node.ValueRef.Data.Length; + if (node.ValueRef.Fragment == 0) + { + break; + } + node = node.Next; + } + + if (node is null) + { + // incomplete packet + result = default; + bufferTooSmall = false; + return; + } + + if (bytesInPacket > buffer.Length) + { + result = default; + bufferTooSmall = true; + return; + } + } + + bool anyDataReceived = false; + bytesInPacket = 0; + node = _queue.First; + LinkedListNodeOfQueueItem next; + while (node is not null) + { + next = node.Next; + + byte fragment = node.ValueRef.Fragment; + ref KcpBuffer data = ref node.ValueRef.Data; + + int sizeToCopy = Math.Min(data.Length, buffer.Length); + data.DataRegion.Span.Slice(0, sizeToCopy).CopyTo(buffer); + buffer = buffer.Slice(sizeToCopy); + bytesInPacket += sizeToCopy; + anyDataReceived = true; + + if (sizeToCopy != data.Length) + { + // partial data is received. + node.ValueRef = (data.Consume(sizeToCopy), node.ValueRef.Fragment); + } + else + { + // full fragment is consumed + data.Release(); + _queue.Remove(node); + _cache.Return(node); + if (fragment == 0) + { + _completedPacketsCount--; + } + } + + if (!_stream && fragment == 0) + { + break; + } + + if (sizeToCopy == 0) + { + break; + } + + node = next; + } + + if (!anyDataReceived) + { + result = default; + bufferTooSmall = false; + } + else + { + result = new KcpConversationReceiveResult(bytesInPacket); + bufferTooSmall = false; + } + } + + private static bool CalculatePacketSize(LinkedListNodeOfQueueItem first, out int packetSize) + { + int bytesRecevied = first.ValueRef.Data.Length; + if (first.ValueRef.Fragment == 0) + { + packetSize = bytesRecevied; + return true; + } + + LinkedListNodeOfQueueItem node = first.Next; + while (node is not null) + { + bytesRecevied += node.ValueRef.Data.Length; + if (node.ValueRef.Fragment == 0) + { + packetSize = bytesRecevied; + return true; + } + node = node.Next; + } + + // deadlink + packetSize = 0; + return false; + } + + private static bool CheckQueeuSize(LinkedListOfQueueItem queue, int minimumBytes, int minimumSegments, bool stream) + { + LinkedListNodeOfQueueItem node = queue.First; + while (node is not null) + { + ref KcpBuffer buffer = ref node.ValueRef.Data; + minimumBytes = Math.Max(minimumBytes - buffer.Length, 0); + if (stream || node.ValueRef.Fragment == 0) + { + minimumSegments = Math.Max(minimumSegments - 1, 0); + } + if (minimumBytes == 0 && minimumSegments == 0) + { + return true; + } + node = node.Next; + } + + return minimumBytes == 0 && minimumSegments == 0; + } + + public void SetTransportClosed() + { + lock (_queue) + { + if (_transportClosed || _disposed) + { + return; + } + if (_activeWait && !_signaled) + { + ClearPreviousOperation(true); + _mrvtsc.SetResult(default); + } + _transportClosed = true; + } + } + + public int GetQueueSize() + { + int count; + lock (_queue) + { + count = _queue.Count; + } + return Math.Max(_queue.Count - _queueSize, 0); + } + + public void Dispose() + { + lock (_queue) + { + if (_disposed) + { + return; + } + if (_activeWait && !_signaled) + { + ClearPreviousOperation(true); + _mrvtsc.SetResult(default); + } + LinkedListNodeOfQueueItem node = _queue.First; + while (node is not null) + { + node.ValueRef.Data.Release(); + node = node.Next; + } + _queue.Clear(); + _disposed = true; + _transportClosed = true; + } + } + } +} diff --git a/NahidaImpact.Kcp/KcpReceiveWindowNotificationOptions.cs b/NahidaImpact.Kcp/KcpReceiveWindowNotificationOptions.cs new file mode 100644 index 0000000..e611f85 --- /dev/null +++ b/NahidaImpact.Kcp/KcpReceiveWindowNotificationOptions.cs @@ -0,0 +1,37 @@ +namespace NahidaImpact.Kcp +{ + /// + /// Options for sending receive window size notification. + /// + public sealed class KcpReceiveWindowNotificationOptions + { + /// + /// Create an instance of option object for receive window size notification functionality. + /// + /// The initial interval in milliseconds of sending window size notification. + /// The maximum interval in milliseconds of sending window size notification. + public KcpReceiveWindowNotificationOptions(int initialInterval, int maximumInterval) + { + if (initialInterval <= 0) + { + throw new ArgumentOutOfRangeException(nameof(initialInterval)); + } + if (maximumInterval < initialInterval) + { + throw new ArgumentOutOfRangeException(nameof(maximumInterval)); + } + InitialInterval = initialInterval; + MaximumInterval = maximumInterval; + } + + /// + /// The initial interval in milliseconds of sending window size notification. + /// + public int InitialInterval { get; } + + /// + /// The maximum interval in milliseconds of sending window size notification. + /// + public int MaximumInterval { get; } + } +} diff --git a/NahidaImpact.Kcp/KcpRentedBuffer.cs b/NahidaImpact.Kcp/KcpRentedBuffer.cs new file mode 100644 index 0000000..123b2f8 --- /dev/null +++ b/NahidaImpact.Kcp/KcpRentedBuffer.cs @@ -0,0 +1,222 @@ +using System.Buffers; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace NahidaImpact.Kcp +{ + /// + /// The buffer rented and owned by KcpSharp. + /// + public readonly struct KcpRentedBuffer : IEquatable, IDisposable + { + private readonly object _owner; + private readonly Memory _memory; + + internal object Owner => _owner; + + /// + /// The rented buffer. + /// + public Memory Memory => _memory; + + /// + /// The rented buffer. + /// + public Span Span => _memory.Span; + + /// + /// Whether this struct contains buffer rented from the pool. + /// + public bool IsAllocated => _owner is not null; + + /// + /// Whether this buffer contains no data. + /// + public bool IsEmpry => _memory.IsEmpty; + + internal KcpRentedBuffer(object owner, Memory buffer) + { + _owner = owner; + _memory = buffer; + } + + /// + /// Create the buffer from the specified . + /// + /// The memory region of this buffer. + /// The rented buffer. + public static KcpRentedBuffer FromMemory(Memory memory) + { + return new KcpRentedBuffer(null, memory); + } + + /// + /// Create the buffer from the shared array pool. + /// + /// The minimum size of the buffer required. + /// The rented buffer. + public static KcpRentedBuffer FromSharedArrayPool(int size) + { + if (size < 0) + { + throw new ArgumentOutOfRangeException(nameof(size)); + } + byte[] buffer = ArrayPool.Shared.Rent(size); + return new KcpRentedBuffer(ArrayPool.Shared, buffer); + } + + /// + /// Create the buffer from the specified array pool. + /// + /// The array pool to use. + /// The byte array rented from the specified pool. + /// The rented buffer. + public static KcpRentedBuffer FromArrayPool(ArrayPool pool, byte[] buffer) + { + if (pool is null) + { + throw new ArgumentNullException(nameof(pool)); + } + if (buffer is null) + { + throw new ArgumentNullException(nameof(buffer)); + } + return new KcpRentedBuffer(pool, buffer); + } + + /// + /// Create the buffer from the specified array pool. + /// + /// The array pool to use. + /// The byte array segment rented from the specified pool. + /// The rented buffer. + public static KcpRentedBuffer FromArrayPool(ArrayPool pool, ArraySegment arraySegment) + { + if (pool is null) + { + throw new ArgumentNullException(nameof(pool)); + } + return new KcpRentedBuffer(pool, arraySegment); + } + + /// + /// Create the buffer from the specified array pool. + /// + /// The array pool to use. + /// The minimum size of the buffer required. + /// The rented buffer. + public static KcpRentedBuffer FromArrayPool(ArrayPool pool, int size) + { + if (pool is null) + { + throw new ArgumentNullException(nameof(pool)); + } + if (size < 0) + { + throw new ArgumentOutOfRangeException(nameof(size)); + } + return new KcpRentedBuffer(pool, pool.Rent(size)); + } + + /// + /// Create the buffer from the memory owner. + /// + /// The owner of this memory region. + /// The rented buffer. + public static KcpRentedBuffer FromMemoryOwner(IMemoryOwner memoryOwner) + { + if (memoryOwner is null) + { + throw new ArgumentNullException(nameof(memoryOwner)); + } + return new KcpRentedBuffer(memoryOwner, memoryOwner.Memory); + } + + + /// + /// Create the buffer from the memory owner. + /// + /// The owner of this memory region. + /// The memory region of the buffer. + /// The rented buffer. + public static KcpRentedBuffer FromMemoryOwner(IDisposable memoryOwner, Memory memory) + { + if (memoryOwner is null) + { + throw new ArgumentNullException(nameof(memoryOwner)); + } + return new KcpRentedBuffer(memoryOwner, memory); + } + + /// + /// Forms a slice out of the current buffer that begins at a specified index. + /// + /// The index at which to begin the slice. + /// An object that contains all elements of the current instance from start to the end of the instance. + public KcpRentedBuffer Slice(int start) + { + Memory memory = _memory; + if ((uint)start > (uint)memory.Length) + { + ThrowHelper.ThrowArgumentOutOfRangeException(nameof(start)); + } + return new KcpRentedBuffer(_owner, memory.Slice(start)); + } + + /// + /// Forms a slice out of the current memory starting at a specified index for a specified length. + /// + /// The index at which to begin the slice. + /// The number of elements to include in the slice. + /// An object that contains elements from the current instance starting at . + public KcpRentedBuffer Slice(int start, int length) + { + Memory memory = _memory; + if ((uint)start > (uint)memory.Length) + { + ThrowHelper.ThrowArgumentOutOfRangeException(nameof(start)); + } + if ((uint)length > (uint)(memory.Length - start)) + { + ThrowHelper.ThrowArgumentOutOfRangeException(nameof(length)); + } + return new KcpRentedBuffer(_owner, memory.Slice(start, length)); + } + + /// + public void Dispose() + { + Debug.Assert(_owner is null || _owner is ArrayPool || _owner is IDisposable); + + if (_owner is null) + { + return; + } + if (_owner is ArrayPool arrayPool) + { + if (MemoryMarshal.TryGetArray(_memory, out ArraySegment arraySegment)) + { + arrayPool.Return(arraySegment.Array!); + return; + } + } + if (_owner is IDisposable disposable) + { + disposable.Dispose(); + } + } + + /// + public bool Equals(KcpRentedBuffer other) => ReferenceEquals(_owner, other._owner) && _memory.Equals(other._memory); + + /// + public override bool Equals(object obj) => obj is KcpRentedBuffer other && Equals(other); + + /// + public override int GetHashCode() => _owner is null ? _memory.GetHashCode() : HashCode.Combine(RuntimeHelpers.GetHashCode(_owner), _memory); + + /// + public override string ToString() => $"KcpSharp.KcpRentedBuffer[{_memory.Length}]"; + } +} diff --git a/NahidaImpact.Kcp/KcpSendQueue.cs b/NahidaImpact.Kcp/KcpSendQueue.cs new file mode 100644 index 0000000..c7ebeac --- /dev/null +++ b/NahidaImpact.Kcp/KcpSendQueue.cs @@ -0,0 +1,715 @@ +using System.Diagnostics; +using System.Threading.Tasks.Sources; + +#if NEED_LINKEDLIST_SHIM +using LinkedListOfQueueItem = KcpSharp.NetstandardShim.LinkedList<(KcpSharp.KcpBuffer Data, byte Fragment)>; +using LinkedListNodeOfQueueItem = KcpSharp.NetstandardShim.LinkedListNode<(KcpSharp.KcpBuffer Data, byte Fragment)>; +#else +using LinkedListOfQueueItem = System.Collections.Generic.LinkedList<(NahidaImpact.Kcp.KcpBuffer Data, byte Fragment)>; +using LinkedListNodeOfQueueItem = System.Collections.Generic.LinkedListNode<(NahidaImpact.Kcp.KcpBuffer Data, byte Fragment)>; +#endif + +namespace NahidaImpact.Kcp +{ + internal sealed class KcpSendQueue : IValueTaskSource, IValueTaskSource, IDisposable + { + private readonly IKcpBufferPool _bufferPool; + private readonly KcpConversationUpdateActivation _updateActivation; + private readonly bool _stream; + private readonly int _capacity; + private readonly int _mss; + private readonly KcpSendReceiveQueueItemCache _cache; + private ManualResetValueTaskSourceCore _mrvtsc; + + private readonly LinkedListOfQueueItem _queue; + private long _unflushedBytes; + + private bool _transportClosed; + private bool _disposed; + + private bool _activeWait; + private bool _signled; + private bool _forStream; + private byte _operationMode; // 0-send 1-flush 2-wait for space + private ReadOnlyMemory _buffer; + private int _waitForByteCount; + private int _waitForSegmentCount; + private CancellationToken _cancellationToken; + private CancellationTokenRegistration _cancellationRegistration; + + private bool _ackListNotEmpty; + public KcpSendQueue(IKcpBufferPool bufferPool, KcpConversationUpdateActivation updateActivation, bool stream, int capacity, int mss, KcpSendReceiveQueueItemCache cache) + { + _bufferPool = bufferPool; + _updateActivation = updateActivation; + _stream = stream; + _capacity = capacity; + _mss = mss; + _cache = cache; + _mrvtsc = new ManualResetValueTaskSourceCore() + { + RunContinuationsAsynchronously = true + }; + + _queue = new LinkedListOfQueueItem(); + } + + public ValueTaskSourceStatus GetStatus(short token) => _mrvtsc.GetStatus(token); + public void OnCompleted(Action continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) + => _mrvtsc.OnCompleted(continuation, state, token, flags); + + bool IValueTaskSource.GetResult(short token) + { + _cancellationRegistration.Dispose(); + try + { + return _mrvtsc.GetResult(token); + } + finally + { + _mrvtsc.Reset(); + lock (_queue) + { + _activeWait = false; + _signled = false; + _cancellationRegistration = default; + } + } + } + + void IValueTaskSource.GetResult(short token) + { + try + { + _mrvtsc.GetResult(token); + } + finally + { + _mrvtsc.Reset(); + lock (_queue) + { + _activeWait = false; + _signled = false; + _cancellationRegistration = default; + } + } + } + + public bool TryGetAvailableSpace(out int byteCount, out int segmentCount) + { + lock (_queue) + { + if (_transportClosed || _disposed) + { + byteCount = 0; + segmentCount = 0; + return false; + } + if (_activeWait && _operationMode == 0) + { + byteCount = 0; + segmentCount = 0; + return true; + } + GetAvailableSpaceCore(out byteCount, out segmentCount); + return true; + } + } + + private void GetAvailableSpaceCore(out int byteCount, out int segmentCount) + { + int mss = _mss; + int availableFragments = _capacity - _queue.Count; + if (availableFragments < 0) + { + byteCount = 0; + segmentCount = 0; + return; + } + int availableBytes = availableFragments * mss; + if (_stream) + { + LinkedListNodeOfQueueItem last = _queue.Last; + if (last is not null) + { + availableBytes += _mss - last.ValueRef.Data.Length; + } + } + byteCount = availableBytes; + segmentCount = availableFragments; + } + + public ValueTask WaitForAvailableSpaceAsync(int minimumBytes, int minimumSegments, CancellationToken cancellationToken) + { + short token; + lock (_queue) + { + if (_transportClosed || _disposed) + { + minimumBytes = 0; + minimumSegments = 0; + return default; + } + if ((uint)minimumBytes > (uint)(_mss * _capacity)) + { + return new ValueTask(Task.FromException(ThrowHelper.NewArgumentOutOfRangeException(nameof(minimumBytes)))); + } + if ((uint)minimumSegments > (uint)_capacity) + { + return new ValueTask(Task.FromException(ThrowHelper.NewArgumentOutOfRangeException(nameof(minimumSegments)))); + } + if (_activeWait) + { + return new ValueTask(Task.FromException(ThrowHelper.NewConcurrentSendException())); + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + GetAvailableSpaceCore(out int currentByteCount, out int currentSegmentCount); + if (currentByteCount >= minimumBytes && currentSegmentCount >= minimumSegments) + { + return new ValueTask(true); + } + + _activeWait = true; + Debug.Assert(!_signled); + _forStream = false; + _operationMode = 2; + _waitForByteCount = minimumBytes; + _waitForSegmentCount = minimumSegments; + _cancellationToken = cancellationToken; + token = _mrvtsc.Version; + } + + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((KcpSendQueue)state)!.SetCanceled(), this); + + return new ValueTask(this, token); + } + + public bool TrySend(ReadOnlySpan buffer, bool allowPartialSend, out int bytesWritten) + { + lock (_queue) + { + if (allowPartialSend && !_stream) + { + ThrowHelper.ThrowAllowPartialSendArgumentException(); + } + if (_transportClosed || _disposed) + { + bytesWritten = 0; + return false; + } + + int mss = _mss; + // Make sure there is enough space. + if (!allowPartialSend) + { + int spaceAvailable = mss * (_capacity - _queue.Count); + if (spaceAvailable < 0) + { + bytesWritten = 0; + return false; + } + if (_stream) + { + LinkedListNodeOfQueueItem last = _queue.Last; + if (last is not null) + { + spaceAvailable += mss - last.ValueRef.Data.Length; + } + } + + if (buffer.Length > spaceAvailable) + { + bytesWritten = 0; + return false; + } + } + + // Copy buffer content. + bytesWritten = 0; + if (_stream) + { + LinkedListNodeOfQueueItem node = _queue.Last; + if (node is not null) + { + ref KcpBuffer data = ref node.ValueRef.Data; + int expand = mss - data.Length; + expand = Math.Min(expand, buffer.Length); + if (expand > 0) + { + data = data.AppendData(buffer.Slice(0, expand)); + buffer = buffer.Slice(expand); + Interlocked.Add(ref _unflushedBytes, expand); + bytesWritten = expand; + } + } + + if (buffer.IsEmpty) + { + return true; + } + } + + bool anySegmentAdded = false; + int count = buffer.Length <= mss ? 1 : (buffer.Length + mss - 1) / mss; + Debug.Assert(count >= 1); + while (count > 0 && _queue.Count < _capacity) + { + int fragment = --count; + + int size = buffer.Length > mss ? mss : buffer.Length; + + KcpRentedBuffer owner = _bufferPool.Rent(new KcpBufferPoolRentOptions(mss, false)); + KcpBuffer kcpBuffer = KcpBuffer.CreateFromSpan(owner, buffer.Slice(0, size)); + buffer = buffer.Slice(size); + + _queue.AddLast(_cache.Rent(kcpBuffer, _stream ? (byte)0 : (byte)fragment)); + Interlocked.Add(ref _unflushedBytes, size); + bytesWritten += size; + anySegmentAdded = true; + } + + if (anySegmentAdded) + { + _updateActivation.Notify(); + } + return anySegmentAdded; + } + } + + public ValueTask SendAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken) + { + short token; + lock (_queue) + { + if (_transportClosed || _disposed) + { + return new ValueTask(false); + } + if (_activeWait) + { + return new ValueTask(Task.FromException(ThrowHelper.NewConcurrentSendException())); + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + + int mss = _mss; + if (_stream) + { + LinkedListNodeOfQueueItem node = _queue.Last; + if (node is not null) + { + ref KcpBuffer data = ref node.ValueRef.Data; + int expand = mss - data.Length; + expand = Math.Min(expand, buffer.Length); + if (expand > 0) + { + data = data.AppendData(buffer.Span.Slice(0, expand)); + buffer = buffer.Slice(expand); + Interlocked.Add(ref _unflushedBytes, expand); + } + } + + if (buffer.IsEmpty) + { + return new ValueTask(true); + } + } + + int count = buffer.Length <= mss ? 1 : (buffer.Length + mss - 1) / mss; + Debug.Assert(count >= 1); + + if (!_stream && count > 256) + { + return new ValueTask(Task.FromException(ThrowHelper.NewMessageTooLargeForBufferArgument())); + } + + // synchronously put fragments into queue. + while (count > 0 && _queue.Count < _capacity) + { + int fragment = --count; + + int size = buffer.Length > mss ? mss : buffer.Length; + KcpRentedBuffer owner = _bufferPool.Rent(new KcpBufferPoolRentOptions(mss, false)); + KcpBuffer kcpBuffer = KcpBuffer.CreateFromSpan(owner, buffer.Span.Slice(0, size)); + buffer = buffer.Slice(size); + + _queue.AddLast(_cache.Rent(kcpBuffer, _stream ? (byte)0 : (byte)fragment)); + Interlocked.Add(ref _unflushedBytes, size); + } + + _updateActivation.Notify(); + + if (count == 0) + { + return new ValueTask(true); + } + + _activeWait = true; + Debug.Assert(!_signled); + _forStream = false; + _operationMode = 0; + _buffer = buffer; + _cancellationToken = cancellationToken; + token = _mrvtsc.Version; + } + + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((KcpSendQueue)state)!.SetCanceled(), this); + + return new ValueTask(this, token); + } + + public ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken) + { + short token; + lock (_queue) + { + if (_transportClosed || _disposed) + { + return new ValueTask(Task.FromException(ThrowHelper.NewTransportClosedForStreamException())); + } + if (_activeWait) + { + return new ValueTask(Task.FromException(ThrowHelper.NewConcurrentSendException())); + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + + int mss = _mss; + if (_stream) + { + LinkedListNodeOfQueueItem node = _queue.Last; + if (node is not null) + { + ref KcpBuffer data = ref node.ValueRef.Data; + int expand = mss - data.Length; + expand = Math.Min(expand, buffer.Length); + if (expand > 0) + { + data = data.AppendData(buffer.Span.Slice(0, expand)); + buffer = buffer.Slice(expand); + Interlocked.Add(ref _unflushedBytes, expand); + } + } + + if (buffer.IsEmpty) + { + return default; + } + } + + int count = buffer.Length <= mss ? 1 : (buffer.Length + mss - 1) / mss; + Debug.Assert(count >= 1); + + Debug.Assert(_stream); + // synchronously put fragments into queue. + while (count > 0 && _queue.Count < _capacity) + { + int size = buffer.Length > mss ? mss : buffer.Length; + KcpRentedBuffer owner = _bufferPool.Rent(new KcpBufferPoolRentOptions(mss, false)); + KcpBuffer kcpBuffer = KcpBuffer.CreateFromSpan(owner, buffer.Span.Slice(0, size)); + buffer = buffer.Slice(size); + + _queue.AddLast(_cache.Rent(kcpBuffer, 0)); + Interlocked.Add(ref _unflushedBytes, size); + } + + _updateActivation.Notify(); + + if (count == 0) + { + return default; + } + + _activeWait = true; + Debug.Assert(!_signled); + _forStream = true; + _operationMode = 0; + _buffer = buffer; + _cancellationToken = cancellationToken; + token = _mrvtsc.Version; + } + + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((KcpSendQueue)state)!.SetCanceled(), this); + + return new ValueTask(this, token); + } + + public ValueTask FlushAsync(CancellationToken cancellationToken) + { + short token; + lock (_queue) + { + if (_transportClosed || _disposed) + { + return new ValueTask(false); + } + if (_activeWait) + { + return new ValueTask(Task.FromException(ThrowHelper.NewConcurrentSendException())); + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + + _activeWait = true; + Debug.Assert(!_signled); + _forStream = false; + _operationMode = 1; + _buffer = default; + _cancellationToken = cancellationToken; + token = _mrvtsc.Version; + } + + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((KcpSendQueue)state)!.SetCanceled(), this); + + return new ValueTask(this, token); + } + + public ValueTask FlushForStreamAsync(CancellationToken cancellationToken) + { + short token; + lock (_queue) + { + if (_transportClosed || _disposed) + { + return new ValueTask(Task.FromException(ThrowHelper.NewTransportClosedForStreamException())); + } + if (_activeWait) + { + return new ValueTask(Task.FromException(ThrowHelper.NewConcurrentSendException())); + } + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask(Task.FromCanceled(cancellationToken)); + } + + _activeWait = true; + Debug.Assert(!_signled); + _forStream = true; + _operationMode = 1; + _buffer = default; + _cancellationToken = cancellationToken; + token = _mrvtsc.Version; + } + + _cancellationRegistration = cancellationToken.UnsafeRegister(state => ((KcpSendQueue)state)!.SetCanceled(), this); + + return new ValueTask(this, token); + } + + public bool CancelPendingOperation(Exception innerException, CancellationToken cancellationToken) + { + lock (_queue) + { + if (_activeWait && !_signled) + { + ClearPreviousOperation(); + _mrvtsc.SetException(ThrowHelper.NewOperationCanceledExceptionForCancelPendingSend(innerException, cancellationToken)); + return true; + } + } + return false; + } + + private void SetCanceled() + { + lock (_queue) + { + if (_activeWait && !_signled) + { + CancellationToken cancellationToken = _cancellationToken; + ClearPreviousOperation(); + _mrvtsc.SetException(new OperationCanceledException(cancellationToken)); + } + } + } + + private void ClearPreviousOperation() + { + _signled = true; + _forStream = false; + _operationMode = 0; + _buffer = default; + _waitForByteCount = default; + _waitForSegmentCount = default; + _cancellationToken = default; + } + + public bool TryDequeue(out KcpBuffer data, out byte fragment) + { + lock (_queue) + { + LinkedListNodeOfQueueItem node = _queue.First; + if (node is null) + { + data = default; + fragment = default; + return false; + } + else + { + (data, fragment) = node.ValueRef; + _queue.RemoveFirst(); + node.ValueRef = default; + _cache.Return(node); + + MoveOneSegmentIn(); + CheckForAvailableSpace(); + return true; + } + } + } + + public void NotifyAckListChanged(bool itemsListNotEmpty) + { + lock (_queue) + { + if (_transportClosed || _disposed) + { + return; + } + + _ackListNotEmpty = itemsListNotEmpty; + TryCompleteFlush(Interlocked.Read(ref _unflushedBytes)); + } + } + + private void MoveOneSegmentIn() + { + if (_activeWait && !_signled && _operationMode == 0) + { + ReadOnlyMemory buffer = _buffer; + int mss = _mss; + int count = buffer.Length <= mss ? 1 : (buffer.Length + mss - 1) / mss; + + int size = buffer.Length > mss ? mss : buffer.Length; + KcpRentedBuffer owner = _bufferPool.Rent(new KcpBufferPoolRentOptions(mss, false)); + KcpBuffer kcpBuffer = KcpBuffer.CreateFromSpan(owner, buffer.Span.Slice(0, size)); + _buffer = buffer.Slice(size); + + _queue.AddLast(_cache.Rent(kcpBuffer, _stream ? (byte)0 : (byte)(count - 1))); + Interlocked.Add(ref _unflushedBytes, size); + + if (count == 1) + { + ClearPreviousOperation(); + _mrvtsc.SetResult(true); + } + } + } + + private void CheckForAvailableSpace() + { + if (_activeWait && !_signled && _operationMode == 2) + { + GetAvailableSpaceCore(out int byteCount, out int segmentCount); + if (byteCount >= _waitForByteCount && segmentCount >= _waitForSegmentCount) + { + ClearPreviousOperation(); + _mrvtsc.SetResult(true); + } + } + } + + private void TryCompleteFlush(long unflushedBytes) + { + if (_activeWait && !_signled && _operationMode == 1) + { + if (_queue.Last is null && unflushedBytes == 0 && !_ackListNotEmpty) + { + ClearPreviousOperation(); + _mrvtsc.SetResult(true); + } + } + } + + public void SubtractUnflushedBytes(int size) + { + long unflushedBytes = Interlocked.Add(ref _unflushedBytes, -size); + if (unflushedBytes == 0) + { + lock (_queue) + { + TryCompleteFlush(0); + } + } + } + + public long GetUnflushedBytes() + { + if (_transportClosed || _disposed) + { + return 0; + } + return Interlocked.Read(ref _unflushedBytes); + } + + public void SetTransportClosed() + { + lock (_queue) + { + if (_transportClosed || _disposed) + { + return; + } + if (_activeWait && !_signled) + { + if (_forStream) + { + ClearPreviousOperation(); + _mrvtsc.SetException(ThrowHelper.NewTransportClosedForStreamException()); + } + else + { + ClearPreviousOperation(); + _mrvtsc.SetResult(false); + } + } + _transportClosed = true; + Interlocked.Exchange(ref _unflushedBytes, 0); + } + } + + public void Dispose() + { + lock (_queue) + { + if (_disposed) + { + return; + } + if (_activeWait && !_signled) + { + if (_forStream) + { + ClearPreviousOperation(); + _mrvtsc.SetException(ThrowHelper.NewTransportClosedForStreamException()); + } + else + { + ClearPreviousOperation(); + _mrvtsc.SetResult(false); + } + } + LinkedListNodeOfQueueItem node = _queue.First; + while (node is not null) + { + node.ValueRef.Data.Release(); + node = node.Next; + } + _queue.Clear(); + _disposed = true; + _transportClosed = true; + } + } + + } +} diff --git a/NahidaImpact.Kcp/KcpSendReceiveBufferItem.cs b/NahidaImpact.Kcp/KcpSendReceiveBufferItem.cs new file mode 100644 index 0000000..d5ce814 --- /dev/null +++ b/NahidaImpact.Kcp/KcpSendReceiveBufferItem.cs @@ -0,0 +1,9 @@ +namespace NahidaImpact.Kcp +{ + internal struct KcpSendReceiveBufferItem + { + public KcpBuffer Data; + public KcpPacketHeader Segment; + public KcpSendSegmentStats Stats; + } +} diff --git a/NahidaImpact.Kcp/KcpSendReceiveBufferItemCache.cs b/NahidaImpact.Kcp/KcpSendReceiveBufferItemCache.cs new file mode 100644 index 0000000..fb70a49 --- /dev/null +++ b/NahidaImpact.Kcp/KcpSendReceiveBufferItemCache.cs @@ -0,0 +1,73 @@ + +#if NEED_LINKEDLIST_SHIM +using LinkedListOfBufferItem = KcpSharp.NetstandardShim.LinkedList; +using LinkedListNodeOfBufferItem = KcpSharp.NetstandardShim.LinkedListNode; +#else +using LinkedListNodeOfBufferItem = System.Collections.Generic.LinkedListNode; +using LinkedListOfBufferItem = System.Collections.Generic.LinkedList; +#endif + +namespace NahidaImpact.Kcp +{ + internal struct KcpSendReceiveBufferItemCache + { + private LinkedListOfBufferItem _items; + private SpinLock _lock; + + public static KcpSendReceiveBufferItemCache Create() + { + return new KcpSendReceiveBufferItemCache + { + _items = new LinkedListOfBufferItem(), + _lock = new SpinLock() + }; + } + + public LinkedListNodeOfBufferItem Allocate(in KcpSendReceiveBufferItem item) + { + bool lockAcquired = false; + try + { + _lock.Enter(ref lockAcquired); + + LinkedListNodeOfBufferItem node = _items.First; + if (node is null) + { + node = new LinkedListNodeOfBufferItem(item); + } + else + { + _items.Remove(node); + node.ValueRef = item; + } + return node; + } + finally + { + if (lockAcquired) + { + _lock.Exit(); + } + } + } + + public void Return(LinkedListNodeOfBufferItem node) + { + bool lockAcquired = false; + try + { + _lock.Enter(ref lockAcquired); + + node.ValueRef = default; + _items.AddLast(node); + } + finally + { + if (lockAcquired) + { + _lock.Exit(); + } + } + } + } +} diff --git a/NahidaImpact.Kcp/KcpSendReceiveQueueItemCache.cs b/NahidaImpact.Kcp/KcpSendReceiveQueueItemCache.cs new file mode 100644 index 0000000..0a5a711 --- /dev/null +++ b/NahidaImpact.Kcp/KcpSendReceiveQueueItemCache.cs @@ -0,0 +1,84 @@ + +#if NEED_LINKEDLIST_SHIM +using LinkedListOfQueueItem = KcpSharp.NetstandardShim.LinkedList<(KcpSharp.KcpBuffer Data, byte Fragment)>; +using LinkedListNodeOfQueueItem = KcpSharp.NetstandardShim.LinkedListNode<(KcpSharp.KcpBuffer Data, byte Fragment)>; +#else +using LinkedListNodeOfQueueItem = System.Collections.Generic.LinkedListNode<(NahidaImpact.Kcp.KcpBuffer Data, byte Fragment)>; +using LinkedListOfQueueItem = System.Collections.Generic.LinkedList<(NahidaImpact.Kcp.KcpBuffer Data, byte Fragment)>; +#endif + +namespace NahidaImpact.Kcp +{ + internal sealed class KcpSendReceiveQueueItemCache + { + private LinkedListOfQueueItem _list = new(); + private SpinLock _lock; + + public LinkedListNodeOfQueueItem Rent(in KcpBuffer buffer, byte fragment) + { + bool lockTaken = false; + try + { + _lock.Enter(ref lockTaken); + + LinkedListNodeOfQueueItem node = _list.First; + if (node is null) + { + node = new LinkedListNodeOfQueueItem((buffer, fragment)); + } + else + { + node.ValueRef = (buffer, fragment); + _list.RemoveFirst(); + } + + return node; + } + finally + { + if (lockTaken) + { + _lock.Exit(); + } + } + } + + public void Return(LinkedListNodeOfQueueItem node) + { + node.ValueRef = default; + + bool lockTaken = false; + try + { + _lock.Enter(ref lockTaken); + + _list.AddLast(node); + } + finally + { + if (lockTaken) + { + _lock.Exit(); + } + } + } + + public void Clear() + { + bool lockTaken = false; + try + { + _lock.Enter(ref lockTaken); + + _list.Clear(); + } + finally + { + if (lockTaken) + { + _lock.Exit(); + } + } + } + } +} diff --git a/NahidaImpact.Kcp/KcpSendSegmentStats.cs b/NahidaImpact.Kcp/KcpSendSegmentStats.cs new file mode 100644 index 0000000..f2d3127 --- /dev/null +++ b/NahidaImpact.Kcp/KcpSendSegmentStats.cs @@ -0,0 +1,20 @@ +namespace NahidaImpact.Kcp +{ + internal readonly struct KcpSendSegmentStats + { + public KcpSendSegmentStats(uint resendTimestamp, uint rto, uint fastAck, uint transmitCount) + { + ResendTimestamp = resendTimestamp; + Rto = rto; + FastAck = fastAck; + TransmitCount = transmitCount; + } + + public uint ResendTimestamp { get; } + public uint Rto { get; } + public uint FastAck { get; } + public uint TransmitCount { get; } + + + } +} diff --git a/NahidaImpact.Kcp/KcpSocketTransport.cs b/NahidaImpact.Kcp/KcpSocketTransport.cs new file mode 100644 index 0000000..a32f8a3 --- /dev/null +++ b/NahidaImpact.Kcp/KcpSocketTransport.cs @@ -0,0 +1,158 @@ +using System.Net; +using System.Net.Sockets; + +namespace NahidaImpact.Kcp +{ + + /// + /// Helper methods to create socket transports for KCP conversations. + /// + public static class KcpSocketTransport + { + /// + /// Create a socket transport for KCP covnersation. + /// + /// The udp listener instance. + /// The remote endpoint. + /// The conversation ID. + /// The options of the . + /// The created socket transport instance. + public static IKcpTransport CreateConversation(UdpClient listener, IPEndPoint endPoint, long conversationId, KcpConversationOptions options) + { + if (listener is null) + { + throw new ArgumentNullException(nameof(listener)); + } + if (endPoint is null) + { + throw new ArgumentNullException(nameof(endPoint)); + } + + return new KcpSocketTransportForConversation(listener, endPoint, conversationId, options); + } + + /// + /// Create a socket transport for KCP covnersation with no conversation ID. + /// + /// The udp listener instance. + /// The remote endpoint. + /// The options of the . + /// The created socket transport instance. + public static IKcpTransport CreateConversation(UdpClient listener, IPEndPoint endPoint, KcpConversationOptions options) + { + if (listener is null) + { + throw new ArgumentNullException(nameof(listener)); + } + if (endPoint is null) + { + throw new ArgumentNullException(nameof(endPoint)); + } + + return new KcpSocketTransportForConversation(listener, endPoint, null, options); + } + + /// + /// Create a socket transport for raw channel. + /// + /// The udp listener instance. + /// The remote endpoint. + /// The conversation ID. + /// The options of the . + /// The created socket transport instance. + public static IKcpTransport CreateRawChannel(UdpClient listener, IPEndPoint endPoint, long conversationId, KcpRawChannelOptions options) + { + if (listener is null) + { + throw new ArgumentNullException(nameof(listener)); + } + if (endPoint is null) + { + throw new ArgumentNullException(nameof(endPoint)); + } + + return new KcpSocketTransportForRawChannel(listener, endPoint, conversationId, options); + } + + /// + /// Create a socket transport for raw channel with no conversation ID. + /// + /// The udp listener instance. + /// The remote endpoint. + /// The options of the . + /// The created socket transport instance. + public static IKcpTransport CreateRawChannel(UdpClient listener, IPEndPoint endPoint, KcpRawChannelOptions options) + { + if (listener is null) + { + throw new ArgumentNullException(nameof(listener)); + } + if (endPoint is null) + { + throw new ArgumentNullException(nameof(endPoint)); + } + + return new KcpSocketTransportForRawChannel(listener, endPoint, null, options); + } + + /// + /// Create a socket transport for multiplex connection. + /// + /// The udp listener instance. + /// The maximum packet size that can be transmitted over the socket. + /// + public static IKcpTransport CreateMultiplexConnection(UdpClient listener, int mtu) + { + if (listener is null) + { + throw new ArgumentNullException(nameof(listener)); + } + + return new KcpSocketTransportForMultiplexConnection(listener, mtu); + } + + /// + /// Create a socket transport for multiplex connection. + /// + /// The type of the user state. + /// The udp listener instance. + /// The maximum packet size that can be transmitted over the socket. + /// + public static IKcpTransport> CreateMultiplexConnection(UdpClient listener, IPEndPoint endPoint, int mtu) + { + if (listener is null) + { + throw new ArgumentNullException(nameof(listener)); + } + if (endPoint is null) + { + throw new ArgumentNullException(nameof(endPoint)); + } + + return new KcpSocketTransportForMultiplexConnection(listener, mtu); + } + + /// + /// Create a socket transport for multiplex connection. + /// + /// The type of the user state. + /// The udp listener instance. + /// The remote endpoint. + /// The maximum packet size that can be transmitted over the socket. + /// The action to invoke when state object is removed. + /// + public static IKcpTransport> CreateMultiplexConnection(UdpClient listener, EndPoint endPoint, int mtu, Action disposeAction) + { + if (listener is null) + { + throw new ArgumentNullException(nameof(listener)); + } + if (endPoint is null) + { + throw new ArgumentNullException(nameof(endPoint)); + } + + return new KcpSocketTransportForMultiplexConnection(listener, mtu, disposeAction); + } + } +} diff --git a/NahidaImpact.Kcp/KcpSocketTransportForConversation.cs b/NahidaImpact.Kcp/KcpSocketTransportForConversation.cs new file mode 100644 index 0000000..3b1c5b4 --- /dev/null +++ b/NahidaImpact.Kcp/KcpSocketTransportForConversation.cs @@ -0,0 +1,45 @@ +using System.Net; +using System.Net.Sockets; + +namespace NahidaImpact.Kcp +{ + /// + /// Socket transport for KCP conversation. + /// + internal sealed class KcpSocketTransportForConversation : KcpSocketTransport, IKcpTransport + { + private readonly long? _conversationId; + private readonly IPEndPoint _remoteEndPoint; + private readonly KcpConversationOptions _options; + + private Func, object, bool> _exceptionHandler; + private object _exceptionHandlerState; + + + internal KcpSocketTransportForConversation(UdpClient listener, IPEndPoint endPoint, long? conversationId, KcpConversationOptions options) + : base(listener, options?.Mtu ?? KcpConversationOptions.MtuDefaultValue) + { + _conversationId = conversationId; + _remoteEndPoint = endPoint; + _options = options; + } + + protected override KcpConversation Activate() => _conversationId.HasValue ? new KcpConversation(_remoteEndPoint, this, _conversationId.GetValueOrDefault(), _options) : new KcpConversation(_remoteEndPoint, this, _options); + + protected override bool HandleException(Exception ex) + { + if (_exceptionHandler is not null) + { + return _exceptionHandler.Invoke(ex, this, _exceptionHandlerState); + } + return false; + } + + public void SetExceptionHandler(Func, object, bool> handler, object state) + { + _exceptionHandler = handler; + _exceptionHandlerState = state; + } + + } +} diff --git a/NahidaImpact.Kcp/KcpSocketTransportForMultiplexConnection.cs b/NahidaImpact.Kcp/KcpSocketTransportForMultiplexConnection.cs new file mode 100644 index 0000000..1c07a72 --- /dev/null +++ b/NahidaImpact.Kcp/KcpSocketTransportForMultiplexConnection.cs @@ -0,0 +1,40 @@ +using System.Net.Sockets; + +namespace NahidaImpact.Kcp +{ + internal sealed class KcpSocketTransportForMultiplexConnection : KcpSocketTransport>, IKcpTransport> + { + private readonly Action _disposeAction; + private Func>, object, bool> _exceptionHandler; + private object _exceptionHandlerState; + + internal KcpSocketTransportForMultiplexConnection(UdpClient listener, int mtu) + : base(listener, mtu) + { } + + internal KcpSocketTransportForMultiplexConnection(UdpClient listener, int mtu, Action disposeAction) + : base(listener, mtu) + { + _disposeAction = disposeAction; + } + + protected override KcpMultiplexConnection Activate() => new KcpMultiplexConnection(this, _disposeAction); + + IKcpMultiplexConnection IKcpTransport>.Connection => Connection; + + protected override bool HandleException(Exception ex) + { + if (_exceptionHandler is not null) + { + return _exceptionHandler.Invoke(ex, this, _exceptionHandlerState); + } + return false; + } + + public void SetExceptionHandler(Func>, object, bool> handler, object state) + { + _exceptionHandler = handler; + _exceptionHandlerState = state; + } + } +} diff --git a/NahidaImpact.Kcp/KcpSocketTransportForRawChannel.cs b/NahidaImpact.Kcp/KcpSocketTransportForRawChannel.cs new file mode 100644 index 0000000..a408acc --- /dev/null +++ b/NahidaImpact.Kcp/KcpSocketTransportForRawChannel.cs @@ -0,0 +1,41 @@ +using System.Net; +using System.Net.Sockets; + +namespace NahidaImpact.Kcp +{ + internal sealed class KcpSocketTransportForRawChannel : KcpSocketTransport, IKcpTransport + { + private readonly long? _conversationId; + private readonly IPEndPoint _remoteEndPoint; + private readonly KcpRawChannelOptions _options; + + private Func, object, bool> _exceptionHandler; + private object _exceptionHandlerState; + + + internal KcpSocketTransportForRawChannel(UdpClient listener, IPEndPoint endPoint, long? conversationId, KcpRawChannelOptions options) + : base(listener, options?.Mtu ?? KcpConversationOptions.MtuDefaultValue) + { + _conversationId = conversationId; + _remoteEndPoint = endPoint; + _options = options; + } + + protected override KcpRawChannel Activate() => _conversationId.HasValue ? new KcpRawChannel(_remoteEndPoint, this, _conversationId.GetValueOrDefault(), _options) : new KcpRawChannel(_remoteEndPoint, this, _options); + + protected override bool HandleException(Exception ex) + { + if (_exceptionHandler is not null) + { + return _exceptionHandler.Invoke(ex, this, _exceptionHandlerState); + } + return false; + } + + public void SetExceptionHandler(Func, object, bool> handler, object state) + { + _exceptionHandler = handler; + _exceptionHandlerState = state; + } + } +} diff --git a/NahidaImpact.Kcp/KcpSocketTransportOfT.cs b/NahidaImpact.Kcp/KcpSocketTransportOfT.cs new file mode 100644 index 0000000..3e45c3f --- /dev/null +++ b/NahidaImpact.Kcp/KcpSocketTransportOfT.cs @@ -0,0 +1,224 @@ +using System.Buffers; +using System.Net; +using System.Net.Sockets; + +namespace NahidaImpact.Kcp +{ + /// + /// A Socket transport for upper-level connections. + /// + /// + public abstract class KcpSocketTransport : IKcpTransport, IDisposable where T : class, IKcpConversation + { + private readonly UdpClient _udpListener; + private readonly int _mtu; + private T _connection; + private CancellationTokenSource _cts; + private bool _disposed; + + private int _handshakeSize; + private Func _handshakeHandler; + + /// + /// Construct a socket transport with the specified socket and remote endpoint. + /// + /// The socket instance. + /// The maximum packet size that can be transmitted. + protected KcpSocketTransport(UdpClient listener, int mtu) + { + _udpListener = listener ?? throw new ArgumentNullException(nameof(listener)); + _mtu = mtu; + if (mtu < 50) + { + throw new ArgumentOutOfRangeException(nameof(mtu)); + } + } + + public void SetCallbacks(int handshakeSize, Func handshakeHandler) + { + _handshakeSize = handshakeSize; + _handshakeHandler = handshakeHandler; + } + + /// + /// Get the upper-level connection instace. If Start is not called or the transport is closed, will be thrown. + /// + /// Start is not called or the transport is closed. + public T Connection => _connection ?? throw new InvalidOperationException(); + + /// + /// Create the upper-level connection instance. + /// + /// The upper-level connection instance. + protected abstract T Activate(); + + /// + /// Allocate a block of memory used to receive from socket. + /// + /// The minimum size of the buffer. + /// The allocated memory buffer. + protected virtual IMemoryOwner AllocateBuffer(int size) + { +#if NEED_POH_SHIM + return MemoryPool.Shared.Rent(size); +#else + return new ArrayMemoryOwner(GC.AllocateUninitializedArray(size, pinned: true)); +#endif + } + + /// + /// Handle exception thrown when receiving from remote endpoint. + /// + /// The exception thrown. + /// Whether error should be ignored. + protected virtual bool HandleException(Exception ex) => false; + + /// + /// Create the upper-level connection and start pumping packets from the socket to the upper-level connection. + /// + public void Start() + { + if (_disposed) + { + throw new ObjectDisposedException(nameof(KcpSocketTransport)); + } + if (_connection is not null) + { + throw new InvalidOperationException(); + } + + _connection = Activate(); + if (_connection is null) + { + throw new InvalidOperationException(); + } + _cts = new CancellationTokenSource(); + RunReceiveLoop(); + } + + /// + public ValueTask SendPacketAsync(Memory packet, IPEndPoint endpoint, CancellationToken cancellationToken = default) + { + if (_disposed) + { + return default; + } + if (packet.Length > _mtu) + { + return default; + } + + return new ValueTask(_udpListener.SendAsync(packet.ToArray(), endpoint, cancellationToken).AsTask()); + } + + private async void RunReceiveLoop() + { + CancellationToken cancellationToken = _cts?.Token ?? new CancellationToken(true); + IKcpConversation connection = _connection; + + if (connection is null || cancellationToken.IsCancellationRequested) + { + return; + } + + using IMemoryOwner memoryOwner = AllocateBuffer(_mtu); + try + { + while (!cancellationToken.IsCancellationRequested) + { + int bytesReceived = 0; + bool error = false; + UdpReceiveResult result = default; + try + { + result = await _udpListener.ReceiveAsync(cancellationToken); + bytesReceived = result.Buffer.Length; + } + catch (Exception ex) + { + // похуй + } + + if (bytesReceived != 0 && bytesReceived <= _mtu) + { + if (bytesReceived == _handshakeSize) + await _handshakeHandler(result); + else if (!error) + await connection.InputPakcetAsync(result, cancellationToken).ConfigureAwait(false); + } + } + } + catch (OperationCanceledException) + { + // Do nothing + } + catch (Exception ex) + { + HandleExceptionWrapper(ex); + } + } + + private bool HandleExceptionWrapper(Exception ex) + { + bool result; + try + { + result = HandleException(ex); + } + catch + { + result = false; + } + + _connection?.SetTransportClosed(); + CancellationTokenSource cts = Interlocked.Exchange(ref _cts, null); + if (cts is not null) + { + cts.Cancel(); + cts.Dispose(); + } + + return result; + } + + /// + /// Dispose all the managed and the unmanaged resources used by this instance. + /// + /// If managed resources should be disposed. + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + CancellationTokenSource cts = Interlocked.Exchange(ref _cts, null); + if (cts is not null) + { + cts.Cancel(); + cts.Dispose(); + } + _connection?.Dispose(); + } + + _connection = null; + _cts = null; + _disposed = true; + } + } + + /// + /// Dispose the unmanaged resources used by this instance. + /// + ~KcpSocketTransport() + { + Dispose(disposing: false); + } + + /// + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/NahidaImpact.Kcp/KcpStream.cs b/NahidaImpact.Kcp/KcpStream.cs new file mode 100644 index 0000000..aa2e848 --- /dev/null +++ b/NahidaImpact.Kcp/KcpStream.cs @@ -0,0 +1,166 @@ +namespace NahidaImpact.Kcp +{ + /// + /// A stream wrapper of . + /// + public sealed class KcpStream : Stream + { + private KcpConversation _conversation; + private readonly bool _ownsConversation; + + /// + /// Create a stream wrapper over an existing instance. + /// + /// The conversation instance. It must be in stream mode. + /// Whether to dispose the instance when is disposed. + public KcpStream(KcpConversation conversation, bool ownsConversation) + { + if (conversation is null) + { + throw new ArgumentNullException(nameof(conversation)); + } + if (!conversation.StreamMode) + { + throw new ArgumentException("Non-stream mode conversation is not supported.", nameof(conversation)); + } + _conversation = conversation; + _ownsConversation = ownsConversation; + } + + /// + public override bool CanRead => true; + + /// + public override bool CanSeek => false; + + /// + public override bool CanWrite => true; + + /// + /// The length of the stream. This always throws . + /// + public override long Length => throw new NotSupportedException(); + + /// + /// The position of the stream. This always throws . + /// + public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } + + /// + public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException(); + + /// + public override void SetLength(long value) => throw new NotSupportedException(); + + /// + /// Indicates data is available on the stream to be read. This property checks to see if at least one byte of data is currently available + /// + public bool DataAvailable + { + get + { + if (_conversation is null) + { + ThrowHelper.ThrowObjectDisposedForKcpStreamException(); + } + return _conversation!.TryPeek(out KcpConversationReceiveResult result) && result.BytesReceived != 0; + } + } + + /// + public override void Flush() => throw new NotSupportedException(); + + /// + public override Task FlushAsync(CancellationToken cancellationToken) + { + if (_conversation is null) + { + return Task.FromException(ThrowHelper.NewObjectDisposedForKcpStreamException()); + } + return _conversation!.FlushAsync(cancellationToken).AsTask(); + } + + /// + public override int Read(byte[] buffer, int offset, int count) => throw new NotSupportedException(); + + /// + public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException(); + + /// + public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + if (_conversation is null) + { + return Task.FromException(new ObjectDisposedException(nameof(KcpStream))); + } + return _conversation.ReadAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); + } + + /// + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + if (_conversation is null) + { + return Task.FromException(new ObjectDisposedException(nameof(KcpStream))); + } + return _conversation.WriteAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); + } + + /// + public override int ReadByte() => throw new NotSupportedException(); + + /// + public override void WriteByte(byte value) => throw new NotSupportedException(); + + /// + protected override void Dispose(bool disposing) + { + if (disposing && _ownsConversation) + { + _conversation?.Dispose(); + } + _conversation = null; + base.Dispose(disposing); + } + +#if !NO_FAST_SPAN + /// + public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) + { + if (_conversation is null) + { + return new ValueTask(Task.FromException(new ObjectDisposedException(nameof(KcpStream)))); + } + return _conversation.ReadAsync(buffer, cancellationToken); + } + + /// + public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) + { + if (_conversation is null) + { + return new ValueTask(Task.FromException(new ObjectDisposedException(nameof(KcpStream)))); + } + return _conversation.WriteAsync(buffer, cancellationToken); + } + + /// + public override ValueTask DisposeAsync() + { + if (_conversation is not null) + { + _conversation.Dispose(); + _conversation = null; + } + return base.DisposeAsync(); + } + + /// + public override int Read(Span buffer) => throw new NotSupportedException(); + + /// + public override void Write(ReadOnlySpan buffer) => throw new NotSupportedException(); +#endif + + } +} diff --git a/NahidaImpact.Kcp/NahidaImpact.Kcp.csproj b/NahidaImpact.Kcp/NahidaImpact.Kcp.csproj new file mode 100644 index 0000000..30402ac --- /dev/null +++ b/NahidaImpact.Kcp/NahidaImpact.Kcp.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/NahidaImpact.Kcp/ThrowHelper.cs b/NahidaImpact.Kcp/ThrowHelper.cs new file mode 100644 index 0000000..0cfa0dd --- /dev/null +++ b/NahidaImpact.Kcp/ThrowHelper.cs @@ -0,0 +1,66 @@ +namespace NahidaImpact.Kcp +{ + internal static class ThrowHelper + { + public static void ThrowArgumentOutOfRangeException(string paramName) + { + throw new ArgumentOutOfRangeException(paramName); + } + public static void ThrowTransportClosedForStreanException() + { + throw new IOException("The underlying transport is closed."); + } + public static Exception NewMessageTooLargeForBufferArgument() + { + return new ArgumentException("Message is too large.", "buffer"); + } + public static Exception NewBufferTooSmallForBufferArgument() + { + return new ArgumentException("Buffer is too small.", "buffer"); + } + public static Exception ThrowBufferTooSmall() + { + throw new ArgumentException("Buffer is too small.", "buffer"); + } + public static Exception ThrowAllowPartialSendArgumentException() + { + throw new ArgumentException("allowPartialSend should not be set to true in non-stream mode.", "allowPartialSend"); + } + public static Exception NewArgumentOutOfRangeException(string paramName) + { + return new ArgumentOutOfRangeException(paramName); + } + public static Exception NewConcurrentSendException() + { + return new InvalidOperationException("Concurrent send operations are not allowed."); + } + public static Exception NewConcurrentReceiveException() + { + return new InvalidOperationException("Concurrent receive operations are not allowed."); + } + public static Exception NewTransportClosedForStreamException() + { + throw new IOException("The underlying transport is closed."); + } + public static Exception NewOperationCanceledExceptionForCancelPendingSend(Exception innerException, CancellationToken cancellationToken) + { + return new OperationCanceledException("This operation is cancelled by a call to CancelPendingSend.", innerException, cancellationToken); + } + public static Exception NewOperationCanceledExceptionForCancelPendingReceive(Exception innerException, CancellationToken cancellationToken) + { + return new OperationCanceledException("This operation is cancelled by a call to CancelPendingReceive.", innerException, cancellationToken); + } + public static void ThrowConcurrentReceiveException() + { + throw new InvalidOperationException("Concurrent receive operations are not allowed."); + } + public static Exception NewObjectDisposedForKcpStreamException() + { + return new ObjectDisposedException(nameof(KcpStream)); + } + public static void ThrowObjectDisposedForKcpStreamException() + { + throw new ObjectDisposedException(nameof(KcpStream)); + } + } +} diff --git a/NahidaImpact.Protocol/AbilityActionCreateGadget.proto b/NahidaImpact.Protocol/AbilityActionCreateGadget.proto new file mode 100644 index 0000000..c93e706 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityActionCreateGadget.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "Vector.proto"; +// Obf: BAFEPPHIOGH +message AbilityActionCreateGadget { + Vector pos = 1; + Vector rot = 2; + uint32 room_id = 3; +} diff --git a/NahidaImpact.Protocol/AbilityActionGenerateElemBall.proto b/NahidaImpact.Protocol/AbilityActionGenerateElemBall.proto new file mode 100644 index 0000000..d7e7098 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityActionGenerateElemBall.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +import "Vector.proto"; +message AbilityActionGenerateElemBall { + Vector pos = 11; + Vector rot = 7; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AbilityActionSetRandomOverrideMapValue.proto b/NahidaImpact.Protocol/AbilityActionSetRandomOverrideMapValue.proto new file mode 100644 index 0000000..2e07f86 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityActionSetRandomOverrideMapValue.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message AbilityActionSetRandomOverrideMapValue { + float random_value = 8; +} diff --git a/NahidaImpact.Protocol/AbilityAppliedAbility.proto b/NahidaImpact.Protocol/AbilityAppliedAbility.proto new file mode 100644 index 0000000..1150434 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityAppliedAbility.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + + +import "AbilityString.proto"; +import "AbilityScalarValueEntry.proto"; + +message AbilityAppliedAbility { + AbilityString ability_name = 1; + AbilityString ability_override = 2; + repeated AbilityScalarValueEntry override_map = 3; + uint32 instanced_ability_id = 4; +} diff --git a/NahidaImpact.Protocol/AbilityAppliedModifier.proto b/NahidaImpact.Protocol/AbilityAppliedModifier.proto new file mode 100644 index 0000000..265c5bf --- /dev/null +++ b/NahidaImpact.Protocol/AbilityAppliedModifier.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + + +import "AbilityString.proto"; +import "ModifierDurability.proto"; +import "AbilityAttachedModifier.proto"; + +message AbilityAppliedModifier { + AbilityString parent_ability_override = 4; + ModifierDurability modifier_durability = 11; + AbilityString parent_ability_name = 3; + AbilityAttachedModifier attached_instanced_modifier = 8; + float exist_duration = 7; + uint32 apply_entity_id = 9; + uint32 sbuff_uid = 12; + bool is_attached_parent_ability = 10; + bool is_serverbuff_modifier = 13; + uint32 parent_ability_entity_id = 2; + uint32 instanced_ability_id = 5; + int32 modifier_local_id = 1; + uint32 instanced_modifier_id = 6; +} diff --git a/NahidaImpact.Protocol/AbilityAttachedModifier.proto b/NahidaImpact.Protocol/AbilityAttachedModifier.proto new file mode 100644 index 0000000..fe76255 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityAttachedModifier.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +message AbilityAttachedModifier { + bool is_serverbuff_modifier = 4; + bool is_invalid = 1; + int32 attach_name_hash = 5; + uint32 instanced_modifier_id = 3; + uint32 owner_entity_id = 2; +} diff --git a/NahidaImpact.Protocol/AbilityBornType.proto b/NahidaImpact.Protocol/AbilityBornType.proto new file mode 100644 index 0000000..6d56f4d --- /dev/null +++ b/NahidaImpact.Protocol/AbilityBornType.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "Vector.proto"; +// Obf: AJIIAKCDDHA +message AbilityBornType { + Vector move_dir = 8; + Vector rot = 13; + Vector pos = 10; +} diff --git a/NahidaImpact.Protocol/AbilityControlBlock.proto b/NahidaImpact.Protocol/AbilityControlBlock.proto new file mode 100644 index 0000000..56d9026 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityControlBlock.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + + +import "AbilityEmbryo.proto"; + +message AbilityControlBlock { + repeated AbilityEmbryo ability_embryo_list = 1; +} diff --git a/NahidaImpact.Protocol/AbilityEmbryo.proto b/NahidaImpact.Protocol/AbilityEmbryo.proto new file mode 100644 index 0000000..4f95dc5 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityEmbryo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message AbilityEmbryo { + fixed32 ability_name_hash = 2; + fixed32 ability_override_name_hash = 3; + uint32 ability_id = 1; +} diff --git a/NahidaImpact.Protocol/AbilityGadgetInfo.proto b/NahidaImpact.Protocol/AbilityGadgetInfo.proto new file mode 100644 index 0000000..8f1fef0 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityGadgetInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message AbilityGadgetInfo { + uint32 camp_target_type = 2; + uint32 camp_id = 1; + uint32 target_entity_id = 3; +} diff --git a/NahidaImpact.Protocol/AbilityInvocationsNotify.proto b/NahidaImpact.Protocol/AbilityInvocationsNotify.proto new file mode 100644 index 0000000..25e43a5 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityInvocationsNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +import "AbilityInvokeEntry.proto"; +message AbilityInvocationsNotify { + repeated AbilityInvokeEntry invokes = 6; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AbilityInvokeArgument.proto b/NahidaImpact.Protocol/AbilityInvokeArgument.proto new file mode 100644 index 0000000..94aadc5 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityInvokeArgument.proto @@ -0,0 +1,71 @@ +syntax = "proto3"; + +enum AbilityInvokeArgument { + ABILITY_INVOKE_ARGUMENT_NONE = 0; + ABILITY_INVOKE_ARGUMENT_META_MODIFIER_CHANGE = 1; + ABILITY_INVOKE_ARGUMENT_META_COMMAND_MODIFIER_CHANGE_REQUEST = 2; + ABILITY_INVOKE_ARGUMENT_META_SPECIAL_FLOAT_ARGUMENT = 3; + ABILITY_INVOKE_ARGUMENT_META_OVERRIDE_PARAM = 4; + ABILITY_INVOKE_ARGUMENT_META_CLEAR_OVERRIDE_PARAM = 5; + ABILITY_INVOKE_ARGUMENT_META_REINIT_OVERRIDEMAP = 6; + ABILITY_INVOKE_ARGUMENT_META_GLOBAL_FLOAT_VALUE = 7; + ABILITY_INVOKE_ARGUMENT_META_CLEAR_GLOBAL_FLOAT_VALUE = 8; + ABILITY_INVOKE_ARGUMENT_META_ABILITY_ELEMENT_STRENGTH = 9; + ABILITY_INVOKE_ARGUMENT_META_ADD_OR_GET_ABILITY_AND_TRIGGER = 10; + ABILITY_INVOKE_ARGUMENT_META_SET_KILLED_SETATE = 11; + ABILITY_INVOKE_ARGUMENT_META_SET_ABILITY_TRIGGER = 12; + ABILITY_INVOKE_ARGUMENT_META_ADD_NEW_ABILITY = 13; + ABILITY_INVOKE_ARGUMENT_META_REMOVE_ABILITY = 14; + ABILITY_INVOKE_ARGUMENT_META_SET_MODIFIER_APPLY_ENTITY = 15; + ABILITY_INVOKE_ARGUMENT_META_MODIFIER_DURABILITY_CHANGE = 16; + ABILITY_INVOKE_ARGUMENT_META_ELEMENT_REACTION_VISUAL = 17; + ABILITY_INVOKE_ARGUMENT_META_SET_POSE_PARAMETER = 18; + ABILITY_INVOKE_ARGUMENT_META_UPDATE_BASE_REACTION_DAMAGE = 19; + ABILITY_INVOKE_ARGUMENT_META_TRIGGER_ELEMENT_REACTION = 20; + ABILITY_INVOKE_ARGUMENT_META_LOSE_HP = 21; + ABILITY_INVOKE_ARGUMENT_META_DURABILITY_IS_ZERO = 22; + ABILITY_INVOKE_ARGUMENT_ACTION_TRIGGER_ABILITY = 50; + ABILITY_INVOKE_ARGUMENT_ACTION_SET_CRASH_DAMAGE = 51; + ABILITY_INVOKE_ARGUMENT_ACTION_EFFECT = 52; + ABILITY_INVOKE_ARGUMENT_ACTION_SUMMON = 53; + ABILITY_INVOKE_ARGUMENT_ACTION_BLINK = 54; + ABILITY_INVOKE_ARGUMENT_ACTION_CREATE_GADGET = 55; + ABILITY_INVOKE_ARGUMENT_ACTION_APPLY_LEVEL_MODIFIER = 56; + ABILITY_INVOKE_ARGUMENT_ACTION_GENERATE_ELEM_BALL = 57; + ABILITY_INVOKE_ARGUMENT_ACTION_SET_RANDOM_OVERRIDE_MAP_VALUE = 58; + ABILITY_INVOKE_ARGUMENT_ACTION_SERVER_MONSTER_LOG = 59; + ABILITY_INVOKE_ARGUMENT_ACTION_CREATE_TILE = 60; + ABILITY_INVOKE_ARGUMENT_ACTION_DESTROY_TILE = 61; + ABILITY_INVOKE_ARGUMENT_ACTION_FIRE_AFTER_IMAGE = 62; + ABILITY_INVOKE_ARGUMENT_ACTION_DEDUCT_STAMINA = 63; + ABILITY_INVOKE_ARGUMENT_ACTION_HIT_EFFECT = 64; + ABILITY_INVOKE_ARGUMENT_ACTION_SET_BULLET_TRACK_TARGET = 65; + ABILITY_INVOKE_ARGUMENT_ACTION_FIREWORK_EFFECT = 66; + ABILITY_INVOKE_ARGUMENT_MIXIN_AVATAR_STEER_BY_CAMERA = 100; + ABILITY_INVOKE_ARGUMENT_MIXIN_MONSTER_DEFEND = 101; + ABILITY_INVOKE_ARGUMENT_MIXIN_WIND_ZONE = 102; + ABILITY_INVOKE_ARGUMENT_MIXIN_COST_STAMINA = 103; + ABILITY_INVOKE_ARGUMENT_MIXIN_ELITE_SHIELD = 104; + ABILITY_INVOKE_ARGUMENT_MIXIN_ELEMENT_SHIELD = 105; + ABILITY_INVOKE_ARGUMENT_MIXIN_GLOBAL_SHIELD = 106; + ABILITY_INVOKE_ARGUMENT_MIXIN_SHIELD_BAR = 107; + ABILITY_INVOKE_ARGUMENT_MIXIN_WIND_SEED_SPAWNER = 108; + ABILITY_INVOKE_ARGUMENT_MIXIN_DO_ACTION_BY_ELEMENT_REACTION = 109; + ABILITY_INVOKE_ARGUMENT_MIXIN_FIELD_ENTITY_COUNT_CHANGE = 110; + ABILITY_INVOKE_ARGUMENT_MIXIN_SCENE_PROP_SYNC = 111; + ABILITY_INVOKE_ARGUMENT_MIXIN_WIDGET_MP_SUPPORT = 112; + ABILITY_INVOKE_ARGUMENT_MIXIN_DO_ACTION_BY_SELF_MODIFIER_ELEMENT_DURABILITY_INVOKE_ARGUMENT_RATIO = 113; + ABILITY_INVOKE_ARGUMENT_MIXIN_FIREWORKS_LAUNCHER = 114; + ABILITY_INVOKE_ARGUMENT_MIXIN_ATTACK_RESULT_CREATE_COUNT = 115; + ABILITY_INVOKE_ARGUMENT_MIXIN_UGC_TIME_CONTROL = 116; + ABILITY_INVOKE_ARGUMENT_MIXIN_AVATAR_COMBAT = 117; + ABILITY_INVOKE_ARGUMENT_MIXIN_DEATH_ZONE_REGIONAL_PLAY_MIXIN = 118; + ABILITY_INVOKE_ARGUMENT_MIXIN_UI_INTERACT = 119; + ABILITY_INVOKE_ARGUMENT_MIXIN_SHOOT_FROM_CAMERA = 120; + ABILITY_INVOKE_ARGUMENT_MIXIN_ERASE_BRICK_ACTIVITY = 121; + ABILITY_INVOKE_ARGUMENT_MIXIN_BREAKOUT = 122; + ABILITY_INVOKE_ARGUMENT_MIXIN_DAMAGE_LOAN = 123; + ABILITY_INVOKE_ARGUMENT_MIXIN_BROADCAST_GV = 124; + ABILITY_INVOKE_ARGUMENT_MIXIN_RECEIVE_GV = 125; + ABILITY_INVOKE_ARGUMENT_MIXIN_ENERGY_CRYSTAL_TARGET = 127; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AbilityInvokeEntry.proto b/NahidaImpact.Protocol/AbilityInvokeEntry.proto new file mode 100644 index 0000000..484bb4a --- /dev/null +++ b/NahidaImpact.Protocol/AbilityInvokeEntry.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +import "AbilityInvokeArgument.proto"; +import "AbilityInvokeEntryHead.proto"; +import "ForwardType.proto"; +message AbilityInvokeEntry { + uint32 entity_id = 9; + bytes ability_data = 1; + AbilityInvokeEntryHead head = 4; + ForwardType forward_type = 13; + AbilityInvokeArgument argument_type = 15; +} diff --git a/NahidaImpact.Protocol/AbilityInvokeEntryHead.proto b/NahidaImpact.Protocol/AbilityInvokeEntryHead.proto new file mode 100644 index 0000000..81cbdc1 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityInvokeEntryHead.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message AbilityInvokeEntryHead { + uint32 instanced_ability_id = 11; + uint32 target_id = 10; + int32 local_id = 4; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AbilityMetaModifierChange.proto b/NahidaImpact.Protocol/AbilityMetaModifierChange.proto new file mode 100644 index 0000000..4b89690 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityMetaModifierChange.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +import "AbilityString.proto"; +import "ModifierProperty.proto"; +import "AbilityAttachedModifier.proto"; +message AbilityMetaModifierChange { + uint32 apply_entity_id = 13; + AbilityString parent_ability_name = 5; + repeated ModifierProperty properties = 14; + AbilityAttachedModifier attached_instanced_modifier = 6; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AbilityMetaModifierDurabilityChange.proto b/NahidaImpact.Protocol/AbilityMetaModifierDurabilityChange.proto new file mode 100644 index 0000000..2e621f3 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityMetaModifierDurabilityChange.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message AbilityMetaModifierDurabilityChange { + float remain_durability = 9; //sus + float reduce_durability = 6; //sus +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AbilityMetaSetKilledState.proto b/NahidaImpact.Protocol/AbilityMetaSetKilledState.proto new file mode 100644 index 0000000..a044789 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityMetaSetKilledState.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message AbilityMetaSetKilledState { + bool killed = 1; +} diff --git a/NahidaImpact.Protocol/AbilityMetaSetModifierApplyEntityId.proto b/NahidaImpact.Protocol/AbilityMetaSetModifierApplyEntityId.proto new file mode 100644 index 0000000..9d0fe01 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityMetaSetModifierApplyEntityId.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message AbilityMetaSetModifierApplyEntityId { + uint32 apply_entity_id = 13; +} diff --git a/NahidaImpact.Protocol/AbilityMetaTriggerElementReaction.proto b/NahidaImpact.Protocol/AbilityMetaTriggerElementReaction.proto new file mode 100644 index 0000000..df8b879 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityMetaTriggerElementReaction.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message AbilityMetaTriggerElementReaction { + int32 hit_index = 5; + uint32 element_reaction_type = 11; + uint32 trigger_entity_id = 7; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AbilityMetaUpdateBaseReactionDamage.proto b/NahidaImpact.Protocol/AbilityMetaUpdateBaseReactionDamage.proto new file mode 100644 index 0000000..93166d7 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityMetaUpdateBaseReactionDamage.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + + +import "AbilityString.proto"; + +message AbilityMetaUpdateBaseReactionDamage { + uint32 reaction_type = 13; + AbilityString global_value_key = 12; //12 or 1 + AbilityString ability_name = 1; + uint32 source_caster_id = 4; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AbilityMixinAvatarSteerByCamera.proto b/NahidaImpact.Protocol/AbilityMixinAvatarSteerByCamera.proto new file mode 100644 index 0000000..e615b72 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityMixinAvatarSteerByCamera.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +import "Vector.proto"; +message AbilityMixinAvatarSteerByCamera { + Vector target_dir = 11; + Vector target_pos = 4; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AbilityMixinFieldEntityCountChange.proto b/NahidaImpact.Protocol/AbilityMixinFieldEntityCountChange.proto new file mode 100644 index 0000000..d28e70c --- /dev/null +++ b/NahidaImpact.Protocol/AbilityMixinFieldEntityCountChange.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message AbilityMixinFieldEntityCountChange { + uint32 field_entity_count = 8; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AbilityMixinRecoverInfo.proto b/NahidaImpact.Protocol/AbilityMixinRecoverInfo.proto new file mode 100644 index 0000000..80e291f --- /dev/null +++ b/NahidaImpact.Protocol/AbilityMixinRecoverInfo.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + + +import "BreakoutSnapShot.proto"; +import "MassivePropSyncInfo.proto"; + +message AbilityMixinRecoverInfo { + oneof source { + uint32 instanced_ability_id = 1; + uint32 instanced_modifier_id = 2; + } + BreakoutSnapShot breakout_snap_shot = 7; + repeated uint32 data_list = 4; + repeated MassivePropSyncInfo massive_prop_list = 6; + bool is_serverbuff_modifier = 5; + uint32 local_id = 3; +} diff --git a/NahidaImpact.Protocol/AbilityScalarType.proto b/NahidaImpact.Protocol/AbilityScalarType.proto new file mode 100644 index 0000000..41615cb --- /dev/null +++ b/NahidaImpact.Protocol/AbilityScalarType.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + + +enum AbilityScalarType { + ABILITY_SCALAR_TYPE_UNKNOW = 0; + ABILITY_SCALAR_TYPE_FLOAT = 1; + ABILITY_SCALAR_TYPE_INT = 2; + ABILITY_SCALAR_TYPE_BOOL = 3; + ABILITY_SCALAR_TYPE_TRIGGER = 4; + ABILITY_SCALAR_TYPE_STRING = 5; + ABILITY_SCALAR_TYPE_UINT = 6; +} diff --git a/NahidaImpact.Protocol/AbilityScalarValueEntry.proto b/NahidaImpact.Protocol/AbilityScalarValueEntry.proto new file mode 100644 index 0000000..f9a18f0 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityScalarValueEntry.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + + +import "AbilityString.proto"; +import "AbilityScalarType.proto"; + +message AbilityScalarValueEntry { + oneof value { + float float_value = 3; + string string_value = 4; + int32 int_value = 5; + uint32 uint_value = 6; + } + AbilityString key = 1; + AbilityScalarType value_type = 2; +} diff --git a/NahidaImpact.Protocol/AbilityString.proto b/NahidaImpact.Protocol/AbilityString.proto new file mode 100644 index 0000000..2ce3b57 --- /dev/null +++ b/NahidaImpact.Protocol/AbilityString.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +message AbilityString { + oneof type { + string str = 1; + uint32 hash = 2; + } +} diff --git a/NahidaImpact.Protocol/AbilitySyncStateInfo.proto b/NahidaImpact.Protocol/AbilitySyncStateInfo.proto new file mode 100644 index 0000000..dd61bb6 --- /dev/null +++ b/NahidaImpact.Protocol/AbilitySyncStateInfo.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + + +import "AbilityAppliedAbility.proto"; +import "AbilityMixinRecoverInfo.proto"; +import "AbilityAppliedModifier.proto"; +import "AbilityScalarValueEntry.proto"; + +message AbilitySyncStateInfo { + repeated AbilityMixinRecoverInfo mixin_recover_infos = 5; + repeated AbilityAppliedAbility applied_abilities = 3; + repeated AbilityAppliedModifier applied_modifiers = 4; + repeated AbilityScalarValueEntry sgv_dynamic_value_map = 6; + repeated AbilityScalarValueEntry dynamic_value_map = 2; + bool is_inited = 1; +} diff --git a/NahidaImpact.Protocol/ActivityDungeonAvatar.proto b/NahidaImpact.Protocol/ActivityDungeonAvatar.proto new file mode 100644 index 0000000..93f950a --- /dev/null +++ b/NahidaImpact.Protocol/ActivityDungeonAvatar.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: OILMJMJGMKP +message ActivityDungeonAvatar { + uint32 avatar_id = 1; + bool is_trial = 2; + uint32 costume_id = 3; +} diff --git a/NahidaImpact.Protocol/ActivityInfo.proto b/NahidaImpact.Protocol/ActivityInfo.proto new file mode 100644 index 0000000..a70b3f7 --- /dev/null +++ b/NahidaImpact.Protocol/ActivityInfo.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + + +message ActivityInfo { + bool is_finished = 13; + uint32 activity_id = 7; + uint32 schedule_id = 5; + uint32 begin_time = 6; + uint32 end_time = 12; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/ActivityInfoNotify.proto b/NahidaImpact.Protocol/ActivityInfoNotify.proto new file mode 100644 index 0000000..9505e6a --- /dev/null +++ b/NahidaImpact.Protocol/ActivityInfoNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +import "ActivityInfo.proto"; + +message ActivityInfoNotify { + ActivityInfo activity_info = 1; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/ActivityPushTipsState.proto b/NahidaImpact.Protocol/ActivityPushTipsState.proto new file mode 100644 index 0000000..8df8540 --- /dev/null +++ b/NahidaImpact.Protocol/ActivityPushTipsState.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: DKHCNPIKCHO +enum ActivityPushTipsState { + ACTIVITY_PUSH_TIPS_STATE_NONE = 0; + ACTIVITY_PUSH_TIPS_STATE_START = 1; + ACTIVITY_PUSH_TIPS_STATE_READ = 2; +} diff --git a/NahidaImpact.Protocol/AddBackupAvatarTeamReq.proto b/NahidaImpact.Protocol/AddBackupAvatarTeamReq.proto new file mode 100644 index 0000000..cfffe60 --- /dev/null +++ b/NahidaImpact.Protocol/AddBackupAvatarTeamReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 22083 +// Obf: PDKOLMGNNBP +message AddBackupAvatarTeamReq { +} diff --git a/NahidaImpact.Protocol/AdjustTrackingInfo.proto b/NahidaImpact.Protocol/AdjustTrackingInfo.proto new file mode 100644 index 0000000..ac066f0 --- /dev/null +++ b/NahidaImpact.Protocol/AdjustTrackingInfo.proto @@ -0,0 +1,4 @@ +syntax = "proto3"; + +message AdjustTrackingInfo { +} diff --git a/NahidaImpact.Protocol/AllWidgetBackgroundActiveStateNotify.proto b/NahidaImpact.Protocol/AllWidgetBackgroundActiveStateNotify.proto new file mode 100644 index 0000000..aa849dc --- /dev/null +++ b/NahidaImpact.Protocol/AllWidgetBackgroundActiveStateNotify.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message AllWidgetBackgroundActiveStateNotify { + repeated uint32 background_active_widget_list = 4; +} diff --git a/NahidaImpact.Protocol/AnimatorParameterValueInfo.proto b/NahidaImpact.Protocol/AnimatorParameterValueInfo.proto new file mode 100644 index 0000000..d570dd2 --- /dev/null +++ b/NahidaImpact.Protocol/AnimatorParameterValueInfo.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +message AnimatorParameterValueInfo { + oneof para_val { + int32 int_val = 2; + float float_val = 3; + bool bool_val = 4; + } + uint32 para_type = 1; +} diff --git a/NahidaImpact.Protocol/AnimatorParameterValueInfoPair.proto b/NahidaImpact.Protocol/AnimatorParameterValueInfoPair.proto new file mode 100644 index 0000000..294a4e0 --- /dev/null +++ b/NahidaImpact.Protocol/AnimatorParameterValueInfoPair.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + + +import "AnimatorParameterValueInfo.proto"; + +message AnimatorParameterValueInfoPair { + AnimatorParameterValueInfo animator_para = 2; + int32 name_id = 1; +} diff --git a/NahidaImpact.Protocol/AranaraCollectionState.proto b/NahidaImpact.Protocol/AranaraCollectionState.proto new file mode 100644 index 0000000..b5dfcee --- /dev/null +++ b/NahidaImpact.Protocol/AranaraCollectionState.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: KIGGNJOOMNG +enum AranaraCollectionState { + ARANARA_COLLECTION_STATE_NONE = 0; + ARANARA_COLLECTION_STATE_COLLECTABLE = 1; + ARANARA_COLLECTION_STATE_COLLECTED = 2; + ARANARA_COLLECTION_STATE_FINISHED = 3; +} diff --git a/NahidaImpact.Protocol/AreaPlayType.proto b/NahidaImpact.Protocol/AreaPlayType.proto new file mode 100644 index 0000000..14176f2 --- /dev/null +++ b/NahidaImpact.Protocol/AreaPlayType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: ENDBNJAECJM +enum AreaPlayType { + AREA_PLAY_NONE = 0; + AREA_PLAY_CLIMATE = 1; + AREA_PLAY_REGIONAL_PLAY = 2; +} diff --git a/NahidaImpact.Protocol/AsterLittleStageState.proto b/NahidaImpact.Protocol/AsterLittleStageState.proto new file mode 100644 index 0000000..8ed8991 --- /dev/null +++ b/NahidaImpact.Protocol/AsterLittleStageState.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: BIMHEEHBMPM +enum AsterLittleStageState { + ASTER_LITTLE_STAGE_NONE = 0; + ASTER_LITTLE_STAGE_UNSTARTED = 1; + ASTER_LITTLE_STAGE_STARTED = 2; + ASTER_LITTLE_STAGE_FINISHED = 3; +} diff --git a/NahidaImpact.Protocol/AttackResult.proto b/NahidaImpact.Protocol/AttackResult.proto new file mode 100644 index 0000000..82a3c3e --- /dev/null +++ b/NahidaImpact.Protocol/AttackResult.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +import "Vector.proto"; +import "HitCollision.proto"; +message AttackResult { + Vector resolved_dir = 4; + HitCollision hit_collision = 1; + float damage = 13; + float damage_shield = 1422; //sus + uint32 element_type = 255; + uint32 attacker_id = 6; + uint32 defense_id = 11; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AuditState.proto b/NahidaImpact.Protocol/AuditState.proto new file mode 100644 index 0000000..cd17883 --- /dev/null +++ b/NahidaImpact.Protocol/AuditState.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: MDIBKDBOAAO +enum AuditState { + AUDIT_NONE = 0; + AUDIT_WAITING = 1; + AUDIT_FAILED = 2; +} diff --git a/NahidaImpact.Protocol/AvatarAddNotify.proto b/NahidaImpact.Protocol/AvatarAddNotify.proto new file mode 100644 index 0000000..404bfbc --- /dev/null +++ b/NahidaImpact.Protocol/AvatarAddNotify.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "AvatarInfo.proto"; +// CmdId: 7458 +// Obf: MLOIBCFBPKN +message AvatarAddNotify { + AvatarInfo avatar = 5; + bool is_in_team = 13; +} diff --git a/NahidaImpact.Protocol/AvatarBuffAddNotify.proto b/NahidaImpact.Protocol/AvatarBuffAddNotify.proto new file mode 100644 index 0000000..77afddd --- /dev/null +++ b/NahidaImpact.Protocol/AvatarBuffAddNotify.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// CmdId: 24005 +// Obf: LDBEMEAFJOG +message AvatarBuffAddNotify { + uint64 avatar_guid = 15; + uint32 buff_id = 1; +} diff --git a/NahidaImpact.Protocol/AvatarBuffDelNotify.proto b/NahidaImpact.Protocol/AvatarBuffDelNotify.proto new file mode 100644 index 0000000..2a00a3d --- /dev/null +++ b/NahidaImpact.Protocol/AvatarBuffDelNotify.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// CmdId: 3202 +// Obf: HPKFFICFAKP +message AvatarBuffDelNotify { + uint32 buff_id = 5; + uint64 avatar_guid = 10; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AvatarChangeAnimHashReq.proto b/NahidaImpact.Protocol/AvatarChangeAnimHashReq.proto new file mode 100644 index 0000000..96b993a --- /dev/null +++ b/NahidaImpact.Protocol/AvatarChangeAnimHashReq.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + + +message AvatarChangeAnimHashReq { + uint32 anim_hash = 11; + uint64 avatar_guid = 2; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AvatarChangeAnimHashRsp.proto b/NahidaImpact.Protocol/AvatarChangeAnimHashRsp.proto new file mode 100644 index 0000000..4b2ea00 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarChangeAnimHashRsp.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + + +message AvatarChangeAnimHashRsp { + int32 retcode = 14; + uint32 anim_hash = 4; + uint64 avatar_guid = 15; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AvatarDataNotify.proto b/NahidaImpact.Protocol/AvatarDataNotify.proto new file mode 100644 index 0000000..9980540 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarDataNotify.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + + +import "AvatarTeam.proto"; +import "AvatarInfo.proto"; +import "AvatarRenameInfo.proto"; + +// CMD_ID = 24251 +message AvatarDataNotify { + repeated uint32 owned_costume_list = 15; + repeated uint32 backup_avatar_team_order_list = 10; + map avatar_team_map = 1; + repeated AvatarInfo avatar_list = 9; + repeated AvatarRenameInfo avatar_rename_list = 11; + repeated uint64 temp_avatar_guid_list = 4; + uint32 cur_avatar_team_id = 3; + uint64 choose_avatar_guid = 12; + repeated uint32 owned_flycloak_list = 5; +} diff --git a/NahidaImpact.Protocol/AvatarDieAnimationEndReq.proto b/NahidaImpact.Protocol/AvatarDieAnimationEndReq.proto new file mode 100644 index 0000000..593570b --- /dev/null +++ b/NahidaImpact.Protocol/AvatarDieAnimationEndReq.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +import "Vector.proto"; +// CmdId: 4506 +// Obf: HPOMJHEAICH +message AvatarDieAnimationEndReq { + Vector reborn_pos = 12; + uint32 skill_id = 6; + uint64 die_guid = 5; +} diff --git a/NahidaImpact.Protocol/AvatarDieAnimationEndRsp.proto b/NahidaImpact.Protocol/AvatarDieAnimationEndRsp.proto new file mode 100644 index 0000000..bba0a3e --- /dev/null +++ b/NahidaImpact.Protocol/AvatarDieAnimationEndRsp.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// CmdId: 24745 +// Obf: LPNGCMDGKEM +message AvatarDieAnimationEndRsp { + uint32 skill_id = 9; + int32 retcode = 3; + uint64 die_guid = 6; +} diff --git a/NahidaImpact.Protocol/AvatarEnterSceneInfo.proto b/NahidaImpact.Protocol/AvatarEnterSceneInfo.proto new file mode 100644 index 0000000..f7bc22a --- /dev/null +++ b/NahidaImpact.Protocol/AvatarEnterSceneInfo.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + + +import "AbilitySyncStateInfo.proto"; +import "ServerBuff.proto"; + +message AvatarEnterSceneInfo { + AbilitySyncStateInfo ALOIENEAIFJ = 2; + repeated uint32 buff_id_list = 5; + repeated ServerBuff server_buff_list = 3; + AbilitySyncStateInfo MINMMDAAJOH = 15; + uint32 avatar_entity_id = 11; + uint32 weapon_entity_id = 10; + uint64 avatar_guid = 14; + uint64 weapon_guid = 13; +} + + +//ALOIENEAIFJ MINMMDAAJOH +//avatar_ability_info weapon_ability_info \ No newline at end of file diff --git a/NahidaImpact.Protocol/AvatarEquipAffixInfo.proto b/NahidaImpact.Protocol/AvatarEquipAffixInfo.proto new file mode 100644 index 0000000..eb9107e --- /dev/null +++ b/NahidaImpact.Protocol/AvatarEquipAffixInfo.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message AvatarEquipAffixInfo { + uint32 equip_affix_id = 1; + uint32 left_cd_time = 2; +} diff --git a/NahidaImpact.Protocol/AvatarEquipChangeNotify.proto b/NahidaImpact.Protocol/AvatarEquipChangeNotify.proto new file mode 100644 index 0000000..254f1a7 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarEquipChangeNotify.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +import "SceneWeaponInfo.proto"; +import "SceneReliquaryInfo.proto"; +// CmdId: 20682 +// Obf: GOMNKIGKPAH +message AvatarEquipChangeNotify { + SceneWeaponInfo weapon = 15; + SceneReliquaryInfo reliquary = 7; + uint64 equip_guid = 9; + uint32 equip_type = 3; + uint32 item_id = 1; + uint64 avatar_guid = 11; +} diff --git a/NahidaImpact.Protocol/AvatarExcelInfo.proto b/NahidaImpact.Protocol/AvatarExcelInfo.proto new file mode 100644 index 0000000..bde10d0 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarExcelInfo.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +message AvatarExcelInfo { + uint64 prefab_path_hash = 1; + uint64 combat_config_hash = 5; + uint64 prefab_path_remote_hash = 2; + uint64 controller_path_hash = 3; + uint64 controller_path_remote_hash = 4; +} diff --git a/NahidaImpact.Protocol/AvatarExpeditionAllDataReq.proto b/NahidaImpact.Protocol/AvatarExpeditionAllDataReq.proto new file mode 100644 index 0000000..0d3e370 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarExpeditionAllDataReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 24160 +// Obf: IKHOKBJEAGP +message AvatarExpeditionAllDataReq { +} diff --git a/NahidaImpact.Protocol/AvatarExpeditionInfo.proto b/NahidaImpact.Protocol/AvatarExpeditionInfo.proto new file mode 100644 index 0000000..0fbe442 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarExpeditionInfo.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +import "AvatarExpeditionState.proto"; +// Obf: MBBNGLKDKFD +message AvatarExpeditionInfo { + AvatarExpeditionState state = 1; + uint32 exp_id = 2; + uint32 hour_time = 3; + uint32 start_time = 4; + float shorten_ratio = 5; +} diff --git a/NahidaImpact.Protocol/AvatarExpeditionState.proto b/NahidaImpact.Protocol/AvatarExpeditionState.proto new file mode 100644 index 0000000..2d72d85 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarExpeditionState.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +// Obf: OJBIHADNECN +enum AvatarExpeditionState { + AVATAR_EXPEDITION_NONE = 0; + AVATAR_EXPEDITION_DOING = 1; + AVATAR_EXPEDITION_FINISH_WAIT_REWARD = 2; + AVATAR_EXPEDITION_CALLBACK_WAIT_REWARD = 3; + AVATAR_EXPEDITION_LOCKED = 4; +} diff --git a/NahidaImpact.Protocol/AvatarFetterInfo.proto b/NahidaImpact.Protocol/AvatarFetterInfo.proto new file mode 100644 index 0000000..b9eb978 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarFetterInfo.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + + +import "FetterData.proto"; + +message AvatarFetterInfo { + repeated uint32 finish_id_list = 4; + repeated uint32 rewarded_fetter_level_list = 5; + repeated FetterData fetter_list = 6; + repeated uint32 open_id_list = 3; + uint32 exp_number = 1; + uint32 exp_level = 2; +} diff --git a/NahidaImpact.Protocol/AvatarFightPropNotify.proto b/NahidaImpact.Protocol/AvatarFightPropNotify.proto new file mode 100644 index 0000000..4b38655 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarFightPropNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + + +message AvatarFightPropNotify { + uint64 avatar_guid = 2; + map fight_prop_map = 12; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AvatarFightPropUpdateNotify.proto b/NahidaImpact.Protocol/AvatarFightPropUpdateNotify.proto new file mode 100644 index 0000000..9ef65db --- /dev/null +++ b/NahidaImpact.Protocol/AvatarFightPropUpdateNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + + +message AvatarFightPropUpdateNotify { + uint64 avatar_guid = 5; + map fight_prop_map = 10; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AvatarFlycloakChangeNotify.proto b/NahidaImpact.Protocol/AvatarFlycloakChangeNotify.proto new file mode 100644 index 0000000..dcb0ba3 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarFlycloakChangeNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + + +message AvatarFlycloakChangeNotify { + uint32 flycloak_id = 2; + uint64 avatar_guid = 8; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/AvatarInfo.proto b/NahidaImpact.Protocol/AvatarInfo.proto new file mode 100644 index 0000000..888abb8 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarInfo.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; + + +import "PropValue.proto"; +import "TrialAvatarInfo.proto"; +import "AvatarEquipAffixInfo.proto"; +import "AvatarExcelInfo.proto"; +import "AvatarSkillInfo.proto"; +import "AvatarFetterInfo.proto"; +import "AvatarExpeditionState.proto"; + +message AvatarInfo { + TrialAvatarInfo trial_avatar_info = 9; + AvatarExcelInfo excel_info = 26; + map skill_map = 10; + repeated uint32 inherent_proud_skill_list = 14; + map fight_prop_map = 7; + map skill_level_map = 15; + repeated uint32 team_resonance_list = 20; + map prop_map = 3; + repeated uint64 equip_guid_list = 5; + repeated uint32 talent_id_list = 6; + repeated AvatarEquipAffixInfo equip_affix_list = 22; + map proud_skill_extra_level_map = 17; + repeated uint32 pending_promote_reward_list = 24; + AvatarFetterInfo fetter_info = 12; + uint32 avatar_type = 19; + uint32 anim_hash = 27; + uint32 core_proud_skill_level = 13; + uint64 guid = 2; + uint32 life_state = 4; + uint32 wearing_flycloak_id = 21; + uint32 born_time = 23; + uint32 skill_depot_id = 11; + bool is_focus = 18; + AvatarExpeditionState expedition_state = 16; + uint32 costume_id = 25; + uint32 avatar_id = 1; +} diff --git a/NahidaImpact.Protocol/AvatarLifeStateChangeNotify.proto b/NahidaImpact.Protocol/AvatarLifeStateChangeNotify.proto new file mode 100644 index 0000000..17d843c --- /dev/null +++ b/NahidaImpact.Protocol/AvatarLifeStateChangeNotify.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +import "ServerBuff.proto"; +import "PlayerDieType.proto"; +// CmdId: 22381 +// Obf: ANPPCHBBAGA +message AvatarLifeStateChangeNotify { + //string attack_tag = null + //repeated ServerBuff server_buff_list = null + uint32 life_state = 14; + uint32 source_entity_id = 13; + uint64 avatar_guid = 6; + PlayerDieType die_type = 7; + uint32 move_reliable_seq = 2; +} diff --git a/NahidaImpact.Protocol/AvatarRenameInfo.proto b/NahidaImpact.Protocol/AvatarRenameInfo.proto new file mode 100644 index 0000000..4a74345 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarRenameInfo.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message AvatarRenameInfo { + string avatar_name = 15; + uint32 avatar_id = 13; +} diff --git a/NahidaImpact.Protocol/AvatarSkillInfo.proto b/NahidaImpact.Protocol/AvatarSkillInfo.proto new file mode 100644 index 0000000..0231bec --- /dev/null +++ b/NahidaImpact.Protocol/AvatarSkillInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message AvatarSkillInfo { + repeated uint32 full_cd_time_list = 2; + uint32 max_charge_count = 3; + uint32 pass_cd_time = 1; +} diff --git a/NahidaImpact.Protocol/AvatarTeam.proto b/NahidaImpact.Protocol/AvatarTeam.proto new file mode 100644 index 0000000..6748e43 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarTeam.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message AvatarTeam { + repeated uint64 avatar_guid_list = 9; + string team_name = 4; +} diff --git a/NahidaImpact.Protocol/AvatarTeamUpdateNotify.proto b/NahidaImpact.Protocol/AvatarTeamUpdateNotify.proto new file mode 100644 index 0000000..507ccbf --- /dev/null +++ b/NahidaImpact.Protocol/AvatarTeamUpdateNotify.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +import "AvatarTeam.proto"; + +message AvatarTeamUpdateNotify { + repeated uint64 temp_avatar_guid_list = 6; + map avatar_team_map = 7; +} diff --git a/NahidaImpact.Protocol/AvatarType.proto b/NahidaImpact.Protocol/AvatarType.proto new file mode 100644 index 0000000..163782f --- /dev/null +++ b/NahidaImpact.Protocol/AvatarType.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: OPLFNKHAOBP +enum AvatarType { + AVATAR_TYPE_NONE = 0; + AVATAR_TYPE_FORMAL = 1; + AVATAR_TYPE_TRIAL = 2; + AVATAR_TYPE_MIRROR = 3; +} diff --git a/NahidaImpact.Protocol/AvatarWearFlycloakReq.proto b/NahidaImpact.Protocol/AvatarWearFlycloakReq.proto new file mode 100644 index 0000000..ecbd5e6 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarWearFlycloakReq.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// CmdId: 824 +// Obf: LNDKKJJEFBJ +message AvatarWearFlycloakReq { + uint32 flycloak_id = 10; + uint64 avatar_guid = 12; +} diff --git a/NahidaImpact.Protocol/AvatarWearFlycloakRsp.proto b/NahidaImpact.Protocol/AvatarWearFlycloakRsp.proto new file mode 100644 index 0000000..18ac782 --- /dev/null +++ b/NahidaImpact.Protocol/AvatarWearFlycloakRsp.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + + +message AvatarWearFlycloakRsp { + uint64 avatar_guid = 1; + uint32 flycloak_id = 4; + int32 retcode = 12; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/BackMyWorldReq.proto b/NahidaImpact.Protocol/BackMyWorldReq.proto new file mode 100644 index 0000000..0fbb56e --- /dev/null +++ b/NahidaImpact.Protocol/BackMyWorldReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 7284 +// Obf: KMDLHONLMJH +message BackMyWorldReq { +} diff --git a/NahidaImpact.Protocol/BargainResultType.proto b/NahidaImpact.Protocol/BargainResultType.proto new file mode 100644 index 0000000..b19530d --- /dev/null +++ b/NahidaImpact.Protocol/BargainResultType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: AGEMDFOGNBD +enum BargainResultType { + BARGAIN_COMPLETE_SUCC = 0; + BARGAIN_SINGLE_FAIL = 1; + BARGAIN_COMPLETE_FAIL = 2; +} diff --git a/NahidaImpact.Protocol/BattlePassUnlockStatus.proto b/NahidaImpact.Protocol/BattlePassUnlockStatus.proto new file mode 100644 index 0000000..74d5957 --- /dev/null +++ b/NahidaImpact.Protocol/BattlePassUnlockStatus.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: ANLKFPJIOMK +enum BattlePassUnlockStatus { + BATTLE_PASS_UNLOCK_STATUS_INVALID = 0; + BATTLE_PASS_UNLOCK_STATUS_FREE = 1; + BATTLE_PASS_UNLOCK_STATUS_PAID = 2; +} diff --git a/NahidaImpact.Protocol/Birthday.proto b/NahidaImpact.Protocol/Birthday.proto new file mode 100644 index 0000000..ebab9b0 --- /dev/null +++ b/NahidaImpact.Protocol/Birthday.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + + + + +message Birthday { + uint32 month = 1; + uint32 day = 2; +} diff --git a/NahidaImpact.Protocol/BlessingAcceptAllGivePicReq.proto b/NahidaImpact.Protocol/BlessingAcceptAllGivePicReq.proto new file mode 100644 index 0000000..b47ce02 --- /dev/null +++ b/NahidaImpact.Protocol/BlessingAcceptAllGivePicReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 4716 +// Obf: FOKBCAHPCKM +message BlessingAcceptAllGivePicReq { +} diff --git a/NahidaImpact.Protocol/BlessingGetAllRecvPicRecordListReq.proto b/NahidaImpact.Protocol/BlessingGetAllRecvPicRecordListReq.proto new file mode 100644 index 0000000..223651c --- /dev/null +++ b/NahidaImpact.Protocol/BlessingGetAllRecvPicRecordListReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 22820 +// Obf: EDJKPCNNFJC +message BlessingGetAllRecvPicRecordListReq { +} diff --git a/NahidaImpact.Protocol/BlessingGetFriendPicListReq.proto b/NahidaImpact.Protocol/BlessingGetFriendPicListReq.proto new file mode 100644 index 0000000..a84d70e --- /dev/null +++ b/NahidaImpact.Protocol/BlessingGetFriendPicListReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 26732 +// Obf: LCFNMJDCOLF +message BlessingGetFriendPicListReq { +} diff --git a/NahidaImpact.Protocol/BlessingRedeemRewardReq.proto b/NahidaImpact.Protocol/BlessingRedeemRewardReq.proto new file mode 100644 index 0000000..3a4d9a9 --- /dev/null +++ b/NahidaImpact.Protocol/BlessingRedeemRewardReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 5045 +// Obf: OGBCGJIDGOF +message BlessingRedeemRewardReq { +} diff --git a/NahidaImpact.Protocol/BlockInfo.proto b/NahidaImpact.Protocol/BlockInfo.proto new file mode 100644 index 0000000..92f9584 --- /dev/null +++ b/NahidaImpact.Protocol/BlockInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +message BlockInfo { + bytes bin_data = 3; + uint32 data_version = 2; + uint32 block_id = 1; + bool is_dirty = 4; +} diff --git a/NahidaImpact.Protocol/BlossomChestInfo.proto b/NahidaImpact.Protocol/BlossomChestInfo.proto new file mode 100644 index 0000000..fef7259 --- /dev/null +++ b/NahidaImpact.Protocol/BlossomChestInfo.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +message BlossomChestInfo { + repeated uint32 qualify_uid_list = 2; + repeated uint32 remain_uid_list = 3; + uint32 resin = 1; + uint32 dead_time = 4; + uint32 blossom_refresh_type = 5; + uint32 refresh_id = 6; +} diff --git a/NahidaImpact.Protocol/BonusActivityInfoReq.proto b/NahidaImpact.Protocol/BonusActivityInfoReq.proto new file mode 100644 index 0000000..79780b0 --- /dev/null +++ b/NahidaImpact.Protocol/BonusActivityInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 29984 +// Obf: CGGHGPPCGON +message BonusActivityInfoReq { +} diff --git a/NahidaImpact.Protocol/BossChestInfo.proto b/NahidaImpact.Protocol/BossChestInfo.proto new file mode 100644 index 0000000..d8849eb --- /dev/null +++ b/NahidaImpact.Protocol/BossChestInfo.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + + +import "WeeklyBossResinDiscountInfo.proto"; + +message BossChestInfo { + repeated uint32 remain_uid_list = 3; + repeated uint32 qualify_uid_list = 4; + map uid_discount_map = 5; + uint32 resin = 2; + uint32 monster_config_id = 1; +} diff --git a/NahidaImpact.Protocol/BreakoutAction.proto b/NahidaImpact.Protocol/BreakoutAction.proto new file mode 100644 index 0000000..7740f4e --- /dev/null +++ b/NahidaImpact.Protocol/BreakoutAction.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + + +import "BreakoutVector2.proto"; + +message BreakoutAction { + enum BreakoutActionType { + BREAKOUT_ACTION_TYPE_NONE = 0; + BREAKOUT_ACTION_TYPE_LAUNCH_BALL = 1; + BREAKOUT_ACTION_TYPE_DESTROY_BALL = 2; + BREAKOUT_ACTION_TYPE_FALLING_OBJECT = 3; + BREAKOUT_ACTION_TYPE_MISSILE = 4; + } + BreakoutVector2 pos = 7; + BreakoutVector2 extra_ball_dir = 15; + BreakoutVector2 move_dir = 8; + bool has_extra_ball = 14; + bool is_failed = 4; + int32 offset = 17; + int32 speed = 9; + uint32 peer_id = 10; + uint32 pre_index = 5; + BreakoutActionType action_type = 1; + uint32 element_reaction_buff = 12; + uint32 new_index = 6; + uint32 speed_increase_count = 13; + uint32 element_type = 11; + uint32 extra_ball_index = 16; + uint64 client_game_time = 2; + uint64 server_game_time = 3; +} diff --git a/NahidaImpact.Protocol/BreakoutBrickInfo.proto b/NahidaImpact.Protocol/BreakoutBrickInfo.proto new file mode 100644 index 0000000..7cf6e03 --- /dev/null +++ b/NahidaImpact.Protocol/BreakoutBrickInfo.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message BreakoutBrickInfo { + uint32 element_type = 2; + uint32 hp = 1; +} diff --git a/NahidaImpact.Protocol/BreakoutElementReactionCounter.proto b/NahidaImpact.Protocol/BreakoutElementReactionCounter.proto new file mode 100644 index 0000000..ff95722 --- /dev/null +++ b/NahidaImpact.Protocol/BreakoutElementReactionCounter.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message BreakoutElementReactionCounter { + uint32 element_reaction = 1; + uint32 count = 2; +} diff --git a/NahidaImpact.Protocol/BreakoutPhysicalObject.proto b/NahidaImpact.Protocol/BreakoutPhysicalObject.proto new file mode 100644 index 0000000..971ab87 --- /dev/null +++ b/NahidaImpact.Protocol/BreakoutPhysicalObject.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + + +import "BreakoutPhysicalObjectModifier.proto"; +import "BreakoutBrickInfo.proto"; +import "BreakoutVector2.proto"; + +message BreakoutPhysicalObject { + repeated BreakoutPhysicalObjectModifier modifier_list = 11; + repeated BreakoutBrickInfo info_list = 13; + BreakoutVector2 pos = 4; + BreakoutVector2 move_dir = 5; + uint32 state = 8; + uint32 init_peer_id = 7; + uint32 speed_increase_count = 15; + uint32 index = 2; + uint32 element_type = 9; + bool is_active = 3; + uint32 last_hit_peer_id = 14; + int32 offset = 16; + int32 total_rotation = 12; + uint32 element_reaction_buff = 10; + int32 speed = 6; + uint32 id = 1; +} diff --git a/NahidaImpact.Protocol/BreakoutPhysicalObjectModifier.proto b/NahidaImpact.Protocol/BreakoutPhysicalObjectModifier.proto new file mode 100644 index 0000000..e806739 --- /dev/null +++ b/NahidaImpact.Protocol/BreakoutPhysicalObjectModifier.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +message BreakoutPhysicalObjectModifier { + uint32 type = 1; + uint32 choose_player_count = 16; + int32 param3 = 5; + uint32 id = 2; + int32 param4 = 6; + int32 param5 = 7; + int32 duration = 10; + int32 end_time = 11; + uint32 peer_id = 13; + int32 param6 = 8; + uint32 level = 15; + uint32 skill_type = 14; + bool bool1 = 9; + int32 param2 = 4; + uint32 combo = 12; + int32 param1 = 3; +} diff --git a/NahidaImpact.Protocol/BreakoutSnapShot.proto b/NahidaImpact.Protocol/BreakoutSnapShot.proto new file mode 100644 index 0000000..5b2ff7f --- /dev/null +++ b/NahidaImpact.Protocol/BreakoutSnapShot.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + + +import "BreakoutAction.proto"; +import "BreakoutPhysicalObject.proto"; +import "BreakoutSyncConnectUidInfo.proto"; +import "BreakoutElementReactionCounter.proto"; +import "BreakoutSpawnPoint.proto"; + +message BreakoutSnapShot { + repeated BreakoutAction action_list = 5; + repeated BreakoutPhysicalObject physical_object_list = 4; + repeated BreakoutPhysicalObject dynamic_object_list = 18; + repeated BreakoutPhysicalObject ball_list = 3; + repeated BreakoutSyncConnectUidInfo uid_info_list = 17; + repeated BreakoutElementReactionCounter ball_element_reaction_list = 16; + repeated BreakoutElementReactionCounter brick_element_reaction_list = 15; + repeated uint32 id_index_list = 19; + repeated BreakoutSpawnPoint spawn_point_list = 13; + int32 raw_client_game_time = 20; + uint32 remaining_boss_hp = 14; + uint64 server_game_time = 2; + uint32 wave_suite_index = 12; + uint32 wave_index = 6; + uint32 max_combo = 10; + bool is_finish = 7; + uint64 client_game_time = 1; + uint32 score = 8; + uint32 combo = 9; + uint32 life_count = 11; +} diff --git a/NahidaImpact.Protocol/BreakoutSpawnPoint.proto b/NahidaImpact.Protocol/BreakoutSpawnPoint.proto new file mode 100644 index 0000000..cb9bf74 --- /dev/null +++ b/NahidaImpact.Protocol/BreakoutSpawnPoint.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + + +import "BreakoutPhysicalObject.proto"; + +message BreakoutSpawnPoint { + repeated BreakoutPhysicalObject spawned_brick_list = 3; + uint32 brick_suite_id = 2; + uint32 id = 1; +} diff --git a/NahidaImpact.Protocol/BreakoutSyncConnectUidInfo.proto b/NahidaImpact.Protocol/BreakoutSyncConnectUidInfo.proto new file mode 100644 index 0000000..e059ce3 --- /dev/null +++ b/NahidaImpact.Protocol/BreakoutSyncConnectUidInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message BreakoutSyncConnectUidInfo { + repeated uint32 skill_id_list = 2; + repeated uint32 skill_level_list = 3; + uint32 uid = 1; +} diff --git a/NahidaImpact.Protocol/BreakoutVector2.proto b/NahidaImpact.Protocol/BreakoutVector2.proto new file mode 100644 index 0000000..3a82515 --- /dev/null +++ b/NahidaImpact.Protocol/BreakoutVector2.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message BreakoutVector2 { + int32 x = 1; + int32 y = 2; +} diff --git a/NahidaImpact.Protocol/BrickBreakerQuitReq.proto b/NahidaImpact.Protocol/BrickBreakerQuitReq.proto new file mode 100644 index 0000000..2fc225e --- /dev/null +++ b/NahidaImpact.Protocol/BrickBreakerQuitReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 2184 +// Obf: FAGOMNKEJHG +message BrickBreakerQuitReq { +} diff --git a/NahidaImpact.Protocol/BrickBreakerSetReadyReq.proto b/NahidaImpact.Protocol/BrickBreakerSetReadyReq.proto new file mode 100644 index 0000000..e59a7ea --- /dev/null +++ b/NahidaImpact.Protocol/BrickBreakerSetReadyReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 3864 +// Obf: LMKDFOBJHKN +message BrickBreakerSetReadyReq { +} diff --git a/NahidaImpact.Protocol/BrickBreakerStageType.proto b/NahidaImpact.Protocol/BrickBreakerStageType.proto new file mode 100644 index 0000000..7b96e5e --- /dev/null +++ b/NahidaImpact.Protocol/BrickBreakerStageType.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +// Obf: EDEDAHIPILO +enum BrickBreakerStageType { + BRICK_BREAKER_STAGE_PREPARE = 0; + BRICK_BREAKER_STAGE_PICK = 1; + BRICK_BREAKER_STAGE_GAME = 2; + BRICK_BREAKER_STAGE_PLAY = 3; + BRICK_BREAKER_STAGE_SETTLE = 4; +} diff --git a/NahidaImpact.Protocol/BrickBreakerTwiceStartReq.proto b/NahidaImpact.Protocol/BrickBreakerTwiceStartReq.proto new file mode 100644 index 0000000..db3a9bc --- /dev/null +++ b/NahidaImpact.Protocol/BrickBreakerTwiceStartReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 7000 +// Obf: EBCGDCALGJI +message BrickBreakerTwiceStartReq { +} diff --git a/NahidaImpact.Protocol/BuyResinReq.proto b/NahidaImpact.Protocol/BuyResinReq.proto new file mode 100644 index 0000000..e2035e8 --- /dev/null +++ b/NahidaImpact.Protocol/BuyResinReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 9368 +// Obf: CJKAMIJPOHL +message BuyResinReq { +} diff --git a/NahidaImpact.Protocol/ChallengeFinishType.proto b/NahidaImpact.Protocol/ChallengeFinishType.proto new file mode 100644 index 0000000..96eea11 --- /dev/null +++ b/NahidaImpact.Protocol/ChallengeFinishType.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: KKEOIBNCMCK +enum ChallengeFinishType { + CHALLENGE_FINISH_TYPE_NONE = 0; + CHALLENGE_FINISH_TYPE_FAIL = 1; + CHALLENGE_FINISH_TYPE_SUCC = 2; + CHALLENGE_FINISH_TYPE_PAUSE = 3; +} diff --git a/NahidaImpact.Protocol/ChangeAvatarReq.proto b/NahidaImpact.Protocol/ChangeAvatarReq.proto new file mode 100644 index 0000000..29645e7 --- /dev/null +++ b/NahidaImpact.Protocol/ChangeAvatarReq.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + + +import "Vector.proto"; + + +message ChangeAvatarReq { + Vector move_pos = 1; + bool is_move = 5; + uint64 guid = 8; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/ChangeAvatarRsp.proto b/NahidaImpact.Protocol/ChangeAvatarRsp.proto new file mode 100644 index 0000000..9ad3d63 --- /dev/null +++ b/NahidaImpact.Protocol/ChangeAvatarRsp.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + + +message ChangeAvatarRsp { + int32 retcode = 10; + uint64 cur_guid = 11; + uint32 skill_id = 14; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/ChangeEnergyReason.proto b/NahidaImpact.Protocol/ChangeEnergyReason.proto new file mode 100644 index 0000000..6127184 --- /dev/null +++ b/NahidaImpact.Protocol/ChangeEnergyReason.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + + + +enum ChangeEnergyReason { + CHANGE_ENERGY_REASON_NONE = 0; + CHANGE_ENERGY_REASON_SKILL_START = 1; +} diff --git a/NahidaImpact.Protocol/ChangeHpDebts.proto b/NahidaImpact.Protocol/ChangeHpDebts.proto new file mode 100644 index 0000000..76bd9ef --- /dev/null +++ b/NahidaImpact.Protocol/ChangeHpDebts.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +enum ChangeHpDebts { + CHANGE_HP_DEBTS_NONE = 0; + CHANGE_HP_DEBTS_PAY = 1; + CHANGE_HP_DEBTS_PAYFINISH = 2; + CHANGE_HP_DEBTS_CLEAR = 21; + CHANGE_HP_DEBTS_ADDABILiTY = 51; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/ChangeHpReason.proto b/NahidaImpact.Protocol/ChangeHpReason.proto new file mode 100644 index 0000000..06e027a --- /dev/null +++ b/NahidaImpact.Protocol/ChangeHpReason.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; + + +enum ChangeHpReason { + CHANGE_HP_REASON_NONE = 0; + CHANGE_HP_REASON_SUB_AVATAR = 1; + CHANGE_HP_REASON_SUB_MONSTER = 2; + CHANGE_HP_REASON_SUB_GEAR = 3; + CHANGE_HP_REASON_SUB_ENVIR = 4; + CHANGE_HP_REASON_SUB_FALL = 5; + CHANGE_HP_REASON_SUB_DRAWN = 6; + CHANGE_HP_REASON_SUB_ABYSS = 7; + CHANGE_HP_REASON_SUB_ABILITY = 8; + CHANGE_HP_REASON_SUB_SUMMON = 9; + CHANGE_HP_REASON_SUB_SCRIPT = 10; + CHANGE_HP_REASON_SUB_GM = 11; + CHANGE_HP_REASON_SUB_KILL_SELF = 12; + CHANGE_HP_REASON_SUB_CLIMATE_COLD = 13; + CHANGE_HP_REASON_SUB_STORM_LIGHTNING = 14; + CHANGE_HP_REASON_SUB_KILL_SERVER_GADGET = 15; + CHANGE_HP_REASON_SUB_REPLACE = 16; + CHANGE_HP_REASON_SUB_PLAYER_LEAVE = 17; + CHANGE_HP_REASON_ATTACK_BY_ENERGY = 18; + CHANGE_HP_REASON_ATTACK_BY_RECYCLE = 19; + CHANGE_HP_REASON_SUB_PLAYER_BACK = 20; + CHANGE_HP_REASON_SUB_UGC = 21; + CHANGE_HP_REASON_BY_LUA = 51; + CHANGE_HP_REASON_ADD_ABILITY = 101; + CHANGE_HP_REASON_ADD_ITEM = 102; + CHANGE_HP_REASON_ADD_REVIVE = 103; + CHANGE_HP_REASON_ADD_UPGRADE = 104; + CHANGE_HP_REASON_ADD_STATUE = 105; + CHANGE_HP_REASON_ADD_BACKGROUND = 106; + CHANGE_HP_REASON_ADD_GM = 107; + CHANGE_HP_REASON_ADD_TRIAL_AVATAR_ACTIVITY = 108; + CHANGE_HP_REASON_ADD_ROGUELIKE_SPRING = 109; +} diff --git a/NahidaImpact.Protocol/ChangeServerGlobalValueNotify.proto b/NahidaImpact.Protocol/ChangeServerGlobalValueNotify.proto new file mode 100644 index 0000000..9f70ffb --- /dev/null +++ b/NahidaImpact.Protocol/ChangeServerGlobalValueNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// CmdId: 2846 +// Obf: APEIENAMMJC +message ChangeServerGlobalValueNotify { + uint32 entity_id = 9; +} diff --git a/NahidaImpact.Protocol/ChangeWidgetBackgroundActiveStateReq.proto b/NahidaImpact.Protocol/ChangeWidgetBackgroundActiveStateReq.proto new file mode 100644 index 0000000..92495cf --- /dev/null +++ b/NahidaImpact.Protocol/ChangeWidgetBackgroundActiveStateReq.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + + + + +message ChangeWidgetBackgroundActiveStateReq { + bool is_active = 1; + uint32 material_id = 15; +} diff --git a/NahidaImpact.Protocol/ChangeWidgetBackgroundActiveStateRsp.proto b/NahidaImpact.Protocol/ChangeWidgetBackgroundActiveStateRsp.proto new file mode 100644 index 0000000..49f10f1 --- /dev/null +++ b/NahidaImpact.Protocol/ChangeWidgetBackgroundActiveStateRsp.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + + + +message ChangeWidgetBackgroundActiveStateRsp { + int32 retcode = 9; + uint32 material_id = 8; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/ChangeWorldToSingleModeNotify.proto b/NahidaImpact.Protocol/ChangeWorldToSingleModeNotify.proto new file mode 100644 index 0000000..0e97016 --- /dev/null +++ b/NahidaImpact.Protocol/ChangeWorldToSingleModeNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 24701 +// Obf: PGFINJBAJOF +message ChangeWorldToSingleModeNotify { +} diff --git a/NahidaImpact.Protocol/ChangeWorldToSingleModeReq.proto b/NahidaImpact.Protocol/ChangeWorldToSingleModeReq.proto new file mode 100644 index 0000000..a4bc5e7 --- /dev/null +++ b/NahidaImpact.Protocol/ChangeWorldToSingleModeReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 23683 +// Obf: DBLNBBNCINO +message ChangeWorldToSingleModeReq { +} diff --git a/NahidaImpact.Protocol/ChannellerSlabCheckEnterLoopDungeonReq.proto b/NahidaImpact.Protocol/ChannellerSlabCheckEnterLoopDungeonReq.proto new file mode 100644 index 0000000..d9e5d80 --- /dev/null +++ b/NahidaImpact.Protocol/ChannellerSlabCheckEnterLoopDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 386 +// Obf: LIIECEBDGNJ +message ChannellerSlabCheckEnterLoopDungeonReq { +} diff --git a/NahidaImpact.Protocol/ChannellerSlabOneOffDungeonInfoReq.proto b/NahidaImpact.Protocol/ChannellerSlabOneOffDungeonInfoReq.proto new file mode 100644 index 0000000..f0d95b3 --- /dev/null +++ b/NahidaImpact.Protocol/ChannellerSlabOneOffDungeonInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 26360 +// Obf: EDKOBFIEMAG +message ChannellerSlabOneOffDungeonInfoReq { +} diff --git a/NahidaImpact.Protocol/ChapterState.proto b/NahidaImpact.Protocol/ChapterState.proto new file mode 100644 index 0000000..722b703 --- /dev/null +++ b/NahidaImpact.Protocol/ChapterState.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: IGBMFOLFJLJ +enum ChapterState { + CHAPTER_STATE_INVALID = 0; + CHAPTER_STATE_UNABLE_TO_BEGIN = 1; + CHAPTER_STATE_BEGIN = 2; + CHAPTER_STATE_END = 3; +} diff --git a/NahidaImpact.Protocol/ChatChannelInfo.proto b/NahidaImpact.Protocol/ChatChannelInfo.proto new file mode 100644 index 0000000..50707b8 --- /dev/null +++ b/NahidaImpact.Protocol/ChatChannelInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: KDHDHJBABKP +message ChatChannelInfo { + uint32 channel_id = 6; + bool is_shield = 9; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/ChatInfo.proto b/NahidaImpact.Protocol/ChatInfo.proto new file mode 100644 index 0000000..b7a072b --- /dev/null +++ b/NahidaImpact.Protocol/ChatInfo.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + + + + +message ChatInfo { + message SystemHint { + uint32 type = 9; + } + + uint32 time = 7; + uint32 to_uid = 6; + bool is_read = 4; + uint32 uid = 5; + uint32 sequence = 12; + oneof content { + string text = 408; + uint32 icon = 1308; + SystemHint system_hint = 166; + } +} diff --git a/NahidaImpact.Protocol/CheckUgcStateReq.proto b/NahidaImpact.Protocol/CheckUgcStateReq.proto new file mode 100644 index 0000000..321fcdc --- /dev/null +++ b/NahidaImpact.Protocol/CheckUgcStateReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 3955 +// Obf: HAIPIFGOHHJ +message CheckUgcStateReq { +} diff --git a/NahidaImpact.Protocol/ChessManualRefreshCardsReq.proto b/NahidaImpact.Protocol/ChessManualRefreshCardsReq.proto new file mode 100644 index 0000000..f6eb9b3 --- /dev/null +++ b/NahidaImpact.Protocol/ChessManualRefreshCardsReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 9762 +// Obf: HEDEBDIHKAP +message ChessManualRefreshCardsReq { +} diff --git a/NahidaImpact.Protocol/CityInfo.proto b/NahidaImpact.Protocol/CityInfo.proto new file mode 100644 index 0000000..a27f222 --- /dev/null +++ b/NahidaImpact.Protocol/CityInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: ADHJGFHHPLP +message CityInfo { + uint32 city_id = 3; + uint32 level = 9; + uint32 crystal_num = 10; +} diff --git a/NahidaImpact.Protocol/ClientBulletCreateNotify.proto b/NahidaImpact.Protocol/ClientBulletCreateNotify.proto new file mode 100644 index 0000000..4c776e7 --- /dev/null +++ b/NahidaImpact.Protocol/ClientBulletCreateNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// CmdId: 4966 +// Obf: GPOBOMCCOMK +message ClientBulletCreateNotify { + uint32 param = 9; +} diff --git a/NahidaImpact.Protocol/ClientGadgetInfo.proto b/NahidaImpact.Protocol/ClientGadgetInfo.proto new file mode 100644 index 0000000..2f22ad7 --- /dev/null +++ b/NahidaImpact.Protocol/ClientGadgetInfo.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +message ClientGadgetInfo { + repeated uint32 target_lock_point_index_list = 9; + repeated uint32 target_entity_id_list = 8; + uint64 guid = 3; + uint32 camp_type = 2; + uint32 owner_entity_id = 4; + bool is_peer_id_from_player = 7; + bool async_load = 6; + uint32 target_entity_id = 5; + uint32 camp_id = 1; +} diff --git a/NahidaImpact.Protocol/ClientInputType.proto b/NahidaImpact.Protocol/ClientInputType.proto new file mode 100644 index 0000000..8126f36 --- /dev/null +++ b/NahidaImpact.Protocol/ClientInputType.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: NIHDBIEPBGP +enum ClientInputType { + CLIENT_INPUT_NONE = 0; + CLIENT_INPUT_KEYBORD_MOUSE = 1; + CLIENT_INPUT_GAMEPAD = 2; + CLIENT_INPUT_TOUCH_PANEL = 3; +} diff --git a/NahidaImpact.Protocol/ClientMassiveEntity.proto b/NahidaImpact.Protocol/ClientMassiveEntity.proto new file mode 100644 index 0000000..9dfe3e3 --- /dev/null +++ b/NahidaImpact.Protocol/ClientMassiveEntity.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +import "MassiveWaterInfo.proto"; +import "MassiveGrassInfo.proto"; +import "MassiveBoxInfo.proto"; +// Obf: LPCNMINODMN +message ClientMassiveEntity { + uint32 entity_type = 1; + uint32 config_id = 2; + int64 obj_id = 3; + oneof entity_info { + MassiveWaterInfo water_info = 4; + MassiveGrassInfo grass_info = 5; + MassiveBoxInfo box_info = 6; + } +} diff --git a/NahidaImpact.Protocol/ClientReconnectReason.proto b/NahidaImpact.Protocol/ClientReconnectReason.proto new file mode 100644 index 0000000..3dcbd6a --- /dev/null +++ b/NahidaImpact.Protocol/ClientReconnectReason.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: BKNDPKGIHLP +enum ClientReconnectReason { + CLIENT_RECONNNECT_NONE = 0; + CLIENT_RECONNNECT_QUIT_MP = 1; +} diff --git a/NahidaImpact.Protocol/CloseCommonTipsNotify.proto b/NahidaImpact.Protocol/CloseCommonTipsNotify.proto new file mode 100644 index 0000000..84680ca --- /dev/null +++ b/NahidaImpact.Protocol/CloseCommonTipsNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 27695 +// Obf: DGCCDLAPKBE +message CloseCommonTipsNotify { +} diff --git a/NahidaImpact.Protocol/CmdType.cs b/NahidaImpact.Protocol/CmdType.cs new file mode 100644 index 0000000..b3863c7 --- /dev/null +++ b/NahidaImpact.Protocol/CmdType.cs @@ -0,0 +1,2601 @@ +namespace NahidaImpact.Protocol; +public enum CmdType +{ + AbilityInvocationFixedNotify = 24213, + AbilityInvocationsNotify = 27059, + ClientAbilityInitBeginNotify = 3313, + ClientAbilityInitFinishNotify = 4338, + AbilityInvocationFailNotify = 26198, + ClientAbilitiesInitFinishCombineNotify = 29849, + WindSeedClientNotify = 25062, + AbilityChangeNotify = 27899, + ClientAbilityChangeNotify = 25166, + ServerUpdateGlobalValueNotify = 7478, + ServerGlobalValueChangeNotify = 727, + ClientAIStateNotify = 8537, + ServerCombatEndNotify = 23099, + ClientRemoveCombatEndModifierNotify = 26928, + PerformOperationNotify = 6266, + AchievementAllDataNotify = 28301, + AchievementUpdateNotify = 2700, + TakeAchievementRewardReq = 1426, + TakeAchievementRewardRsp = 1432, + TakeAchievementGoalRewardReq = 2196, + TakeAchievementGoalRewardRsp = 3006, + GetActivityScheduleReq = 5277, + GetActivityScheduleRsp = 2456, + GetActivityInfoReq = 9732, + GetActivityInfoRsp = 9769, + ActivityPlayOpenAnimNotify = 1342, + ActivityInfoNotify = 20475, + ActivityScheduleInfoNotify = 27146, + ActivityTakeWatcherRewardReq = 27571, + ActivityTakeWatcherRewardRsp = 24030, + ActivityUpdateWatcherNotify = 25876, + ActivitySelectAvatarCardReq = 20267, + ActivitySelectAvatarCardRsp = 22748, + ActivityCoinInfoNotify = 3462, + SeaLampFlyLampReq = 29439, + SeaLampFlyLampRsp = 6420, + SeaLampTakeContributionRewardReq = 4670, + SeaLampTakeContributionRewardRsp = 9237, + SeaLampTakePhaseRewardReq = 6203, + SeaLampTakePhaseRewardRsp = 20819, + SeaLampContributeItemReq = 29203, + SeaLampContributeItemRsp = 24564, + SeaLampFlyLampNotify = 28944, + SeaLampCoinNotify = 6893, + SeaLampPopularityNotify = 2445, + LoadActivityTerrainNotify = 27304, + ServerAnnounceNotify = 29940, + ServerAnnounceRevokeNotify = 1586, + ActivityBannerNotify = 29278, + ActivityBannerClearReq = 20478, + ActivityBannerClearRsp = 28464, + SalesmanDeliverItemReq = 28548, + SalesmanDeliverItemRsp = 23775, + SalesmanTakeRewardReq = 6606, + SalesmanTakeRewardRsp = 28788, + ActivityCondStateChangeNotify = 26830, + SalesmanTakeSpecialRewardReq = 9088, + SalesmanTakeSpecialRewardRsp = 29674, + GetAuthSalesmanInfoReq = 4773, + GetAuthSalesmanInfoRsp = 5645, + DLHDKLNGABH = 28765, + ABFEDMMCOHI = 28405, + NMICOCDALCJ = 22840, + CKPBBBBPOPL = 24984, + CBGIIDHPBGH = 24821, + PDLBGDLIMKI = 25767, + NEHHPKHNKHM = 26061, + ICFNHEEPKIE = 2219, + DKGPJMJIJBG = 9685, + HEBJOGOIBFO = 3728, + EPGMPDBMINK = 28473, + JGOEKGKKBED = 21292, + DFAKNLNPHHD = 1056, + GLKNABIILKM = 20173, + OHCANKJNFPJ = 28607, + DDHGCIDDOIG = 7863, + LFJNOAAIBAN = 3568, + LIEDJLDDLPD = 21308, + EKODODFJCDC = 28247, + CLALDIENALB = 6808, + MLLONLMAIGL = 2902, + IMPHIEOGDAH = 8582, + IJHOPFODNGN = 22644, + PHEMBJPPNCP = 27619, + LAGGNMNAGON = 24198, + LPCEPFMFDPF = 24967, + DNFLMAKCFHN = 25522, + HDMOAPFPEKL = 21659, + OHHKABMPDCC = 26381, + JBAECNDFHFD = 4089, + NOOHFOKENKL = 27115, + OOODAHCDFFD = 29163, + ALILCNKEFLI = 25006, + COJNHGNEFCL = 20594, + LFEHHPCFKMA = 5521, + PDFDNCDDNAA = 22771, + DMHNKDDFJIN = 22494, + OMJCDDMJCEJ = 24100, + ONBOGCLHKBG = 5806, + FCGLNNCIOPH = 21815, + GLOBCEPEMHN = 20578, + NFBNELEBEAJ = 4938, + ACGFHPLJGCI = 1131, + BELFLJJJOLE = 27067, + HLMCHLFIPGC = 380, + DHDMNBLFKJM = 5183, + OEHOHLIICFD = 4021, + LDABKJPFGCB = 26113, + BNMMHJFMMFC = 6318, + BBNBIIHGDAA = 27618, + DHOMBDGLCHG = 24317, + OBLACAGENJC = 1348, + FDFODDDHIDI = 20367, + NIMALIBCNDA = 25774, + NLHLBLHOBND = 21321, + CDHAHDMGDFP = 3518, + EGCHMLJNOAN = 3581, + DFMPPKHJBMP = 21979, + HJJHCPINCNE = 7940, + GFCDOAKIEIP = 23505, + CLIJPOPLGEM = 6946, + HBLBGHBJCOP = 6852, + ELLIOEPKLLJ = 6740, + KPGKGAEHIOC = 3561, + GIINPEIDMOA = 23553, + GGOMFEKGEGF = 25157, + JHCNHEMAALE = 28776, + IKFPJDLGCAK = 6485, + GOECCIDPEJA = 1694, + LHOBFPCHJGG = 6429, + ADGMELDPAAC = 2162, + NPLOHBGGJAE = 26975, + IDHODHFNEAA = 8332, + DMDDDIFEIBG = 2920, + MOGLDAKNKJM = 2959, + OKMPDPGMDLH = 25814, + HIHIFJECIKD = 4903, + OFOILMPHHDI = 6818, + GJFBIBGGHFG = 7121, + KKPMBGJLKAN = 21269, + KIBKDAPJIAP = 8553, + JIIICGKJHCH = 27902, + CIAOOCAGMGA = 20976, + LOHEFOPKDFJ = 22888, + NLHLOGDMGPB = 1662, + CNLIEOOCAFN = 20692, + LAIIMBGKJON = 7302, + DHANJNCILEG = 2668, + IJJKEHKAHJB = 28191, + MLMIDAMNGCC = 6920, + OKGDINDMKFK = 26873, + CPPJNFNEMHJ = 27185, + DOADHFANFBP = 3676, + EFOGCBKEMDC = 24409, + KCIFNGNEACO = 24426, + PNOBBMJFMMP = 23971, + ALKNPGINPHP = 3048, + DOBPNJHNMKM = 28699, + ADHBMAKNIIM = 26201, + EJFHPJGOIAE = 20611, + DKCBLBIIHPF = 25714, + AOKIHNEIPLN = 29474, + DLODDCEJANC = 3530, + HJMBEGHMOOM = 3622, + HPKGGJJOLDN = 652, + AKHAFOBJALK = 29300, + BAKPKOMCANK = 7764, + MFGAEJJLBLP = 8335, + IFCPINPBCOO = 1842, + LNBFNKAJGLF = 5169, + IDFHDKEOFIB = 1377, + EKEJCKBAMNF = 25296, + MLFGBJMEGMM = 5919, + CIMDEFHJOEN = 8222, + GPMCNEDBCGO = 24720, + JFJEMJNEEEJ = 23163, + KOKDLEMHIDK = 8316, + BICJJBJDIGH = 28614, + ODEHEODALNG = 23079, + AGHCKCEDJAJ = 1128, + JICJIMCAOMH = 1976, + BKBMGFMNCMB = 29851, + AJBDCAAGIPL = 5694, + FPHINCMBHIH = 5775, + NCGKPMLFNFP = 24512, + BJPFGFEHJJO = 3203, + OMBMGOLBMJB = 20351, + HPONAAAKMLK = 24469, + DPPKOFGAPGH = 2461, + AIJLFAHGJJI = 26256, + NMEPLFPEBEN = 9006, + NGDPBMBNEEH = 28513, + OCBNMFJOFJE = 8286, + GGIGIGEMFFF = 1288, + IPDNPOJGIMH = 5570, + FCLPAKJOGIO = 5294, + HKHBPGMFOBL = 29561, + AJINNMBPFKH = 26706, + BGBPAFDIHAI = 2720, + NJHIEHCGNDE = 3603, + KCICHOFMHMC = 29867, + KAKHFKMDGBC = 26160, + BDAODENMPDB = 1716, + OICJGJPJJIM = 28178, + HMLGCIJLFBP = 28352, + CLCPCEKGKNM = 27707, + OCFFPFHMDOD = 2731, + MNANDKGOIGA = 22630, + BFCAFNAPCLM = 23421, + LFGICGEHPCH = 4649, + NCBGDPDAOCF = 22220, + BDJCFPPBLLE = 5029, + PIFIKACCGPE = 5485, + CNEPKEHJIGG = 6727, + JCBDFAHENIF = 3727, + NLBCPCFKPBK = 1252, + DAEKEMHLNJL = 768, + FIFIKBCBBLN = 20753, + FLEBBJOGOBM = 9502, + MBGKJIKNBMG = 28272, + MBCGMOINLDO = 23883, + HMIJLADCKEM = 23783, + ANBNCJLBEJA = 22678, + EPBGCHAIDEA = 22066, + JGCGGGONNAN = 27496, + JCGMNKNKFHL = 23817, + DMAGHACHPIJ = 22858, + JGMNFGOIFON = 26869, + IHJGIHHJLJI = 9208, + GPGJBEJOEEF = 20909, + DDEJLENFEOJ = 29637, + KPFIGCIOFHF = 26945, + FIGDHJKBOIF = 6339, + GDGMOKGDOPH = 1530, + KIHMHDFNICP = 26288, + JLHPMBKOAOC = 9113, + OGOMDOAGMKF = 23925, + OAKJGCPMAKJ = 20305, + EIPCDJKIIPC = 1531, + LCJPAGNBGOF = 27228, + GPENOFJPPFL = 27663, + MFLHLAEHDMP = 25762, + BHMFPIAFDKI = 21291, + JABBEOEEIIM = 9999, + LMOMGHKKFGB = 8817, + PlantFlowerEditFlowerCombinationReq = 1835, + PlantFlowerEditFlowerCombinationRsp = 9479, + MJLEOFDAOMF = 20602, + CPAADOANIJO = 8594, + LFMMDFGFAFM = 29357, + HNDOMFAEHND = 28680, + LCKOAMLDANP = 6473, + BIMIAMPLCHL = 27763, + DPOBHAKIPED = 1895, + HMGBKOJEDEA = 8652, + LOOBBHOLNCA = 26398, + ONJLICKIENP = 76, + PBHFBEKBKPD = 7453, + GJFNMLMEPAE = 4254, + IAPEPBNILPA = 4206, + OEKOCKFFKPK = 24084, + FPLCCEECMKD = 1943, + JDHDGCJICCN = 9644, + MPOJECFGFGG = 8173, + NBEMPLDLNHC = 23557, + EDHLOMKHOKN = 464, + BKHPLKNNEMJ = 2298, + CEDPGKFOMJC = 26657, + EFIIODLKOEF = 5245, + JJCLPELCAKD = 23124, + FELGFOFNBHB = 20032, + OBJIODEHPDH = 24657, + CENEFIPFMBL = 28537, + FAOAAOMECLJ = 7981, + PNCLNFBPLFM = 28478, + EMMOADEPKBO = 9973, + PFGPLNFDIME = 1160, + PPANPIEPLKI = 7763, + KALPDJNAAGL = 24789, + POBKPBMJMLJ = 27946, + MLKBFJPGMBH = 9792, + BLEOEDJMCIF = 25736, + HDAMDPHPFGP = 26942, + JLBCADBLDCO = 3892, + KDALFCCGLBI = 8581, + EIOCPDHNGJH = 3611, + KJCFAPMHFGI = 28135, + PNDIIKOINLE = 23175, + EOMGDFJJCPO = 9794, + CDFJGKDOAOM = 29070, + MEMEOAANKOF = 28992, + LINGOFDNCIN = 22176, + CLLGBACEJJA = 5238, + NOCAELHKDGD = 8950, + FGGHCIOJLPC = 7215, + LMFECFEFOIJ = 8295, + BCJAMLJPENL = 6385, + JAHFGIGHEBK = 7477, + GEAKBLBOHJK = 22531, + EJFJGOCOJBN = 752, + JLINKAGHMFD = 24938, + CIGHDJKHIEI = 25124, + OJCGPDOOPMN = 1967, + OMLLPDDHIHC = 3335, + BGBHDPOLMPA = 881, + GFEDBEDGNNM = 27870, + APBGJEICIEI = 4251, + KKEJCOCPNPG = 29243, + CGAEBDOBFLB = 28495, + MMBMEPINCED = 20463, + HHBBOLOBJMM = 21736, + NABLLMAIHKD = 29830, + MCCNODBJFNE = 20840, + JIHOOKDMJPN = 1162, + LLJLBOOFIFD = 3043, + JNMJBJFGACL = 26887, + FKCMDGEPBNB = 4611, + BFCJBKFGFMF = 22200, + PNOPFKGBEBL = 5027, + FLKMFOHLBOH = 23824, + IBNAHNEMEOB = 3710, + PIBMLHHGIAH = 29872, + OGEKKFJNLCA = 574, + MDHLIHNOMAC = 3772, + NGIOHKNMBJN = 23206, + CGJAAAGOFBP = 1756, + EOFNFMMEPAO = 23161, + IHOPOFPEGGG = 26230, + EGEHBEIPLHL = 8206, + EGOHAKCFPBM = 2173, + PHAIFDMCDCI = 5683, + MHNLELBMDBF = 3095, + FOJMLIDLLDG = 5742, + CMJEGFDEDIF = 24701, + FJOMBNNJPGA = 5065, + OFEEHBBCJNC = 1939, + MHDNHDBJGNM = 8411, + DEHMDAPMPLL = 2851, + NFIDJJDEJLA = 25806, + KAHDJBAOBJI = 1004, + JBJNMIFOBFA = 4152, + LEILIADLPJA = 7700, + HCJIHAOCJGN = 4751, + PAAOFGOPJBJ = 29275, + GOEMCLNIPHH = 8118, + BGABLKMGIBE = 6264, + BFNOMBAMEAC = 24000, + PDFKJNLDPLI = 3189, + OBPLENDFNKH = 20227, + MOJIKPKJGOL = 6820, + MOEKNBINPGM = 5969, + EBEOCOHFJCM = 28575, + PJDOOBDEHKM = 28921, + PGGEKIOINKG = 8174, + GEOMELDDNEO = 7606, + COJJDJACJPJ = 8459, + NNCDNMNEEBG = 2643, + CFLOHLKLHID = 25338, + IJPOCEDDFDN = 29158, + NNFKBBNADJM = 29348, + GFMCPHNHAOP = 8860, + KONKONCIJKP = 28764, + FHLMGPEMFHK = 8607, + BDIJEFEDNDM = 7104, + MOAAEFCAFFL = 25438, + CDFGMOBBNGC = 29149, + OFLFACNNGLD = 5298, + FBAGOBEDAKC = 23803, + NFGDIMMNOKI = 324, + EMDHEPLAKMD = 20670, + LCMPJNCNDPB = 21278, + ADGNCHNLHFA = 23551, + PMHNNOHHEBM = 4469, + FCLCEOOPNNF = 25372, + NCLHGGLMKOD = 7297, + FDALBGHCICL = 22496, + EEGNBOKDMIA = 22314, + PDLKPDGPHAO = 29161, + ELFOOPCPOFO = 22311, + ACHCODHJIEN = 24043, + NMKBEMMLPBI = 23489, + JBOLFAELBHH = 6068, + ALPEHMGGCLI = 22322, + MCHJGOPKBFI = 5269, + PFDHPACGCHK = 142, + MHPDBJOGFPC = 8870, + JMHLHEFLBBJ = 22198, + EHGILGOALNN = 22618, + FLDBEBGONBM = 26709, + CGNOFEHEJJK = 25642, + POCEHDEIMJA = 21982, + OIHHDCMNJCE = 7194, + JHNNKHFFFKO = 7939, + IrodoriScanEntityReq = 1822, + IrodoriScanEntityRsp = 24542, + AIPGBPEKBHC = 21158, + CJBPOKFEKFG = 28095, + LFPEBHEGHDG = 25264, + BJGNBPPDGHJ = 7678, + APHDFOMPAMN = 4718, + EIPHKGALEDC = 24636, + JAHHABKIPNJ = 25803, + FAIMLHLLIFL = 6928, + JINIJIBBCPG = 26573, + KIFDMCKDPME = 22284, + HJKEBOOCHAJ = 9417, + OOICIFDCIIO = 23492, + PBNOFCNKHPD = 6801, + OMODDMEJDAD = 21478, + FOFKGANHKHD = 28101, + CIFGAEINODL = 5091, + PCLPFOOEIHE = 6729, + NNJICDAGANL = 23621, + CPPJFLFCIME = 25882, + BOFPLKINNKN = 20928, + HPHOLIMDBDB = 22909, + FCEKIADHJJF = 29845, + HLNKABHNIPK = 3251, + HFHOBHJFBJN = 20915, + PJDBLNLJMLL = 29584, + PBMDMOAMPBF = 6847, + FGKFODJEFOO = 22620, + CMOMIHLIOCK = 4511, + NAMNJKIFCCG = 1644, + OLPFOAFHFCL = 5493, + BIDLNGODOIO = 29073, + FAAFMADPHOP = 21865, + MGICKDBDFFG = 6630, + LLLPFHIILOP = 22303, + HELMLAIJDHM = 448, + FGMFMKAFAPN = 3749, + IFBNFAHNPBM = 26071, + HMIBMPGPODH = 27222, + DKDFPEJPPFO = 23876, + HBHPADELJOO = 5906, + GFADBJBBJME = 26356, + OJOJOIOBDLH = 991, + GPAIOLOGKCI = 25677, + ANJKLJOONEP = 7340, + ECNNJHCNNND = 7845, + MIIACCOLHIK = 23409, + DFCBIOHMAMK = 7589, + DHJMICGMJMH = 26856, + BPBGLJFDOHO = 2479, + CKIEEEFNBCN = 25035, + DBCMPHNMBKJ = 27402, + IBBCLELENCF = 25985, + JOPGCOINGEJ = 9499, + GNIHGOEOILM = 20302, + BJAAFCCDBDK = 25115, + NCJIGDCCJHJ = 3695, + GDOIJDBBHGB = 25299, + GIACLNEMKOD = 29344, + DIKDCJMENBE = 3110, + INLKOLFJEFF = 2961, + MJFKHIKHBPF = 25970, + PHCEAGMOFIL = 5282, + ONAIPHNJAFH = 6947, + MHOODPOEGKJ = 26805, + DALMAOCOBBL = 29573, + HJMPFHDBBAG = 1107, + LGNGOGJLMHA = 1542, + OFCGJGLNBND = 23361, + LGCEIHEFBNE = 29377, + OICOBBGACLG = 4946, + EKHKJCDDLPM = 24420, + HNAEGOAAKDC = 24571, + DAKLIIJCEMD = 4223, + BNMAIBNNCKH = 1287, + FKBBGIPMDJB = 4121, + LLBLEKEIFGK = 7774, + MLGKMPAAIOD = 22665, + NJECDEDHKKK = 20377, + EJHEHMHDNGI = 347, + LKEAKCLGCLP = 25927, + GPBOHKMBFIB = 27167, + KEIJHJOMKOF = 20011, + OPKDCOBMADL = 4892, + GCHMFBOHDCL = 20814, + BMGJNKDAMKL = 29897, + OOPKGDPNIEC = 7356, + KJJCMEBPAPK = 25288, + JNNMHLHCCCP = 2698, + MEGLDBAFLDG = 27282, + IGBLGNABIBI = 1026, + PDJOCAEIBDK = 29032, + EOMEEPICOBP = 28377, + BJDCAAJCPJE = 7784, + MLDMOKBEGLD = 6750, + LGBMHCJLLLJ = 23821, + FIHCEBLBADA = 29147, + EKGBMEBJCDI = 27108, + CJCMODILOOM = 6522, + HFFFIKOMFPH = 3316, + EBBHINKDGCK = 24799, + MOMKMKPPOMP = 20872, + CGFFKOEOBKF = 725, + BBKCCBNMLDG = 20386, + OIECBIMNGID = 3685, + LGFIDNMHACO = 21707, + IAPDODMLCGB = 28946, + OBFJIKHHMLK = 143, + PEOLFJKBDCK = 20925, + DIBBBFBILOJ = 3388, + CFKIICMLPGA = 8984, + NDNNHAEIEIN = 20045, + JJIIMLNCPFP = 2183, + EIAIAIGIAKB = 9697, + KGJMFKOJFHN = 5665, + AGDJCJHFDOM = 25449, + KJINKJEOKBB = 29444, + PFPMJHNNCGM = 22490, + CDIOFAJEIGA = 7877, + IJDLMGPBJNJ = 8516, + ALEHBIPDPME = 9764, + CIMDIONEDFD = 7490, + ICMEAPPFLGF = 28480, + NBKBMGOKLDO = 7344, + NKIIFECJCNM = 7588, + FAIABOENMFL = 29189, + LGJKLAKMPHE = 3004, + HLDOBONENPK = 3333, + CGNMPPKKJDF = 28067, + EFDFBADMDJB = 22335, + MDCNEJOAPJC = 6563, + CNGPMCFJJHI = 22781, + OKGHHNFKBAN = 1226, + PFCPKPFKGFH = 5881, + FHKLPCBMFOF = 26971, + BFKEAMNCGHM = 27736, + NJDCFFEJPPH = 6216, + JDDFNNPLEBA = 24333, + BBGPPJCLKDD = 2813, + BFBMPFLHPDF = 25459, + DJBPDIFLICA = 28549, + CLCMPGNEFLI = 4140, + LDMIFDNOHJD = 20755, + HANDABNJNFB = 25593, + GALDPKFGMID = 25412, + IIEGDFIGDFC = 29620, + FEOENHNFKPP = 25649, + CPPNAAHFPCE = 25248, + HJOLDFLEOKN = 29191, + KKBAKDEPLML = 24404, + AFGOCAEKCMK = 8804, + KAEFKOLIFCC = 3959, + NLKILGOPGFP = 6650, + KNCMFIJEBAG = 28208, + MCPKKDCGPBF = 5042, + OBELPCKMCPO = 8145, + GJPJAMGGHNO = 8662, + OAHMOICCDED = 1302, + LLMNNLDJAJP = 4308, + NEKBFBICHFK = 22262, + AOABEBGMBIJ = 21155, + OLEMCDOPEDC = 4852, + IFPIOJMNCKJ = 27428, + EINDFLJFHCL = 22667, + CJCNCOOEJNC = 4639, + PCCCECDHBML = 8901, + LAGBENCCKCG = 6091, + CAKLFLCCJCO = 1385, + PJANOHFCLKD = 28904, + LLCIAHJDAKK = 824, + PKFGFDBLCGN = 25036, + FNJBPAKHEPB = 22553, + BBICHIBDLID = 20271, + GEMHKKODOLF = 28284, + JOKEPECEDIG = 898, + CCMGNEMDLKO = 7794, + OOAMEANGFPB = 179, + LAMLDNKCILK = 23981, + MPFPLGMOGCC = 5186, + FHEIADBBEAJ = 23487, + JMNPLDDEPFK = 28823, + PGNBLIJFIKC = 1482, + OLFFLJMAHHH = 2718, + ALEMHHLGEKE = 2865, + BOEOCLOHKLP = 1351, + OFDKCIICFBI = 8979, + FHAAJGNAKPB = 27400, + KGIHNJMOHDL = 5325, + JBHKKPDNMOI = 6467, + EICJDLIFNMD = 2838, + POLGAELBPKP = 27223, + IFILDOKLGPO = 26508, + OCEKHGHJKCB = 26673, + IDMGELBAOEE = 5395, + LDOLKKLKKFH = 29495, + IFLDIDFBPHM = 4478, + CCHKNJJCDPP = 6, + KEEMNMHNNFJ = 2582, + DGKBIJMBNNO = 9822, + PDOMDHLBNOJ = 7760, + EDDBFFEGOLC = 22349, + NOIOBDBIPPF = 1975, + PPMBHIPHLCM = 7957, + CLDBCCNEPDB = 20289, + FIAGGKKILDL = 7090, + KNIGOMPCICK = 23662, + DPAALNFLJMH = 28577, + PDJOCDKCMFN = 22599, + LNDCHKLAGJC = 8966, + CPPHBENLCGE = 24907, + LHNGEDHCNHO = 9400, + NJLDPACKBKK = 9799, + OPGBANKBKFK = 8734, + MHFBAONCCJJ = 8855, + OHINAGJDHCF = 9901, + GIFDJCEHFGK = 3311, + INIPKPHMAHJ = 1849, + BGCKLEPPKAP = 26810, + HKNFCFCCCBP = 8665, + KEGGDFCGNBE = 29072, + MCEEJNNBHIB = 7438, + MEJGBEPIOBO = 5827, + EBJOECGGGLB = 22823, + JADCLDGAGNA = 2027, + JBFFIFPLGBC = 25933, + HDLIDGFCJIF = 23739, + WindSeedType1Notify = 24525, + WindSeedType2Notify = 28053, + WindSeedType3Notify = 21443, + ElectroherculesBattleSelectDifficultyReq = 2290, + ElectroherculesBattleSelectDifficultyRsp = 24905, + MCKNMKIPMGD = 21188, + OBIBAEDGGKP = 21219, + FIBLNMKNGJC = 6449, + IFHCOGBINEM = 5457, + PGCLLDEMDKA = 20325, + KCOOLHGDGNI = 4404, + OLDAELFKDHN = 27166, + GGKCDEBAGDK = 1325, + EBKJMCHFBLO = 5417, + PLKLJOJKAMC = 29264, + MBELJJFKJOG = 9729, + MOGMCKMFKNN = 26394, + HCJIPJCFGJA = 9659, + IMDLDDNCIDD = 21344, + LFLEHMCKKHD = 28844, + CMBDMDBNDMI = 6032, + NLPCHDGJJBF = 29677, + IGDGBECJEGF = 26982, + BGCHAGHLJAN = 29274, + CMADBNDCKMI = 4022, + BILAKINIBGG = 8859, + PLNNAIAGKIO = 20040, + OKIGMIDDECE = 29713, + ALBONMAOOMH = 372, + OMJEMELJAIO = 24204, + HHAOOIPJJPF = 29519, + IGDEPLLHDFF = 27193, + OEOECAPMMJI = 2113, + CLCLGDGJACH = 3419, + LHJIOFAEOMJ = 9892, + FLOFLFCPHEA = 5385, + NFCPLMHCEND = 22241, + GNFGEOBMPLB = 24411, + IKBLCKKEHIG = 29622, + GDNKGBKNBCO = 29975, + DFOMKDEDFOO = 9339, + PLGCENGLBIF = 3155, + OCBBMIOELCO = 319, + JDAFGGHAIIK = 2276, + LHLNNDNEION = 6306, + DKJHINOANIF = 28720, + CMALPGGJPLM = 21455, + LIGNJLJOJDL = 2525, + KDBEIDKJKKA = 3031, + PKBLOINIOKP = 29423, + OLGMEABCOEC = 740, + IBINBEOLHKP = 58, + HGENCKDDOPB = 6527, + EMKAKGLCEEM = 26275, + EENCHNADEFK = 21723, + LJCBLDJFKNM = 3182, + PBOJHKMCNMN = 28723, + EKGOMGALOHF = 8508, + IFPDAKNHNFC = 24507, + LLFEHGNPKBE = 24955, + CNKBMJOICCJ = 7372, + CGIJMJHMDIC = 6375, + LFILOODEBNJ = 24988, + CNEDIABCFFI = 8964, + CANMOPCFMIH = 5163, + PFHAJCMPNID = 2585, + ICCAGOFLHKP = 19, + KIOOBLMEBEM = 8818, + DIDDBIMKACA = 23656, + FOOLICBIGJF = 28070, + HHEFMKFHMCL = 9004, + FCDCIJBDCFD = 29326, + KBMJINEKFBG = 29994, + JKGNDHNFHGG = 27719, + MFBGONCOANE = 21602, + EKCNINDCJAG = 5789, + MNPOFBGIHLP = 5214, + FOEHHJDILNM = 5258, + KCBCJAAMLGD = 28715, + PABJDJFPJAN = 26596, + DGFHIHPKJGO = 24913, + MGOMGNDJECA = 24211, + ODGNPHPNAOD = 26983, + JHKOGKOPCCK = 20223, + EHCAENPKANE = 29514, + MBOCGNHKENO = 299, + DEGBFCEGPHN = 28769, + GFBJODMKGIF = 20661, + NHGKJMMFCBJ = 6007, + APEGHEJNFBE = 26968, + FLKJAFLMIAL = 29092, + JGOHNNADMID = 22376, + IKNPPGBMMEN = 20480, + LPIGAJMKONA = 26195, + JJINBANNOHI = 28685, + GAAHHLIGPJI = 28976, + JFABFMDDONI = 4583, + HEOCDHJOLJP = 20553, + JLJAJANOAMB = 3456, + GKONFBBCPEJ = 6433, + KIKBLNFALGA = 22168, + LFJBOCDCJHM = 3537, + MHJLLKDLIDO = 6465, + MBLEPFKICCO = 9180, + MKHFMOLDKHC = 20986, + MLBNPCJMFFE = 29926, + BGEMJPEIAJK = 9629, + KLLMEDJOFNN = 3003, + FHJFPNEALLH = 27368, + POOPHMGNOMK = 505, + OPANMAMMFAP = 5033, + LHKJGEHEPGD = 20191, + CHOFMMPAOJA = 6814, + JOFKOMHMGMK = 22896, + NMEAODHDJNL = 23512, + LBEKBENDKHD = 22541, + DAAPMGDLKCI = 8110, + EGHLMBKKCKF = 5134, + BICCDOKCLNE = 20858, + CPIPDGIEKPJ = 29581, + FCJCMJCKJHH = 5026, + DPDDIJGOADH = 5442, + BBGPONFKEBA = 21034, + IFBJFJNFAEH = 27709, + FKLOKOGGGPH = 23752, + HHIHHCEMIOD = 25397, + ECJCALIKNME = 21297, + FHPMKKHFOKL = 3872, + NMGGIPMAGKI = 26588, + GDAPOGMBGHD = 8309, + BLOILEFJDBA = 1486, + OIMGAGJMIHE = 24552, + FMMBCODALPH = 27320, + HMONBACKIDB = 28253, + BEIPLNDHMBB = 3076, + AAFCDGGKEME = 3381, + ACJOPOAIMLM = 20030, + IANDFECJDHP = 683, + HIKGOCEPBEO = 22006, + FCCNKHDEIGF = 26436, + CFLNOAKKPMD = 9367, + LNFBAAMPMLL = 989, + CMFANONELLC = 20037, + AGAHMCJFLKC = 1270, + PAIEHDFECPO = 20639, + JNLGBABKBDC = 1953, + CMFIKFIMCMM = 25413, + ECIGIDKJKEP = 26681, + PHFDPAICFIB = 20839, + AOAFHKEPKCI = 28318, + OMONIMGFOMP = 23322, + GILKKKJBKLI = 3014, + AMPFBMJOABF = 26295, + CGGBHLDCMNL = 20903, + BHIMABBNGJK = 2854, + NLOOFNHEMML = 6394, + DBFNANLHAPE = 6823, + KJBAAEEOMOA = 20365, + GBHOKJKBBEA = 6316, + EOLHEJKAOCO = 6748, + MCKFJNNOIGB = 2607, + OOGADCCGNDE = 1758, + IEELIIEBPBO = 29755, + FNIEPPGDALH = 23162, + EJPJOENDABM = 28995, + NIAFCPBFFLD = 3538, + MEONDKJBNHL = 123, + KCLILMMDOAL = 6217, + ICGEJLPBEBB = 4320, + OEHDAGAFPCP = 9452, + GJODKIEEFKJ = 9024, + KAKDOMFKHJK = 21430, + EFHEPKPJKHN = 24104, + OIEEHKNFEJF = 22264, + LDHGFLEOAJG = 21695, + CHFDPDLLIKF = 22588, + JMDMNDABGHJ = 3491, + BGDHFGNPNDN = 9820, + PAMCBGNLKBM = 22740, + FNCMLLGGBHI = 21094, + ENEIDLNAEIN = 26939, + KJBMEELEKDC = 8584, + BEAPPJLLACL = 20301, + JGGKCCAIDEA = 28309, + PPNJLLOBAKD = 7434, + FNIFIBBBJNC = 6534, + OFHFODCKMKE = 23777, + NKPKCOJCOFJ = 4202, + LGOIBJDGFIN = 5888, + NBMMHOOINHJ = 1690, + CCGIAJFEMPL = 28718, + AranaraCollectionDataNotify = 7423, + AddAranaraCollectionNotify = 25954, + CataLogFinishedGlobalWatcherAllDataNotify = 7378, + CataLogNewFinishedGlobalWatcherNotify = 1855, + AvatarAddNotify = 2089, + AvatarDelNotify = 3466, + SetUpAvatarTeamReq = 27894, + SetUpAvatarTeamRsp = 5102, + ChooseCurAvatarTeamReq = 26370, + ChooseCurAvatarTeamRsp = 20406, + ChangeAvatarReq = 3268, + ChangeAvatarRsp = 25733, + AvatarPromoteReq = 25923, + AvatarPromoteRsp = 20584, + SpringUseReq = 25243, + SpringUseRsp = 6094, + RefreshBackgroundAvatarReq = 4439, + RefreshBackgroundAvatarRsp = 26322, + AvatarTeamUpdateNotify = 9275, + AvatarDataNotify = 24251, + AvatarUpgradeReq = 5998, + AvatarUpgradeRsp = 5307, + AvatarDieAnimationEndReq = 975, + AvatarDieAnimationEndRsp = 682, + AvatarChangeElementTypeReq = 357, + AvatarChangeElementTypeRsp = 6674, + AvatarFetterDataNotify = 23393, + AvatarExpeditionDataNotify = 29154, + AvatarExpeditionAllDataReq = 4744, + AvatarExpeditionAllDataRsp = 7688, + AvatarExpeditionStartReq = 5378, + AvatarExpeditionStartRsp = 6254, + AvatarExpeditionCallBackReq = 8368, + AvatarExpeditionCallBackRsp = 7282, + AvatarExpeditionGetRewardReq = 24375, + AvatarExpeditionGetRewardRsp = 27697, + ChangeMpTeamAvatarReq = 8849, + ChangeMpTeamAvatarRsp = 8504, + ChangeTeamNameReq = 863, + ChangeTeamNameRsp = 23087, + SceneTeamUpdateNotify = 5835, + FocusAvatarReq = 28289, + FocusAvatarRsp = 20633, + AvatarSatiationDataNotify = 6275, + AvatarWearFlycloakReq = 25883, + AvatarWearFlycloakRsp = 24346, + AvatarFlycloakChangeNotify = 2786, + AvatarGainFlycloakNotify = 3655, + AvatarEquipAffixStartNotify = 20123, + AvatarFetterLevelRewardReq = 8790, + AvatarFetterLevelRewardRsp = 932, + AddNoGachaAvatarCardNotify = 9529, + AvatarPromoteGetRewardReq = 29282, + AvatarPromoteGetRewardRsp = 7224, + AvatarChangeCostumeReq = 25195, + AvatarChangeCostumeRsp = 9962, + AvatarChangeCostumeNotify = 4214, + AvatarGainCostumeNotify = 8677, + AvatarChangeAnimHashReq = 20581, + AvatarChangeAnimHashRsp = 25301, + PersistentDungeonSwitchAvatarReq = 9839, + PersistentDungeonSwitchAvatarRsp = 24502, + AddBackupAvatarTeamReq = 21738, + AddBackupAvatarTeamRsp = 5377, + DelBackupAvatarTeamReq = 24110, + DelBackupAvatarTeamRsp = 29545, + AvatarTeamAllDataNotify = 5054, + AvatarRenameInfoNotify = 22299, + ItemRenameAvatarReq = 9321, + ItemRenameAvatarRsp = 22271, + DGONPJHMNNL = 289, + HNGLJKIOOAK = 21239, + FPEEONAPBPJ = 25535, + AEFGLFJENNG = 7093, + KGPHFJEBGGA = 5135, + MGBPFEDPFBF = 20212, + BattlePassAllDataNotify = 6398, + BattlePassMissionUpdateNotify = 8829, + BattlePassMissionDelNotify = 29375, + BattlePassCurScheduleUpdateNotify = 22986, + TakeBattlePassRewardReq = 28264, + TakeBattlePassRewardRsp = 8754, + TakeBattlePassMissionPointReq = 22146, + TakeBattlePassMissionPointRsp = 3560, + GetBattlePassProductReq = 3267, + GetBattlePassProductRsp = 7775, + SetBattlePassViewedReq = 4527, + SetBattlePassViewedRsp = 28752, + BattlePassBuySuccNotify = 2619, + BuyBattlePassLevelReq = 4630, + BuyBattlePassLevelRsp = 20272, + GetBlossomBriefInfoListReq = 29405, + GetBlossomBriefInfoListRsp = 28809, + BlossomBriefInfoNotify = 8994, + WorldOwnerBlossomBriefInfoNotify = 20849, + WorldOwnerBlossomScheduleInfoNotify = 2757, + BlossomChestCreateNotify = 27102, + OpenBlossomCircleCampGuideNotify = 1195, + PrivateChatReq = 9675, + PrivateChatRsp = 8530, + PrivateChatNotify = 6349, + PullPrivateChatReq = 23698, + PullPrivateChatRsp = 3924, + PullRecentChatReq = 28137, + PullRecentChatRsp = 29621, + ReadPrivateChatReq = 8926, + ReadPrivateChatRsp = 24765, + ChatChannelUpdateNotify = 9362, + ChatChannelDataNotify = 24284, + ChatChannelShieldNotify = 6566, + ChatChannelInfoNotify = 27824, + HMIACMGLFDB = 8436, + HJKLFHOAMDC = 28372, + DLEAIFJFMGO = 27505, + FBNBHJLOODJ = 28644, + ECBDKGJFHKC = 8726, + DAOHNGMOEJI = 8909, + GOGKKLDFPDP = 667, + PNGAHGNKIMI = 5311, + JPFPBGCCHFA = 4256, + CICHMNLGCFC = 6414, + CMBPJNABJBH = 21452, + LFMNJBNOKGO = 22469, + MMNJMMAKFDF = 8231, + DGAHEMNAMHJ = 5782, + MBMNKOMLDHJ = 9662, + FLIJMMNBBKB = 28554, + DFDOFOHMGJJ = 21664, + OJCJJCIJLNC = 21983, + IPPEHJPNGLF = 3595, + FCJDHGEKPPN = 27702, + EKMOCLJAAJC = 468, + FKDJAEDFOPB = 24918, + NNEHHOHMDBA = 28311, + GFDGKLPHOAP = 9023, + LDDPANPHMEP = 29477, + ALFIDBBDLBH = 238, + HHGJNHNGECH = 27219, + GBLLNIKJILM = 20800, + MKLPECLFMOO = 24975, + JGGIKNBLDCD = 22544, + BBJNJCDKIPG = 24171, + PBMCNKAMKHM = 9726, + PFBPFLDDADP = 5559, + DADACLBKMAI = 21618, + JEEEBDDCCNC = 5713, + JOEHBBJNINH = 29608, + HAKOMBPKBIF = 900, + OJOGMLPEJAE = 2759, + EHPJHEJFHNH = 22357, + BILLDHMMBLA = 415, + BMJMOFBDHIK = 4933, + MMFEIDFCGJE = 25941, + PJIEIDODNGG = 638, + GAIABNBGAEM = 23729, + DABCFHGMJNP = 2019, + PAHAJHPCAAB = 27415, + FBGKAMHDKNE = 20862, + DDHEOCEHOCE = 9580, + IGPIHLCABMO = 22047, + PDJNMACDGBB = 23343, + AFBNELKODJO = 21555, + IHHLFMMLFGB = 6803, + FMEIMLILEML = 27980, + CPGAGNDMKIB = 3612, + JLBMCLGGMEN = 26986, + HDMEHJGGKIE = 205, + IFAOHKPCELH = 926, + NFEGKPDMCNF = 7060, + FHJMPKFNEIP = 24852, + IIHKDGGKECG = 1546, + JJGDJJJLAFP = 28864, + BNJKPFPNNLF = 28587, + GFDBBABOFCG = 22979, + GEAGBEGNKCE = 28219, + GBBINFHBFAJ = 29935, + MJEBBCLNCNM = 27567, + FKLHKLGMHCB = 8928, + BIOFBHNAIAM = 2783, + JHLJNFEFGPL = 20754, + BMDILLFHLKF = 5799, + PBNNECMBPDM = 9971, + LIJFGFJIDKB = 28889, + BINEEFEHGNB = 21973, + NJBJNABIOAO = 27889, + CLMCDDKLHHD = 1031, + HACBHECDPDL = 2670, + POFDPECKOKF = 21108, + NOLCKEDHCLC = 21531, + KGEHFLDNEGP = 28360, + LPIKAANCKCO = 28267, + JCMMAIBIEGD = 3371, + OMFDKKLNAAM = 6771, + LGBEAJBIBCG = 9627, + OMGMHGADJCI = 20919, + IINADLECAGK = 6412, + EJIFAJJOKGH = 26638, + PEDHKMDONFH = 9583, + DPNOLCEDKMF = 25827, + LGCAIBHOFCP = 25371, + PMKKCGABJLB = 8507, + CAPEDLBEHJP = 7569, + CPEFFAGNIPG = 5167, + FNNPHHGBJCK = 316, + HIAGFADFGHP = 135, + AOPPPLDGCCB = 9547, + DOLDHHMKHKF = 25394, + DungeonPlayerDieReq = 6360, + DungeonPlayerDieRsp = 25214, + DungeonDataNotify = 711, + DungeonChallengeBeginNotify = 6633, + GNJLAIEFBPP = 29742, + ODLKFGBOBOB = 4252, + NKBBHNPKOJL = 4350, + NEGHEAPIKIJ = 8520, + ICJKFAKNMJF = 26222, + DFCOMCPOGLC = 25875, + OLNGHIIKEMM = 22031, + KELAPBMMAHB = 25181, + LKAMPMLEBFG = 4447, + KKHDDHMOIBK = 27332, + KGOEKFGDKKI = 21507, + CGFCJEGHKAD = 22338, + PIKDPGBHOHL = 26268, + POKDIGLBJEA = 21070, + CLNPPBPNJEO = 8105, + IDNFGNOHMBJ = 7985, + MHLKPFNOPKJ = 2669, + GFKJBPLFMAL = 6092, + NHELFCCPPMH = 706, + KCLOMDEDFIA = 2068, + OOMLMNHLHAK = 20073, + JCOPLCGKKHB = 24581, + LDDIIKOHPIN = 946, + MLBAMFIMDIL = 25990, + ABOHMIMGOJI = 20197, + BBODLDNKKAH = 28879, + CCMHCIMMKCN = 27283, + KBMOKPGHOPF = 1395, + GOHEONEELDN = 2423, + KJPNEONEMLB = 4712, + DJLDKKEEJBM = 21499, + PJOOMMPIMDD = 4747, + IKPNLELKMND = 1390, + IILKDBIEEAI = 28739, + PNOJJKDDFDH = 22084, + ONLHNGKNNEF = 5968, + INNPDGFPBGF = 21885, + CECDNFMLODN = 8153, + DGFEJGDPEAF = 4166, + LODNIGHMLCO = 28306, + AJFJFNAMFFG = 3045, + DNBKFAIFEBI = 8510, + OEILAILICKL = 5057, + CHBHOOOMDAF = 27660, + FOAICGMNAIM = 22948, + PFCGJHJALGL = 29691, + PADANJKLJFD = 21642, + HostPlayerNotify = 26380, + EvtDoSkillSuccNotify = 7555, + EvtCreateGadgetNotify = 7831, + EvtDestroyGadgetNotify = 65, + EvtFaceToEntityNotify = 23086, + EvtFaceToDirNotify = 28299, + EvtCostStaminaNotify = 4750, + EvtSetAttackTargetNotify = 20615, + EvtAnimatorStateChangedNotify = 25824, + EvtRushMoveNotify = 20913, + EvtBulletHitNotify = 9823, + EvtBulletDeactiveNotify = 27013, + EvtEntityStartDieEndNotify = 22516, + EvtBulletMoveNotify = 5739, + EvtAvatarEnterFocusNotify = 27156, + EvtAvatarExitFocusNotify = 905, + EvtAvatarUpdateFocusNotify = 786, + EntityAuthorityChangeNotify = 1602, + AvatarBuffAddNotify = 9309, + AvatarBuffDelNotify = 8458, + MonsterAlertChangeNotify = 3144, + MonsterForceAlertNotify = 5461, + AvatarEnterElementViewNotify = 20237, + TriggerCreateGadgetToEquipPartNotify = 24644, + EvtEntityRenderersChangedNotify = 27478, + AnimatorForceSetAirMoveNotify = 2491, + EvtAiSyncSkillCdNotify = 22295, + EvtBeingHitsCombineNotify = 23223, + EvtAvatarSitDownNotify = 373, + EvtAvatarStandUpNotify = 8420, + CreateMassiveEntityReq = 7488, + CreateMassiveEntityRsp = 1435, + CreateMassiveEntityNotify = 23016, + DestroyMassiveEntityNotify = 2026, + MassiveEntityStateChangedNotify = 9917, + SyncTeamEntityNotify = 21584, + DelTeamEntityNotify = 28150, + CombatInvocationsNotify = 4643, + ServerBuffChangeNotify = 7658, + EvtAiSyncCombatThreatInfoNotify = 3432, + MassiveEntityElementOpBatchNotify = 1864, + EntityAiSyncNotify = 7015, + LuaSetOptionNotify = 9589, + EvtDestroyServerGadgetNotify = 27417, + EntityAiKillSelfNotify = 4912, + EvtAvatarLockChairReq = 381, + EvtAvatarLockChairRsp = 110, + ReportFightAntiCheatNotify = 24651, + EvtBeingHealedNotify = 9323, + EvtLocalGadgetOwnerLeaveSceneNotify = 7895, + EnterFishingReq = 21089, + EnterFishingRsp = 24132, + StartFishingReq = 2999, + StartFishingRsp = 22998, + FishCastRodReq = 28388, + FishCastRodRsp = 965, + FishChosenNotify = 25391, + FishEscapeNotify = 9899, + FishBiteReq = 27004, + FishBiteRsp = 656, + FishBattleBeginReq = 2608, + FishBattleBeginRsp = 8587, + FishBattleEndReq = 701, + FishBattleEndRsp = 7516, + ExitFishingReq = 23692, + ExitFishingRsp = 25143, + FishAttractNotify = 23018, + FishBaitGoneNotify = 3278, + PlayerFishingDataNotify = 23940, + FishPoolDataNotify = 9398, + GetGachaInfoReq = 22791, + GetGachaInfoRsp = 27309, + DoGachaReq = 8791, + DoGachaRsp = 1372, + GachaWishReq = 8656, + GachaWishRsp = 21619, + GachaOpenWishNotify = 1685, + GachaSimpleInfoNotify = 4113, + HAOMGBPAFFP = 26154, + GadgetInteractReq = 29611, + GadgetInteractRsp = 5232, + GadgetStateNotify = 29582, + WorktopOptionNotify = 8771, + SelectWorktopOptionReq = 25858, + SelectWorktopOptionRsp = 24214, + BossChestActivateNotify = 7228, + BlossomChestInfoNotify = 21552, + GadgetPlayStartNotify = 27366, + APMAANJDJBO = 6832, + BAPHFINNIPI = 21061, + DCHDNLNFLJB = 22283, + HIKDJAGDOEM = 3925, + FOGFLCCJLGI = 7032, + ENHHJOAMBIK = 3494, + CAFLLIODBHH = 27362, + HJENBNIKFIL = 20085, + PJOJDCOBBIA = 6450, + OMBMOJIEAKB = 6828, + EGAGOJPBJEO = 21497, + BPAFINAPANN = 527, + COOKAOBIHFO = 23026, + MMPNINAGOAJ = 27718, + NGCNEHDFJID = 25304, + DFPLIBEPHLH = 982, + MHMCCKKJOOH = 97, + AFAMCFLNNDN = 5788, + MDMCCCKAJLA = 20514, + PKADPBPIIBK = 5333, + BLJCNKGMAHD = 6844, + JCBJJMCKBKP = 24106, + GILDCMMJBLH = 2986, + ELPPBNGMDMO = 27346, + IPKAJEAJCJL = 29315, + OPHBJJKJDHD = 26229, + GMCONBFFBGE = 28795, + AHAPMIHEJKB = 22718, + DBCADLFANEE = 23493, + KICFCLHECFH = 8047, + MJAIOBLJPLH = 9773, + NOLNNFCBBGE = 23266, + NJJNJJMECAO = 21134, + DOKGAPHNIJD = 26101, + JBCANHOMGKN = 792, + GGFADIDMFPH = 29180, + EMDNIAGNLLJ = 28385, + HJMBFEONKPJ = 7021, + CAOOOOLPBMI = 649, + LMHPIJHEHJH = 23366, + KFIBNCCABHF = 29467, + NNMKHCHIEMB = 28339, + LPAJMPOCMEL = 590, + GKFINDLMPDK = 24441, + CGFCCHJBCBG = 23200, + FOJACFPJPBI = 9366, + JPIFJMCILGK = 26910, + MBFJNCJNKHO = 20658, + JALIHKNGPPK = 8838, + MFBPNFNABCD = 28228, + GLNELBAJPFJ = 26727, + ONPKNKAAKDF = 23717, + LBANLFONPCH = 28380, + PNCGCLEAIIA = 22728, + NIBNIFAGDAE = 6952, + HOGOOMLJPBL = 2003, + FEBCPIDKJFP = 5340, + GLJABMCMFOG = 5787, + FHBOLNHJBJH = 6345, + BDEHHLPNGIO = 2435, + HMHHCGFKBDK = 9922, + GMKNKKAOLAE = 27058, + NGJPABCIFNE = 6731, + AFELFNNJNEB = 24736, + BCCGHAOFCBN = 746, + HNLKNOPGDKN = 4924, + INAILMJNLJF = 24682, + NHKPBNCOEBP = 3854, + BGNNAJDIBKO = 23386, + JBBDIJCLMKH = 1336, + CHLKLLFDHJL = 5860, + DBEIBJDKIIC = 24788, + AIMIMONPKJF = 2524, + PGCPBHMNGOF = 382, + PDOLHIGECLL = 7701, + NHGFGPKGLOH = 20932, + KFKIDPBHGNK = 21264, + LOPCNAIGIPA = 24648, + HBALAHAOEHD = 20635, + BPPDEGKBAAD = 25775, + LPDEPOMJMJE = 27232, + NEMMPAFJFHI = 6890, + GKONHFGCEJG = 6720, + FBONNMMAKEI = 4609, + MJOBHIONEEJ = 1995, + OLKDNAIKFFF = 748, + CAHJMDDGENP = 9223, + FOJBPDONOMO = 9491, + OGIIBAAMPHE = 6747, + OIMMOIODOIJ = 1594, + FHFNFKJJDLD = 23919, + FGGKPPCGCAI = 23516, + CMFNCOONGKH = 25472, + JBDBIFBFDAM = 24267, + LLCMGLOLDNH = 27016, + MIBCHPFKNOO = 3940, + JLCJNHJNLAD = 9835, + JMHFHKEFIII = 27532, + NBPCKJDAPMN = 25684, + NHDBONKOMOL = 23576, + NAFICEBNGNL = 28305, + AFEKBALHGED = 21468, + HMLEKDFAKGO = 25136, + KFOHPLNGJEJ = 21080, + ENDJDOBJIJC = 26046, + MOEIMLBJFIH = 4268, + BFOCPEOCNHA = 9730, + LFGLCHLAPBA = 5669, + EIEMIEPJGPD = 9555, + OBDHIPNKOAH = 28314, + MOPOLMAIOCC = 842, + KMKKODIPOKK = 23312, + KLHMGLNBFEN = 1465, + MPBMHLPOFDA = 6270, + JNLIPJDFEJP = 8059, + IAJPKKKAOEA = 25310, + JKPPBLOIMNM = 26346, + HJIPENAONFF = 3843, + GBEINCKCBOM = 7392, + AHGJOHCBDBF = 29022, + EKOCPDNLDNH = 20540, + KALBMIAPCBC = 21237, + OOLHJMIMLAC = 39, + KLKGJHHJKBD = 26589, + EOOMDDPNBFK = 9253, + DPCMHJLKFEN = 4361, + MGIIOOJNCNN = 29536, + CODNBKNFPCG = 4229, + FCFEBBMBMFO = 28167, + AOFNLNHMMOP = 22926, + KEDLNMNKMPJ = 29410, + BFANKIKMEBM = 897, + IBGBLNEPCEE = 7169, + DDCJGKOBIGL = 7186, + NBMOHONIOBD = 21840, + MOLFLOBKFPL = 24263, + NNKALMOPGPF = 23056, + JBGIGIIBMDP = 29623, + IBHCGCFGLAD = 4842, + OPNGDJJIFFB = 20557, + OKKBAOPENOJ = 25398, + BNFFBENHFPB = 25746, + JADBIIIFJFG = 27314, + ALNFMAFCBFK = 6445, + NEKJELPHBMP = 5490, + GNNDKBNHLNE = 7137, + KECFKGCAIOI = 27481, + KAECNNGJIHH = 5901, + JOPICPFAEGP = 6662, + BADNAONJEEE = 29331, + GCBIGIKLIFI = 1094, + HLAEHEGGAKA = 1293, + KIPOCBAEJHL = 24945, + AFJCANIJBIN = 9624, + MOFJNEMLHDJ = 8973, + HFHCIJIMLLF = 27155, + HNEBLEMOOKM = 7480, + LCHEBJADOFI = 29775, + LNLICHGDAAK = 847, + ICHLAGKAJNE = 8046, + FKAHEEMPGJI = 1930, + KFLHKHKDJII = 4695, + OAPKIMMJEKG = 1191, + JNDEILOCOOE = 4883, + DJIFBBCOLJK = 25043, + MMGLBIAMPFF = 3673, + EMMECJFLBLM = 7384, + OBMAPFJGKNN = 9428, + PNMMNDLHMFD = 29005, + AODLEMHANLM = 6884, + LFAENOLAAAI = 22475, + NPKMLJLAOFO = 7470, + AFCGHACKLAJ = 8858, + LEKLLOADGNK = 21565, + NIJBNCPGJBH = 22389, + DGGDIKEHMFL = 23759, + GFGPPAEFKGC = 2453, + AHOCKLDDAIG = 9191, + JAAMIOCOIPE = 29150, + HCIKDDKOLHP = 2972, + FEIFLCJAOGD = 8015, + FBBBJBJDEAN = 5660, + OOIBHANGJBO = 1764, + ALADHJDFGDH = 5810, + MMPLFOEAHNK = 6484, + EEBFDCMPIPJ = 692, + MINDGJLEFEH = 28906, + NIBCHOKPFCO = 27880, + APOHGGCKIGK = 1709, + JMNFEMALAJA = 6683, + KFGKBJFOBKL = 2088, + JOGDJMEFDFN = 27138, + PELLIAJHDJA = 4398, + DEOGCNJGIGM = 24099, + IEMICGHDOPP = 25417, + PMOBMKBLPCO = 1679, + MOKEPOCPKKK = 26800, + EDEJCCPPOOL = 6543, + EECIHPPLANH = 7252, + JEDEKDNLIJC = 26543, + DBIDDFHHBCK = 1665, + HLAPNCKMHOC = 7348, + EBDDNKKFBKA = 8093, + JLLFOOPCCKG = 755, + CLOFAADHGEK = 3029, + GECBJKDJLCP = 9561, + OODBAGKNNGI = 1119, + NIKMNDKKGME = 1707, + PIBDPGKBFFP = 29117, + PEDJPOAKILB = 25825, + PEHDBGDECLJ = 1833, + DPKFPHNAKDK = 6648, + FJPDCECJHEC = 1899, + AIJPFJOJILJ = 20537, + PLEGPILDHNI = 144, + EAEKFEOPDKE = 3071, + DDMLDCCDBOD = 2974, + IBDDMKPCDFC = 8753, + JOGMGBHDIJE = 251, + LBDBGAJCDCB = 29270, + KAIKMBNEPNG = 24299, + EKPAIEIGAFH = 1984, + HDHDNJBFLJN = 262, + PALHPHAINLI = 29276, + APMDHGDFIPO = 3814, + GDOLLKCDKGO = 9961, + ANIPJAMNHJB = 8155, + GKAFIAPEPIO = 4659, + BIKIFFBNBAO = 25349, + GMDHKBHKNKP = 5482, + NJCIEJJCJCB = 3400, + KDMEDIBAALN = 25067, + JKAMPIGIJEJ = 23839, + ACAKAIFLLLA = 3198, + FIJFFDFPCBB = 22821, + BDBKBOPECME = 21054, + LMJBPOIDMFM = 28643, + FEHIKMPBENL = 23070, + GECPKADDFCN = 8810, + JPADPOBMAAC = 21226, + LLLBJOPHBNB = 8306, + CGBENKKBCHP = 20671, + HOLKBOBNILJ = 24276, + JLKCGEJGFOP = 5558, + BKNECCNGKFB = 1788, + JMDOMNFOFCL = 24838, + JBGBHMHMHAM = 8437, + PMCOKEPAPAN = 1029, + LLKHBPKHIBL = 23217, + NKJHOBGMPNA = 25197, + MNDOJFDGANM = 28920, + CCKMGBKCHLC = 5430, + DHAJDENGFAO = 24368, + BLOMGLMMOGA = 6492, + LGPLINHBNLL = 22690, + KFEHLDIEDCI = 22642, + HCEDCKAKLAF = 20379, + KELOLLEHCBF = 1600, + HDNKADOGFCA = 8010, + EDBNGIBKNGC = 21137, + HOBAOKFJFAO = 27404, + HDAIGKCNCAB = 22861, + KECEAOJBKMN = 20558, + HKMDOGCDALA = 21911, + MEPCGEADODI = 5565, + MGNADMOCPFE = 2614, + HCMJKJMEGNG = 25223, + BEPNKDCIJGF = 23003, + GCLJBONDKAP = 21181, + KLDLCCOLINI = 28416, + JBDGAMFIDAN = 21879, + EADNNCKCJBH = 28966, + MDOOOHEPALF = 5929, + FJNJMGFMLAC = 26340, + FODPOBCCBCF = 29692, + BKMFEDBGODE = 7871, + PADEHDFALFK = 29781, + ODDLAMLNLNB = 510, + MDOEKFKOAMO = 28863, + BLFGKMKHPBH = 7817, + HNFKPDDLNNC = 29256, + CAPHNCAEPBI = 9998, + GGOMDHCMFPC = 6278, + JHHAMGFFAOO = 27212, + DKCINJOJBNI = 9613, + AGCJBPFEMEB = 1913, + GPGJLDBLADH = 21284, + JNGODCLEEEA = 9317, + BNGNGBHPHJI = 27664, + NIIKCNECFLG = 9531, + KDHBBLAAILA = 33, + HFGLOECGCEF = 21785, + PPKIANMMCOE = 7221, + DJCLIONHMJL = 28354, + ILGFMCOMAKD = 22064, + EFEFEOGCDEO = 7441, + EBAEHGKFNAC = 27245, + NEMBBJNDPPN = 28108, + BJLHKDOOJOI = 29091, + KAJEHGMGMOB = 5182, + CGPEIFEAOIK = 23497, + MDODPEMJOPN = 8837, + JHNLHOJBNCP = 9829, + HOFPBFIFHDN = 8965, + HDNNIBOCNCK = 8144, + NNDDHMJEPKB = 26654, + HGFDFKLNGMG = 6066, + IAKDHOBHDJE = 6307, + HBJBJOGKKEK = 7333, + PKINGNJGEFF = 22763, + LCEIAGGFEIN = 25760, + EMJIPFKLNCF = 1580, + MBDFKPPPOIC = 25032, + FHDGGJBNKML = 1305, + KNNINDHFBHD = 21554, + AMOPHIECOKB = 26871, + ELAFMKFDEKN = 1778, + HDOFMIONOOB = 26867, + NMHEFCHCIEM = 3807, + MDDNJGGPEMO = 23933, + HNAHBHPLCGL = 9277, + GHIAFPGLKCC = 26118, + ADHBCONLIOC = 2896, + GCILNMCHMLC = 20233, + EBAELJABIEP = 21105, + DHGDNKMPBIC = 4667, + IKNNIGPCIKN = 26650, + HKNPPMLHOMA = 27730, + HBOGFDEJBEI = 24902, + PDOOBHELDOO = 29529, + CNONNHAOKIK = 20288, + DPPIKCHIFAB = 7656, + AOJOJLLHMGA = 5198, + NJMLLADOCDC = 23281, + FPLOOLOLIFL = 28165, + MGGODBOIDFH = 20327, + ALBDHELKEBO = 577, + DCDBFMFKFAP = 1015, + LFCEBOMJIAN = 8061, + IGNKINJFJPG = 2730, + CGJJDJKKAEE = 27539, + NEFOIPPHNJO = 6274, + IACCICHJLGJ = 24997, + ECEHHNFFPIA = 2839, + OFFNLFKABJG = 25633, + ICCLAGBMAOG = 3747, + OLPLJNGBEPC = 3922, + ABIFANHPHDG = 1283, + AAIIFIPBHKG = 22509, + LHACLAJGJMJ = 684, + ALMFGHDIACI = 6725, + LJIFIPBDEHO = 22002, + MJHIDCBDHAN = 3117, + EFPGNDPGHHE = 28677, + EAJOHOEBOLK = 24454, + LOCJCLECJPC = 28865, + AHEAANOJOKM = 5815, + AJGEACOCNCM = 29640, + HPGJLPHEHFA = 5780, + FLILPEPDIHH = 8135, + AOHAGAJMNHB = 29526, + JNIAIGNOHMA = 9027, + BGNPJFLGNFF = 6421, + MLOMPAGELCH = 3692, + BFIAGJGPOEO = 29324, + JPCFEFIMKFJ = 20433, + MPKELCEAAFA = 27890, + ALKHBBEIHNC = 5215, + PDKPDKPDAGN = 8362, + LKBHOABOCHA = 22785, + CKMPPNCPEAL = 9143, + BDIOHHKMBPA = 7376, + OHIKIOOJKMM = 9219, + PCBIFPKLEMP = 5073, + DNFOOANFDII = 7729, + CBNBHBCPFMA = 4529, + NKIEALJGAKL = 9009, + BINJFBDEDLH = 28326, + IFFAAAADBCA = 4952, + AKGAIBBPGAA = 23794, + FAJLJFPHMBG = 598, + FODIKDCLMEH = 9170, + OBOKFJJJGAA = 7182, + JACPMJMEAHB = 23372, + KFFLLLKNMJC = 23088, + PKOHNNFOEJK = 7894, + ILADAHOIMBM = 5871, + NIIEPKIOGEI = 22554, + OIHKPOFCCGA = 20279, + OHGCPIOOJOE = 27881, + BOIACFPMLPG = 22636, + HJOHGLFIGHD = 25111, + NFPCCLKNHHE = 4222, + PFGMEDDMHOA = 25362, + CFMABKHDICP = 100, + HPDGFMFEOMH = 27957, + GIHFOPLALLB = 2188, + NPHIEIBIOIL = 8805, + IMHIIOBLDAM = 24224, + ANAIEABKGDD = 25141, + DCKEOJBJLMF = 287, + CKAACPHECGJ = 7963, + JGMOHCNKDNB = 5561, + BPBBOCAJCIJ = 6774, + IBKFJGOLIGF = 29209, + BCNCBPBMKNN = 20604, + IPOOJJMIGIK = 25566, + EDHAMGKJPHC = 20851, + MarkTargetInvestigationMonsterNotify = 1139, + InvestigationMonsterUpdateNotify = 6371, + InvestigationQuestDailyNotify = 20246, + InvestigationReadQuestDailyNotify = 5350, + PlayerStoreNotify = 9906, + StoreWeightLimitNotify = 21113, + StoreItemChangeNotify = 8149, + StoreItemDelNotify = 28608, + ItemAddHintNotify = 3131, + UseItemReq = 2534, + UseItemRsp = 20729, + DropItemReq = 23353, + DropItemRsp = 29522, + WearEquipReq = 24944, + WearEquipRsp = 5984, + TakeoffEquipReq = 27552, + TakeoffEquipRsp = 2216, + AvatarEquipChangeNotify = 20741, + WeaponUpgradeReq = 23464, + WeaponUpgradeRsp = 21925, + WeaponPromoteReq = 2451, + WeaponPromoteRsp = 24851, + ReliquaryUpgradeReq = 6618, + ReliquaryUpgradeRsp = 1278, + ReliquaryPromoteReq = 29159, + ReliquaryPromoteRsp = 27564, + AvatarCardChangeReq = 9108, + AvatarCardChangeRsp = 6453, + GrantRewardNotify = 4504, + WeaponAwakenReq = 20961, + GFPKLPPPGGH = 9748, + EDDDOHFBOGP = 26027, + DOJGAPFNKFK = 2984, + CombineReq = 27077, + CombineRsp = 26015, + HOJFPPLGPKD = 6835, + KIGEDIAEAAC = 29299, + GGIPANMGAHI = 29509, + JLBPMIJBBKG = 29380, + EHGAIJFPPKJ = 22702, + ELFCFOCLNFH = 26092, + HJBNOHOFGGL = 9437, + BKBBIBBMKHJ = 9450, + MINHFIAHLOK = 5407, + DKDMADLCKOF = 25233, + KDPBOCMDNEJ = 9485, + DJDDLBALFAP = 4270, + OLENODBBNIF = 27978, + ECNLMOAHPPO = 28287, + AHIBGDCBNEE = 20860, + PEHJILJKNCI = 2862, + HHIPGEDNKNE = 25548, + DCBFFLEIOLH = 27573, + CDEAHHNMJFO = 3746, + CBFHLAKIDPM = 9118, + DFGDECNPGKO = 24378, + PCHHOJGBAPD = 3061, + OHLDLFNKLOE = 21948, + CDFDLCKOLHI = 24437, + MNALMLHBCHP = 704, + OIJDMNCEOOI = 21302, + ACFMODANPJD = 4352, + GFHKEHOJKBD = 28754, + DKFMMNIMCJI = 1931, + CCKBFIBLNBH = 29892, + PKJCJADHPFE = 21903, + JKLDKCNAGNF = 27562, + GLLOJNFEOIG = 1909, + GIBKIMOFFCE = 888, + HJELFDOOLPO = 1246, + IOFAOCEHGDI = 9568, + COJDFGPPCOB = 24459, + DJAKDNGDAMF = 7814, + HBKBLHAGPAJ = 24800, + KNJABFEELID = 5209, + HMOBOBCEKHE = 27420, + MFOAKMEBBNI = 493, + FJBODFBGOJE = 1163, + ODINKEDPAFJ = 6548, + JDNECPBJBDE = 26324, + MPMMEKJIBPE = 22191, + JJDDDMLOOKF = 27575, + DPLPPGNFLKH = 26004, + KNLGODKLGPE = 2203, + OKMFKKEDLCK = 29580, + DBLHDGKMNCD = 4048, + NBFAJPOFCIC = 20894, + JCFCJJMHFJK = 3963, + LEKANFFBLPA = 8329, + IPPPIEBJHEG = 26245, + ODLCLCHABDM = 22906, + EKIFEBBIBCA = 1689, + NFPPLNLIPNJ = 8807, + HANPGLFJLEK = 21349, + BBEOAOKILMG = 4248, + DOMKGIFHJAF = 9077, + AEHNEEFCLHE = 545, + LEANKNBAPGE = 71, + KFCNJPGOOHI = 26219, + BKICGJKIMOF = 3067, + FPKINOCHHHF = 6898, + DHOMOMAHBBC = 22997, + HBALAFJMDAG = 29576, + GJOKCNCHEHL = 28402, + HBFNCFBKGLN = 4160, + CDIMLHKEMCN = 1793, + AGHGFIEIGDJ = 21890, + HNOGEMMJHKE = 28942, + DHIDNCGCFFP = 22753, + OMJBHLKDIIH = 4144, + HIPPKPNMDKK = 7599, + JHNINMGOPCF = 24977, + KKDBKNIBHDO = 8702, + NKFJCDACGMO = 4881, + LOOJHAHJCOP = 5408, + JKFLKNIFCBA = 20562, + FFOPBKDLNAI = 24484, + BPKPAPHIIJO = 5800, + JMPCJMFJGFO = 9495, + FMHMOGBCNIH = 6047, + IJAPNGFABOI = 3788, + PLPBIJMMDPF = 26753, + INNHPDDGAOO = 29310, + DHHPAPCAKAP = 6497, + PJEMBAIDOAB = 22981, + ECLCCDEKAON = 25527, + PEAADACDPNA = 27974, + NMFPFFIOIFL = 20005, + ECBHKINBIIE = 8429, + MGMPIDGIHBI = 27030, + KDNDPIPACKA = 3691, + PingReq = 549, + PingRsp = 20939, + GetOnlinePlayerListReq = 3976, + GetOnlinePlayerListRsp = 9942, + ServerTimeNotify = 5680, + ServerLogNotify = 26338, + ClientReconnectNotify = 4480, + RobotPushPlayerDataNotify = 22093, + ClientReportNotify = 8080, + UnionCmdNotify = 26538, + GetOnlinePlayerInfoReq = 1875, + GetOnlinePlayerInfoRsp = 27735, + CheckSegmentCRCNotify = 29560, + CheckSegmentCRCReq = 25604, + WorldPlayerRTTNotify = 6869, + EchoNotify = 4795, + UpdateRedPointNotify = 546, + ClientBulletCreateNotify = 20341, + ChangeServerGlobalValueNotify = 3085, + GmTalkNotify = 5753, + ACNHJKBDDAO = 2450, + IHBFEFALCMK = 26933, + ODOMCODKGGN = 28364, + CBIFMFNBFFM = 23881, + PAIHCGNKHMH = 8157, + BOLPIKFKFAJ = 9477, + HAJKBJOKDOL = 21464, + ALKFDFGCHOB = 7866, + NKKIFAOEIHA = 8140, + CLMPNHNCNBI = 26546, + HPMPIMLCMDB = 20068, + CLLNLNDLHJC = 3323, + HGNJKIFLALE = 25023, + FIPKNLPEPFJ = 27713, + BCOJHFDINEO = 6507, + CMEGEFBFIMM = 4791, + NPAIKADJNMD = 3709, + IMHJHADOIAO = 7170, + IFMECGLBHFP = 9851, + DLMCAKOFKKO = 26041, + DPKHCDJPIAE = 25926, + JNOJHDCNHDD = 28498, + CGNBLIGEAPG = 26624, + OFBEJKOFNDG = 26989, + CCBPEHCLJKP = 24432, + DKHPMCELCND = 2473, + OOBKHNLBAEA = 7156, + FNHOOBOMFIA = 29328, + AABJJHPBFNK = 29039, + PBMKBKCAHMC = 5511, + LOGFHDOLAPA = 4968, + IIINKCOIANB = 1221, + DHEJNDKKOGO = 3999, + OHJHIFNPCMF = 27289, + LFADCKEFBOP = 23518, + IEFIMHOBAEE = 20513, + KLIJINKAHHB = 25180, + JJJOMHPNBPN = 2852, + DEPOOADKAKD = 5463, + CBCBHBJIAHL = 1907, + INJJFOIMAIH = 1574, + JJKAHPKGPBI = 24160, + PIKPMNMLBKN = 29896, + GGPOAFHNAIC = 1731, + EAPBBGHHKGO = 29343, + FJJOAOHIJME = 6990, + IAEKIOMDHII = 4212, + GIOKGFIKALD = 20065, + EFFDEKJOECD = 21480, + HDMDHDMIBKM = 20245, + PCPCBAFGHEJ = 7231, + LNDAIDNADKH = 26929, + HKJLKGNPMEF = 26095, + DIBHIBDNKOG = 4085, + DLKCNLLBAKD = 1261, + HPEDMJLNGPD = 9885, + KGFKANNDGAC = 28355, + MICEGDNCOFM = 23907, + MKOOAPCOCJN = 20548, + FCMMBGLNLPA = 8366, + CELEPOJGLGH = 20229, + ANKGHDELJPB = 27043, + OMJEEDDLMIN = 920, + KMHKDFNNMAE = 28923, + HCOGNOEEAJO = 3196, + LOFENNCANLL = 1547, + AFIENMJIEPL = 1108, + FNDAKPBEIMC = 20086, + GNHFKIBACBE = 9637, + HCLAKCKADKK = 3169, + KDAFCHKENOD = 20908, + NCHBDJHOMDL = 25101, + FJLKMMLIHFI = 4461, + MDLJACLCGOH = 1453, + OAMBMKIFFKD = 5695, + BCCHFNHIHPI = 28829, + GJDCDMNLDNP = 28590, + GECFIOEOIOL = 1663, + OJOGDMCKHHK = 1910, + PKMGCLKMKFE = 8215, + IMIAALEEEBC = 1873, + CCOPJBHNDNL = 8126, + CAIMGOJPEPD = 24861, + BBHKDKOFDIE = 23946, + HJFPINLNAOH = 2005, + ANHIOCCLEGA = 9393, + NpcTalkReq = 28263, + NpcTalkRsp = 2519, + KFFPHDOACCE = 24143, + JGFLHPPOCKL = 3797, + HIPPLFHBAPE = 29010, + KBJNOOGDDFI = 2184, + KPGAPAFLMDL = 2794, + CGEHEPDPLAM = 25087, + MFBFFEFNMHO = 26153, + GALJKNJGLMN = 26691, + CDOIKPMIDII = 23848, + CADHBKPOONN = 9064, + PBPNCHLCDCC = 8902, + BLBOCLIMCKK = 6959, + BBAOKPAHFGL = 25164, + JAEKOJDLKGJ = 23908, + HEPDIIPHEFI = 29246, + HIHEEFHMAIN = 5178, + LHGFODKPCIO = 25610, + JHBAABGHODD = 7019, + POJFCEFOFNM = 22309, + HGNPLNBOPBE = 3344, + DLFEDBGKGNE = 941, + IIHODCFBJGD = 27853, + LDCHNJGCBHO = 22436, + GDFMNNPKFLG = 2301, + ADMKPIDFAMH = 2314, + FEIIPHJAHOK = 2342, + FFMFNFHBAJA = 2325, + BODLBLMHCLK = 2316, + PGIACBCNELF = 2353, + MMGGHHCEMIB = 2363, + PBNMDPPENKH = 2385, + GLLPKOJGLLJ = 2362, + GIOFCNMPIEI = 2375, + CNIOECBENDJ = 2357, + IDGFDLNOHJB = 2304, + GHBDJDBFDMB = 2311, + GetPlayerTokenReq = 27208, + GetPlayerTokenRsp = 24642, + PlayerLoginReq = 8889, + PlayerLoginRsp = 9913, + PlayerLogoutReq = 3247, + PlayerLogoutRsp = 9875, + PlayerLogoutNotify = 23209, + PlayerDataNotify = 1969, + ChangeGameTimeReq = 7442, + ChangeGameTimeRsp = 4498, + PlayerGameTimeNotify = 5758, + PlayerPropNotify = 20759, + ClientTriggerEventNotify = 21283, + SetPlayerPropReq = 5646, + SetPlayerPropRsp = 29235, + SetPlayerBornDataReq = 22402, + SetPlayerBornDataRsp = 2561, + DoSetPlayerBornDataNotify = 25031, + PlayerPropChangeNotify = 6374, + SetPlayerNameReq = 22404, + SetPlayerNameRsp = 25976, + SetOpenStateReq = 20146, + SetOpenStateRsp = 1900, + OpenStateUpdateNotify = 1575, + OpenStateChangeNotify = 1378, + PlayerCookReq = 6501, + PlayerCookRsp = 6533, + BKJNBFCEJKL = 29617, + IDJJGJMLPND = 9854, + ALFNPKKCHCA = 6285, + IDEECFMBGML = 26365, + LIAFIIJDHKC = 8834, + NPHCKJMENLO = 23216, + DBDCCFPOEBI = 2971, + HCPHFMCPGFM = 6082, + EIDALEGNBGA = 9987, + ODGDKKAPMJI = 3443, + CLEOHAGGEBM = 2254, + NKIOPPGFOOG = 6517, + PIDLDNLCPGO = 28160, + MHIIHDOCHNC = 5573, + NJEGBNKAILO = 28831, + NGJPEAMBMAL = 28136, + HBHBHEDNKOD = 9332, + NLKDCLICJLC = 27123, + MNFLGMDPHCP = 4261, + DGOPDOMFIMH = 21407, + KALPPCKPMCJ = 28581, + HNKAOPFAMFC = 27175, + GDMJOFOLAKH = 21387, + NAKPNFEOGBE = 3064, + JMBLLAGBPPJ = 20201, + JEKKMEPPOKD = 7462, + DPPNEMJEMID = 25764, + FIDNFBLDPGL = 4069, + IOIOMNBNLMB = 9149, + FDBOMFJOBLI = 27995, + JOGDLKGKIKK = 7476, + LHJDGKILKBL = 7890, + CBEDHBHDLHG = 9670, + CDCMNNDNOBJ = 2063, + MCDAICBPKLG = 22732, + AntiAddictNotify = 27206, + FMBJCMKFCEN = 1583, + BIJOAAPPDCE = 25773, + JOMNFGLAPPM = 27091, + MJJEPPDKMIO = 7679, + FHDGOANJBIJ = 24131, + CKBOPNNACEA = 21190, + HEAODIHEDLC = 9319, + FMJIHMDELAO = 9070, + DJDHDGPBEKA = 20533, + ADMGKEHJABC = 6572, + KOKDCPNLDLC = 24817, + APGIDGPBHAD = 2086, + FKNKNBFILJC = 2008, + GHCEKMEBHFJ = 4114, + DPNDMKMAAAH = 26127, + LMHNHCMNACK = 20836, + NLBKOOGEMJO = 139, + JLAEBCOLEII = 23815, + LIGHAKGNNJO = 28277, + OEOLHHALAOO = 28297, + MIMFAMEACAM = 28055, + AEBNBOFAPEI = 27687, + BJJPGKLIGPJ = 23900, + FJLDEPMOMGM = 21687, + PEEALIJCLGA = 1974, + LFIKDIPEPNE = 1434, + LENCHJHPLOA = 7379, + PMDEAPPGJKN = 4651, + MEBEAJCJHIM = 601, + FLMENIKDGLI = 3784, + DGPCEGNOCKC = 24443, + AINHKOMCHNJ = 29208, + IINDOPDMHHC = 25519, + IMFGIDFENJJ = 2014, + MLJNAMBMJHL = 20281, + BJLONGAOOOL = 9194, + LifeStateChangeNotify = 28259, + EntityFightPropNotify = 23128, + EntityFightPropUpdateNotify = 6915, + AvatarFightPropNotify = 26014, + AvatarFightPropUpdateNotify = 397, + EntityFightPropChangeReasonNotify = 9747, + AvatarLifeStateChangeNotify = 24239, + AvatarPropChangeReasonNotify = 21373, + PlayerPropChangeReasonNotify = 29938, + AvatarPropNotify = 27784, + MarkNewNotify = 4860, + JCHKBEDNPHE = 20128, + LHMNFCACAOF = 24287, + BNPEIKMDKLG = 9389, + KGIEMCIKOOE = 23446, + LHJMJLOAOFG = 27432, + CIGAPFPCNOC = 7239, + JEHJLPCMOJN = 8557, + DKDJAEDCNJN = 37, + PLBFKIFOJPD = 23601, + LHADNPFHFFO = 20012, + FHPGKJOFNHH = 28411, + JCOLNIGAICC = 5416, + CFEFOBEDDJA = 3829, + IOLPBIJCHFJ = 3478, + DBHKMCGDOCI = 20667, + BMOIAJKDPPB = 21303, + EDDBHNOIALM = 27757, + NCKDIFCOCLD = 5679, + HFFODBBDBHA = 211, + CNMIJOOFLJI = 620, + DEHPHKIKMAB = 29361, + LNEELENEKNC = 24957, + BCPGIKPIJCK = 20652, + KGAFCCOCLMP = 27277, + CBJIDJEOPBG = 21254, + DNOFJPBKFKB = 5798, + OAPPEHKFDEJ = 23267, + OFEAABMGIOD = 25929, + HGLHOKGJMIJ = 26049, + HOPCLFPKAHF = 20508, + MIOLGPCEBML = 3079, + MAOEOGCHHBL = 20307, + BALDAKJADDK = 1010, + PAJAIJNOFIL = 7057, + GGDJNGKEDPB = 20096, + EGDJCDDFNAD = 28174, + HINIPALEEDJ = 721, + OFCEAJIFENO = 592, + CHCDKKGFBMK = 25423, + FALGBOMCHJK = 1981, + ILOJCPHOLNC = 28993, + HEAILPKLPHA = 1632, + EELOGLONJAN = 5052, + NGJAMMDMONG = 20632, + ABLDOLGJGDH = 5472, + NPFFIECJBGB = 28200, + GDBEDEFHOAB = 29528, + FEGFDGKOIAB = 3345, + DANDPJMBOKP = 9480, + AABFNNOFPEN = 3500, + DDPAEGIKIPL = 3406, + NJGPONCINCC = 6341, + BHOAKFKCBOD = 3167, + IPMAGLCFHJB = 4824, + KGOANBACOPH = 27305, + OCMGDDIBKNK = 27919, + OAJHLIHAENI = 6916, + HOPMNGMGICP = 3911, + GFCMHDJMNDG = 5302, + GLOFJECFCBJ = 1569, + NICGILHEBOO = 24679, + JBBEDKHJKCK = 5168, + DBDDCAPPIGP = 20563, + NMJLKPBAKOC = 181, + DIBCNAOAFLJ = 24747, + EMIOPGLAPKD = 24193, + IJIJFKIHEGC = 23244, + FAPMKCPJAKM = 25847, + IPCBBPBFCPM = 338, + MGGHHHLOGOA = 5832, + OIAMJOAHFPI = 27814, + JNBDFCPEKKH = 29881, + POODAMOKKMO = 24283, + DIPHAGBFMBG = 9039, + KILKIMJAKEG = 9656, + GJHFHODODKB = 270, + GEMEJIOKABC = 22609, + LAAMBKOGCMO = 26367, + KKOOBOBMHNE = 999, + KMNEMHBBNKI = 5481, + IFEJOMHLMKC = 5060, + POPKNJPNNNP = 29355, + KJMAKAKONCA = 26374, + EDIIJADOKDA = 3010, + CKMADAGDEHI = 24897, + LIMPKLNMIAG = 25542, + JIECEOCCHDA = 29893, + EOOGEIEHLKC = 5356, + LHDHLGHFDNK = 20989, + GNEAGONEBDH = 27158, + BGLDBEEKCDG = 20675, + OECABODPCNN = 23961, + HJNFOKHHDOK = 20973, + NONFPHDGCIL = 5734, + HKLJPBIFKEB = 24901, + PIMHADNNHPL = 3355, + AGKKCMLCINH = 8502, + AAOKENHBNCJ = 8442, + BDMHNBLBKJC = 2627, + GNJOHKDOLNL = 29818, + KIEGKDPOGPL = 28918, + CIALPJHAHPK = 21542, + BJBGNOJECEE = 23496, + FLIBBHFJOBG = 8514, + FAEIGEFHJJD = 3569, + CHPIKNEHDKI = 2554, + HOLMJKPLOFP = 98, + EKBKGACFHCP = 234, + GCMEJCMLKAK = 8588, + DLBBAABHLAN = 3250, + GAKFIKKOHAK = 29284, + BLMHONOBBAL = 9306, + BGAAMCAODDB = 8897, + NCNDEIEFDDC = 27944, + OPPAAOAAKPJ = 8575, + OPCPAKGCLGA = 9073, + NFFNJFHKKGK = 26178, + EJNGKPFODDO = 22664, + HGLMGABMIEK = 6604, + FEGAMOKNEOO = 2776, + EFAFEKBAEEK = 22619, + KAIEPNLJCGA = 7883, + MOEFKPHPFMP = 3913, + IONIGFFKIOI = 6518, + DKIPHGCADPO = 22514, + PlayerEnterSceneNotify = 27217, + LeaveSceneReq = 28881, + LeaveSceneRsp = 24194, + SceneInitFinishReq = 8917, + SceneInitFinishRsp = 9212, + SceneEntityAppearNotify = 21994, + SceneEntityDisappearNotify = 4715, + SceneEntityMoveReq = 24965, + SceneEntityMoveRsp = 28771, + SceneAvatarStaminaStepReq = 29950, + SceneAvatarStaminaStepRsp = 29397, + SceneEntityMoveNotify = 26181, + ScenePlayerLocationNotify = 21626, + GetScenePointReq = 3602, + GetScenePointRsp = 23131, + EnterTransPointRegionNotify = 23379, + ExitTransPointRegionNotify = 1488, + ScenePointUnlockNotify = 23450, + SceneTransToPointReq = 3817, + SceneTransToPointRsp = 28965, + EntityJumpNotify = 26718, + GetSceneAreaReq = 26865, + GetSceneAreaRsp = 28243, + SceneAreaUnlockNotify = 23415, + SceneEntityDrownReq = 24233, + SceneEntityDrownRsp = 26140, + BLFAPMFMBPH = 25490, + EFKJGIGMMLP = 1898, + FLBMEPFDNOH = 20538, + KKOBJOGLNNO = 25793, + CMOLBIPNBJC = 20038, + PEDMAAELKFD = 23650, + NPKOKIMOAML = 3210, + CEIMMHBLJAN = 28605, + IAJHGPIPBEK = 26462, + PODINAIGLPK = 7088, + BGGKOAGDFBH = 1795, + BHGPBAKNMIE = 4030, + BKBPLFHDGLJ = 8601, + MJLDJCHOBLF = 26458, + OLNEHENGDCC = 4381, + FNHDNIGBIOH = 29967, + HLCNFIHFCHL = 26562, + LKIHHGBCPFN = 3660, + MPILPJHKAOC = 1631, + POLHECMPOGB = 27073, + DOLENMAEONN = 3832, + CMMPPDNPPDJ = 1231, + GECJBLGEBJM = 26448, + FCKOMFMKPHE = 2493, + CHMOPGGPJCE = 8653, + GGALBCKOHNF = 25045, + BLNLDPPODFD = 5051, + OAIKLEIPAGO = 27096, + FLOJMGFIFFD = 3108, + GCFOGDPKOFG = 23718, + OJOPODPFODH = 28007, + IDJFGIEEEME = 25090, + DIPAHCPLNHD = 28686, + OEDKKHHLKHH = 25790, + NKEKBMDOKLI = 1142, + GAJBKKDGFLD = 9050, + DDFINMJFOLN = 20001, + ClientPauseNotify = 5200, + PlayerEnterSceneInfoNotify = 26732, + JoinPlayerSceneReq = 29250, + JoinPlayerSceneRsp = 29842, + SceneKickPlayerReq = 27578, + SceneKickPlayerRsp = 21963, + SceneKickPlayerNotify = 24402, + HitClientTrivialNotify = 24711, + BackMyWorldReq = 28030, + BackMyWorldRsp = 8483, + SeeMonsterReq = 23827, + SeeMonsterRsp = 7508, + AddSeenMonsterNotify = 22458, + AllSeenMonsterNotify = 28050, + SceneTimeNotify = 4509, + EnterSceneReadyReq = 272, + EnterSceneReadyRsp = 28859, + EnterScenePeerNotify = 23914, + EnterSceneDoneReq = 6434, + EnterSceneDoneRsp = 29301, + WorldPlayerDieNotify = 23859, + WorldPlayerReviveReq = 6851, + WorldPlayerReviveRsp = 7822, + JoinPlayerFailNotify = 23344, + SetSceneWeatherAreaReq = 24996, + SetSceneWeatherAreaRsp = 24190, + ExecuteGadgetLuaReq = 24582, + ExecuteGadgetLuaRsp = 25696, + CutSceneBeginNotify = 6874, + CutSceneFinishNotify = 6243, + CutSceneEndNotify = 9550, + ClientScriptEventNotify = 3947, + SceneEntitiesMovesReq = 8922, + SceneEntitiesMovesRsp = 2919, + SceneEntitiesMoveCombineNotify = 7718, + UnlockTransPointReq = 20703, + UnlockTransPointRsp = 21991, + SceneWeatherForcastReq = 1209, + SceneWeatherForcastRsp = 25316, + MarkMapReq = 3421, + MarkMapRsp = 4597, + AllMarkPointNotify = 28812, + WorldDataNotify = 2101, + EntityMoveRoomNotify = 4063, + WorldPlayerInfoNotify = 21934, + PostEnterSceneReq = 9304, + PostEnterSceneRsp = 5422, + PlayerChatReq = 4374, + PlayerChatRsp = 27855, + PlayerChatNotify = 4410, + PlayerChatCDNotify = 26057, + ChatHistoryNotify = 29451, + SceneDataNotify = 27173, + DungeonEntryToBeExploreNotify = 29457, + GetDungeonEntryExploreConditionReq = 4575, + JHCNLIIBIGJ = 6709, + PCLNFPFKGKL = 5750, + IPGEBKIKOGM = 23715, + EFPHNNJHEAK = 5406, + AJNOIILOFCC = 912, + MINOGGDKEJO = 21217, + LDCIMDMACKH = 28087, + GHPBIKNMLJB = 9369, + JCKMEBFMHLC = 27412, + GPDIKGDHLOC = 20164, + CFONCJPPJKN = 27132, + OGPAPNDGIGJ = 5607, + HHCFPFEHGHN = 22126, + HHHBKGDDOIJ = 21118, + OBFMGODDBGI = 2697, + KHBMICKGOCJ = 29525, + BFFCGDHHIHO = 24014, + LCKPJHFBHNK = 20049, + GOHJLEAOJEN = 26419, + LIOMINAPJOM = 23503, + COMODBAOOMP = 502, + MFGLGDGECMB = 21248, + LJNBMCPIADN = 3526, + ADMEMFABBCM = 5088, + LLEPPIJOAOM = 23198, + ILPIMDKDNFP = 24056, + HitTreeNotify = 21091, + DDCCIAGENND = 7149, + IAHDKAKJDPE = 5173, + HANOJDIBDJN = 6305, + MMOPKHKOJFE = 9268, + OAIBINGOLKN = 9216, + GDBIMOEDDOL = 26183, + FEAHEJLIAGH = 7259, + GOCLLLAHDPL = 3563, + DEIKLMGCMOK = 6298, + CLAFCLNIKKO = 27849, + AOCDFMAKENP = 4901, + PIPDDDCCPOM = 25387, + OGJHDNLIDPF = 27349, + POIDFANBBGN = 20159, + MCIJIMOINMA = 25447, + FKLDGKMJDIJ = 22877, + JDNKNGOAIIA = 8304, + FHGFGIEEKON = 2785, + LEMEEEFCFJF = 6578, + FKGPLCJGLFI = 28384, + DLOAIBIOFAF = 27201, + NPAOJKEEOFI = 20526, + LGFEMDKCIEG = 28890, + JEFBJCJGHPC = 4680, + HKHDDCBHNCN = 6765, + CFHGBCPHIEA = 24947, + AOOPMODJPLA = 24505, + OBJCNOHHGHG = 23197, + PPNMMKAOAPG = 21955, + JOHJLGDEOON = 2141, + BELFMNJOKCE = 23658, + MIBPGHJGBKG = 6481, + EEHALDFKPBP = 27424, + BPFNAAFJIKB = 5454, + GBFIHHMADOM = 802, + CJOHGDMMGNN = 24310, + BGJAGONMJHA = 23272, + CDMJDBIBGMM = 2100, + OOCOMGDPOGA = 24102, + OLIIBPKMDIL = 9291, + JGCLCBJIIHE = 25663, + ScenePlayBattleInfoNotify = 26216, + ScenePlayOwnerCheckReq = 9227, + ScenePlayOwnerCheckRsp = 1198, + MPFBCDDCAPP = 2810, + GAIIDEJBAJB = 22143, + PDONIMFGAGI = 1120, + OOCLPKCAMPD = 3551, + PBFGBNJKPFD = 7332, + BCMGMAIEIOG = 20062, + IOEJDFOMKOO = 20019, + FGPJLCEDCHL = 3201, + BAAPEJFGGFO = 2413, + IIDEKCICCJM = 3916, + IJHPEAJENHG = 25051, + OHFCGDPOFHI = 28300, + BENPLHINCCK = 25353, + OPFMDADHJDO = 24167, + DGKOAFNFKIK = 3019, + MFDKHOILGNL = 28056, + PFOPPKGPKEA = 3803, + FBHLCIKKIML = 2096, + AACNNJMOLHH = 28985, + HBMJKFBOEMF = 25937, + PGFDGABGEOK = 21245, + KEAMDLEGMBL = 2538, + GADHNAPGIFG = 28651, + MCILIDEFEFN = 3726, + EDOPCCKLHKP = 4725, + IAIEAJMEMGK = 27703, + DDHAPJDOEGH = 26744, + IBIDNNELKMK = 3102, + DFAELHEAODO = 5260, + AHMIEGPGJOF = 1739, + FNJKHAOLNKG = 22282, + PFDNDDLHCAB = 4177, + EEDLBMBOMHH = 564, + NLKLAMGMFKM = 28589, + KFBCKIEEOGG = 4190, + MKPDHDNEMBH = 27644, + CIGILJGIIJF = 9144, + LPEMHFIMDCM = 25237, + EAGGJECOKPH = 22159, + OCNMHMHPOOB = 1194, + GIGFIAHLFOC = 757, + OELEBMNLCNK = 27141, + ANHPDFGJIEE = 29395, + CEFHIKKOPCB = 1563, + DIGHNIEKEDB = 24425, + DCMKOPIBBJI = 2858, + JFFFDPCACFP = 8862, + KAOMNBJCCPF = 9078, + HHABDGBDHMD = 26316, + LOFJIICMDBE = 26259, + PJPGPDBNFAD = 26653, + GetPlayerFriendListReq = 26642, + GetPlayerFriendListRsp = 2749, + AskAddFriendReq = 6673, + AskAddFriendRsp = 2923, + DealAddFriendReq = 29169, + DealAddFriendRsp = 2407, + GetPlayerSocialDetailReq = 25877, + GetPlayerSocialDetailRsp = 21823, + DeleteFriendReq = 640, + DeleteFriendRsp = 1883, + SetPlayerBirthdayReq = 8029, + SetPlayerBirthdayRsp = 6015, + SetPlayerSignatureReq = 8292, + SetPlayerSignatureRsp = 21352, + SetPlayerHeadImageReq = 9970, + SetPlayerHeadImageRsp = 3920, + UpdatePS4FriendListNotify = 22921, + DeleteFriendNotify = 27531, + AddFriendNotify = 20930, + AskAddFriendNotify = 761, + SetNameCardReq = 917, + SetNameCardRsp = 23823, + GetAllUnlockNameCardReq = 28052, + GetAllUnlockNameCardRsp = 23825, + AddBlacklistReq = 7711, + AddBlacklistRsp = 25174, + RemoveBlacklistReq = 8823, + RemoveBlacklistRsp = 28650, + UnlockNameCardNotify = 29965, + GetRecentMpPlayerListReq = 24070, + GetRecentMpPlayerListRsp = 24513, + SocialDataNotify = 24740, + TakeFirstShareRewardReq = 9904, + TakeFirstShareRewardRsp = 1633, + UpdatePS4BlockListReq = 4042, + UpdatePS4BlockListRsp = 1994, + GetPlayerBlacklistReq = 27113, + GetPlayerBlacklistRsp = 2481, + PlayerReportReq = 8914, + PlayerReportRsp = 22426, + SetFriendRemarkNameReq = 27045, + SetFriendRemarkNameRsp = 22129, + UpdatePlayerShowAvatarListReq = 3226, + UpdatePlayerShowAvatarListRsp = 7542, + GetFriendShowAvatarInfoReq = 26427, + GetFriendShowAvatarInfoRsp = 23702, + UpdatePlayerShowNameCardListReq = 9539, + UpdatePlayerShowNameCardListRsp = 6738, + GetFriendShowNameCardInfoReq = 22007, + GetFriendShowNameCardInfoRsp = 21639, + ForceAddPlayerFriendReq = 7996, + ForceAddPlayerFriendRsp = 23287, + ProfilePictureChangeNotify = 4628, + PSNFriendListNotify = 9817, + PSNBlackListNotify = 24379, + GetPlayerAskFriendListReq = 24226, + GetPlayerAskFriendListRsp = 9717, + FEFEGCFFIHJ = 21413, + ANHHMPOACHD = 22341, + OKOFFDPMPII = 8549, + IAEIEDMKBIM = 9123, + ANHPPNPIGCL = 27874, + JDLBMIJDIKD = 1201, + OPILPLIEOIK = 4894, + OOKPOPDODOK = 4288, + IHDKFKMKHCF = 8176, + FFBPFDEEMID = 3831, + OCCPBJNJIJB = 7300, + GFKKHLCNPNK = 27054, + KKJCBEBHDOI = 24258, + DJODIODMNCL = 4929, + FHIPAJMEJGL = 29749, + LOMCHNNLHCO = 6116, + NDKFLDDOGIJ = 6163, + HMFPMFPBJNE = 6107, + OEFCIPIENCI = 6105, + LAOHGPIEKOD = 6142, + PFLKIJABOIB = 6166, + JKJGEGHDCIK = 6121, + ONAMOBJEMGF = 6118, + AEALLHOLJHJ = 6124, + CHDIILMGBKG = 6185, + LCEEGKLCMNO = 6170, + LNCEIPFPHEL = 6153, + PKILOPIFEOA = 6157, + GEJFEJNNJPN = 6138, + MOFGCFOPNPO = 6169, + AAJMFOMHGGN = 20398, + FJPMHGFBHIN = 6830, + JEIBIOHCEII = 23548, + GMLHAOMAIOF = 8884, + AJDFNKCPKAM = 7640, + OFIGFPOMDCG = 2780, + DAHAJGOMOGO = 5024, + GPMBKCOBHHJ = 21203, + EGJAKPANCDG = 4948, + AAIBBLDJONG = 27647, + HCIMGPFMCCN = 20090, + LNGIGJJONPC = 23482, + BKMAHIEGHKE = 25546, + GNOOHHCBIEN = 8426, + NIPHLMABEKH = 1790, + OCPGDFFMBJJ = 21140, + GHDEOFEDFFM = 23624, + JPICOCOCPIC = 8679, + HBPKPGOJFMH = 20600, + IBFMBOFGEPH = 9563, + NFDICCOMLMK = 3087, + GIFCBIBOALC = 8499, + JPFDAAEIBCC = 23856, + EHOHGMMPDCH = 27550, + LLAEALDKAEO = 24697, + GNHDOFFFGJO = 7748, + LMIHGFKBNKH = 8498, + HJGLGLNEIGO = 5803, + HDKODIAAPJD = 6462, + CDDMGMFHCPE = 26411, + BMDEFKLNOID = 7307, + DODHPCMAGFN = 2496, + GAABCLBBEPL = 20323, + ENLPKKDJPEP = 28083, + BCOHONPCNKH = 9863, + NDKNCLOHMCM = 3775, + JBLFKGKLDND = 27465, + KIGKMDAGDKE = 28725, + GIBLEGGDPOH = 1127, + GMCFOGNDEBN = 22999, + OOOCJHLFJLE = 7083, + BOGNHIIGJEF = 29157, + GLEFOBKCOJL = 4061, + EFENNEDHIJB = 27650, + KLGHDIIKLMC = 8636, + FKPMMBBPJCG = 3527, + CAMHBICIFLE = 3338, + CODEKFHKHKE = 983, + EOGOMLJIAOJ = 28162, + NFHHEIJNNBJ = 819, + IEGNKFHCBID = 600, + PBMJGILKFGL = 4762, + KCAGOPAMHJA = 26575, + HNHKACBPHNP = 28139, + FMMFFOFPIKC = 26114, + KJOMLNJBHHM = 28387, + AFKLDPHAKGN = 22572, + BKAGEEHJKGG = 8788, + ADCBPLEGPJO = 26176, + INCGCFINIAB = 28172, + KNHDJKLNKMM = 165, + BCJHPAOLAHB = 25735, + CNHOEMLNGOB = 126, + NEDFACOKENG = 20683, + ILIMIOHGNPH = 6716, + FHHLMPGCCHO = 9903, + IAPFAGGOAAL = 2448, + HNJNDCMHDAG = 9345, + BNBOLAABPHM = 5928, + PJPDNIPODKK = 25603, + JDGPDOGFDND = 22489, + FLHGGDDGLCP = 21694, + FBJJANJEKIM = 3097, + BKNOFKBHACH = 20270, + JDDLLMDDJAM = 195, + IEMGEIMPBHI = 8664, + INOOAHEPEED = 9075, + AEGOHPHFHKE = 511, + OKIMNONFPHH = 28048, + IJJPGOACDPM = 29939, + JEMGGFKADBL = 2879, + HBPGOCOGFCA = 24912, + DMLNPPKLJMG = 23288, + IOCIDFLCLEH = 27614, + IBKOGBPPJOH = 2192, + BCNFEPCNMIF = 5909, + PCEFMJCFKDG = 5147, + FFKBAMEDBEI = 25483, + COMOOMDKDBP = 1394, + KLGCEADNOIE = 28547, + FKLHJKAGHND = 723, + FACJOGMBKBG = 23675, + HEMNDLILJFP = 22912, + ELLOKCGHJHD = 1084, + PNPBBCHNNIJ = 22094, + OBPDAAAAMDN = 6877, + DCPAEEHBODO = 21418, + MOMKAPHLPEO = 24613, + NPICICOLCBG = 5514, + BILNPJMMGDG = 2721, + KOOOHIINALA = 6943, + DKEKJOJNKLF = 1343, + IIMLKHLJPEG = 22023, + JCFAHIHCALJ = 29134, + HBLIOCHJDGJ = 229, + DCKBDLADJAE = 8298, + FPOCBGPCMCI = 23316, + CENKLGJEGMJ = 7275, + GMJDOPNAGAM = 20344, + FGBAMOGPLOO = 26425, + HNBCCACIGHB = 158, + PPBHGFJFLOE = 27318, + BBGHHMKPMFJ = 24090, + POPGJFBAJMA = 826, + AOPMAEGDIPE = 20436, + JPMILDEOGEC = 23661, + JODHOKHCCME = 4230, + KADONOOLAFP = 8655, + BEMMBBPNPMI = 3512, + MHKJAKHNBDI = 20462, + FOPBCFBCGNJ = 4057, + NIKMAIKKEME = 8219, + ABHFNEDGFPB = 4838, + HNNCGCOOEGI = 3480, + GECAIFOHDKC = 6802, + ACPNGKFPGCL = 27909, + OMCIEOOALLB = 9207, + FAALHGDICGC = 7882, + DEFJKJFGFHG = 496, + LMDFJDPOOJO = 6065, + FHHIMIJLMGJ = 29090, + MDEEMNBPCPA = 327, + NAFDLCCKBMP = 7660, + CJDKCACEFCN = 7404, + FFHHOLAIMJM = 29964, + AOGDCJEGIKB = 3272, + ONCONBCMPPL = 29607, + GBCILKHKLMJ = 26712, + DILNJILKLCC = 24148, + GGCCMIMACIF = 4070, + CEEAFIGHMJD = 2139, + ACBIKPHDHMD = 343, + AILNNNIGLBE = 1223, + OMAOGKGGFMJ = 28911, + IGBEMGPOLPL = 9803, + JHFBNNLPGNJ = 28022, + ECMAEDJCLCK = 7020, + HFAIJINEHPP = 25366, + HNNHHODAHAH = 26099, + IEPIHECMPEN = 504, + BPKBCDGHKGK = 22226, + SetWidgetSlotReq = 24761, + SetWidgetSlotRsp = 21941, + WidgetSlotChangeNotify = 8802, + GetWidgetSlotReq = 7552, + GetWidgetSlotRsp = 4020, + AllWidgetDataNotify = 24097, + UseWidgetCreateGadgetReq = 8256, + UseWidgetCreateGadgetRsp = 23377, + UseWidgetRetractGadgetReq = 5727, + UseWidgetRetractGadgetRsp = 27710, + WidgetGadgetAllDataNotify = 27929, + WidgetGadgetDataNotify = 25681, + WidgetGadgetDestroyNotify = 9052, + WidgetDoBagReq = 27588, + WidgetDoBagRsp = 25738, + WidgetActiveChangeNotify = 26799, + WidgetUseAttachAbilityGroupChangeNotify = 1367, + WidgetCaptureAnimalReq = 27897, + WidgetCaptureAnimalRsp = 4900, + WidgetUpdateExtraCDReq = 4692, + WidgetUpdateExtraCDRsp = 6739, + FireworksReformDataNotify = 21340, + ReformFireworksReq = 2543, + ReformFireworksRsp = 4265, + LaunchFireworksReq = 25813, + LaunchFireworksRsp = 45, + FireworksLaunchDataNotify = 29884, + ChangeWidgetBackgroundActiveStateReq = 7825, + ChangeWidgetBackgroundActiveStateRsp = 26488, + AllWidgetBackgroundActiveStateNotify = 836, + RemotePlayerWidgetNotify = 29156, + WidgetWeatherWizardDataNotify = 2797, + AILOPHMJIOJ = 5972, + IMJHONADIGH = 551, + ENAIGLHOMFE = 22180, + PGIKFMBAOLH = 4083, + KIDDAMPMOHG = 3706, + KPGEGALOODD = 429, + BLICDFHBHLB = 22857, + DDPFCBEPNJF = 25448, + OCEADDCBKPN = 7248, + KOKJBELAOBD = 26813, + MFNOAALHEJE = 3284, + HFJHEHBGBEH = 27025 +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/CodexType.proto b/NahidaImpact.Protocol/CodexType.proto new file mode 100644 index 0000000..0b0564b --- /dev/null +++ b/NahidaImpact.Protocol/CodexType.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +// Obf: LHGEGGKAFLM +enum CodexType { + CODEX_NONE = 0; + CODEX_QUEST = 1; + CODEX_WEAPON = 2; + CODEX_ANIMAL = 3; + CODEX_MATERIAL = 4; + CODEX_BOOKS = 5; + CODEX_PUSHTIPS = 6; + CODEX_VIEW = 7; + CODEX_RELIQUARY = 8; +} diff --git a/NahidaImpact.Protocol/CoinCollectOperatorInfo.proto b/NahidaImpact.Protocol/CoinCollectOperatorInfo.proto new file mode 100644 index 0000000..4c7d468 --- /dev/null +++ b/NahidaImpact.Protocol/CoinCollectOperatorInfo.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message CoinCollectOperatorInfo { + uint32 level_id = 1; +} diff --git a/NahidaImpact.Protocol/CoinCollectPrepareReq.proto b/NahidaImpact.Protocol/CoinCollectPrepareReq.proto new file mode 100644 index 0000000..9256967 --- /dev/null +++ b/NahidaImpact.Protocol/CoinCollectPrepareReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 21763 +// Obf: MCJPOLDLGHL +message CoinCollectPrepareReq { +} diff --git a/NahidaImpact.Protocol/CombatInvocationsNotify.proto b/NahidaImpact.Protocol/CombatInvocationsNotify.proto new file mode 100644 index 0000000..5a10756 --- /dev/null +++ b/NahidaImpact.Protocol/CombatInvocationsNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + + +import "CombatInvokeEntry.proto"; +message CombatInvocationsNotify { + repeated CombatInvokeEntry invoke_list = 11; +} diff --git a/NahidaImpact.Protocol/CombatInvokeEntry.proto b/NahidaImpact.Protocol/CombatInvokeEntry.proto new file mode 100644 index 0000000..19d3eee --- /dev/null +++ b/NahidaImpact.Protocol/CombatInvokeEntry.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "ForwardType.proto"; +import "CombatTypeArgument.proto"; +message CombatInvokeEntry { + bytes combat_data = 11; + ForwardType forward_type = 7; + CombatTypeArgument argument_type = 5; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/CombatTypeArgument.proto b/NahidaImpact.Protocol/CombatTypeArgument.proto new file mode 100644 index 0000000..fd94d1c --- /dev/null +++ b/NahidaImpact.Protocol/CombatTypeArgument.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; + + +enum CombatTypeArgument { + COMBAT_TYPE_ARGUMENT_NONE = 0; + COMBAT_TYPE_ARGUMENT_EVT_BEING_HIT = 1; + COMBAT_TYPE_ARGUMENT_ANIMATOR_STATE_CHANGED = 2; + COMBAT_TYPE_ARGUMENT_FACE_TO_DIR = 3; + COMBAT_TYPE_ARGUMENT_SET_ATTACK_TARGET = 4; + COMBAT_TYPE_ARGUMENT_RUSH_MOVE = 5; + COMBAT_TYPE_ARGUMENT_ANIMATOR_PARAMETER_CHANGED = 6; + COMBAT_TYPE_ARGUMENT_ENTITY_MOVE = 7; + COMBAT_TYPE_ARGUMENT_SYNC_ENTITY_POSITION = 8; + COMBAT_TYPE_ARGUMENT_STEER_MOTION_INFO = 9; + COMBAT_TYPE_ARGUMENT_FORCE_SET_POS_INFO = 10; + COMBAT_TYPE_ARGUMENT_COMPENSATE_POS_DIFF = 11; + COMBAT_TYPE_ARGUMENT_MONSTER_DO_BLINK = 12; + COMBAT_TYPE_ARGUMENT_FIXED_RUSH_MOVE = 13; + COMBAT_TYPE_ARGUMENT_SYNC_TRANSFORM = 14; + COMBAT_TYPE_ARGUMENT_LIGHT_CORE_MOVE = 15; + COMBAT_TYPE_ARGUMENT_BEING_HEALED_NTF = 16; + COMBAT_TYPE_ARGUMENT_SKILL_ANCHOR_POSITION_NTF = 17; + COMBAT_TYPE_ARGUMENT_GRAPPLING_HOOK_MOVE = 18; +} diff --git a/NahidaImpact.Protocol/CompoundBoostTakeStatusType.proto b/NahidaImpact.Protocol/CompoundBoostTakeStatusType.proto new file mode 100644 index 0000000..248b65d --- /dev/null +++ b/NahidaImpact.Protocol/CompoundBoostTakeStatusType.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: BPPJNIAJACJ +enum CompoundBoostTakeStatusType { + COMPOUND_BOOST_TAKE_STATUS_NONE = 0; + COMPOUND_BOOST_TAKE_STATUS_BOOST_ONLY = 1; + COMPOUND_BOOST_TAKE_STATUS_BOOST_AND_TAKE = 2; + COMPOUND_BOOST_TAKE_STATUS_BAG_FULL = 3; +} diff --git a/NahidaImpact.Protocol/ContentAuditInfo.proto b/NahidaImpact.Protocol/ContentAuditInfo.proto new file mode 100644 index 0000000..3be6ac0 --- /dev/null +++ b/NahidaImpact.Protocol/ContentAuditInfo.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +import "AuditState.proto"; +// Obf: MOIJAPOKNPK +message ContentAuditInfo { + bool is_open = 1; + string content = 2; + uint32 submit_count = 3; + AuditState audit_state = 4; + uint32 submit_limit = 5; +} diff --git a/NahidaImpact.Protocol/CreateReason.proto b/NahidaImpact.Protocol/CreateReason.proto new file mode 100644 index 0000000..5097a0c --- /dev/null +++ b/NahidaImpact.Protocol/CreateReason.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: DDPMPGDLDEN +enum CreateReason { + CREATE_NONE = 0; + CREATE_QUEST = 1; + CREATE_ENERGY = 2; +} diff --git a/NahidaImpact.Protocol/CrystalLinkRestartDungeonReq.proto b/NahidaImpact.Protocol/CrystalLinkRestartDungeonReq.proto new file mode 100644 index 0000000..faba21c --- /dev/null +++ b/NahidaImpact.Protocol/CrystalLinkRestartDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 28616 +// Obf: OFNMEJKIHLG +message CrystalLinkRestartDungeonReq { +} diff --git a/NahidaImpact.Protocol/CurVehicleInfo.proto b/NahidaImpact.Protocol/CurVehicleInfo.proto new file mode 100644 index 0000000..c6f5f0f --- /dev/null +++ b/NahidaImpact.Protocol/CurVehicleInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message CurVehicleInfo { + uint32 entity_id = 1; + uint32 pos = 2; + uint32 gadget_id = 3; +} diff --git a/NahidaImpact.Protocol/CustomCommonNodeInfo.proto b/NahidaImpact.Protocol/CustomCommonNodeInfo.proto new file mode 100644 index 0000000..95f229d --- /dev/null +++ b/NahidaImpact.Protocol/CustomCommonNodeInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message CustomCommonNodeInfo { + string slot_identifier = 3; + int32 parent_index = 1; + uint32 config_id = 2; +} diff --git a/NahidaImpact.Protocol/CustomDungeonBanType.proto b/NahidaImpact.Protocol/CustomDungeonBanType.proto new file mode 100644 index 0000000..ebe69da --- /dev/null +++ b/NahidaImpact.Protocol/CustomDungeonBanType.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: DHBHFOPCKCO +enum CustomDungeonBanType { + CUSTOM_DUNGEON_BAN_TYPE_NONE = 0; + CUSTOM_DUNGEON_BAN_TYPE_LAYOUT = 1; +} diff --git a/NahidaImpact.Protocol/CustomDungeonFinishType.proto b/NahidaImpact.Protocol/CustomDungeonFinishType.proto new file mode 100644 index 0000000..c781a3b --- /dev/null +++ b/NahidaImpact.Protocol/CustomDungeonFinishType.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: AJGOAOOHDHK +enum CustomDungeonFinishType { + CUSTOM_DUNGEON_FINISH_PLAY_NORMAL = 0; + CUSTOM_DUNGEON_FINISH_PLAY_TRY = 1; + CUSTOM_DUNGEON_FINISH_EDIT_TRY = 2; + CUSTOM_DUNGEON_FINISH_SELF_PLAY_NORMAL = 3; +} diff --git a/NahidaImpact.Protocol/CustomDungeonState.proto b/NahidaImpact.Protocol/CustomDungeonState.proto new file mode 100644 index 0000000..b600d96 --- /dev/null +++ b/NahidaImpact.Protocol/CustomDungeonState.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: FNOIEOJLKAB +enum CustomDungeonState { + CUSTOM_DUNGEON_STATE_EDIT = 0; + CUSTOM_DUNGEON_STATE_SELF_PASS = 1; + CUSTOM_DUNGEON_STATE_PUBLISHED = 2; +} diff --git a/NahidaImpact.Protocol/CustomGadgetTreeInfo.proto b/NahidaImpact.Protocol/CustomGadgetTreeInfo.proto new file mode 100644 index 0000000..d74e65d --- /dev/null +++ b/NahidaImpact.Protocol/CustomGadgetTreeInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + + +import "CustomCommonNodeInfo.proto"; + +message CustomGadgetTreeInfo { + repeated CustomCommonNodeInfo node_list = 1; +} diff --git a/NahidaImpact.Protocol/DealAddFriendResultType.proto b/NahidaImpact.Protocol/DealAddFriendResultType.proto new file mode 100644 index 0000000..d4445ad --- /dev/null +++ b/NahidaImpact.Protocol/DealAddFriendResultType.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: AIMELHBOBLC +enum DealAddFriendResultType { + DEAL_ADD_FRIEND_RESULT_TYPE_REJECT = 0; + DEAL_ADD_FRIEND_RESULT_TYPE_ACCEPT = 1; +} diff --git a/NahidaImpact.Protocol/DeshretObeliskGadgetInfo.proto b/NahidaImpact.Protocol/DeshretObeliskGadgetInfo.proto new file mode 100644 index 0000000..21d59d6 --- /dev/null +++ b/NahidaImpact.Protocol/DeshretObeliskGadgetInfo.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message DeshretObeliskGadgetInfo { + repeated uint32 argument_list = 1; +} diff --git a/NahidaImpact.Protocol/DoSetPlayerBornDataNotify.proto b/NahidaImpact.Protocol/DoSetPlayerBornDataNotify.proto new file mode 100644 index 0000000..a98ba17 --- /dev/null +++ b/NahidaImpact.Protocol/DoSetPlayerBornDataNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 5710 +// Obf: JJKIDLCAPLA +message DoSetPlayerBornDataNotify { +} diff --git a/NahidaImpact.Protocol/DraftInviteFailReason.proto b/NahidaImpact.Protocol/DraftInviteFailReason.proto new file mode 100644 index 0000000..704b772 --- /dev/null +++ b/NahidaImpact.Protocol/DraftInviteFailReason.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +// Obf: ABGFENJLAMG +enum DraftInviteFailReason { + DRAFT_FAIL_UNKNOWN = 0; + DRAFT_ACTIVITY_NOT_OPEN = 1; + DRAFT_ACTIVITY_PLAY_NOT_OPEN = 2; + DRAFT_SCENE_NOT_MEET = 3; + DRAFT_WORLD_NOT_MEET = 4; + DRAFT_PLAY_LIMIT_NOT_MEET = 5; + LNILPEDBCDB_DraftActivityConfigNotFound = 6; +} diff --git a/NahidaImpact.Protocol/DuelHeartCgEndNotify.proto b/NahidaImpact.Protocol/DuelHeartCgEndNotify.proto new file mode 100644 index 0000000..231cc8c --- /dev/null +++ b/NahidaImpact.Protocol/DuelHeartCgEndNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 509 +// Obf: NCLDLEACMPK +message DuelHeartCgEndNotify { +} diff --git a/NahidaImpact.Protocol/DuelHeartRestartDungeonReq.proto b/NahidaImpact.Protocol/DuelHeartRestartDungeonReq.proto new file mode 100644 index 0000000..0f93c28 --- /dev/null +++ b/NahidaImpact.Protocol/DuelHeartRestartDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 20474 +// Obf: JBIEBFNCMLG +message DuelHeartRestartDungeonReq { +} diff --git a/NahidaImpact.Protocol/DungeonCandidateTeamDismissReason.proto b/NahidaImpact.Protocol/DungeonCandidateTeamDismissReason.proto new file mode 100644 index 0000000..c69ebfb --- /dev/null +++ b/NahidaImpact.Protocol/DungeonCandidateTeamDismissReason.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: MFAGPGGHPLK +enum DungeonCandidateTeamDismissReason { + DUNGEON_CANDIDATE_TPDR_NORMAL = 0; + DUNGEON_CANDIDATE_TPDR_DIE = 1; + DUNGEON_CANDIDATE_TPDR_DISCONNECT = 2; +} diff --git a/NahidaImpact.Protocol/DungeonCandidateTeamLeaveReq.proto b/NahidaImpact.Protocol/DungeonCandidateTeamLeaveReq.proto new file mode 100644 index 0000000..a17aaa3 --- /dev/null +++ b/NahidaImpact.Protocol/DungeonCandidateTeamLeaveReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 22562 +// Obf: GJDCBHBIHFB +message DungeonCandidateTeamLeaveReq { +} diff --git a/NahidaImpact.Protocol/DungeonCandidateTeamPlayerLeaveReason.proto b/NahidaImpact.Protocol/DungeonCandidateTeamPlayerLeaveReason.proto new file mode 100644 index 0000000..6e827f3 --- /dev/null +++ b/NahidaImpact.Protocol/DungeonCandidateTeamPlayerLeaveReason.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: ILAFDGNADFG +enum DungeonCandidateTeamPlayerLeaveReason { + DUNGEON_CANDIDATE_TPLR_NORMAL = 0; + DUNGEON_CANDIDATE_TPLR_DIE = 1; + DUNGEON_CANDIDATE_TPLR_BE_KICK = 2; + DUNGEON_CANDIDATE_DISCONNECT = 3; +} diff --git a/NahidaImpact.Protocol/DungeonCandidateTeamPlayerState.proto b/NahidaImpact.Protocol/DungeonCandidateTeamPlayerState.proto new file mode 100644 index 0000000..56e3557 --- /dev/null +++ b/NahidaImpact.Protocol/DungeonCandidateTeamPlayerState.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: KMBKLPECAEO +enum DungeonCandidateTeamPlayerState { + DUNGEON_CANDIDATE_TEAM_PLAYER_STATE_IDLE = 0; + DUNGEON_CANDIDATE_TEAM_PLAYER_STATE_CHANGING_AVATAR = 1; + DUNGEON_CANDIDATE_TEAM_PLAYER_STATE_READY = 2; +} diff --git a/NahidaImpact.Protocol/DungeonEntryBlockReason.proto b/NahidaImpact.Protocol/DungeonEntryBlockReason.proto new file mode 100644 index 0000000..2a65136 --- /dev/null +++ b/NahidaImpact.Protocol/DungeonEntryBlockReason.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: DKFHNAHNGFE +enum DungeonEntryBlockReason { + DUNGEON_ENTRY_REASON_NONE = 0; + DUNGEON_ENTRY_REASON_LEVEL = 1; + DUNGEON_ENTRY_REASON_QUEST = 2; + DUNGEON_ENTRY_REASON_MULIPLE = 3; +} diff --git a/NahidaImpact.Protocol/DungeonGetStatueDropReq.proto b/NahidaImpact.Protocol/DungeonGetStatueDropReq.proto new file mode 100644 index 0000000..f20ae0c --- /dev/null +++ b/NahidaImpact.Protocol/DungeonGetStatueDropReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 22105 +// Obf: DCPLBOFPKII +message DungeonGetStatueDropReq { +} diff --git a/NahidaImpact.Protocol/DungeonPlayerDieReq.proto b/NahidaImpact.Protocol/DungeonPlayerDieReq.proto new file mode 100644 index 0000000..229a1e8 --- /dev/null +++ b/NahidaImpact.Protocol/DungeonPlayerDieReq.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "PlayerDieType.proto"; +// CmdId: 3239 +// Obf: KLKMLEAJHNH +message DungeonPlayerDieReq { + PlayerDieType die_type = 15; + uint32 dungeon_id = 1; +} diff --git a/NahidaImpact.Protocol/DungeonPlayerDieRsp.proto b/NahidaImpact.Protocol/DungeonPlayerDieRsp.proto new file mode 100644 index 0000000..767577c --- /dev/null +++ b/NahidaImpact.Protocol/DungeonPlayerDieRsp.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// CmdId: 29888 +// Obf: OAJOHKDAIJF +message DungeonPlayerDieRsp { + int32 retcode = 14; +} diff --git a/NahidaImpact.Protocol/DungeonRestartReq.proto b/NahidaImpact.Protocol/DungeonRestartReq.proto new file mode 100644 index 0000000..300d3ef --- /dev/null +++ b/NahidaImpact.Protocol/DungeonRestartReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 29252 +// Obf: FFNEOOIKHIA +message DungeonRestartReq { +} diff --git a/NahidaImpact.Protocol/EchoShellInfo.proto b/NahidaImpact.Protocol/EchoShellInfo.proto new file mode 100644 index 0000000..74d7330 --- /dev/null +++ b/NahidaImpact.Protocol/EchoShellInfo.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message EchoShellInfo { + uint32 shell_id = 1; +} diff --git a/NahidaImpact.Protocol/EffigyChallengeV2RestartDungeonReq.proto b/NahidaImpact.Protocol/EffigyChallengeV2RestartDungeonReq.proto new file mode 100644 index 0000000..6169321 --- /dev/null +++ b/NahidaImpact.Protocol/EffigyChallengeV2RestartDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 3728 +// Obf: MBNGMBKBAGL +message EffigyChallengeV2RestartDungeonReq { +} diff --git a/NahidaImpact.Protocol/EndCameraSceneLookNotify.proto b/NahidaImpact.Protocol/EndCameraSceneLookNotify.proto new file mode 100644 index 0000000..1014d45 --- /dev/null +++ b/NahidaImpact.Protocol/EndCameraSceneLookNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 4771 +// Obf: ENEFGMFFKJI +message EndCameraSceneLookNotify { +} diff --git a/NahidaImpact.Protocol/EnterCustomDungeonType.proto b/NahidaImpact.Protocol/EnterCustomDungeonType.proto new file mode 100644 index 0000000..8cb701b --- /dev/null +++ b/NahidaImpact.Protocol/EnterCustomDungeonType.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: PCCMGHKHKNL +enum EnterCustomDungeonType { + ENTER_CUSTOM_DUNGEON_NONE = 0; + ENTER_CUSTOM_DUNGEON_EDIT = 1; + ENTER_CUSTOM_DUNGEON_PLAY = 2; + ENTER_CUSTOM_DUNGEON_OFFICIAL = 3; +} diff --git a/NahidaImpact.Protocol/EnterSceneDoneReq.proto b/NahidaImpact.Protocol/EnterSceneDoneReq.proto new file mode 100644 index 0000000..3af743e --- /dev/null +++ b/NahidaImpact.Protocol/EnterSceneDoneReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message EnterSceneDoneReq { + // CMD_ID = 6434 + uint32 enter_scene_token = 1; +} diff --git a/NahidaImpact.Protocol/EnterSceneDoneRsp.proto b/NahidaImpact.Protocol/EnterSceneDoneRsp.proto new file mode 100644 index 0000000..8d43d54 --- /dev/null +++ b/NahidaImpact.Protocol/EnterSceneDoneRsp.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message EnterSceneDoneRsp { + // CMD_ID = 29301 + int32 retcode = 13; + uint32 enter_scene_token = 1; +} diff --git a/NahidaImpact.Protocol/EnterScenePeerNotify.proto b/NahidaImpact.Protocol/EnterScenePeerNotify.proto new file mode 100644 index 0000000..b4f5d8c --- /dev/null +++ b/NahidaImpact.Protocol/EnterScenePeerNotify.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +message EnterScenePeerNotify { + // CMD_ID = 23914 + uint32 enter_scene_token = 6; + uint32 dest_scene_id = 13; + uint32 host_peer_id = 11; + uint32 peer_id = 2; +} diff --git a/NahidaImpact.Protocol/EnterSceneReadyReq.proto b/NahidaImpact.Protocol/EnterSceneReadyReq.proto new file mode 100644 index 0000000..a6b69ce --- /dev/null +++ b/NahidaImpact.Protocol/EnterSceneReadyReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message EnterSceneReadyReq { + // CMD_ID = 272 + uint32 enter_scene_token = 3; +} diff --git a/NahidaImpact.Protocol/EnterSceneReadyRsp.proto b/NahidaImpact.Protocol/EnterSceneReadyRsp.proto new file mode 100644 index 0000000..6ec30d8 --- /dev/null +++ b/NahidaImpact.Protocol/EnterSceneReadyRsp.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message EnterSceneReadyRsp { + // CMD_ID = 28859 + uint32 enter_scene_token = 13; + int32 retcode = 15; +} diff --git a/NahidaImpact.Protocol/EnterTransPointRegionNotify.proto b/NahidaImpact.Protocol/EnterTransPointRegionNotify.proto new file mode 100644 index 0000000..e3a620e --- /dev/null +++ b/NahidaImpact.Protocol/EnterTransPointRegionNotify.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// CmdId: 22064 +// Obf: ECDCICGGBDA +message EnterTransPointRegionNotify { + uint32 scene_id = 7; + uint32 point_id = 4; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/EnterType.proto b/NahidaImpact.Protocol/EnterType.proto new file mode 100644 index 0000000..dc21d8d --- /dev/null +++ b/NahidaImpact.Protocol/EnterType.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + + +enum EnterType { + ENTER_TYPE_NONE = 0; + ENTER_TYPE_SELF = 1; + ENTER_TYPE_GOTO = 2; + ENTER_TYPE_JUMP = 3; + ENTER_TYPE_OTHER = 4; + ENTER_TYPE_BACK = 5; + ENTER_TYPE_DUNGEON = 6; + ENTER_TYPE_DUNGEON_REPLAY = 7; + ENTER_TYPE_GOTO_BY_PORTAL = 8; + ENTER_TYPE_SELF_HOME = 9; + ENTER_TYPE_OTHER_HOME = 10; + ENTER_TYPE_GOTO_RECREATE = 11; +} diff --git a/NahidaImpact.Protocol/EntityAiKillSelfNotify.proto b/NahidaImpact.Protocol/EntityAiKillSelfNotify.proto new file mode 100644 index 0000000..d137f97 --- /dev/null +++ b/NahidaImpact.Protocol/EntityAiKillSelfNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// CmdId: 2606 +// Obf: FPIKKIKFHDA +message EntityAiKillSelfNotify { + uint32 entity_id = 6; +} diff --git a/NahidaImpact.Protocol/EntityAuthorityInfo.proto b/NahidaImpact.Protocol/EntityAuthorityInfo.proto new file mode 100644 index 0000000..9c28afb --- /dev/null +++ b/NahidaImpact.Protocol/EntityAuthorityInfo.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + + +import "SceneEntityAiInfo.proto"; +import "Vector.proto"; +import "AnimatorParameterValueInfoPair.proto"; +import "EntityClientExtraInfo.proto"; +import "AbilitySyncStateInfo.proto"; +import "EntityRendererChangedInfo.proto"; + +message EntityAuthorityInfo { + SceneEntityAiInfo ai_info = 3; + repeated AnimatorParameterValueInfoPair pose_para_list = 5; + EntityClientExtraInfo client_extra_info = 6; + Vector born_pos = 4; + AbilitySyncStateInfo ability_info = 1; + EntityRendererChangedInfo renderer_changed_info = 2; +} diff --git a/NahidaImpact.Protocol/EntityClientData.proto b/NahidaImpact.Protocol/EntityClientData.proto new file mode 100644 index 0000000..a50d83a --- /dev/null +++ b/NahidaImpact.Protocol/EntityClientData.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message EntityClientData { + float windmill_sync_angle = 2; + uint32 wind_change_scene_time = 1; + int32 wind_change_target_level = 3; +} diff --git a/NahidaImpact.Protocol/EntityClientExtraInfo.proto b/NahidaImpact.Protocol/EntityClientExtraInfo.proto new file mode 100644 index 0000000..f0e27f8 --- /dev/null +++ b/NahidaImpact.Protocol/EntityClientExtraInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + + +import "Vector.proto"; + +message EntityClientExtraInfo { + Vector skill_anchor_position = 1; +} diff --git a/NahidaImpact.Protocol/EntityEnvironmentInfo.proto b/NahidaImpact.Protocol/EntityEnvironmentInfo.proto new file mode 100644 index 0000000..2b4790f --- /dev/null +++ b/NahidaImpact.Protocol/EntityEnvironmentInfo.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message EntityEnvironmentInfo { + uint32 climate_area_id = 2; + uint32 json_climate_type = 1; +} diff --git a/NahidaImpact.Protocol/EntityFightPropChangeReasonNotify.proto b/NahidaImpact.Protocol/EntityFightPropChangeReasonNotify.proto new file mode 100644 index 0000000..546f6b8 --- /dev/null +++ b/NahidaImpact.Protocol/EntityFightPropChangeReasonNotify.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + + +import "ChangeEnergyReason.proto"; +import "ChangeHpReason.proto"; +import "PropChangeReason.proto"; +import "ChangeHpDebts.proto"; + +message EntityFightPropChangeReasonNotify { + //EJGGCHDDMEE detail_info = 1; + repeated uint32 param_list = 32; + ChangeEnergyReason change_energy_reason = 5; + ChangeHpReason change_hp_reason = 11; + ChangeHpDebts change_hp_debts = 8; + PropChangeReason reason = 3; + //float OOGJHIJPGLF = 7; + //float prop_delta = 3; + uint32 prop_type = 10; + uint32 entity_id = 7; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/EntityFightPropNotify.proto b/NahidaImpact.Protocol/EntityFightPropNotify.proto new file mode 100644 index 0000000..929ef81 --- /dev/null +++ b/NahidaImpact.Protocol/EntityFightPropNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message EntityFightPropNotify { + map fight_prop_map = 11; + uint32 entity_id = 7; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/EntityFightPropUpdateNotify.proto b/NahidaImpact.Protocol/EntityFightPropUpdateNotify.proto new file mode 100644 index 0000000..7f8faad --- /dev/null +++ b/NahidaImpact.Protocol/EntityFightPropUpdateNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + + +message EntityFightPropUpdateNotify { + uint32 entity_id = 4; + map fight_prop_map = 15; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/EntityJumpNotify.proto b/NahidaImpact.Protocol/EntityJumpNotify.proto new file mode 100644 index 0000000..d5a22c6 --- /dev/null +++ b/NahidaImpact.Protocol/EntityJumpNotify.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +import "Vector.proto"; +// CmdId: 8767 +// Obf: KLMLLNEFCEG +message EntityJumpNotify { + // Obf: ONNNDBFLCGB + enum Type { + NULL = 0; + ACTIVE = 1; + PASSIVE = 2; + } + + Vector rot = 1; + Vector pos = 12; + Type jump_type = 2; + uint32 entity_id = 5; +} diff --git a/NahidaImpact.Protocol/EntityMoveInfo.proto b/NahidaImpact.Protocol/EntityMoveInfo.proto new file mode 100644 index 0000000..7ba0436 --- /dev/null +++ b/NahidaImpact.Protocol/EntityMoveInfo.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + + +import "MotionInfo.proto"; +message EntityMoveInfo { + uint32 entity_id = 1; + MotionInfo motion_info = 2; + uint32 scene_time = 3; + uint32 reliable_seq = 4; + bool is_reliable = 5; +} diff --git a/NahidaImpact.Protocol/EntityRendererChangedInfo.proto b/NahidaImpact.Protocol/EntityRendererChangedInfo.proto new file mode 100644 index 0000000..91b7740 --- /dev/null +++ b/NahidaImpact.Protocol/EntityRendererChangedInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message EntityRendererChangedInfo { + map changed_renderers = 1; + bool is_cached = 3; + uint32 visibility_count = 2; +} diff --git a/NahidaImpact.Protocol/Equip.proto b/NahidaImpact.Protocol/Equip.proto new file mode 100644 index 0000000..a673a6e --- /dev/null +++ b/NahidaImpact.Protocol/Equip.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + + +import "Reliquary.proto"; +import "Weapon.proto"; + +message Equip { + oneof detail { + Reliquary reliquary = 1; + Weapon weapon = 2; + } + bool is_locked = 3; +} diff --git a/NahidaImpact.Protocol/EquipParam.proto b/NahidaImpact.Protocol/EquipParam.proto new file mode 100644 index 0000000..7266c94 --- /dev/null +++ b/NahidaImpact.Protocol/EquipParam.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: HPFNFEJGODI +message EquipParam { + uint32 item_id = 1; + uint32 item_num = 2; + uint32 item_level = 3; + uint32 promote_level = 4; +} diff --git a/NahidaImpact.Protocol/EventTriggerType.proto b/NahidaImpact.Protocol/EventTriggerType.proto new file mode 100644 index 0000000..3c13475 --- /dev/null +++ b/NahidaImpact.Protocol/EventTriggerType.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: NCBNIKIODKP +enum EventTriggerType { + EVENT_TRIGGER_NONE = 0; + EVENT_TRIGGER_ENTER_FORCE = 1; +} diff --git a/NahidaImpact.Protocol/EvtAnimatorParameterInfo.proto b/NahidaImpact.Protocol/EvtAnimatorParameterInfo.proto new file mode 100644 index 0000000..90d91d7 --- /dev/null +++ b/NahidaImpact.Protocol/EvtAnimatorParameterInfo.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "AnimatorParameterValueInfo.proto"; +message EvtAnimatorParameterInfo { + uint32 entity_id = 6; + int32 name_id = 1; + AnimatorParameterValueInfo value = 2; + bool is_server_cache = 4; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/EvtAvatarLockChairReq.proto b/NahidaImpact.Protocol/EvtAvatarLockChairReq.proto new file mode 100644 index 0000000..969eda0 --- /dev/null +++ b/NahidaImpact.Protocol/EvtAvatarLockChairReq.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +import "Vector.proto"; +// CmdId: 23086 +// Obf: LBJMDFGMGBD +message EvtAvatarLockChairReq { + Vector position = 10; + uint64 chair_id = 14; + int32 direction = 15; +} diff --git a/NahidaImpact.Protocol/EvtAvatarLockChairRsp.proto b/NahidaImpact.Protocol/EvtAvatarLockChairRsp.proto new file mode 100644 index 0000000..e77de33 --- /dev/null +++ b/NahidaImpact.Protocol/EvtAvatarLockChairRsp.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +import "Vector.proto"; +// CmdId: 26356 +// Obf: ABACJEJFCJJ +message EvtAvatarLockChairRsp { + uint64 chair_id = 5; + Vector position = 9; + int32 retcode = 14; + uint32 entity_id = 10; + int32 direction = 13; +} diff --git a/NahidaImpact.Protocol/EvtBeingHitInfo.proto b/NahidaImpact.Protocol/EvtBeingHitInfo.proto new file mode 100644 index 0000000..f4f8610 --- /dev/null +++ b/NahidaImpact.Protocol/EvtBeingHitInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +import "AttackResult.proto"; +message EvtBeingHitInfo { + uint32 frame_num = 15; + AttackResult attack_result = 4; + uint32 peer_id = 2; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/EvtCostStaminaNotify.proto b/NahidaImpact.Protocol/EvtCostStaminaNotify.proto new file mode 100644 index 0000000..9dec00f --- /dev/null +++ b/NahidaImpact.Protocol/EvtCostStaminaNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + + +message EvtCostStaminaNotify { + float cost_stamina = 3; + uint32 skill_id = 12; +} diff --git a/NahidaImpact.Protocol/EvtCreateGadgetNotify.proto b/NahidaImpact.Protocol/EvtCreateGadgetNotify.proto new file mode 100644 index 0000000..d59773c --- /dev/null +++ b/NahidaImpact.Protocol/EvtCreateGadgetNotify.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +import "Vector.proto"; +import "ForwardType.proto"; +message EvtCreateGadgetNotify { + Vector init_pos = 9; + Vector init_euler_angles = 11; + uint32 prop_owner_entity_id = 4; + bool is_peer_id_from_player = 580; + uint32 room_id = 10; + uint32 camp_type = 2; + uint32 owner_entity_id = 7; + ForwardType forward_type = 13; + uint32 config_id = 14; + uint32 entity_id = 6; + uint32 camp_id = 1; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/EvtDestroyGadgetNotify.proto b/NahidaImpact.Protocol/EvtDestroyGadgetNotify.proto new file mode 100644 index 0000000..fca06b6 --- /dev/null +++ b/NahidaImpact.Protocol/EvtDestroyGadgetNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +import "ForwardType.proto"; +message EvtDestroyGadgetNotify { + ForwardType forward_type = 3; + uint32 entity_id = 10; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/EvtDestroyServerGadgetNotify.proto b/NahidaImpact.Protocol/EvtDestroyServerGadgetNotify.proto new file mode 100644 index 0000000..b154b49 --- /dev/null +++ b/NahidaImpact.Protocol/EvtDestroyServerGadgetNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// CmdId: 23600 +// Obf: OGEONEOAOEN +message EvtDestroyServerGadgetNotify { + uint32 entity_id = 13; +} diff --git a/NahidaImpact.Protocol/EvtDoSkillSuccNotify.proto b/NahidaImpact.Protocol/EvtDoSkillSuccNotify.proto new file mode 100644 index 0000000..daf4da5 --- /dev/null +++ b/NahidaImpact.Protocol/EvtDoSkillSuccNotify.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +import "ForwardType.proto"; +import "Vector.proto"; +message EvtDoSkillSuccNotify { + ForwardType forward_type = 7; + Vector forward = 11; + uint32 skill_id = 12; + uint32 caster_id = 10; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/EvtEntityStartDieEndNotify.proto b/NahidaImpact.Protocol/EvtEntityStartDieEndNotify.proto new file mode 100644 index 0000000..23a09a7 --- /dev/null +++ b/NahidaImpact.Protocol/EvtEntityStartDieEndNotify.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +import "ForwardType.proto"; +// CmdId: 27889 +// Obf: BIBKKFDFKEH +message EvtEntityStartDieEndNotify { + ForwardType forward_type = 8; + uint32 entity_id = 1; + uint32 die_state_flag = 4; + bool immediately = 9; +} diff --git a/NahidaImpact.Protocol/EvtFaceToDirInfo.proto b/NahidaImpact.Protocol/EvtFaceToDirInfo.proto new file mode 100644 index 0000000..0d2cc0d --- /dev/null +++ b/NahidaImpact.Protocol/EvtFaceToDirInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +import "Vector.proto"; +message EvtFaceToDirInfo { + Vector face_dir = 3; + uint32 entity_id = 14; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/EvtFixedRushMove.proto b/NahidaImpact.Protocol/EvtFixedRushMove.proto new file mode 100644 index 0000000..6140edb --- /dev/null +++ b/NahidaImpact.Protocol/EvtFixedRushMove.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "Vector.proto"; +message EvtFixedRushMove { + Vector target_pos = 9; + uint32 entity_id = 2; + string override_collider = 13; + float speed = 15; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/EvtSetAttackTargetInfo.proto b/NahidaImpact.Protocol/EvtSetAttackTargetInfo.proto new file mode 100644 index 0000000..43796e8 --- /dev/null +++ b/NahidaImpact.Protocol/EvtSetAttackTargetInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message EvtSetAttackTargetInfo { + uint32 entity_id = 6; + uint32 attack_target_id = 5; + uint32 select_point_index = 2; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/ExhibitionDisplayInfo.proto b/NahidaImpact.Protocol/ExhibitionDisplayInfo.proto new file mode 100644 index 0000000..c1b752b --- /dev/null +++ b/NahidaImpact.Protocol/ExhibitionDisplayInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: MCIHMDBLAPP +message ExhibitionDisplayInfo { + uint32 id = 1; + uint32 param = 2; + uint32 detail_param = 3; +} diff --git a/NahidaImpact.Protocol/ExitCustomDungeonTryReq.proto b/NahidaImpact.Protocol/ExitCustomDungeonTryReq.proto new file mode 100644 index 0000000..f579cce --- /dev/null +++ b/NahidaImpact.Protocol/ExitCustomDungeonTryReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 23043 +// Obf: JFIJMPLBGPL +message ExitCustomDungeonTryReq { +} diff --git a/NahidaImpact.Protocol/ExitFishingReq.proto b/NahidaImpact.Protocol/ExitFishingReq.proto new file mode 100644 index 0000000..3905bd2 --- /dev/null +++ b/NahidaImpact.Protocol/ExitFishingReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 5737 +// Obf: MAMNOGOKBCH +message ExitFishingReq { +} diff --git a/NahidaImpact.Protocol/ExitTransPointRegionNotify.proto b/NahidaImpact.Protocol/ExitTransPointRegionNotify.proto new file mode 100644 index 0000000..a0c7dbe --- /dev/null +++ b/NahidaImpact.Protocol/ExitTransPointRegionNotify.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// CmdId: 2696 +// Obf: BBGPGHPCHGN +message ExitTransPointRegionNotify { + uint32 point_id = 7; + uint32 scene_id = 6; +} diff --git a/NahidaImpact.Protocol/ExpeditionState.proto b/NahidaImpact.Protocol/ExpeditionState.proto new file mode 100644 index 0000000..2ab72da --- /dev/null +++ b/NahidaImpact.Protocol/ExpeditionState.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +// Obf: OMJCJJGBBNI +enum ExpeditionState { + EXPEDITION_NONE = 0; + EXPEDITION_STARTED = 1; + EXPEDITION_FINISHED = 2; + EXPEDITION_REWARDED = 3; + EXPEDITION_LOCKED = 4; +} diff --git a/NahidaImpact.Protocol/FeatureBlockInfo.proto b/NahidaImpact.Protocol/FeatureBlockInfo.proto new file mode 100644 index 0000000..63fe32b --- /dev/null +++ b/NahidaImpact.Protocol/FeatureBlockInfo.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message FeatureBlockInfo { + uint32 end_time = 2; + uint32 feature_type = 1; +} diff --git a/NahidaImpact.Protocol/FetterData.proto b/NahidaImpact.Protocol/FetterData.proto new file mode 100644 index 0000000..c3f0b1c --- /dev/null +++ b/NahidaImpact.Protocol/FetterData.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message FetterData { + repeated uint32 cond_index_list = 3; + uint32 fetter_state = 2; + uint32 fetter_id = 1; +} diff --git a/NahidaImpact.Protocol/FightPropPair.proto b/NahidaImpact.Protocol/FightPropPair.proto new file mode 100644 index 0000000..a1ae7c3 --- /dev/null +++ b/NahidaImpact.Protocol/FightPropPair.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message FightPropPair { + float prop_value = 2; + uint32 prop_type = 1; +} diff --git a/NahidaImpact.Protocol/FindHilichurlAcceptQuestNotify.proto b/NahidaImpact.Protocol/FindHilichurlAcceptQuestNotify.proto new file mode 100644 index 0000000..aff7134 --- /dev/null +++ b/NahidaImpact.Protocol/FindHilichurlAcceptQuestNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 29747 +// Obf: GKEGJFHNGEJ +message FindHilichurlAcceptQuestNotify { +} diff --git a/NahidaImpact.Protocol/FireworksLaunchParamType.proto b/NahidaImpact.Protocol/FireworksLaunchParamType.proto new file mode 100644 index 0000000..c4119ee --- /dev/null +++ b/NahidaImpact.Protocol/FireworksLaunchParamType.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +// Obf: EDNDPFHDNHB +enum FireworksLaunchParamType { + FIREWORKS_LAUNCH_PARAM_NONE = 0; + FIREWORKS_LAUNCH_PARAM_REPEAT = 1; + FIREWORKS_LAUNCH_PARAM_INTEVAL = 2; + FIREWORKS_LAUNCH_PARAM_DELAY = 3; + FIREWORKS_LAUNCH_PARAM_ROUND_INTEVAL = 4; + FIREWORKS_LAUNCH_PARAM_MAX = 5; +} diff --git a/NahidaImpact.Protocol/FireworksReformParamType.proto b/NahidaImpact.Protocol/FireworksReformParamType.proto new file mode 100644 index 0000000..a3f67fb --- /dev/null +++ b/NahidaImpact.Protocol/FireworksReformParamType.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +// Obf: FPEFLILOLGL +enum FireworksReformParamType { + FIREWORKS_REFORM_PARAM_NONE = 0; + FIREWORKS_REFORM_PARAM_COLOR = 1; + FIREWORKS_REFORM_PARAM_HEIGHT = 2; + FIREWORKS_REFORM_PARAM_SIZE = 3; + FIREWORKS_REFORM_PARAM_DENSITY = 4; + FIREWORKS_REFORM_PARAM_ROTATION = 5; +} diff --git a/NahidaImpact.Protocol/FishBattleBeginReq.proto b/NahidaImpact.Protocol/FishBattleBeginReq.proto new file mode 100644 index 0000000..f8a92ec --- /dev/null +++ b/NahidaImpact.Protocol/FishBattleBeginReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 23596 +// Obf: GNDDFDMHMHN +message FishBattleBeginReq { +} diff --git a/NahidaImpact.Protocol/FishBattleResult.proto b/NahidaImpact.Protocol/FishBattleResult.proto new file mode 100644 index 0000000..521c75f --- /dev/null +++ b/NahidaImpact.Protocol/FishBattleResult.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +// Obf: LCKAOMFDGLP +enum FishBattleResult { + FISH_BATTLE_RESULT_NONE = 0; + FISH_BATTLE_RESULT_SUCC = 1; + FISH_BATTLE_RESULT_FAIL = 2; + FISH_BATTLE_RESULT_TIMEOUT = 3; + FISH_BATTLE_RESULT_CANCEL = 4; + FISH_BATTLE_RESULT_EXIT = 5; +} diff --git a/NahidaImpact.Protocol/FishBiteReq.proto b/NahidaImpact.Protocol/FishBiteReq.proto new file mode 100644 index 0000000..c9a7289 --- /dev/null +++ b/NahidaImpact.Protocol/FishBiteReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 3118 +// Obf: ABBFKLGIAJG +message FishBiteReq { +} diff --git a/NahidaImpact.Protocol/FishEscapeReason.proto b/NahidaImpact.Protocol/FishEscapeReason.proto new file mode 100644 index 0000000..be972d5 --- /dev/null +++ b/NahidaImpact.Protocol/FishEscapeReason.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: ILAHKGBCAOC +enum FishEscapeReason { + FISN_ESCAPE_NONE = 0; + FISH_ESCAPE_SHOCKED = 1; + FISH_ESCAPE_UNHOOK = 2; +} diff --git a/NahidaImpact.Protocol/FishPoolInfo.proto b/NahidaImpact.Protocol/FishPoolInfo.proto new file mode 100644 index 0000000..8fd8bb3 --- /dev/null +++ b/NahidaImpact.Protocol/FishPoolInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message FishPoolInfo { + repeated uint32 fish_area_list = 2; + uint32 pool_id = 1; + uint32 today_fish_num = 3; +} diff --git a/NahidaImpact.Protocol/FishtankFishInfo.proto b/NahidaImpact.Protocol/FishtankFishInfo.proto new file mode 100644 index 0000000..ec4b6ad --- /dev/null +++ b/NahidaImpact.Protocol/FishtankFishInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message FishtankFishInfo { + float initial_rotation_y = 3; + float fish_distance_from_water = 1; + float fish_scale = 2; +} diff --git a/NahidaImpact.Protocol/FleurFairFinishGalleryStageNotify.proto b/NahidaImpact.Protocol/FleurFairFinishGalleryStageNotify.proto new file mode 100644 index 0000000..020f765 --- /dev/null +++ b/NahidaImpact.Protocol/FleurFairFinishGalleryStageNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 5694 +// Obf: BEBMKKFHAGB +message FleurFairFinishGalleryStageNotify { +} diff --git a/NahidaImpact.Protocol/ForceDragBackTransferNotify.proto b/NahidaImpact.Protocol/ForceDragBackTransferNotify.proto new file mode 100644 index 0000000..fc0b78b --- /dev/null +++ b/NahidaImpact.Protocol/ForceDragBackTransferNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 5469 +// Obf: JHMDCJHOOEA +message ForceDragBackTransferNotify { +} diff --git a/NahidaImpact.Protocol/ForceUpdateInfo.proto b/NahidaImpact.Protocol/ForceUpdateInfo.proto new file mode 100644 index 0000000..a417314 --- /dev/null +++ b/NahidaImpact.Protocol/ForceUpdateInfo.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message ForceUpdateInfo { + string force_update_url = 1; +} diff --git a/NahidaImpact.Protocol/ForgeGetQueueDataReq.proto b/NahidaImpact.Protocol/ForgeGetQueueDataReq.proto new file mode 100644 index 0000000..4c99f39 --- /dev/null +++ b/NahidaImpact.Protocol/ForgeGetQueueDataReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 477 +// Obf: AFDBIGNEOMH +message ForgeGetQueueDataReq { +} diff --git a/NahidaImpact.Protocol/ForgeQueueManipulateType.proto b/NahidaImpact.Protocol/ForgeQueueManipulateType.proto new file mode 100644 index 0000000..e666795 --- /dev/null +++ b/NahidaImpact.Protocol/ForgeQueueManipulateType.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: DLEFODPKAGI +enum ForgeQueueManipulateType { + FORGE_QUEUE_MANIPULATE_TYPE_RECEIVE_OUTPUT = 0; + FORGE_QUEUE_MANIPULATE_TYPE_STOP_FORGE = 1; +} diff --git a/NahidaImpact.Protocol/ForwardType.proto b/NahidaImpact.Protocol/ForwardType.proto new file mode 100644 index 0000000..1cda7ef --- /dev/null +++ b/NahidaImpact.Protocol/ForwardType.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + + +enum ForwardType { + FORWARD_TYPE_LOCAL = 0; + FORWARD_TYPE_TO_ALL = 1; + FORWARD_TYPE_TO_ALL_EXCEPT_CUR = 2; + FORWARD_TYPE_TO_HOST = 3; + FORWARD_TYPE_TO_ALL_GUEST = 4; + FORWARD_TYPE_TO_PEER = 5; + FORWARD_TYPE_TO_PEERS = 6; + FORWARD_TYPE_ONLY_SERVER = 7; + FORWARD_TYPE_TO_ALL_EXIST_EXCEPT_CUR = 8; +} diff --git a/NahidaImpact.Protocol/FoundationInfo.proto b/NahidaImpact.Protocol/FoundationInfo.proto new file mode 100644 index 0000000..dac4f3a --- /dev/null +++ b/NahidaImpact.Protocol/FoundationInfo.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + + +import "FoundationStatus.proto"; + +message FoundationInfo { + repeated uint32 uid_list = 2; + uint32 current_building_id = 3; + uint32 locked_by_uid = 4; + FoundationStatus status = 1; +} diff --git a/NahidaImpact.Protocol/FoundationOpType.proto b/NahidaImpact.Protocol/FoundationOpType.proto new file mode 100644 index 0000000..ce27356 --- /dev/null +++ b/NahidaImpact.Protocol/FoundationOpType.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +// Obf: LJLDCFOCBKF +enum FoundationOpType { + FOUNDATION_OP_NONE = 0; + FOUNDATION_OP_BUILD = 1; + FOUNDATION_OP_DEMOLITION = 2; + FOUNDATION_OP_REBUILD = 3; + FOUNDATION_OP_ROTATE = 4; + FOUNDATION_OP_LOCK = 5; + FOUNDATION_OP_UNLOCK = 6; +} diff --git a/NahidaImpact.Protocol/FoundationStatus.proto b/NahidaImpact.Protocol/FoundationStatus.proto new file mode 100644 index 0000000..aa76ff8 --- /dev/null +++ b/NahidaImpact.Protocol/FoundationStatus.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + + +enum FoundationStatus { + FOUNDATION_STATUS_NONE = 0; + FOUNDATION_STATUS_INIT = 1; + FOUNDATION_STATUS_BUILDING = 2; + FOUNDATION_STATUS_BUILT = 3; +} diff --git a/NahidaImpact.Protocol/FriendBrief.proto b/NahidaImpact.Protocol/FriendBrief.proto new file mode 100644 index 0000000..761e5b1 --- /dev/null +++ b/NahidaImpact.Protocol/FriendBrief.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; + +import "FriendOnlineState.proto"; +import "SocialShowAvatarInfo.proto"; +import "FriendEnterHomeOption.proto"; +import "ProfilePicture.proto"; +import "PlatformType.proto"; + +message FriendBrief { + uint32 uid = 1; + string nickname = 2; + uint32 level = 3; + uint32 avatar_id = 4; + uint32 world_level = 5; + string signature = 6; + FriendOnlineState online_state = 7; + uint32 param = 8; + bool is_mp_mode_available = 10; + string online_id = 11; + uint32 last_active_time = 12; + uint32 name_card_id = 13; + uint32 mp_player_num = 14; + bool is_chat_no_disturb = 15; + uint32 chat_sequence = 16; + string remark_name = 17; + repeated SocialShowAvatarInfo show_avatar_info_list = 22; + FriendEnterHomeOption friend_enter_home_option = 23; + ProfilePicture profile_picture = 24; + bool is_game_source = 25; + bool is_psn_source = 26; + PlatformType platform_type = 27; + bool IEAHDCLDOEJ = 28; + bool BJFJJMGENCH = 29; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/FriendEnterHomeOption.proto b/NahidaImpact.Protocol/FriendEnterHomeOption.proto new file mode 100644 index 0000000..b5c3f6f --- /dev/null +++ b/NahidaImpact.Protocol/FriendEnterHomeOption.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + + + + +enum FriendEnterHomeOption { + FriendEnterHomeOption_NeedConfirm = 0; + FriendEnterHomeOption_Refuse = 1; + FriendEnterHomeOption_Direct = 2; +} diff --git a/NahidaImpact.Protocol/FriendOnlineState.proto b/NahidaImpact.Protocol/FriendOnlineState.proto new file mode 100644 index 0000000..f6bc35a --- /dev/null +++ b/NahidaImpact.Protocol/FriendOnlineState.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + + + + +enum FriendOnlineState { + FriendOnlineState_FreiendDisconnect = 0; + FriendOnlineState_FriendOnline = 1; +} diff --git a/NahidaImpact.Protocol/FungusFighterRestartTraningDungeonReq.proto b/NahidaImpact.Protocol/FungusFighterRestartTraningDungeonReq.proto new file mode 100644 index 0000000..db70403 --- /dev/null +++ b/NahidaImpact.Protocol/FungusFighterRestartTraningDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 20911 +// Obf: FHMJCIOJAEA +message FungusFighterRestartTraningDungeonReq { +} diff --git a/NahidaImpact.Protocol/Furniture.proto b/NahidaImpact.Protocol/Furniture.proto new file mode 100644 index 0000000..3f7a1ce --- /dev/null +++ b/NahidaImpact.Protocol/Furniture.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message Furniture { + uint32 count = 1; +} diff --git a/NahidaImpact.Protocol/FurnitureMakeFinishNotify.proto b/NahidaImpact.Protocol/FurnitureMakeFinishNotify.proto new file mode 100644 index 0000000..8c738ce --- /dev/null +++ b/NahidaImpact.Protocol/FurnitureMakeFinishNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 5151 +// Obf: LDABDLLOMKP +message FurnitureMakeFinishNotify { +} diff --git a/NahidaImpact.Protocol/FurnitureMakeHelpReq.proto b/NahidaImpact.Protocol/FurnitureMakeHelpReq.proto new file mode 100644 index 0000000..b6f724b --- /dev/null +++ b/NahidaImpact.Protocol/FurnitureMakeHelpReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 27122 +// Obf: DALFEONAJCG +message FurnitureMakeHelpReq { +} diff --git a/NahidaImpact.Protocol/FurnitureMakeReq.proto b/NahidaImpact.Protocol/FurnitureMakeReq.proto new file mode 100644 index 0000000..842c84b --- /dev/null +++ b/NahidaImpact.Protocol/FurnitureMakeReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 23349 +// Obf: OBBOIIBGLPH +message FurnitureMakeReq { +} diff --git a/NahidaImpact.Protocol/GCGAskDuelReq.proto b/NahidaImpact.Protocol/GCGAskDuelReq.proto new file mode 100644 index 0000000..b9197d4 --- /dev/null +++ b/NahidaImpact.Protocol/GCGAskDuelReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 9805 +// Obf: BPBEHFFOFDJ +message GCGAskDuelReq { +} diff --git a/NahidaImpact.Protocol/GCGClientSettleReq.proto b/NahidaImpact.Protocol/GCGClientSettleReq.proto new file mode 100644 index 0000000..514e9a2 --- /dev/null +++ b/NahidaImpact.Protocol/GCGClientSettleReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 5826 +// Obf: MAPPJDLLDEM +message GCGClientSettleReq { +} diff --git a/NahidaImpact.Protocol/GCGDiceSideType.proto b/NahidaImpact.Protocol/GCGDiceSideType.proto new file mode 100644 index 0000000..029a883 --- /dev/null +++ b/NahidaImpact.Protocol/GCGDiceSideType.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +// Obf: FNMHKJNGFMI +enum GCGDiceSideType { + GCG_DICE_SIDE_INVALID = 0; + GCG_DICE_SIDE_CRYO = 1; + GCG_DICE_SIDE_HYDRO = 2; + GCG_DICE_SIDE_PYRO = 3; + GCG_DICE_SIDE_ELECTRO = 4; + GCG_DICE_SIDE_GEO = 5; + GCG_DICE_SIDE_DENDRO = 6; + GCG_DICE_SIDE_ANEMO = 7; + GCG_DICE_SIDE_PAIMON = 8; +} diff --git a/NahidaImpact.Protocol/GCGEndReason.proto b/NahidaImpact.Protocol/GCGEndReason.proto new file mode 100644 index 0000000..192f1f3 --- /dev/null +++ b/NahidaImpact.Protocol/GCGEndReason.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +// Obf: PNMCCGIBCDL +enum GCGEndReason { + GCG_END_REASON_DEFAULT = 0; + GCG_END_REASON_DIE = 1; + GCG_END_REASON_SURRENDER = 2; + GCG_END_REASON_DISCONNECTED = 3; + GCG_END_REASON_ROUND_LIMIT = 4; + GCG_END_REASON_GM = 5; + GCG_END_REASON_NO_PLAYER = 6; + GCG_END_REASON_GIVE_UP = 7; + GCG_END_REASON_INIT_TIMEOUT = 8; + GCG_END_REASON_EFFECT = 9; + GCG_END_REASON_EXPIRE_TIMEOUT = 10; +} diff --git a/NahidaImpact.Protocol/GCGGameMaxNotify.proto b/NahidaImpact.Protocol/GCGGameMaxNotify.proto new file mode 100644 index 0000000..449520d --- /dev/null +++ b/NahidaImpact.Protocol/GCGGameMaxNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 2039 +// Obf: PEHBIAOIPHD +message GCGGameMaxNotify { +} diff --git a/NahidaImpact.Protocol/GCGInitFinishReq.proto b/NahidaImpact.Protocol/GCGInitFinishReq.proto new file mode 100644 index 0000000..077c28d --- /dev/null +++ b/NahidaImpact.Protocol/GCGInitFinishReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 25601 +// Obf: JNBMOBCMHKK +message GCGInitFinishReq { +} diff --git a/NahidaImpact.Protocol/GCGIntentionChangeType.proto b/NahidaImpact.Protocol/GCGIntentionChangeType.proto new file mode 100644 index 0000000..c405b58 --- /dev/null +++ b/NahidaImpact.Protocol/GCGIntentionChangeType.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: EKDNNONAKME +enum GCGIntentionChangeType { + GCG_INTENTION_CHANGE_NONE = 0; + GCG_INTENTION_CHANGE_RM = 1; +} diff --git a/NahidaImpact.Protocol/GCGMsgPhaseContinue.proto b/NahidaImpact.Protocol/GCGMsgPhaseContinue.proto new file mode 100644 index 0000000..04d1d81 --- /dev/null +++ b/NahidaImpact.Protocol/GCGMsgPhaseContinue.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +// Obf: LINAABJFDJL +message GCGMsgPhaseContinue { +} diff --git a/NahidaImpact.Protocol/GCGOperationPass.proto b/NahidaImpact.Protocol/GCGOperationPass.proto new file mode 100644 index 0000000..df22ce7 --- /dev/null +++ b/NahidaImpact.Protocol/GCGOperationPass.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +// Obf: NIFHACLJODD +message GCGOperationPass { +} diff --git a/NahidaImpact.Protocol/GCGOperationSurrender.proto b/NahidaImpact.Protocol/GCGOperationSurrender.proto new file mode 100644 index 0000000..fd0b68e --- /dev/null +++ b/NahidaImpact.Protocol/GCGOperationSurrender.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +// Obf: BGEEMCOJKPG +message GCGOperationSurrender { +} diff --git a/NahidaImpact.Protocol/GCGPhaseType.proto b/NahidaImpact.Protocol/GCGPhaseType.proto new file mode 100644 index 0000000..8b3d1b2 --- /dev/null +++ b/NahidaImpact.Protocol/GCGPhaseType.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +// Obf: NNHMLKCECBP +enum GCGPhaseType { + OFOHJIEDJKD_GcgPhaseInvalid = 0; + OFOHJIEDJKD_GcgPhaseStart = 1; + OFOHJIEDJKD_GcgPhaseDraw = 2; + OFOHJIEDJKD_GcgPhaseOnStage = 3; + OFOHJIEDJKD_GcgPhaseDice = 4; + OFOHJIEDJKD_GcgPhaseMain = 5; + OFOHJIEDJKD_GcgPhaseEnd = 6; + OFOHJIEDJKD_GcgPhaseDie = 7; + OFOHJIEDJKD_GcgPhaseFin = 8; + OFOHJIEDJKD_GcgPhasePreMain = 9; + OFOHJIEDJKD_GcgPhaseReroll = 10; + OFOHJIEDJKD_GcgPhaseRedraw = 11; +} diff --git a/NahidaImpact.Protocol/GCGReason.proto b/NahidaImpact.Protocol/GCGReason.proto new file mode 100644 index 0000000..8411961 --- /dev/null +++ b/NahidaImpact.Protocol/GCGReason.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +// Obf: MEDIDIAPFAD +enum GCGReason { + MNDCMMKBIBP_Default = 0; + MNDCMMKBIBP_Effect = 1; + MNDCMMKBIBP_Cost = 2; + MNDCMMKBIBP_Gm = 3; + MNDCMMKBIBP_Attack = 4; + MNDCMMKBIBP_Reboot = 5; + MNDCMMKBIBP_PlayCard = 6; + MNDCMMKBIBP_QuicklyOnstage = 7; + MNDCMMKBIBP_RemoveAfterDie = 8; + MNDCMMKBIBP_Init = 9; + MNDCMMKBIBP_EffectDamage = 10; + MNDCMMKBIBP_EffectHeal = 11; + MNDCMMKBIBP_EffectRevive = 12; + MNDCMMKBIBP_InitOnstage = 13; + MNDCMMKBIBP_DieOnstage = 14; + MNDCMMKBIBP_SelectOnstage = 15; + MNDCMMKBIBP_CharacterDie = 16; + MNDCMMKBIBP_ReviveWhenDeath = 17; + MNDCMMKBIBP_TransferToOpponent = 18; + MNDCMMKBIBP_TransferDice = 19; +} diff --git a/NahidaImpact.Protocol/GCGSettleOption.proto b/NahidaImpact.Protocol/GCGSettleOption.proto new file mode 100644 index 0000000..4237bb8 --- /dev/null +++ b/NahidaImpact.Protocol/GCGSettleOption.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: HMHCFCIHGCO +enum GCGSettleOption { + GCG_SETTLE_OPT_NONE = 0; + GCG_SETTLE_OPT_EXIT = 1; + GCG_SETTLE_OPT_CONTINUE = 2; + GCG_SETTLE_OPT_RESTART = 3; +} diff --git a/NahidaImpact.Protocol/GCGSkillHpChangeType.proto b/NahidaImpact.Protocol/GCGSkillHpChangeType.proto new file mode 100644 index 0000000..dac338b --- /dev/null +++ b/NahidaImpact.Protocol/GCGSkillHpChangeType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: EIJGIMEOODA +enum GCGSkillHpChangeType { + GCG_SKILL_HP_CHANGE_NONE = 0; + GCG_SKILL_HP_CHANGE_DAMAGE = 1; + GCG_SKILL_HP_CHANGE_HEAL = 2; +} diff --git a/NahidaImpact.Protocol/GCGSkillPreviewAskReq.proto b/NahidaImpact.Protocol/GCGSkillPreviewAskReq.proto new file mode 100644 index 0000000..5488d44 --- /dev/null +++ b/NahidaImpact.Protocol/GCGSkillPreviewAskReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 3512 +// Obf: JBJPOFPGMJB +message GCGSkillPreviewAskReq { +} diff --git a/NahidaImpact.Protocol/GCGWorldPlayerGCGStateReq.proto b/NahidaImpact.Protocol/GCGWorldPlayerGCGStateReq.proto new file mode 100644 index 0000000..53d86d0 --- /dev/null +++ b/NahidaImpact.Protocol/GCGWorldPlayerGCGStateReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 24419 +// Obf: NFGGAMILGAE +message GCGWorldPlayerGCGStateReq { +} diff --git a/NahidaImpact.Protocol/GCGZoneType.proto b/NahidaImpact.Protocol/GCGZoneType.proto new file mode 100644 index 0000000..ac99988 --- /dev/null +++ b/NahidaImpact.Protocol/GCGZoneType.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +// Obf: BENDDOOFHHP +enum GCGZoneType { + GCG_ZONE_INVALID = 0; + GCG_ZONE_DECK = 1; + GCG_ZONE_HAND = 2; + GCG_ZONE_CHARACTER = 3; + GCG_ZONE_MODIFY = 4; + GCG_ZONE_SUMMON = 5; + GCG_ZONE_ASSIST = 7; + GCG_ZONE_ONSTAGE = 8; + GCG_ZONE_RULE = 9; +} diff --git a/NahidaImpact.Protocol/GachaActivityCreateRobotReq.proto b/NahidaImpact.Protocol/GachaActivityCreateRobotReq.proto new file mode 100644 index 0000000..fa8d8a9 --- /dev/null +++ b/NahidaImpact.Protocol/GachaActivityCreateRobotReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 24297 +// Obf: HECONJKGHHN +message GachaActivityCreateRobotReq { +} diff --git a/NahidaImpact.Protocol/GachaActivityNextStageReq.proto b/NahidaImpact.Protocol/GachaActivityNextStageReq.proto new file mode 100644 index 0000000..bf1c687 --- /dev/null +++ b/NahidaImpact.Protocol/GachaActivityNextStageReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 28908 +// Obf: PBCEHPMKNBG +message GachaActivityNextStageReq { +} diff --git a/NahidaImpact.Protocol/GadgetBornType.proto b/NahidaImpact.Protocol/GadgetBornType.proto new file mode 100644 index 0000000..78d5645 --- /dev/null +++ b/NahidaImpact.Protocol/GadgetBornType.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + + +enum GadgetBornType { + GADGET_BORN_TYPE_NONE = 0; + GADGET_BORN_TYPE_IN_AIR = 1; + GADGET_BORN_TYPE_PLAYER = 2; + GADGET_BORN_TYPE_MONSTER_HIT = 3; + GADGET_BORN_TYPE_MONSTER_DIE = 4; + GADGET_BORN_TYPE_GADGET = 5; + GADGET_BORN_TYPE_GROUND = 6; +} diff --git a/NahidaImpact.Protocol/GadgetCrucibleInfo.proto b/NahidaImpact.Protocol/GadgetCrucibleInfo.proto new file mode 100644 index 0000000..17464d1 --- /dev/null +++ b/NahidaImpact.Protocol/GadgetCrucibleInfo.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message GadgetCrucibleInfo { + uint32 prepare_end_time = 2; + uint32 mp_play_id = 1; +} diff --git a/NahidaImpact.Protocol/GadgetGeneralRewardInfo.proto b/NahidaImpact.Protocol/GadgetGeneralRewardInfo.proto new file mode 100644 index 0000000..47e3342 --- /dev/null +++ b/NahidaImpact.Protocol/GadgetGeneralRewardInfo.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + + +import "ItemParam.proto"; + +message GadgetGeneralRewardInfo { + ItemParam item_param = 5; + repeated uint32 qualify_uid_list = 4; + repeated uint32 remain_uid_list = 3; + uint32 dead_time = 2; + uint32 resin = 1; +} diff --git a/NahidaImpact.Protocol/GadgetPlayInfo.proto b/NahidaImpact.Protocol/GadgetPlayInfo.proto new file mode 100644 index 0000000..d304c77 --- /dev/null +++ b/NahidaImpact.Protocol/GadgetPlayInfo.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + + +import "GadgetCrucibleInfo.proto"; + +message GadgetPlayInfo { + oneof play_info { + GadgetCrucibleInfo crucible_info = 21; + } + repeated uint32 progress_stage_list = 3; + uint32 progress = 6; + uint32 play_type = 1; + uint32 start_cd = 4; + uint32 start_time = 5; + uint32 duration = 2; +} diff --git a/NahidaImpact.Protocol/GalleryStageType.proto b/NahidaImpact.Protocol/GalleryStageType.proto new file mode 100644 index 0000000..7dea41f --- /dev/null +++ b/NahidaImpact.Protocol/GalleryStageType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: BNFCHMDPDFG +enum GalleryStageType { + GALLERY_NONE = 0; + GALLERY_PRESTART = 1; + GALLERY_START = 2; +} diff --git a/NahidaImpact.Protocol/GalleryStartSource.proto b/NahidaImpact.Protocol/GalleryStartSource.proto new file mode 100644 index 0000000..7fe9801 --- /dev/null +++ b/NahidaImpact.Protocol/GalleryStartSource.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: KENCCPDLDJG +enum GalleryStartSource { + GALLERY_START_BY_NONE = 0; + GALLERY_START_BY_MATCH = 1; + GALLERY_START_BY_DRAFT = 2; +} diff --git a/NahidaImpact.Protocol/GatherGadgetInfo.proto b/NahidaImpact.Protocol/GatherGadgetInfo.proto new file mode 100644 index 0000000..0070c35 --- /dev/null +++ b/NahidaImpact.Protocol/GatherGadgetInfo.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message GatherGadgetInfo { + bool is_forbid_guest = 2; + uint32 item_id = 1; +} diff --git a/NahidaImpact.Protocol/GearActivityStartPlayPictureReq.proto b/NahidaImpact.Protocol/GearActivityStartPlayPictureReq.proto new file mode 100644 index 0000000..d0e43ed --- /dev/null +++ b/NahidaImpact.Protocol/GearActivityStartPlayPictureReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 440 +// Obf: HLHLMLGPCIE +message GearActivityStartPlayPictureReq { +} diff --git a/NahidaImpact.Protocol/GetActivityScheduleReq.proto b/NahidaImpact.Protocol/GetActivityScheduleReq.proto new file mode 100644 index 0000000..ed24d17 --- /dev/null +++ b/NahidaImpact.Protocol/GetActivityScheduleReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 885 +// Obf: AFFEMCHGKFN +message GetActivityScheduleReq { +} diff --git a/NahidaImpact.Protocol/GetAllActivatedBargainDataReq.proto b/NahidaImpact.Protocol/GetAllActivatedBargainDataReq.proto new file mode 100644 index 0000000..12db93e --- /dev/null +++ b/NahidaImpact.Protocol/GetAllActivatedBargainDataReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 22200 +// Obf: KGMCPOKKAIL +message GetAllActivatedBargainDataReq { +} diff --git a/NahidaImpact.Protocol/GetAllH5ActivityInfoReq.proto b/NahidaImpact.Protocol/GetAllH5ActivityInfoReq.proto new file mode 100644 index 0000000..441f0a7 --- /dev/null +++ b/NahidaImpact.Protocol/GetAllH5ActivityInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 4793 +// Obf: CFMGENNHKOD +message GetAllH5ActivityInfoReq { +} diff --git a/NahidaImpact.Protocol/GetAllSceneGalleryInfoReq.proto b/NahidaImpact.Protocol/GetAllSceneGalleryInfoReq.proto new file mode 100644 index 0000000..6068203 --- /dev/null +++ b/NahidaImpact.Protocol/GetAllSceneGalleryInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 22232 +// Obf: DOLAHKBMABC +message GetAllSceneGalleryInfoReq { +} diff --git a/NahidaImpact.Protocol/GetAllUnlockNameCardReq.proto b/NahidaImpact.Protocol/GetAllUnlockNameCardReq.proto new file mode 100644 index 0000000..c398c09 --- /dev/null +++ b/NahidaImpact.Protocol/GetAllUnlockNameCardReq.proto @@ -0,0 +1,4 @@ +syntax = "proto3"; + +message GetAllUnlockNameCardReq { +} diff --git a/NahidaImpact.Protocol/GetAllUnlockNameCardRsp.proto b/NahidaImpact.Protocol/GetAllUnlockNameCardRsp.proto new file mode 100644 index 0000000..b946fc2 --- /dev/null +++ b/NahidaImpact.Protocol/GetAllUnlockNameCardRsp.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message GetAllUnlockNameCardRsp { + repeated uint32 name_card_list = 13; + int32 retcode = 16; +} diff --git a/NahidaImpact.Protocol/GetChatEmojiCollectionReq.proto b/NahidaImpact.Protocol/GetChatEmojiCollectionReq.proto new file mode 100644 index 0000000..e31179c --- /dev/null +++ b/NahidaImpact.Protocol/GetChatEmojiCollectionReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 25164 +// Obf: PIAMFKEAKIB +message GetChatEmojiCollectionReq { +} diff --git a/NahidaImpact.Protocol/GetCityReputationMapInfoReq.proto b/NahidaImpact.Protocol/GetCityReputationMapInfoReq.proto new file mode 100644 index 0000000..29a80fa --- /dev/null +++ b/NahidaImpact.Protocol/GetCityReputationMapInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 26582 +// Obf: MOGOMIBKAHA +message GetCityReputationMapInfoReq { +} diff --git a/NahidaImpact.Protocol/GetCompoundDataReq.proto b/NahidaImpact.Protocol/GetCompoundDataReq.proto new file mode 100644 index 0000000..6239f70 --- /dev/null +++ b/NahidaImpact.Protocol/GetCompoundDataReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 8732 +// Obf: IHBMOEIBEGJ +message GetCompoundDataReq { +} diff --git a/NahidaImpact.Protocol/GetCustomDungeonReq.proto b/NahidaImpact.Protocol/GetCustomDungeonReq.proto new file mode 100644 index 0000000..2ed34ab --- /dev/null +++ b/NahidaImpact.Protocol/GetCustomDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 24516 +// Obf: AJIHPMOOCHF +message GetCustomDungeonReq { +} diff --git a/NahidaImpact.Protocol/GetExpeditionAssistInfoListReq.proto b/NahidaImpact.Protocol/GetExpeditionAssistInfoListReq.proto new file mode 100644 index 0000000..834cb27 --- /dev/null +++ b/NahidaImpact.Protocol/GetExpeditionAssistInfoListReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 2643 +// Obf: PDAPPFINCAE +message GetExpeditionAssistInfoListReq { +} diff --git a/NahidaImpact.Protocol/GetFurnitureCurModuleArrangeCountReq.proto b/NahidaImpact.Protocol/GetFurnitureCurModuleArrangeCountReq.proto new file mode 100644 index 0000000..ed862de --- /dev/null +++ b/NahidaImpact.Protocol/GetFurnitureCurModuleArrangeCountReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 27516 +// Obf: KPANNNCEOKM +message GetFurnitureCurModuleArrangeCountReq { +} diff --git a/NahidaImpact.Protocol/GetGachaInfoReq.proto b/NahidaImpact.Protocol/GetGachaInfoReq.proto new file mode 100644 index 0000000..c477f5d --- /dev/null +++ b/NahidaImpact.Protocol/GetGachaInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 181 +// Obf: ICLGLDGHDGP +message GetGachaInfoReq { +} diff --git a/NahidaImpact.Protocol/GetHomeExchangeWoodInfoReq.proto b/NahidaImpact.Protocol/GetHomeExchangeWoodInfoReq.proto new file mode 100644 index 0000000..753216b --- /dev/null +++ b/NahidaImpact.Protocol/GetHomeExchangeWoodInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 20885 +// Obf: BFCMDBHEBGK +message GetHomeExchangeWoodInfoReq { +} diff --git a/NahidaImpact.Protocol/GetMapAreaReq.proto b/NahidaImpact.Protocol/GetMapAreaReq.proto new file mode 100644 index 0000000..b0baece --- /dev/null +++ b/NahidaImpact.Protocol/GetMapAreaReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 8758 +// Obf: IIOCEMHKDEF +message GetMapAreaReq { +} diff --git a/NahidaImpact.Protocol/GetMapMarkTipsReq.proto b/NahidaImpact.Protocol/GetMapMarkTipsReq.proto new file mode 100644 index 0000000..c00235a --- /dev/null +++ b/NahidaImpact.Protocol/GetMapMarkTipsReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 4445 +// Obf: EFPLHMCHFDJ +message GetMapMarkTipsReq { +} diff --git a/NahidaImpact.Protocol/GetMechanicusInfoReq.proto b/NahidaImpact.Protocol/GetMechanicusInfoReq.proto new file mode 100644 index 0000000..432b927 --- /dev/null +++ b/NahidaImpact.Protocol/GetMechanicusInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 6012 +// Obf: LAMDLLMLMJE +message GetMechanicusInfoReq { +} diff --git a/NahidaImpact.Protocol/GetNextResourceInfoReq.proto b/NahidaImpact.Protocol/GetNextResourceInfoReq.proto new file mode 100644 index 0000000..8aed002 --- /dev/null +++ b/NahidaImpact.Protocol/GetNextResourceInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 24599 +// Obf: EOODHGFCINK +message GetNextResourceInfoReq { +} diff --git a/NahidaImpact.Protocol/GetOnlinePlayerListReq.proto b/NahidaImpact.Protocol/GetOnlinePlayerListReq.proto new file mode 100644 index 0000000..d8fe5b5 --- /dev/null +++ b/NahidaImpact.Protocol/GetOnlinePlayerListReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 27587 +// Obf: IGNGJNHHJBM +message GetOnlinePlayerListReq { +} diff --git a/NahidaImpact.Protocol/GetOpActivityInfoReq.proto b/NahidaImpact.Protocol/GetOpActivityInfoReq.proto new file mode 100644 index 0000000..dbab8af --- /dev/null +++ b/NahidaImpact.Protocol/GetOpActivityInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 25823 +// Obf: FGMBOCEJFKB +message GetOpActivityInfoReq { +} diff --git a/NahidaImpact.Protocol/GetPlayerAskFriendListReq.proto b/NahidaImpact.Protocol/GetPlayerAskFriendListReq.proto new file mode 100644 index 0000000..5078585 --- /dev/null +++ b/NahidaImpact.Protocol/GetPlayerAskFriendListReq.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + + +message GetPlayerAskFriendListReq { +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/GetPlayerAskFriendListRsp.proto b/NahidaImpact.Protocol/GetPlayerAskFriendListRsp.proto new file mode 100644 index 0000000..f9aa10e --- /dev/null +++ b/NahidaImpact.Protocol/GetPlayerAskFriendListRsp.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +import "FriendBrief.proto"; + +message GetPlayerAskFriendListRsp { + repeated FriendBrief ask_friend_list = 11; + int32 retcode = 13; +} diff --git a/NahidaImpact.Protocol/GetPlayerBlacklistReq.proto b/NahidaImpact.Protocol/GetPlayerBlacklistReq.proto new file mode 100644 index 0000000..3597a93 --- /dev/null +++ b/NahidaImpact.Protocol/GetPlayerBlacklistReq.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + + +message GetPlayerBlacklistReq { +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/GetPlayerBlacklistRsp.proto b/NahidaImpact.Protocol/GetPlayerBlacklistRsp.proto new file mode 100644 index 0000000..8f867ce --- /dev/null +++ b/NahidaImpact.Protocol/GetPlayerBlacklistRsp.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +import "FriendBrief.proto"; + +message GetPlayerBlacklistRsp { + repeated FriendBrief blacklist = 11; + int32 retcode = 10; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/GetPlayerFriendListReq.proto b/NahidaImpact.Protocol/GetPlayerFriendListReq.proto new file mode 100644 index 0000000..18b00db --- /dev/null +++ b/NahidaImpact.Protocol/GetPlayerFriendListReq.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + + +message GetPlayerFriendListReq { +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/GetPlayerFriendListRsp.proto b/NahidaImpact.Protocol/GetPlayerFriendListRsp.proto new file mode 100644 index 0000000..2843a24 --- /dev/null +++ b/NahidaImpact.Protocol/GetPlayerFriendListRsp.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "FriendBrief.proto"; + +message GetPlayerFriendListRsp { + int32 retcode = 6; + repeated FriendBrief friend_list = 11; + repeated FriendBrief ask_friend_list = 2; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/GetPlayerHomeCompInfoReq.proto b/NahidaImpact.Protocol/GetPlayerHomeCompInfoReq.proto new file mode 100644 index 0000000..1b18407 --- /dev/null +++ b/NahidaImpact.Protocol/GetPlayerHomeCompInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 3709 +// Obf: DCHBFDKENHG +message GetPlayerHomeCompInfoReq { +} diff --git a/NahidaImpact.Protocol/GetPlayerMpModeAvailabilityReq.proto b/NahidaImpact.Protocol/GetPlayerMpModeAvailabilityReq.proto new file mode 100644 index 0000000..f519c34 --- /dev/null +++ b/NahidaImpact.Protocol/GetPlayerMpModeAvailabilityReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 26251 +// Obf: IEIHGELBNKF +message GetPlayerMpModeAvailabilityReq { +} diff --git a/NahidaImpact.Protocol/GetPlayerSocialDetailReq.proto b/NahidaImpact.Protocol/GetPlayerSocialDetailReq.proto new file mode 100644 index 0000000..f796c69 --- /dev/null +++ b/NahidaImpact.Protocol/GetPlayerSocialDetailReq.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// CmdId: 25877 +// Obf: PPPFPCKCCIG +message GetPlayerSocialDetailReq { + uint32 uid = 11; +} diff --git a/NahidaImpact.Protocol/GetPlayerSocialDetailRsp.proto b/NahidaImpact.Protocol/GetPlayerSocialDetailRsp.proto new file mode 100644 index 0000000..f9d9006 --- /dev/null +++ b/NahidaImpact.Protocol/GetPlayerSocialDetailRsp.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "SocialDetail.proto"; +// CmdId: 21823 +// Obf: CFKGBOLEJCB +message GetPlayerSocialDetailRsp { + SocialDetail detail_data = 4; + int32 retcode = 3; +} diff --git a/NahidaImpact.Protocol/GetPlayerTokenReq.proto b/NahidaImpact.Protocol/GetPlayerTokenReq.proto new file mode 100644 index 0000000..20f4f73 --- /dev/null +++ b/NahidaImpact.Protocol/GetPlayerTokenReq.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +message GetPlayerTokenReq { +// CmdId: 27208 + uint32 OAALCMDDLEH = 1201; + string account_uid = 1; + string account_token = 6; + string AGPBMJALCLH = 11; + string birthday = 969; + string country_code = 7; + string KPDLIHKCKEC = 14; + string online_id = 15; + string client_rand_key = 273; + string AJDCDFOGMKM = 69; + string psn_id = 4; + string PKDJNIBNDCK = 3; + uint32 account_type = 10; + uint32 CJMBIOCBEAD = 8; + uint32 key_id = 1353; + uint32 platform_type = 5; + uint32 uid = 2; + uint32 channel_id = 12; + uint32 HANDAGLHBKL = 13; + uint32 JMJFADOIBLD = 808; + bool is_guest = 9; +} diff --git a/NahidaImpact.Protocol/GetPlayerTokenRsp.proto b/NahidaImpact.Protocol/GetPlayerTokenRsp.proto new file mode 100644 index 0000000..fb67361 --- /dev/null +++ b/NahidaImpact.Protocol/GetPlayerTokenRsp.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + + +import "StopServerInfo.proto"; + +// CmdId: 24642 +message GetPlayerTokenRsp { + repeated uint32 finish_collection_id_list = 952; + string accountUid = 3; + string birthday = 822; + string client_ip_str = 856; + string sign = 1326; + string server_rand_key = 1632; + string GHBHPENFKGH = 1475; + bytes extra_bin_data = 7; + bytes security_cmd_buffer = 2; + string token = 4; + string msg = 12; + StopServerInfo stop_server = 569; + string psn_id = 1075; + string country_code = 418; + string secret_key = 15; + uint64 secret_key_seed = 14; + bool is_guest = 10; + bool IsProficientPlayer = 52; + bool OPLCNIEFAFN = 9; + bool HHHFEOKPFCD = 1703; + uint32 RegPlatform = 1; + uint32 key_id = 351; + uint32 PEONMNFOADG = 457; + uint32 HANDAGLHBKL = 1837; + uint32 OAALCMDDLEH = 1444; + uint32 platform_type = 6; + uint32 accountType = 5; + int32 retcode = 11; + uint32 tag = 1490; + uint32 black_uid_end_time = 8; + uint32 uid = 13; + uint32 channel_id = 194; +} diff --git a/NahidaImpact.Protocol/GetRecentMpPlayerListReq.proto b/NahidaImpact.Protocol/GetRecentMpPlayerListReq.proto new file mode 100644 index 0000000..42bc6f9 --- /dev/null +++ b/NahidaImpact.Protocol/GetRecentMpPlayerListReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 9833 +// Obf: MLIHDMMOIJO +message GetRecentMpPlayerListReq { +} diff --git a/NahidaImpact.Protocol/GetRegionSearchReq.proto b/NahidaImpact.Protocol/GetRegionSearchReq.proto new file mode 100644 index 0000000..736bccc --- /dev/null +++ b/NahidaImpact.Protocol/GetRegionSearchReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 2030 +// Obf: BHEPKPEBEGB +message GetRegionSearchReq { +} diff --git a/NahidaImpact.Protocol/GetRogueDairyRepairInfoReq.proto b/NahidaImpact.Protocol/GetRogueDairyRepairInfoReq.proto new file mode 100644 index 0000000..f94335f --- /dev/null +++ b/NahidaImpact.Protocol/GetRogueDairyRepairInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 6887 +// Obf: JFEBJKJKNHI +message GetRogueDairyRepairInfoReq { +} diff --git a/NahidaImpact.Protocol/GetSceneAreaReq.proto b/NahidaImpact.Protocol/GetSceneAreaReq.proto new file mode 100644 index 0000000..bbd3b55 --- /dev/null +++ b/NahidaImpact.Protocol/GetSceneAreaReq.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// CmdId: 25175 +// Obf: LABAJDKACOG +message GetSceneAreaReq { + uint32 scene_id = 15; + uint32 belong_uid = 8; +} diff --git a/NahidaImpact.Protocol/GetSceneAreaRsp.proto b/NahidaImpact.Protocol/GetSceneAreaRsp.proto new file mode 100644 index 0000000..69531bc --- /dev/null +++ b/NahidaImpact.Protocol/GetSceneAreaRsp.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// CmdId: 27029 +// Obf: GOPJBKDDELB +message GetSceneAreaRsp { + uint32 scene_id = 2; + repeated uint32 area_id_list = 8; +} diff --git a/NahidaImpact.Protocol/GetScenePerformanceReq.proto b/NahidaImpact.Protocol/GetScenePerformanceReq.proto new file mode 100644 index 0000000..b016526 --- /dev/null +++ b/NahidaImpact.Protocol/GetScenePerformanceReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 3953 +// Obf: CPFOMLDDHLK +message GetScenePerformanceReq { +} diff --git a/NahidaImpact.Protocol/GetScenePointReq.proto b/NahidaImpact.Protocol/GetScenePointReq.proto new file mode 100644 index 0000000..2ec533c --- /dev/null +++ b/NahidaImpact.Protocol/GetScenePointReq.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// CmdId: 23197 +// Obf: PBIPDICGDKH +message GetScenePointReq { + uint32 belong_uid = 13; + bool FBFJPEPMAOF = 5; + uint32 scene_id =15; +} diff --git a/NahidaImpact.Protocol/GetScenePointRsp.proto b/NahidaImpact.Protocol/GetScenePointRsp.proto new file mode 100644 index 0000000..5fb4c78 --- /dev/null +++ b/NahidaImpact.Protocol/GetScenePointRsp.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +// CmdId: 7133 +// Obf: PMONCPENJMK +message GetScenePointRsp { + repeated uint32 unlocked_point_list = 12; + repeated uint32 unhide_point_list = 1; + uint32 belong_uid = 13; + uint32 scene_id = 3; +} diff --git a/NahidaImpact.Protocol/GetShopmallDataReq.proto b/NahidaImpact.Protocol/GetShopmallDataReq.proto new file mode 100644 index 0000000..5b89858 --- /dev/null +++ b/NahidaImpact.Protocol/GetShopmallDataReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 2616 +// Obf: GKCCFCPCHAK +message GetShopmallDataReq { +} diff --git a/NahidaImpact.Protocol/GetStoreCustomDungeonReq.proto b/NahidaImpact.Protocol/GetStoreCustomDungeonReq.proto new file mode 100644 index 0000000..7460bd1 --- /dev/null +++ b/NahidaImpact.Protocol/GetStoreCustomDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 8591 +// Obf: JOIHPLKGFJD +message GetStoreCustomDungeonReq { +} diff --git a/NahidaImpact.Protocol/GetUgcType.proto b/NahidaImpact.Protocol/GetUgcType.proto new file mode 100644 index 0000000..d40a4f9 --- /dev/null +++ b/NahidaImpact.Protocol/GetUgcType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: KNNNABKDKMA +enum GetUgcType { + GET_UGC_NONE = 0; + GET_UGC_TYPE_MINE = 1; + GET_UGC_TYPE_PUBLISH = 2; +} diff --git a/NahidaImpact.Protocol/GetWidgetSlotReq.proto b/NahidaImpact.Protocol/GetWidgetSlotReq.proto new file mode 100644 index 0000000..0d8dfb3 --- /dev/null +++ b/NahidaImpact.Protocol/GetWidgetSlotReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 24304 +// Obf: BCJMLGNMNHC +message GetWidgetSlotReq { +} diff --git a/NahidaImpact.Protocol/GetWorldMpInfoReq.proto b/NahidaImpact.Protocol/GetWorldMpInfoReq.proto new file mode 100644 index 0000000..0a66f00 --- /dev/null +++ b/NahidaImpact.Protocol/GetWorldMpInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 6964 +// Obf: EGCDJCJPCCI +message GetWorldMpInfoReq { +} diff --git a/NahidaImpact.Protocol/GiveUpRoguelikeDungeonCardReq.proto b/NahidaImpact.Protocol/GiveUpRoguelikeDungeonCardReq.proto new file mode 100644 index 0000000..47e8c66 --- /dev/null +++ b/NahidaImpact.Protocol/GiveUpRoguelikeDungeonCardReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 8630 +// Obf: GKBNCJBCIDH +message GiveUpRoguelikeDungeonCardReq { +} diff --git a/NahidaImpact.Protocol/HideAndSeekSetReadyReq.proto b/NahidaImpact.Protocol/HideAndSeekSetReadyReq.proto new file mode 100644 index 0000000..e815e06 --- /dev/null +++ b/NahidaImpact.Protocol/HideAndSeekSetReadyReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 24183 +// Obf: NJKMNHCIGEJ +message HideAndSeekSetReadyReq { +} diff --git a/NahidaImpact.Protocol/HideAndSeekStageType.proto b/NahidaImpact.Protocol/HideAndSeekStageType.proto new file mode 100644 index 0000000..8b431c8 --- /dev/null +++ b/NahidaImpact.Protocol/HideAndSeekStageType.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +// Obf: AIHOPPMEJNG +enum HideAndSeekStageType { + HIDE_AND_SEEK_STAGE_PREPARE = 0; + HIDE_AND_SEEK_STAGE_PICK = 1; + HIDE_AND_SEEK_STAGE_GAME = 2; + HIDE_AND_SEEK_STAGE_HIDE = 3; + HIDE_AND_SEEK_STAGE_SEEK = 4; + HIDE_AND_SEEK_STAGE_SETTLE = 5; +} diff --git a/NahidaImpact.Protocol/HitColliderType.proto b/NahidaImpact.Protocol/HitColliderType.proto new file mode 100644 index 0000000..d56661c --- /dev/null +++ b/NahidaImpact.Protocol/HitColliderType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +enum HitColliderType { + HIT_COLLIDER_TYPE_INVALID = 0; + HIT_COLLIDER_TYPE_HIT_BOX = 1; + HIT_COLLIDER_TYPE_WET_HIT_BOX = 2; + HIT_COLLIDER_TYPE_HEAD_BOX = 3; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/HitCollision.proto b/NahidaImpact.Protocol/HitCollision.proto new file mode 100644 index 0000000..fc3ce9d --- /dev/null +++ b/NahidaImpact.Protocol/HitCollision.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +import "HitColliderType.proto"; +import "Vector.proto"; + +message HitCollision { + Vector hit_dir = 2; + Vector hit_point = 5; + HitColliderType hit_collider_type = 9; + float attackee_hit_force_angle = 11; // sus + float attackee_hit_entity_angle = 13; // sus +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/HomeEnterEditModeFinishReq.proto b/NahidaImpact.Protocol/HomeEnterEditModeFinishReq.proto new file mode 100644 index 0000000..d4315f6 --- /dev/null +++ b/NahidaImpact.Protocol/HomeEnterEditModeFinishReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 4149 +// Obf: NCEKAKPOPHC +message HomeEnterEditModeFinishReq { +} diff --git a/NahidaImpact.Protocol/HomeGetBasicInfoReq.proto b/NahidaImpact.Protocol/HomeGetBasicInfoReq.proto new file mode 100644 index 0000000..002aa65 --- /dev/null +++ b/NahidaImpact.Protocol/HomeGetBasicInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 27734 +// Obf: IEPBGIKMJFE +message HomeGetBasicInfoReq { +} diff --git a/NahidaImpact.Protocol/HomeGetBlueprintSlotInfoReq.proto b/NahidaImpact.Protocol/HomeGetBlueprintSlotInfoReq.proto new file mode 100644 index 0000000..74cfe7e --- /dev/null +++ b/NahidaImpact.Protocol/HomeGetBlueprintSlotInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 2811 +// Obf: OHOJDOFPJHI +message HomeGetBlueprintSlotInfoReq { +} diff --git a/NahidaImpact.Protocol/HomeGetFishFarmingInfoReq.proto b/NahidaImpact.Protocol/HomeGetFishFarmingInfoReq.proto new file mode 100644 index 0000000..803de9a --- /dev/null +++ b/NahidaImpact.Protocol/HomeGetFishFarmingInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 21521 +// Obf: AFLAFOBONGJ +message HomeGetFishFarmingInfoReq { +} diff --git a/NahidaImpact.Protocol/HomeGetOnlineStatusReq.proto b/NahidaImpact.Protocol/HomeGetOnlineStatusReq.proto new file mode 100644 index 0000000..af005d4 --- /dev/null +++ b/NahidaImpact.Protocol/HomeGetOnlineStatusReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 2120 +// Obf: ICENLMBOJAI +message HomeGetOnlineStatusReq { +} diff --git a/NahidaImpact.Protocol/HomeLimitedShopGoodsListReq.proto b/NahidaImpact.Protocol/HomeLimitedShopGoodsListReq.proto new file mode 100644 index 0000000..6a8cee8 --- /dev/null +++ b/NahidaImpact.Protocol/HomeLimitedShopGoodsListReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 24383 +// Obf: PEEGKBPPJOB +message HomeLimitedShopGoodsListReq { +} diff --git a/NahidaImpact.Protocol/HomeLimitedShopInfoReq.proto b/NahidaImpact.Protocol/HomeLimitedShopInfoReq.proto new file mode 100644 index 0000000..19318cc --- /dev/null +++ b/NahidaImpact.Protocol/HomeLimitedShopInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 23396 +// Obf: FKEGCNDKLJN +message HomeLimitedShopInfoReq { +} diff --git a/NahidaImpact.Protocol/HomeMarkPointFurnitureData.proto b/NahidaImpact.Protocol/HomeMarkPointFurnitureData.proto new file mode 100644 index 0000000..215ae83 --- /dev/null +++ b/NahidaImpact.Protocol/HomeMarkPointFurnitureData.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +import "Vector.proto"; +import "HomeMarkPointNPCData.proto"; +import "HomeMarkPointSuiteData.proto"; +// Obf: MDHHDACNAEL +message HomeMarkPointFurnitureData { + uint32 guid = 1; + uint32 furniture_id = 2; + uint32 furniture_type = 3; + Vector pos = 4; + oneof extra { + HomeMarkPointNPCData npc_data = 6; + HomeMarkPointSuiteData suite_data = 7; + } +} diff --git a/NahidaImpact.Protocol/HomeMarkPointNPCData.proto b/NahidaImpact.Protocol/HomeMarkPointNPCData.proto new file mode 100644 index 0000000..65f7ee1 --- /dev/null +++ b/NahidaImpact.Protocol/HomeMarkPointNPCData.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: DEEONIENNBB +message HomeMarkPointNPCData { + uint32 avatar_id = 1; + uint32 costume_id = 2; +} diff --git a/NahidaImpact.Protocol/HomeMarkPointSuiteData.proto b/NahidaImpact.Protocol/HomeMarkPointSuiteData.proto new file mode 100644 index 0000000..5c45cde --- /dev/null +++ b/NahidaImpact.Protocol/HomeMarkPointSuiteData.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// Obf: KMHJEPCDMMK +message HomeMarkPointSuiteData { + uint32 suite_id = 1; +} diff --git a/NahidaImpact.Protocol/HomePlantFieldStatus.proto b/NahidaImpact.Protocol/HomePlantFieldStatus.proto new file mode 100644 index 0000000..15771c2 --- /dev/null +++ b/NahidaImpact.Protocol/HomePlantFieldStatus.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: JBPMMAEOHLJ +enum HomePlantFieldStatus { + HOME_FIELD_STATUE_NONE = 0; + HOME_FIELD_STATUE_SEED = 1; + HOME_FIELD_STATUE_SPROUT = 2; + HOME_FIELD_STATUE_GATHER = 3; +} diff --git a/NahidaImpact.Protocol/HomePlantInfoReq.proto b/NahidaImpact.Protocol/HomePlantInfoReq.proto new file mode 100644 index 0000000..0451372 --- /dev/null +++ b/NahidaImpact.Protocol/HomePlantInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 7267 +// Obf: CLGIKAPCPMO +message HomePlantInfoReq { +} diff --git a/NahidaImpact.Protocol/HomeResourceTakeFetterExpReq.proto b/NahidaImpact.Protocol/HomeResourceTakeFetterExpReq.proto new file mode 100644 index 0000000..117f38c --- /dev/null +++ b/NahidaImpact.Protocol/HomeResourceTakeFetterExpReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 4383 +// Obf: KGCMMMMGDBC +message HomeResourceTakeFetterExpReq { +} diff --git a/NahidaImpact.Protocol/HomeResourceTakeHomeCoinReq.proto b/NahidaImpact.Protocol/HomeResourceTakeHomeCoinReq.proto new file mode 100644 index 0000000..3f323f8 --- /dev/null +++ b/NahidaImpact.Protocol/HomeResourceTakeHomeCoinReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 4728 +// Obf: LCHACOIBHAH +message HomeResourceTakeHomeCoinReq { +} diff --git a/NahidaImpact.Protocol/HomeSceneInitFinishReq.proto b/NahidaImpact.Protocol/HomeSceneInitFinishReq.proto new file mode 100644 index 0000000..8437148 --- /dev/null +++ b/NahidaImpact.Protocol/HomeSceneInitFinishReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 27778 +// Obf: DLBMDKGFBOI +message HomeSceneInitFinishReq { +} diff --git a/NahidaImpact.Protocol/HostPlayerNotify.proto b/NahidaImpact.Protocol/HostPlayerNotify.proto new file mode 100644 index 0000000..3a4c820 --- /dev/null +++ b/NahidaImpact.Protocol/HostPlayerNotify.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// CmdId: 26380 +// Obf: FKFBKAKPCPA +message HostPlayerNotify { + uint32 host_uid = 13; + uint32 HostPeerId = 15; +} diff --git a/NahidaImpact.Protocol/HuntingOfferState.proto b/NahidaImpact.Protocol/HuntingOfferState.proto new file mode 100644 index 0000000..871f1df --- /dev/null +++ b/NahidaImpact.Protocol/HuntingOfferState.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: DINBLJHHDJN +enum HuntingOfferState { + HUNTING_OFFER_STATE_NONE = 0; + HUNTING_OFFER_STATE_STARTED = 1; + HUNTING_OFFER_STATE_UNSTARTED = 2; + HUNTING_OFFER_STATE_SUCC = 3; +} diff --git a/NahidaImpact.Protocol/InBattleMechanicusCardChallengeState.proto b/NahidaImpact.Protocol/InBattleMechanicusCardChallengeState.proto new file mode 100644 index 0000000..4a1654b --- /dev/null +++ b/NahidaImpact.Protocol/InBattleMechanicusCardChallengeState.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: NCNMHENBLME +enum InBattleMechanicusCardChallengeState { + IN_BATTLE_MECHANICUS_CARD_CHALLENGE_NONE = 0; + IN_BATTLE_MECHANICUS_CARD_CHALLENGE_ON_GOING = 1; + IN_BATTLE_MECHANICUS_CARD_CHALLENGE_FAIL = 2; + IN_BATTLE_MECHANICUS_CARD_CHALLENGE_SUCCESS = 3; +} diff --git a/NahidaImpact.Protocol/InBattleMechanicusStageType.proto b/NahidaImpact.Protocol/InBattleMechanicusStageType.proto new file mode 100644 index 0000000..54a7a37 --- /dev/null +++ b/NahidaImpact.Protocol/InBattleMechanicusStageType.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: MPJAFJCKMDI +enum InBattleMechanicusStageType { + IN_BATTLE_MECHANICUS_STAGE_NONE = 0; + IN_BATTLE_MECHANICUS_STAGE_BUILD = 1; + IN_BATTLE_MECHANICUS_STAGE_CARD_FLIP = 2; + IN_BATTLE_MECHANICUS_STAGE_KILL = 3; +} diff --git a/NahidaImpact.Protocol/InterOpType.proto b/NahidaImpact.Protocol/InterOpType.proto new file mode 100644 index 0000000..7e4ca98 --- /dev/null +++ b/NahidaImpact.Protocol/InterOpType.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: BGICOOCNDKD +enum InterOpType { + INTER_OP_TYPE_FINISH = 0; + INTER_OP_TYPE_START = 1; +} diff --git a/NahidaImpact.Protocol/InteractDailyDungeonInfoNotify.proto b/NahidaImpact.Protocol/InteractDailyDungeonInfoNotify.proto new file mode 100644 index 0000000..7806dec --- /dev/null +++ b/NahidaImpact.Protocol/InteractDailyDungeonInfoNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 2249 +// Obf: CCJDIFPEDOP +message InteractDailyDungeonInfoNotify { +} diff --git a/NahidaImpact.Protocol/InteractType.proto b/NahidaImpact.Protocol/InteractType.proto new file mode 100644 index 0000000..efeaad9 --- /dev/null +++ b/NahidaImpact.Protocol/InteractType.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +// Obf: MMHNBMOLJBI +enum InteractType { + INTERACT_TYPE_NONE = 0; + INTERACT_TYPE_PICK_ITEM = 1; + INTERACT_TYPE_GATHER = 2; + INTERACT_TYPE_OPEN_CHEST = 3; + INTERACT_TYPE_OPEN_STATUE = 4; + INTERACT_TYPE_CONSUM = 5; + INTERACT_TYPE_MP_PLAY_REWARD = 6; + INTERACT_TYPE_VIEW = 7; + INTERACT_TYPE_GENERAL_REWARD = 8; + INTERACT_TYPE_MIRACLE_RING = 9; + INTERACT_TYPE_FOUNDATION = 10; + INTERACT_TYPE_ECHO_SHELL = 11; + INTERACT_TYPE_HOME_GATHER = 12; + INTERACT_TYPE_ENV_ANIMAL = 13; + INTERACT_TYPE_QUEST_GADGET = 14; + INTERACT_TYPE_UI_INTERACT = 15; + INTERACT_TYPE_DESHRET_OBELISK = 16; +} diff --git a/NahidaImpact.Protocol/InvestigationQuestDailyNotify.proto b/NahidaImpact.Protocol/InvestigationQuestDailyNotify.proto new file mode 100644 index 0000000..820b89d --- /dev/null +++ b/NahidaImpact.Protocol/InvestigationQuestDailyNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 22478 +// Obf: GKGAJBBBCDI +message InvestigationQuestDailyNotify { +} diff --git a/NahidaImpact.Protocol/InvestigationReadQuestDailyNotify.proto b/NahidaImpact.Protocol/InvestigationReadQuestDailyNotify.proto new file mode 100644 index 0000000..cc65db8 --- /dev/null +++ b/NahidaImpact.Protocol/InvestigationReadQuestDailyNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 6920 +// Obf: NNFAHGOLKAK +message InvestigationReadQuestDailyNotify { +} diff --git a/NahidaImpact.Protocol/IslandPartySailStage.proto b/NahidaImpact.Protocol/IslandPartySailStage.proto new file mode 100644 index 0000000..a9dcda7 --- /dev/null +++ b/NahidaImpact.Protocol/IslandPartySailStage.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: IAJMOMGBODC +enum IslandPartySailStage { + ISLAND_PARTY_SAIL_STAGE_NONE = 0; + ISLAND_PARTY_SAIL_STAGE_SAIL = 1; + ISLAND_PARTY_SAIL_STAGE_BATTLE = 2; +} diff --git a/NahidaImpact.Protocol/Item.proto b/NahidaImpact.Protocol/Item.proto new file mode 100644 index 0000000..0d5db01 --- /dev/null +++ b/NahidaImpact.Protocol/Item.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + + +import "Material.proto"; +import "Furniture.proto"; +import "Equip.proto"; + +message Item { + oneof detail { + Material material = 5; + Equip equip = 6; + Furniture furniture = 7; + } + uint32 item_id = 1; + uint64 guid = 2; +} diff --git a/NahidaImpact.Protocol/ItemHint.proto b/NahidaImpact.Protocol/ItemHint.proto new file mode 100644 index 0000000..ea430c6 --- /dev/null +++ b/NahidaImpact.Protocol/ItemHint.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: OLBNAADPLKJ +message ItemHint { + uint64 guid = 10; + uint32 item_id = 5; + uint32 count = 1; + bool is_new = 7; +} diff --git a/NahidaImpact.Protocol/ItemParam.proto b/NahidaImpact.Protocol/ItemParam.proto new file mode 100644 index 0000000..aa504d5 --- /dev/null +++ b/NahidaImpact.Protocol/ItemParam.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message ItemParam { + uint32 item_id = 1; + uint32 count = 2; +} diff --git a/NahidaImpact.Protocol/KeepAliveNotify.proto b/NahidaImpact.Protocol/KeepAliveNotify.proto new file mode 100644 index 0000000..33716ef --- /dev/null +++ b/NahidaImpact.Protocol/KeepAliveNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 28778 +// Obf: HIHAGDONBOK +message KeepAliveNotify { +} diff --git a/NahidaImpact.Protocol/LanV3BoatGameStartSingleReq.proto b/NahidaImpact.Protocol/LanV3BoatGameStartSingleReq.proto new file mode 100644 index 0000000..2017a91 --- /dev/null +++ b/NahidaImpact.Protocol/LanV3BoatGameStartSingleReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 21038 +// Obf: MOBJEOLKNCA +message LanV3BoatGameStartSingleReq { +} diff --git a/NahidaImpact.Protocol/LanV3BoatInterruptSettleStageReq.proto b/NahidaImpact.Protocol/LanV3BoatInterruptSettleStageReq.proto new file mode 100644 index 0000000..936a90f --- /dev/null +++ b/NahidaImpact.Protocol/LanV3BoatInterruptSettleStageReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 24666 +// Obf: NPODMHKIKBB +message LanV3BoatInterruptSettleStageReq { +} diff --git a/NahidaImpact.Protocol/LanternRiteTakeSkinRewardReq.proto b/NahidaImpact.Protocol/LanternRiteTakeSkinRewardReq.proto new file mode 100644 index 0000000..b7fe478 --- /dev/null +++ b/NahidaImpact.Protocol/LanternRiteTakeSkinRewardReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 26440 +// Obf: LMCOJFIFJBF +message LanternRiteTakeSkinRewardReq { +} diff --git a/NahidaImpact.Protocol/LastPacketPrintNotify.proto b/NahidaImpact.Protocol/LastPacketPrintNotify.proto new file mode 100644 index 0000000..f49201d --- /dev/null +++ b/NahidaImpact.Protocol/LastPacketPrintNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 22019 +// Obf: NIPJAAHMNBH +message LastPacketPrintNotify { +} diff --git a/NahidaImpact.Protocol/LeaveSceneReq.proto b/NahidaImpact.Protocol/LeaveSceneReq.proto new file mode 100644 index 0000000..7898d70 --- /dev/null +++ b/NahidaImpact.Protocol/LeaveSceneReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 1616 +// Obf: PJEHOELFIJM +message LeaveSceneReq { +} diff --git a/NahidaImpact.Protocol/LeaveWorldNotify.proto b/NahidaImpact.Protocol/LeaveWorldNotify.proto new file mode 100644 index 0000000..2628f70 --- /dev/null +++ b/NahidaImpact.Protocol/LeaveWorldNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 22405 +// Obf: AFINGDDHMPO +message LeaveWorldNotify { +} diff --git a/NahidaImpact.Protocol/LifeStateChangeNotify.proto b/NahidaImpact.Protocol/LifeStateChangeNotify.proto new file mode 100644 index 0000000..d6f52b1 --- /dev/null +++ b/NahidaImpact.Protocol/LifeStateChangeNotify.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +import "ServerBuff.proto"; +import "PlayerDieType.proto"; + +message LifeStateChangeNotify { + uint32 entity_id = 14; + repeated ServerBuff server_buff_list = 12; + uint32 source_entity_id = 4; + uint32 move_reliable_seq = 15; + string attack_tag = 10; + PlayerDieType die_type = 11; + uint32 life_state = 7; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/LuaShellType.proto b/NahidaImpact.Protocol/LuaShellType.proto new file mode 100644 index 0000000..263f3db --- /dev/null +++ b/NahidaImpact.Protocol/LuaShellType.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: CILPGEMKHFH +enum LuaShellType { + LUASHELL_NONE = 0; + LUASHELL_NORMAL = 1; + LUASHELL_SECURITY = 2; + LUASHELL_SHELL_CODE = 3; +} diff --git a/NahidaImpact.Protocol/LunaRiteHintPointType.proto b/NahidaImpact.Protocol/LunaRiteHintPointType.proto new file mode 100644 index 0000000..8cf0ad1 --- /dev/null +++ b/NahidaImpact.Protocol/LunaRiteHintPointType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: JJBCHIKFBAJ +enum LunaRiteHintPointType { + LUNA_RITE_HINT_TYPE_NONE = 0; + LUNA_RITE_HINT_TYPE_RUNE = 1; + LUNA_RITE_HINT_TYPE_CHEST = 2; +} diff --git a/NahidaImpact.Protocol/LunaRiteHintStatusType.proto b/NahidaImpact.Protocol/LunaRiteHintStatusType.proto new file mode 100644 index 0000000..31fc809 --- /dev/null +++ b/NahidaImpact.Protocol/LunaRiteHintStatusType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: GGCKOHLIGEL +enum LunaRiteHintStatusType { + LUNA_RITE_HINT_STATUS_DEFAULT = 0; + LUNA_RITE_HINT_STATUS_NO_COUNT = 1; + LUNA_RITE_HINT_STATUS_FINISH = 2; +} diff --git a/NahidaImpact.Protocol/MPLevelEntityInfo.proto b/NahidaImpact.Protocol/MPLevelEntityInfo.proto new file mode 100644 index 0000000..83a2beb --- /dev/null +++ b/NahidaImpact.Protocol/MPLevelEntityInfo.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + + +import "AbilitySyncStateInfo.proto"; + +message MPLevelEntityInfo { + AbilitySyncStateInfo ability_info = 11; + uint32 authority_peer_id = 12; + uint32 entity_id = 2; +} diff --git a/NahidaImpact.Protocol/MailCollectState.proto b/NahidaImpact.Protocol/MailCollectState.proto new file mode 100644 index 0000000..95e9d44 --- /dev/null +++ b/NahidaImpact.Protocol/MailCollectState.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: EDOAABBJLID +enum MailCollectState { + MAIL_COLLECT_STATE_COLLECTIBLE_UNKNOWN = 0; + MAIL_COLLECT_STATE_NOT_COLLECTIBLE = 1; + MAIL_COLLECT_STATE_COLLECTIBLE_UNCOLLECTED = 2; + MAIL_COLLECT_STATE_COLLECTIBLE_COLLECTED = 3; +} diff --git a/NahidaImpact.Protocol/MailData.proto b/NahidaImpact.Protocol/MailData.proto new file mode 100644 index 0000000..1f062a8 --- /dev/null +++ b/NahidaImpact.Protocol/MailData.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +import "MailTextContent.proto"; +import "MailItem.proto"; +import "MailCollectState.proto"; +// Obf: NGGHHPIHNPM +message MailData { + uint32 mailId = 1; + MailTextContent mail_text_content = 4; + repeated MailItem item_list = 7; + uint32 send_time = 8; + uint32 expire_time = 9; + uint32 importance = 10; + bool is_read = 11; + bool is_attachment_got = 12; + uint32 config_id = 13; + repeated string argument_list = 14; + MailCollectState collect_state = 15; +} diff --git a/NahidaImpact.Protocol/MailItem.proto b/NahidaImpact.Protocol/MailItem.proto new file mode 100644 index 0000000..2ca49ee --- /dev/null +++ b/NahidaImpact.Protocol/MailItem.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "EquipParam.proto"; +import "MaterialDeleteInfo.proto"; +// Obf: BNPJNAPNHKB +message MailItem { + EquipParam equip_param = 1; + MaterialDeleteInfo delete_info = 2; +} diff --git a/NahidaImpact.Protocol/MailTextContent.proto b/NahidaImpact.Protocol/MailTextContent.proto new file mode 100644 index 0000000..f125b54 --- /dev/null +++ b/NahidaImpact.Protocol/MailTextContent.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: GONDLGCFODB +message MailTextContent { + string title = 1; + string content = 2; + string sender = 3; +} diff --git a/NahidaImpact.Protocol/MapAreaInfo.proto b/NahidaImpact.Protocol/MapAreaInfo.proto new file mode 100644 index 0000000..aa1a34a --- /dev/null +++ b/NahidaImpact.Protocol/MapAreaInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: NOPIOICPEHD +message MapAreaInfo { + uint32 map_area_id = 1; + bool is_open = 2; +} diff --git a/NahidaImpact.Protocol/MapMarkFromType.proto b/NahidaImpact.Protocol/MapMarkFromType.proto new file mode 100644 index 0000000..b58ac5b --- /dev/null +++ b/NahidaImpact.Protocol/MapMarkFromType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: PNMEOLJPFCC +enum MapMarkFromType { + MAP_MARK_FROM_TYPE_NONE = 0; + MAP_MARK_FROM_TYPE_MONSTER = 1; + MAP_MARK_FROM_TYPE_QUEST = 2; +} diff --git a/NahidaImpact.Protocol/MapMarkPoint.proto b/NahidaImpact.Protocol/MapMarkPoint.proto new file mode 100644 index 0000000..120dac9 --- /dev/null +++ b/NahidaImpact.Protocol/MapMarkPoint.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +import "Vector.proto"; +import "MapMarkPointType.proto"; +import "MapMarkFromType.proto"; +message MapMarkPoint { + uint32 scene_id = 1; + string name = 2; + Vector pos = 3; + MapMarkPointType point_type = 4; + uint32 monster_id = 5; + MapMarkFromType from_type = 6; + uint32 quest_id = 7; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/MapMarkPointType.proto b/NahidaImpact.Protocol/MapMarkPointType.proto new file mode 100644 index 0000000..45ac6e9 --- /dev/null +++ b/NahidaImpact.Protocol/MapMarkPointType.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +enum MapMarkPointType { + MAP_MARK_POINT_TYPE_NPC = 0; + MAP_MARK_POINT_TYPE_QUEST = 1; + MAP_MARK_POINT_TYPE_SPECIAL = 2; + MAP_MARK_POINT_TYPE_MINE = 3; + MAP_MARK_POINT_TYPE_COLLECTION = 4; + MAP_MARK_POINT_TYPE_MONSTER = 5; + MAP_MARK_POINT_TYPE_FISH_POOL = 6; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/MapMarkTipsInfo.proto b/NahidaImpact.Protocol/MapMarkTipsInfo.proto new file mode 100644 index 0000000..e6e968a --- /dev/null +++ b/NahidaImpact.Protocol/MapMarkTipsInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +import "MapMarkTipsType.proto"; +// Obf: FCABMPGKCEL +message MapMarkTipsInfo { + MapMarkTipsType tips_type = 1; + repeated uint32 point_id_list = 2; +} diff --git a/NahidaImpact.Protocol/MapMarkTipsType.proto b/NahidaImpact.Protocol/MapMarkTipsType.proto new file mode 100644 index 0000000..49f0add --- /dev/null +++ b/NahidaImpact.Protocol/MapMarkTipsType.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// Obf: EEDDJAMKPAE +enum MapMarkTipsType { + MARK_TIPS_DUNGEON_ELEMENT_TRIAL = 0; +} diff --git a/NahidaImpact.Protocol/MarkMapReq.proto b/NahidaImpact.Protocol/MarkMapReq.proto new file mode 100644 index 0000000..a90e6d5 --- /dev/null +++ b/NahidaImpact.Protocol/MarkMapReq.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +import "MapMarkPoint.proto"; + +message MarkMapReq { + + enum Operation { + OPERATION_ADD = 0; + OPERATION_MOD = 1; + OPERATION_DEL = 2; + OPERATION_GET = 3; + } + + MapMarkPoint mark = 11; // old = 11 + MapMarkPoint old = 15; // mark = ??? + Operation op = 3; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/MassiveBoxInfo.proto b/NahidaImpact.Protocol/MassiveBoxInfo.proto new file mode 100644 index 0000000..7192208 --- /dev/null +++ b/NahidaImpact.Protocol/MassiveBoxInfo.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +import "Vector.proto"; +// Obf: GJEOHIBBKDA +message MassiveBoxInfo { + int32 id = 1; + uint32 config_id = 2; + Vector center = 3; + Vector extents = 4; + Vector up = 5; + Vector forward = 6; + Vector right = 7; +} diff --git a/NahidaImpact.Protocol/MassiveEntityState.proto b/NahidaImpact.Protocol/MassiveEntityState.proto new file mode 100644 index 0000000..956711b --- /dev/null +++ b/NahidaImpact.Protocol/MassiveEntityState.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: JAPAIAMBMFF +message MassiveEntityState { + uint32 entity_type = 1; + int64 obj_id = 2; + uint32 element_state = 3; +} diff --git a/NahidaImpact.Protocol/MassiveGrassInfo.proto b/NahidaImpact.Protocol/MassiveGrassInfo.proto new file mode 100644 index 0000000..dff8f84 --- /dev/null +++ b/NahidaImpact.Protocol/MassiveGrassInfo.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "Vector.proto"; +// Obf: GGNBMDPHDAN +message MassiveGrassInfo { + uint32 id = 1; + Vector center = 2; + Vector size = 3; +} diff --git a/NahidaImpact.Protocol/MassivePropParam.proto b/NahidaImpact.Protocol/MassivePropParam.proto new file mode 100644 index 0000000..d1e06fd --- /dev/null +++ b/NahidaImpact.Protocol/MassivePropParam.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +message MassivePropParam { + repeated uint32 reaction_info_list = 2; + repeated float param_list = 3; + uint32 sync_flag = 4; + int32 type = 1; +} diff --git a/NahidaImpact.Protocol/MassivePropSyncInfo.proto b/NahidaImpact.Protocol/MassivePropSyncInfo.proto new file mode 100644 index 0000000..4209552 --- /dev/null +++ b/NahidaImpact.Protocol/MassivePropSyncInfo.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + + +import "MassivePropParam.proto"; + +message MassivePropSyncInfo { + repeated MassivePropParam prop_list = 2; + int64 id = 1; +} diff --git a/NahidaImpact.Protocol/MassiveWaterInfo.proto b/NahidaImpact.Protocol/MassiveWaterInfo.proto new file mode 100644 index 0000000..3aade2f --- /dev/null +++ b/NahidaImpact.Protocol/MassiveWaterInfo.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// Obf: CGABDBLBBGF +message MassiveWaterInfo { + int64 id = 1; +} diff --git a/NahidaImpact.Protocol/MatchReason.proto b/NahidaImpact.Protocol/MatchReason.proto new file mode 100644 index 0000000..eb01daa --- /dev/null +++ b/NahidaImpact.Protocol/MatchReason.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +// Obf: LKAMMLNBBDM +enum MatchReason { + MATCH_NONE = 0; + MATCH_FINISH = 1; + MATCH_PLAYER_CANCEL = 2; + MATCH_TIMEOUT = 3; + MATCH_PLAYER_CONFIRM = 4; + MATCH_FAILED = 5; + MATCH_SYSTEM_ERROR = 6; + MATCH_INTERRUPTED = 7; + MATCH_MP_UNAVAILABLE = 8; + MATCH_CONFIRM_TIMEOUT = 9; +} diff --git a/NahidaImpact.Protocol/MatchType.proto b/NahidaImpact.Protocol/MatchType.proto new file mode 100644 index 0000000..59274d7 --- /dev/null +++ b/NahidaImpact.Protocol/MatchType.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +// Obf: DAHBJFKJLHG +enum MatchType { + MATCH_TYPE_NONE = 0; + MATCH_TYPE_DUNGEON = 1; + MATCH_TYPE_MP_PLAY = 2; + MATCH_TYPE_MECHANICUS = 3; + MATCH_TYPE_GENERAL = 4; + MATCH_TYPE_GCG = 5; +} diff --git a/NahidaImpact.Protocol/Material.proto b/NahidaImpact.Protocol/Material.proto new file mode 100644 index 0000000..f73f317 --- /dev/null +++ b/NahidaImpact.Protocol/Material.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + + +import "MaterialDeleteInfo.proto"; + +message Material { + MaterialDeleteInfo delete_info = 2; + uint32 count = 1; +} diff --git a/NahidaImpact.Protocol/MaterialDeleteInfo.proto b/NahidaImpact.Protocol/MaterialDeleteInfo.proto new file mode 100644 index 0000000..ab2dcac --- /dev/null +++ b/NahidaImpact.Protocol/MaterialDeleteInfo.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +message MaterialDeleteInfo { + message CountDownDelete { + map delete_time_num_map = 1; + uint32 config_count_down_time = 2; + } + message DateTimeDelete { + uint32 delete_time = 1; + } + message DelayWeekCountDownDelete { + map delete_time_num_map = 1; + uint32 config_delay_week = 2; + uint32 config_count_down_time = 3; + } + oneof delete_info { + CountDownDelete count_down_delete = 2; + DateTimeDelete date_delete = 3; + DelayWeekCountDownDelete delay_week_count_down_delete = 4; + } + bool has_delete_config = 1; +} diff --git a/NahidaImpact.Protocol/MaterialDeleteReturnType.proto b/NahidaImpact.Protocol/MaterialDeleteReturnType.proto new file mode 100644 index 0000000..31bfa15 --- /dev/null +++ b/NahidaImpact.Protocol/MaterialDeleteReturnType.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: NHKCGBBJJGE +enum MaterialDeleteReturnType { + MATERIAL_DELETE_RETURN_BAG = 0; + MATERIAL_DELETE_RETURN_SEED = 1; +} diff --git a/NahidaImpact.Protocol/MaterialDeleteUpdateNotify.proto b/NahidaImpact.Protocol/MaterialDeleteUpdateNotify.proto new file mode 100644 index 0000000..c99dd83 --- /dev/null +++ b/NahidaImpact.Protocol/MaterialDeleteUpdateNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 9737 +// Obf: FKMCADJBOIO +message MaterialDeleteUpdateNotify { +} diff --git a/NahidaImpact.Protocol/MathQuaternion.proto b/NahidaImpact.Protocol/MathQuaternion.proto new file mode 100644 index 0000000..816f496 --- /dev/null +++ b/NahidaImpact.Protocol/MathQuaternion.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +message MathQuaternion { + float x = 1; + float z = 3; + float w = 4; + float y = 2; +} diff --git a/NahidaImpact.Protocol/ModifierAction.proto b/NahidaImpact.Protocol/ModifierAction.proto new file mode 100644 index 0000000..e626c83 --- /dev/null +++ b/NahidaImpact.Protocol/ModifierAction.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: DBPAAGNJNHH +enum ModifierAction { + MODIFIER_ACTION_ADDED = 0; + MODIFIER_ACTION_REMOVED = 1; +} diff --git a/NahidaImpact.Protocol/ModifierDurability.proto b/NahidaImpact.Protocol/ModifierDurability.proto new file mode 100644 index 0000000..0c71d88 --- /dev/null +++ b/NahidaImpact.Protocol/ModifierDurability.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message ModifierDurability { + float reduce_ratio = 1; + float remaining_durability = 2; +} diff --git a/NahidaImpact.Protocol/ModifierProperty.proto b/NahidaImpact.Protocol/ModifierProperty.proto new file mode 100644 index 0000000..2123c13 --- /dev/null +++ b/NahidaImpact.Protocol/ModifierProperty.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +import "AbilityString.proto"; +message ModifierProperty { + float value = 12; + AbilityString key = 2; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/MonsterBornType.proto b/NahidaImpact.Protocol/MonsterBornType.proto new file mode 100644 index 0000000..854e605 --- /dev/null +++ b/NahidaImpact.Protocol/MonsterBornType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + + +enum MonsterBornType { + MONSTER_BORN_TYPE_NONE = 0; + MONSTER_BORN_TYPE_DEFAULT = 1; + MONSTER_BORN_TYPE_RANDOM = 2; +} diff --git a/NahidaImpact.Protocol/MonsterRoute.proto b/NahidaImpact.Protocol/MonsterRoute.proto new file mode 100644 index 0000000..39aaddd --- /dev/null +++ b/NahidaImpact.Protocol/MonsterRoute.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + + +import "RoutePoint.proto"; + +message MonsterRoute { + repeated RoutePoint route_points = 1; + float arrive_range = 4; + uint32 speed_level = 2; + uint32 route_type = 3; +} diff --git a/NahidaImpact.Protocol/MotionInfo.proto b/NahidaImpact.Protocol/MotionInfo.proto new file mode 100644 index 0000000..afe357e --- /dev/null +++ b/NahidaImpact.Protocol/MotionInfo.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + + +import "Vector.proto"; +import "MotionState.proto"; + +message MotionInfo { + Vector rot = 2; + Vector ref_pos = 6; + Vector pos = 1; + repeated Vector params = 5; + Vector speed = 3; + uint32 ref_id = 7; + uint32 scene_time = 8; + uint64 interval_velocity = 9; + MotionState state = 4; +} diff --git a/NahidaImpact.Protocol/MotionState.proto b/NahidaImpact.Protocol/MotionState.proto new file mode 100644 index 0000000..ee69061 --- /dev/null +++ b/NahidaImpact.Protocol/MotionState.proto @@ -0,0 +1,64 @@ +syntax = "proto3"; + + +enum MotionState { + MOTION_STATE_NONE = 0; + MOTION_STATE_RESET = 1; + MOTION_STATE_STANDBY = 2; + MOTION_STATE_STANDBY_MOVE = 3; + MOTION_STATE_WALK = 4; + MOTION_STATE_RUN = 5; + MOTION_STATE_DASH = 6; + MOTION_STATE_CLIMB = 7; + MOTION_STATE_CLIMB_JUMP = 8; + MOTION_STATE_STANDBY_TO_CLIMB = 9; + MOTION_STATE_FIGHT = 10; + MOTION_STATE_JUMP = 11; + MOTION_STATE_DROP = 12; + MOTION_STATE_FLY = 13; + MOTION_STATE_SWIM_MOVE = 14; + MOTION_STATE_SWIM_IDLE = 15; + MOTION_STATE_SWIM_DASH = 16; + MOTION_STATE_SWIM_JUMP = 17; + MOTION_STATE_SLIP = 18; + MOTION_STATE_GO_UPSTAIRS = 19; + MOTION_STATE_FALL_ON_GROUND = 20; + MOTION_STATE_JUMP_UP_WALL_FOR_STANDBY = 21; + MOTION_STATE_JUMP_OFF_WALL = 22; + MOTION_STATE_POWERED_FLY = 23; + MOTION_STATE_LADDER_IDLE = 24; + MOTION_STATE_LADDER_MOVE = 25; + MOTION_STATE_LADDER_SLIP = 26; + MOTION_STATE_STANDBY_TO_LADDER = 27; + MOTION_STATE_LADDER_TO_STANDBY = 28; + MOTION_STATE_DANGER_STANDBY = 29; + MOTION_STATE_DANGER_STANDBY_MOVE = 30; + MOTION_STATE_DANGER_WALK = 31; + MOTION_STATE_DANGER_RUN = 32; + MOTION_STATE_DANGER_DASH = 33; + MOTION_STATE_CROUCH_IDLE = 34; + MOTION_STATE_CROUCH_MOVE = 35; + MOTION_STATE_CROUCH_ROLL = 36; + MOTION_STATE_NOTIFY = 37; + MOTION_STATE_LAND_SPEED = 38; + MOTION_STATE_MOVE_FAIL_ACK = 39; + MOTION_STATE_WATERFALL = 40; + MOTION_STATE_DASH_BEFORE_SHAKE = 41; + MOTION_STATE_SIT_IDLE = 42; + MOTION_STATE_FORCE_SET_POS = 43; + MOTION_STATE_QUEST_FORCE_DRAG = 44; + MOTION_STATE_FOLLOW_ROUTE = 45; + MOTION_STATE_SKIFF_BOARDING = 46; + MOTION_STATE_SKIFF_NORMAL = 47; + MOTION_STATE_SKIFF_DASH = 48; + MOTION_STATE_SKIFF_POWERED_DASH = 49; + MOTION_STATE_DESTROY_VEHICLE = 50; + MOTION_STATE_FLY_IDLE = 51; + MOTION_STATE_FLY_SLOW = 52; + MOTION_STATE_FLY_FAST = 53; + MOTION_STATE_AIM_MOVE = 54; + MOTION_STATE_AIR_COMPENSATION = 55; + MOTION_STATE_SORUSH_NORMAL = 56; + MOTION_STATE_ROLLER_COASTER = 57; + MOTION_STATE_NUM = 58; +} diff --git a/NahidaImpact.Protocol/MovingPlatformType.proto b/NahidaImpact.Protocol/MovingPlatformType.proto new file mode 100644 index 0000000..af5df3e --- /dev/null +++ b/NahidaImpact.Protocol/MovingPlatformType.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + + +enum MovingPlatformType { + MOVING_PLATFORM_TYPE_NONE = 0; + MOVING_PLATFORM_TYPE_USE_CONFIG = 1; + MOVING_PLATFORM_TYPE_ABILITY = 2; + MOVING_PLATFORM_TYPE_ROUTE = 3; +} diff --git a/NahidaImpact.Protocol/MpPlayRewardInfo.proto b/NahidaImpact.Protocol/MpPlayRewardInfo.proto new file mode 100644 index 0000000..dd3e719 --- /dev/null +++ b/NahidaImpact.Protocol/MpPlayRewardInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message MpPlayRewardInfo { + repeated uint32 qualify_uid_list = 3; + repeated uint32 remain_uid_list = 2; + uint32 resin = 1; +} diff --git a/NahidaImpact.Protocol/MpSettingType.proto b/NahidaImpact.Protocol/MpSettingType.proto new file mode 100644 index 0000000..ee71ce9 --- /dev/null +++ b/NahidaImpact.Protocol/MpSettingType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: BICPJCKHOPA +enum MpSettingType { + MP_SETTING_TYPE_NO_ENTER = 0; + MP_SETTING_TYPE_ENTER_FREELY = 1; + MP_SETTING_TYPE_ENTER_AFTER_APPLY = 2; +} diff --git a/NahidaImpact.Protocol/MuqadasPotionRestartDungeonReq.proto b/NahidaImpact.Protocol/MuqadasPotionRestartDungeonReq.proto new file mode 100644 index 0000000..55168c2 --- /dev/null +++ b/NahidaImpact.Protocol/MuqadasPotionRestartDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 7410 +// Obf: IAIGMKGLFGE +message MuqadasPotionRestartDungeonReq { +} diff --git a/NahidaImpact.Protocol/NahidaImpact.Protocol.csproj b/NahidaImpact.Protocol/NahidaImpact.Protocol.csproj new file mode 100644 index 0000000..f5e6219 --- /dev/null +++ b/NahidaImpact.Protocol/NahidaImpact.Protocol.csproj @@ -0,0 +1,161 @@ + + + + net8.0 + enable + enable + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NahidaImpact.Protocol/NightCrowGadgetInfo.proto b/NahidaImpact.Protocol/NightCrowGadgetInfo.proto new file mode 100644 index 0000000..e394c5c --- /dev/null +++ b/NahidaImpact.Protocol/NightCrowGadgetInfo.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message NightCrowGadgetInfo { + repeated uint32 argument_list = 1; +} diff --git a/NahidaImpact.Protocol/NpcPositionInfo.proto b/NahidaImpact.Protocol/NpcPositionInfo.proto new file mode 100644 index 0000000..7c4d131 --- /dev/null +++ b/NahidaImpact.Protocol/NpcPositionInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +import "Vector.proto"; +// Obf: NCOCAOMPAEI +message NpcPositionInfo { + uint32 npc_id = 1; + Vector pos = 2; +} diff --git a/NahidaImpact.Protocol/NpcTalkReq.proto b/NahidaImpact.Protocol/NpcTalkReq.proto new file mode 100644 index 0000000..16c47fc --- /dev/null +++ b/NahidaImpact.Protocol/NpcTalkReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message NpcTalkReq { + uint32 npc_entity_id = 7; + uint32 talk_id = 6; +} diff --git a/NahidaImpact.Protocol/NpcTalkRsp.proto b/NahidaImpact.Protocol/NpcTalkRsp.proto new file mode 100644 index 0000000..3ca8299 --- /dev/null +++ b/NahidaImpact.Protocol/NpcTalkRsp.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +// CmdId: 3890 +// Obf: CJMFBCFOJFL +message NpcTalkRsp { + int32 retcode = 2; + uint32 entity_id = 8; + uint32 cur_talk_id = 14; + uint32 npc_entity_id = 15; +} diff --git a/NahidaImpact.Protocol/OfferingInfo.proto b/NahidaImpact.Protocol/OfferingInfo.proto new file mode 100644 index 0000000..f58dc3a --- /dev/null +++ b/NahidaImpact.Protocol/OfferingInfo.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message OfferingInfo { + uint32 offering_id = 1; +} diff --git a/NahidaImpact.Protocol/OnlinePlayerInfo.proto b/NahidaImpact.Protocol/OnlinePlayerInfo.proto new file mode 100644 index 0000000..2421a8c --- /dev/null +++ b/NahidaImpact.Protocol/OnlinePlayerInfo.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + + + + +import "MpSettingType.proto"; +import "ProfilePicture.proto"; +message OnlinePlayerInfo { + uint32 uid = 1; + string nickname = 2; + uint32 player_level = 3; + uint32 avatar_id = 4; + MpSettingType mp_setting_type = 5; + uint32 cur_player_num_in_world = 6; + uint32 world_level = 7; + string online_id = 8; + uint32 name_card_id = 9; + repeated uint32 blacklist_uid_list = 10; + string signature = 11; + ProfilePicture profile_picture = 12; + string psn_id = 13; +} diff --git a/NahidaImpact.Protocol/OpenStateChangeNotify.proto b/NahidaImpact.Protocol/OpenStateChangeNotify.proto new file mode 100644 index 0000000..17adf53 --- /dev/null +++ b/NahidaImpact.Protocol/OpenStateChangeNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// CmdId: 1378 +// Obf: JKAILEDHMIC +message OpenStateChangeNotify { + map open_state_map = 12; +} diff --git a/NahidaImpact.Protocol/OpenStateUpdateNotify.proto b/NahidaImpact.Protocol/OpenStateUpdateNotify.proto new file mode 100644 index 0000000..e03835c --- /dev/null +++ b/NahidaImpact.Protocol/OpenStateUpdateNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message OpenStateUpdateNotify { + // CMD_ID = 1575 + map open_state_map = 7; +} diff --git a/NahidaImpact.Protocol/OutStuckCustomDungeonReq.proto b/NahidaImpact.Protocol/OutStuckCustomDungeonReq.proto new file mode 100644 index 0000000..4bb3357 --- /dev/null +++ b/NahidaImpact.Protocol/OutStuckCustomDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 8657 +// Obf: GONBFMOOHBP +message OutStuckCustomDungeonReq { +} diff --git a/NahidaImpact.Protocol/PacketHead.proto b/NahidaImpact.Protocol/PacketHead.proto new file mode 100644 index 0000000..5aef09e --- /dev/null +++ b/NahidaImpact.Protocol/PacketHead.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +message PacketHead { + map service_app_id_map = 33; + map ext_map = 23; + uint32 user_id = 11; + uint32 target_service = 32; + bool is_set_game_thread = 34; + uint32 enet_channel_id = 4; + uint32 game_thread_index = 35; + uint32 sender_app_id = 24; + uint32 packet_id = 1; + uint32 rpc_id = 2; + uint32 enet_is_reliable = 5; + uint32 rpc_begin_time_ms = 22; + uint32 user_ip = 12; + uint32 client_sequence_id = 3; + uint64 recv_time_ms = 21; + uint32 source_service = 31; + uint32 user_session_id = 13; + uint64 sent_ms = 6; +} diff --git a/NahidaImpact.Protocol/ParamList.proto b/NahidaImpact.Protocol/ParamList.proto new file mode 100644 index 0000000..7b795cd --- /dev/null +++ b/NahidaImpact.Protocol/ParamList.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// Obf: BLCNFAPGDKG +message ParamList { + repeated uint32 param_list = 1; +} diff --git a/NahidaImpact.Protocol/PathfindingPingNotify.proto b/NahidaImpact.Protocol/PathfindingPingNotify.proto new file mode 100644 index 0000000..eb8da33 --- /dev/null +++ b/NahidaImpact.Protocol/PathfindingPingNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 2311 +// Obf: IGADOOAJCML +message PathfindingPingNotify { +} diff --git a/NahidaImpact.Protocol/PerformOperationNotify.proto b/NahidaImpact.Protocol/PerformOperationNotify.proto new file mode 100644 index 0000000..128161f --- /dev/null +++ b/NahidaImpact.Protocol/PerformOperationNotify.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +import "Vector.proto"; +// CmdId: 373 +// Obf: JGGAHIIMHDF +message PerformOperationNotify { + // Obf: NMEKLIBHDMO + enum OperateType { + OPERATE_TYPE_NONE = 0; + OPERATE_TYPE_EFFECT = 1; + } + + Vector pos = 12; + Vector rot = 3; + uint32 index = 8; + uint32 entity_id = 7; + OperateType operate_type = 5; +} diff --git a/NahidaImpact.Protocol/PersonalLineAllDataReq.proto b/NahidaImpact.Protocol/PersonalLineAllDataReq.proto new file mode 100644 index 0000000..3999b1f --- /dev/null +++ b/NahidaImpact.Protocol/PersonalLineAllDataReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 9323 +// Obf: BDPIKKGLOCD +message PersonalLineAllDataReq { +} diff --git a/NahidaImpact.Protocol/PersonalSceneJumpReq.proto b/NahidaImpact.Protocol/PersonalSceneJumpReq.proto new file mode 100644 index 0000000..d271900 --- /dev/null +++ b/NahidaImpact.Protocol/PersonalSceneJumpReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + + +message PersonalSceneJumpReq { + uint32 point_id = 2; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/PersonalSceneJumpRsp.proto b/NahidaImpact.Protocol/PersonalSceneJumpRsp.proto new file mode 100644 index 0000000..b4e0080 --- /dev/null +++ b/NahidaImpact.Protocol/PersonalSceneJumpRsp.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "Vector.proto"; + +message PersonalSceneJumpRsp { + uint32 dest_scene_id = 6; + Vector dest_pos = 7; + int32 retcode = 1; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/PingReq.proto b/NahidaImpact.Protocol/PingReq.proto new file mode 100644 index 0000000..47888c7 --- /dev/null +++ b/NahidaImpact.Protocol/PingReq.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +message PingReq { + // CMD_ID = 549 + bytes sc_data = 5; + double total_tick_time = 1; + float ue_time = 14; +} diff --git a/NahidaImpact.Protocol/PingRsp.proto b/NahidaImpact.Protocol/PingRsp.proto new file mode 100644 index 0000000..55bd760 --- /dev/null +++ b/NahidaImpact.Protocol/PingRsp.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message PingRsp { + // CMD_ID = 20939 + int32 retcode = 1; +} diff --git a/NahidaImpact.Protocol/PlaceInfo.proto b/NahidaImpact.Protocol/PlaceInfo.proto new file mode 100644 index 0000000..86c3d8c --- /dev/null +++ b/NahidaImpact.Protocol/PlaceInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +import "Vector.proto"; +// Obf: COEPLIBIANG +message PlaceInfo { + Vector pos = 1; + Vector rot = 2; +} diff --git a/NahidaImpact.Protocol/PlatformInfo.proto b/NahidaImpact.Protocol/PlatformInfo.proto new file mode 100644 index 0000000..665ede7 --- /dev/null +++ b/NahidaImpact.Protocol/PlatformInfo.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; + + +import "Route.proto"; +import "MathQuaternion.proto"; +import "Vector.proto"; +import "MovingPlatformType.proto"; + +message PlatformInfo { + Route route = 15; + MathQuaternion rot_offset = 12; + MathQuaternion start_rot = 9; + Vector pos_offset = 11; + Vector start_pos = 7; + int32 start_index = 2; + uint32 start_route_time = 3; + bool is_started = 8; + bool is_active = 14; + uint32 route_id = 1; + uint32 point_id = 16; + uint32 start_scene_time = 4; + MovingPlatformType moving_platform_type = 13; + uint32 stop_scene_time = 10; +} diff --git a/NahidaImpact.Protocol/PlatformType.proto b/NahidaImpact.Protocol/PlatformType.proto new file mode 100644 index 0000000..d4ad285 --- /dev/null +++ b/NahidaImpact.Protocol/PlatformType.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + + +enum PlatformType { + PLATFORM_TYPE_EDITOR = 0; + PLATFORM_TYPE_IOS = 1; + PLATFORM_TYPE_ANDROID = 2; + PLATFORM_TYPE_PC = 3; + PLATFORM_TYPE_PS4 = 4; + PLATFORM_TYPE_SERVER = 5; + PLATFORM_TYPE_CLOUD_ANDROID = 6; + PLATFORM_TYPE_CLOUD_IOS = 7; + PLATFORM_TYPE_PS5 = 8; + PLATFORM_TYPE_CLOUD_WEB = 9; + PLATFORM_TYPE_CLOUD_TV = 10; + PLATFORM_TYPE_CLOUD_MAC = 11; + PLATFORM_TYPE_CLOUD_PC = 12; + PLATFORM_TYPE_CLOUD_THIRD_PARTY_MOBILE = 13; + PLATFORM_TYPE_CLOUD_THIRD_PARTY_PC = 14; + PLATFORM_TYPE_CLOUD_WEB_ANDROID = 15; + PLATFORM_TYPE_CLOUD_WEB_IOS = 16; + PLATFORM_TYPE_CLOUD_WEB_PC = 17; + PLATFORM_TYPE_CLOUD_WEB_MAC = 18; + PLATFORM_TYPE_CLOUD_WEB_TOUCH = 19; + PLATFORM_TYPE_CLOUD_WEB_KEYBOARD = 20; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/PlayProduct.proto b/NahidaImpact.Protocol/PlayProduct.proto new file mode 100644 index 0000000..838228f --- /dev/null +++ b/NahidaImpact.Protocol/PlayProduct.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: JHHADHKEAAD +message PlayProduct { + string product_id = 1; + string price_tier = 2; + uint32 schedule_id = 3; +} diff --git a/NahidaImpact.Protocol/PlayTeamEntityInfo.proto b/NahidaImpact.Protocol/PlayTeamEntityInfo.proto new file mode 100644 index 0000000..e7a3f5b --- /dev/null +++ b/NahidaImpact.Protocol/PlayTeamEntityInfo.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +import "AbilitySyncStateInfo.proto"; +// Obf: EHPIOEOLPIA +message PlayTeamEntityInfo { + uint32 entity_id = 1; + uint32 player_uid = 2; + uint32 authority_peer_id = 3; + uint32 gadget_config_id = 5; + AbilitySyncStateInfo ability_info = 6; +} diff --git a/NahidaImpact.Protocol/PlayerChatCDNotify.proto b/NahidaImpact.Protocol/PlayerChatCDNotify.proto new file mode 100644 index 0000000..54f442e --- /dev/null +++ b/NahidaImpact.Protocol/PlayerChatCDNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// CmdId: 26350 +// Obf: NOKLHPPCPKB +message PlayerChatCDNotify { + uint32 over_time = 15; +} diff --git a/NahidaImpact.Protocol/PlayerChatNotify.proto b/NahidaImpact.Protocol/PlayerChatNotify.proto new file mode 100644 index 0000000..f097a03 --- /dev/null +++ b/NahidaImpact.Protocol/PlayerChatNotify.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "ChatInfo.proto"; +// CmdId: 9541 +// Obf: PAHGJBLBNBM +message PlayerChatNotify { + ChatInfo chat_info = 2; + uint32 channel_id = 6; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/PlayerDataNotify.proto b/NahidaImpact.Protocol/PlayerDataNotify.proto new file mode 100644 index 0000000..9725a16 --- /dev/null +++ b/NahidaImpact.Protocol/PlayerDataNotify.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +import "PropValue.proto"; +// CmdId: 1969 +// Obf: PAFKAIFBANO +message PlayerDataNotify { + string nick_name = 2; + bool is_first_login_today = 6; + uint32 region_id = 11; + map prop_map = 12; + uint64 server_time = 1; +} diff --git a/NahidaImpact.Protocol/PlayerDieOption.proto b/NahidaImpact.Protocol/PlayerDieOption.proto new file mode 100644 index 0000000..4236fff --- /dev/null +++ b/NahidaImpact.Protocol/PlayerDieOption.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: FEBNBMEEDHK +enum PlayerDieOption { + DIE_OPT_NONE = 0; + DIE_OPT_REPLAY = 1; + DIE_OPT_CANCEL = 2; + DIE_OPT_REVIVE = 3; +} diff --git a/NahidaImpact.Protocol/PlayerDieType.proto b/NahidaImpact.Protocol/PlayerDieType.proto new file mode 100644 index 0000000..0cbfb5b --- /dev/null +++ b/NahidaImpact.Protocol/PlayerDieType.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + + +enum PlayerDieType { + PLAYER_DIE_TYPE_NONE = 0; + PLAYER_DIE_TYPE_KILL_BY_MONSTER = 1; + PLAYER_DIE_TYPE_KILL_BY_GEAR = 2; + PLAYER_DIE_TYPE_FALL = 3; + PLAYER_DIE_TYPE_DRAWN = 4; + PLAYER_DIE_TYPE_ABYSS = 5; + PLAYER_DIE_TYPE_GM = 6; + PLAYER_DIE_TYPE_CLIMATE_COLD = 7; + PLAYER_DIE_TYPE_STORM_LIGHTING = 8; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/PlayerEnterSceneInfoNotify.proto b/NahidaImpact.Protocol/PlayerEnterSceneInfoNotify.proto new file mode 100644 index 0000000..6605c34 --- /dev/null +++ b/NahidaImpact.Protocol/PlayerEnterSceneInfoNotify.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + + +import "TeamEnterSceneInfo.proto"; +import "AvatarEnterSceneInfo.proto"; +import "MPLevelEntityInfo.proto"; + +message PlayerEnterSceneInfoNotify { + // CMD_ID = 26732 + TeamEnterSceneInfo team_enter_info = 6; + repeated AvatarEnterSceneInfo avatar_enter_info = 7; + MPLevelEntityInfo mp_level_entity_info = 4; + uint32 cur_avatar_entity_id = 8; + uint32 enter_scene_token = 3; +} diff --git a/NahidaImpact.Protocol/PlayerEnterSceneNotify.proto b/NahidaImpact.Protocol/PlayerEnterSceneNotify.proto new file mode 100644 index 0000000..1f4e7a9 --- /dev/null +++ b/NahidaImpact.Protocol/PlayerEnterSceneNotify.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + + +import "Vector.proto"; +import "EnterType.proto"; + +message PlayerEnterSceneNotify { + // CMD_ID = 27217 + repeated uint32 scene_tag_id_list = 9; + string scene_transaction = 1871; + Vector pos = 10; + Vector prev_pos = 7; + uint64 scene_begin_time = 5; + uint32 dungeon_id = 8; + uint32 enter_scene_token = 2; + uint32 scene_id = 11; + uint32 target_uid = 4; + uint32 world_level = 14; + EnterType type = 13; +} diff --git a/NahidaImpact.Protocol/PlayerForceExitReq.proto b/NahidaImpact.Protocol/PlayerForceExitReq.proto new file mode 100644 index 0000000..2d67f8f --- /dev/null +++ b/NahidaImpact.Protocol/PlayerForceExitReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 1819 +// Obf: EAJKGNFALHF +message PlayerForceExitReq { +} diff --git a/NahidaImpact.Protocol/PlayerGameTimeNotify.proto b/NahidaImpact.Protocol/PlayerGameTimeNotify.proto new file mode 100644 index 0000000..d46987b --- /dev/null +++ b/NahidaImpact.Protocol/PlayerGameTimeNotify.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + + +message PlayerGameTimeNotify { + uint32 game_time = 14; + bool is_home = 12; + uint32 uid = 15; +} diff --git a/NahidaImpact.Protocol/PlayerGetForceQuitBanInfoReq.proto b/NahidaImpact.Protocol/PlayerGetForceQuitBanInfoReq.proto new file mode 100644 index 0000000..7e7dc35 --- /dev/null +++ b/NahidaImpact.Protocol/PlayerGetForceQuitBanInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 24478 +// Obf: FFIHLFOEOGJ +message PlayerGetForceQuitBanInfoReq { +} diff --git a/NahidaImpact.Protocol/PlayerLoginReq.proto b/NahidaImpact.Protocol/PlayerLoginReq.proto new file mode 100644 index 0000000..d6055f6 --- /dev/null +++ b/NahidaImpact.Protocol/PlayerLoginReq.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; + + +import "TrackingIOInfo.proto"; +import "AdjustTrackingInfo.proto"; + +message PlayerLoginReq { + // CMD_ID = 8889 + string platform = 14; + string birthday = 1103; + string country_code = 1942; + string psn_id = 1241; + string IOBGNFBOPDB = 6; + string accountUid = 3; + string deviceInfo = 8; + string token = 7; + string EKJMKANABNG = 75; + string OAGOEDPHHMI = 13; + TrackingIOInfo tracking_io_info = 1564; + string checksumClientVersion = 1195; + string online_id = 600; + string systemVersion = 1; + string deviceName = 15; + string PCIONLIFPNA = 1474; + string OJPMBLGGOEA = 850; + string EBMJALHOJEN = 566; + string LFEONILNGDA = 776; + string NGBFLOJCACC = 1072; + bytes extra_bin_data = 322; + bytes DLJPPJFPMOA = 283; + bytes security_cmd_reply = 2035; + AdjustTrackingInfo adjust_tracking_info = 1787; + uint64 login_rand = 4; + uint32 target_uid = 10; + uint32 tag = 211; + uint32 accountType = 9; + uint32 client_data_version = 131; + uint32 language_type = 12; + uint32 channel_id = 536; + uint32 CJMBIOCBEAD = 1637; + uint32 CJEPHIBBFLP = 1690; + uint32 CNIJMEMEACO = 1452; + uint32 GCIMICDGBHH = 1426; + uint32 FMHKCHJDGHI = 1307; + uint32 IPJKCIOLKEL = 1294; + uint32 HANDAGLHBKL = 812; + uint32 PEONMNFOADG = 2028; + bool is_guest = 2; + bool is_transfer = 1264; + bool is_editor = 11; + uint32 target_home_owner_uid = 480; + uint32 platform_type = 5; +} diff --git a/NahidaImpact.Protocol/PlayerLoginRsp.proto b/NahidaImpact.Protocol/PlayerLoginRsp.proto new file mode 100644 index 0000000..8c3e912 --- /dev/null +++ b/NahidaImpact.Protocol/PlayerLoginRsp.proto @@ -0,0 +1,49 @@ +syntax = "proto3"; + + +import "BlockInfo.proto"; +import "ResVersionConfig.proto"; +import "StopServerInfo.proto"; +import "ShortAbilityHashPair.proto"; +import "FeatureBlockInfo.proto"; + +message PlayerLoginRsp { + // CMD_ID = 9913 + map ability_hash_map = 3; + string client_silence_version_suffix = 477; + map block_info_map = 1662; + string client_version_suffix = 1953; + string birthday = 964; + string country_code = 974; + string game_biz = 8; + string EJOIOKOFNFA = 924; + string JIMFJPFJKFF = 1938; + string ADJCHKHHDLF = 1097; + ResVersionConfig next_res_version_config = 1996; + StopServerInfo DFFMGGODIII = 2005; + repeated ShortAbilityHashPair short_ability_hash_map = 843; + bytes sc_info = 1468; //もう一つのProtoではplayer_dataとsc_infoが逆 + ResVersionConfig res_version_config = 424; + string next_resource_url = 1795; + bytes player_data = 11; //もう一つのProtoではplayer_dataとsc_infoが逆 + repeated FeatureBlockInfo feature_block_info_list = 1359; + string msg = 456; + bool BMHJNKFAAKL = 9; + bool OCPPNCCIPBI = 14; + bool FMBFGEAPJGE = 4; + bool is_data_need_relogin = 1239; + bool is_transfer = 1884; + bool PCEDOAMCGKK = 2010; + bool GHCLMKADGBH = 1962; + uint32 player_data_version = 13; + uint32 client_data_version = 5; + int32 retcode = 1; + double total_tick_time = 1954; + uint32 client_silence_data_version = 12; + int32 ability_hash_code = 2; + uint64 login_rand = 15; + uint32 target_uid = 7; + bool is_audit = 674; + bool IsUseAbilityHash = 385; + uint32 target_home_owner_uid = 401; +} diff --git a/NahidaImpact.Protocol/PlayerLogoutNotify.proto b/NahidaImpact.Protocol/PlayerLogoutNotify.proto new file mode 100644 index 0000000..76f31ae --- /dev/null +++ b/NahidaImpact.Protocol/PlayerLogoutNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + + +message PlayerLogoutNotify { + int32 retcode = 8; +} diff --git a/NahidaImpact.Protocol/PlayerLogoutReq.proto b/NahidaImpact.Protocol/PlayerLogoutReq.proto new file mode 100644 index 0000000..f4084f8 --- /dev/null +++ b/NahidaImpact.Protocol/PlayerLogoutReq.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + + +message PlayerLogoutReq { + enum Reason { + DISCONNECT = 0; + CLIENT_REQ = 1; + TIMEOUT = 2; + ADMIN_REQ = 3; + SERVER_CLOSE = 4; + GM_CLEAR = 5; + PLAYER_TRANSFER = 6; + CLIENT_CHECKSUM_INVALID = 7; + REASON_MUIP_MOVE_SAVE_WAIT = 8; + } + + Reason reason = 14; +} diff --git a/NahidaImpact.Protocol/PlayerLogoutRsp.proto b/NahidaImpact.Protocol/PlayerLogoutRsp.proto new file mode 100644 index 0000000..63a1c9b --- /dev/null +++ b/NahidaImpact.Protocol/PlayerLogoutRsp.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + + +message PlayerLogoutRsp { + int32 retcode = 1; +} diff --git a/NahidaImpact.Protocol/PlayerPropChangeNotify.proto b/NahidaImpact.Protocol/PlayerPropChangeNotify.proto new file mode 100644 index 0000000..8ecc72b --- /dev/null +++ b/NahidaImpact.Protocol/PlayerPropChangeNotify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + + +message PlayerPropChangeNotify { + uint32 prop_type = 11; + uint32 prop_delta = 7; +} diff --git a/NahidaImpact.Protocol/PlayerPropNotify.proto b/NahidaImpact.Protocol/PlayerPropNotify.proto new file mode 100644 index 0000000..c25740a --- /dev/null +++ b/NahidaImpact.Protocol/PlayerPropNotify.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + + +import "PropValue.proto"; + +message PlayerPropNotify { + map prop_map = 13; +} diff --git a/NahidaImpact.Protocol/PlayerRTTInfo.proto b/NahidaImpact.Protocol/PlayerRTTInfo.proto new file mode 100644 index 0000000..c9544a6 --- /dev/null +++ b/NahidaImpact.Protocol/PlayerRTTInfo.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: MCDPPKMOEJJ +message PlayerRTTInfo { + uint32 uid = 6; + uint32 rtt = 14; +} diff --git a/NahidaImpact.Protocol/PlayerStoreNotify.proto b/NahidaImpact.Protocol/PlayerStoreNotify.proto new file mode 100644 index 0000000..4844466 --- /dev/null +++ b/NahidaImpact.Protocol/PlayerStoreNotify.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +import "Item.proto"; +import "StoreType.proto"; +// CmdId: 9906 +// Obf: HILAGDNCPDA +message PlayerStoreNotify { + uint32 weight_limit = 5; + repeated Item item_list = 6; + StoreType store_type = 9; +} diff --git a/NahidaImpact.Protocol/PlayerWidgetInfo.proto b/NahidaImpact.Protocol/PlayerWidgetInfo.proto new file mode 100644 index 0000000..1fba007 --- /dev/null +++ b/NahidaImpact.Protocol/PlayerWidgetInfo.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + + + + +import "WidgetSlotData.proto"; +message PlayerWidgetInfo { + uint32 uid = 13; + repeated WidgetSlotData slot_list = 14; +} diff --git a/NahidaImpact.Protocol/PostEnterSceneReq.proto b/NahidaImpact.Protocol/PostEnterSceneReq.proto new file mode 100644 index 0000000..bcbf9f7 --- /dev/null +++ b/NahidaImpact.Protocol/PostEnterSceneReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message PostEnterSceneReq { + // CMD_ID = 9304 + uint32 enter_scene_token = 10; +} diff --git a/NahidaImpact.Protocol/PostEnterSceneRsp.proto b/NahidaImpact.Protocol/PostEnterSceneRsp.proto new file mode 100644 index 0000000..a04c754 --- /dev/null +++ b/NahidaImpact.Protocol/PostEnterSceneRsp.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message PostEnterSceneRsp { + // CMD_ID = 5422 + int32 retcode = 10; + uint32 enter_scene_token = 11; +} diff --git a/NahidaImpact.Protocol/PotionRestartDungeonReq.proto b/NahidaImpact.Protocol/PotionRestartDungeonReq.proto new file mode 100644 index 0000000..7093e6e --- /dev/null +++ b/NahidaImpact.Protocol/PotionRestartDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 465 +// Obf: KNFAPFPMPNF +message PotionRestartDungeonReq { +} diff --git a/NahidaImpact.Protocol/PrivateChatNotify.proto b/NahidaImpact.Protocol/PrivateChatNotify.proto new file mode 100644 index 0000000..f7fe072 --- /dev/null +++ b/NahidaImpact.Protocol/PrivateChatNotify.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + + + + +import "ChatInfo.proto"; +// CmdId: 4952 +message PrivateChatNotify { + ChatInfo chat_info = 9; +} diff --git a/NahidaImpact.Protocol/PrivateChatReq.proto b/NahidaImpact.Protocol/PrivateChatReq.proto new file mode 100644 index 0000000..061d419 --- /dev/null +++ b/NahidaImpact.Protocol/PrivateChatReq.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + + +message PrivateChatReq { + uint32 target_uid = 12; + oneof content { + string text = 1; + uint32 icon = 4; + } + } \ No newline at end of file diff --git a/NahidaImpact.Protocol/PrivateChatRsp.proto b/NahidaImpact.Protocol/PrivateChatRsp.proto new file mode 100644 index 0000000..615b64e --- /dev/null +++ b/NahidaImpact.Protocol/PrivateChatRsp.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + + +message PrivateChatRsp { + int32 retcode = 3; + uint32 chat_forbidden_endtime = 5; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/ProfilePicture.proto b/NahidaImpact.Protocol/ProfilePicture.proto new file mode 100644 index 0000000..a409911 --- /dev/null +++ b/NahidaImpact.Protocol/ProfilePicture.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + + + + +message ProfilePicture { + uint32 avatar_id = 1; + uint32 costume_id = 2; +} diff --git a/NahidaImpact.Protocol/PropChangeReason.proto b/NahidaImpact.Protocol/PropChangeReason.proto new file mode 100644 index 0000000..b246f40 --- /dev/null +++ b/NahidaImpact.Protocol/PropChangeReason.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + + +enum PropChangeReason { + PROP_CHANGE_REASON_NONE = 0; + PROP_CHANGE_REASON_STATUE_RECOVER = 1; + PROP_CHANGE_REASON_ENERGY_BALL = 2; + PROP_CHANGE_REASON_ABILITY = 3; + PROP_CHANGE_REASON_LEVELUP = 4; + PROP_CHANGE_REASON_ITEM = 5; + PROP_CHANGE_REASON_AVATAR_CARD = 6; + PROP_CHANGE_REASON_CITY_LEVELUP = 7; + PROP_CHANGE_REASON_AVATAR_UPGRADE = 8; + PROP_CHANGE_REASON_AVATAR_PROMOTE = 9; + PROP_CHANGE_REASON_PLAYER_ADD_EXP = 10; + PROP_CHANGE_REASON_FINISH_QUEST = 11; + PROP_CHANGE_REASON_GM = 12; + PROP_CHANGE_REASON_MANUAL_ADJUST_WORLD_LEVEL = 13; +} diff --git a/NahidaImpact.Protocol/PropPair.proto b/NahidaImpact.Protocol/PropPair.proto new file mode 100644 index 0000000..b3d2ec7 --- /dev/null +++ b/NahidaImpact.Protocol/PropPair.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + + +import "PropValue.proto"; + +message PropPair { + PropValue prop_value = 2; + uint32 type = 1; +} diff --git a/NahidaImpact.Protocol/PropValue.proto b/NahidaImpact.Protocol/PropValue.proto new file mode 100644 index 0000000..7a17ec4 --- /dev/null +++ b/NahidaImpact.Protocol/PropValue.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + + +message PropValue { + uint32 type = 1; + oneof value { + int64 ival = 2; + float fval = 3; + } + int64 val = 4; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/ProtEntityType.proto b/NahidaImpact.Protocol/ProtEntityType.proto new file mode 100644 index 0000000..0d07fbe --- /dev/null +++ b/NahidaImpact.Protocol/ProtEntityType.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + + +enum ProtEntityType { + PROT_ENTITY_TYPE_NONE = 0; + PROT_ENTITY_TYPE_AVATAR = 1; + PROT_ENTITY_TYPE_MONSTER = 2; + PROT_ENTITY_TYPE_NPC = 3; + PROT_ENTITY_TYPE_GADGET = 4; + PROT_ENTITY_TYPE_REGION = 5; + PROT_ENTITY_TYPE_WEAPON = 6; + PROT_ENTITY_TYPE_WEATHER = 7; + PROT_ENTITY_TYPE_SCENE = 8; + PROT_ENTITY_TYPE_TEAM = 9; + PROT_ENTITY_TYPE_MASSIVE_ENTITY = 10; + PROT_ENTITY_TYPE_MP_LEVEL = 11; + PROT_ENTITY_TYPE_PLAY_TEAM_ENTITY = 12; + PROT_ENTITY_TYPE_EYE_POINT = 13; + PROT_ENTITY_TYPE_MAX = 14; +} diff --git a/NahidaImpact.Protocol/PullPrivateChatReq.proto b/NahidaImpact.Protocol/PullPrivateChatReq.proto new file mode 100644 index 0000000..4783446 --- /dev/null +++ b/NahidaImpact.Protocol/PullPrivateChatReq.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// CmdId: 22346 +// Obf: CDBDGACCDJI +message PullPrivateChatReq { + uint32 from_sequence = 11; + uint32 target_uid = 7; + uint32 pull_num = 8; +} diff --git a/NahidaImpact.Protocol/PullRecentChatReq.proto b/NahidaImpact.Protocol/PullRecentChatReq.proto new file mode 100644 index 0000000..8d11835 --- /dev/null +++ b/NahidaImpact.Protocol/PullRecentChatReq.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// CmdId: 23337 +// Obf: DLAJEHFIMNF +message PullRecentChatReq { + uint32 pull_num = 7; + uint32 begin_sequence = 14; +} diff --git a/NahidaImpact.Protocol/QueryCurrRegionHttpRsp.proto b/NahidaImpact.Protocol/QueryCurrRegionHttpRsp.proto new file mode 100644 index 0000000..df31e0c --- /dev/null +++ b/NahidaImpact.Protocol/QueryCurrRegionHttpRsp.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + + +import "ForceUpdateInfo.proto"; +import "StopServerInfo.proto"; +import "RegionInfo.proto"; + +message QueryCurrRegionHttpRsp { + oneof detail { + ForceUpdateInfo force_udpate = 4; + StopServerInfo stop_server = 5; + } + RegionInfo region_info = 3; + bytes client_secret_key = 11; + bytes region_custom_config_encrypted = 12; + bytes client_region_custom_config_encrypted = 13; + string msg = 2; + int32 retcode = 1; +} diff --git a/NahidaImpact.Protocol/QueryRegionListHttpRsp.proto b/NahidaImpact.Protocol/QueryRegionListHttpRsp.proto new file mode 100644 index 0000000..9f9e34e --- /dev/null +++ b/NahidaImpact.Protocol/QueryRegionListHttpRsp.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + + +import "RegionSimpleInfo.proto"; + +message QueryRegionListHttpRsp { + bytes client_custom_config_encrypted = 6; + bytes client_secret_key = 5; + repeated RegionSimpleInfo region_list = 2; + int32 retcode = 1; + bool enable_login_pc = 7; +} diff --git a/NahidaImpact.Protocol/Quest.proto b/NahidaImpact.Protocol/Quest.proto new file mode 100644 index 0000000..6e38f8a --- /dev/null +++ b/NahidaImpact.Protocol/Quest.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +// Obf: BLFINGECHDB +message Quest { + uint32 quest_id = 1; + uint32 state = 2; + uint32 start_time = 4; + bool is_random = 5; + uint32 parent_quest_id = 6; + uint32 quest_config_id = 7; + uint32 start_game_time = 8; + uint32 accept_time = 9; + repeated uint32 lacked_npc_list = 10; + repeated uint32 finish_progress_list = 11; + repeated uint32 fail_progress_list = 12; + map lacked_npc_map = 13; + repeated uint32 lacked_place_list = 14; + map lacked_place_map = 15; +} diff --git a/NahidaImpact.Protocol/ReadNicknameAuditReq.proto b/NahidaImpact.Protocol/ReadNicknameAuditReq.proto new file mode 100644 index 0000000..66752c4 --- /dev/null +++ b/NahidaImpact.Protocol/ReadNicknameAuditReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 8131 +// Obf: APEFFPOJEKC +message ReadNicknameAuditReq { +} diff --git a/NahidaImpact.Protocol/ReadPrivateChatReq.proto b/NahidaImpact.Protocol/ReadPrivateChatReq.proto new file mode 100644 index 0000000..0fc72ec --- /dev/null +++ b/NahidaImpact.Protocol/ReadPrivateChatReq.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// CmdId: 5538 +// Obf: BMBHFJMPFKB +message ReadPrivateChatReq { + uint32 target_uid = 12; +} diff --git a/NahidaImpact.Protocol/ReadPrivateChatRsp.proto b/NahidaImpact.Protocol/ReadPrivateChatRsp.proto new file mode 100644 index 0000000..b95bf81 --- /dev/null +++ b/NahidaImpact.Protocol/ReadPrivateChatRsp.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// CmdId: 9593 +// Obf: LOCJJOEEJMG +message ReadPrivateChatRsp { + int32 retcode = 4; +} diff --git a/NahidaImpact.Protocol/ReadSignatureAuditReq.proto b/NahidaImpact.Protocol/ReadSignatureAuditReq.proto new file mode 100644 index 0000000..d64a65d --- /dev/null +++ b/NahidaImpact.Protocol/ReadSignatureAuditReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 29290 +// Obf: GCJILPOLMJP +message ReadSignatureAuditReq { +} diff --git a/NahidaImpact.Protocol/RecordUsage.proto b/NahidaImpact.Protocol/RecordUsage.proto new file mode 100644 index 0000000..a7272ff --- /dev/null +++ b/NahidaImpact.Protocol/RecordUsage.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +// Obf: APFGDKHEIBO +enum RecordUsage { + UGC_RECORD_USAGE_NONE = 0; + UGC_RECORD_USAGE_IMPORT = 1; + UGC_RECORD_USAGE_PLAY = 2; + UGC_RECORD_USAGE_TRIAL = 3; + UGC_RECORD_USAGE_COMPARE = 4; +} diff --git a/NahidaImpact.Protocol/RedPointData.proto b/NahidaImpact.Protocol/RedPointData.proto new file mode 100644 index 0000000..efadcf3 --- /dev/null +++ b/NahidaImpact.Protocol/RedPointData.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: LLNDNAFDJAL +message RedPointData { + uint32 red_point_type = 1; + bool is_show = 2; + uint32 content_id = 3; +} diff --git a/NahidaImpact.Protocol/RedeemLegendaryKeyReq.proto b/NahidaImpact.Protocol/RedeemLegendaryKeyReq.proto new file mode 100644 index 0000000..bbb5083 --- /dev/null +++ b/NahidaImpact.Protocol/RedeemLegendaryKeyReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 8427 +// Obf: EMAMJFBPOLE +message RedeemLegendaryKeyReq { +} diff --git a/NahidaImpact.Protocol/RefreshBackgroundAvatarReq.proto b/NahidaImpact.Protocol/RefreshBackgroundAvatarReq.proto new file mode 100644 index 0000000..643fca5 --- /dev/null +++ b/NahidaImpact.Protocol/RefreshBackgroundAvatarReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 29491 +// Obf: ONGNABLDIOE +message RefreshBackgroundAvatarReq { +} diff --git a/NahidaImpact.Protocol/RefreshRoguelikeDungeonCardReq.proto b/NahidaImpact.Protocol/RefreshRoguelikeDungeonCardReq.proto new file mode 100644 index 0000000..0e1e797 --- /dev/null +++ b/NahidaImpact.Protocol/RefreshRoguelikeDungeonCardReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 23467 +// Obf: LFACOBOMPMG +message RefreshRoguelikeDungeonCardReq { +} diff --git a/NahidaImpact.Protocol/RegionInfo.proto b/NahidaImpact.Protocol/RegionInfo.proto new file mode 100644 index 0000000..81e0322 --- /dev/null +++ b/NahidaImpact.Protocol/RegionInfo.proto @@ -0,0 +1,36 @@ +syntax = "proto3"; + + +import "ResVersionConfig.proto"; + +message RegionInfo { + string user_center_url = 30; + string client_data_md5 = 19; + string resource_url = 8; + string handbook_url = 16; + string client_silence_data_md5 = 20; + string area_type = 7; + string gateserver_ip = 1; + bytes secret_key = 23; + string next_resource_url = 34; + ResVersionConfig next_res_version_config = 35; + string official_community_url = 24; + string account_bind_url = 31; + string pay_callback_url = 3; + string resource_url_bak = 12; + ResVersionConfig res_version_config = 22; + string game_biz = 36; + string feedback_url = 10; + string client_silence_version_suffix = 27; + string data_url = 9; + string client_version_suffix = 26; + string privacy_policy_url = 33; + string data_url_bak = 13; + string gateserver_domain_name = 29; + string bulletin_url = 11; + string cdkey_url = 32; + bool use_gateserver_domain_name = 28; + uint32 gateserver_port = 2; + uint32 client_data_version = 14; + uint32 client_silence_data_version = 18; +} diff --git a/NahidaImpact.Protocol/RegionSearchState.proto b/NahidaImpact.Protocol/RegionSearchState.proto new file mode 100644 index 0000000..c2a276b --- /dev/null +++ b/NahidaImpact.Protocol/RegionSearchState.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +// Obf: PNAKDNOMNOP +enum RegionSearchState { + REGION_SEARCH_NONE = 0; + REGION_SEARCH_UNSTARTED = 1; + REGION_SEARCH_STARTED = 2; + REGION_SEARCH_WAIT_REWARD = 3; + REGION_SEARCH_FINISHED = 4; +} diff --git a/NahidaImpact.Protocol/RegionSimpleInfo.proto b/NahidaImpact.Protocol/RegionSimpleInfo.proto new file mode 100644 index 0000000..ccedada --- /dev/null +++ b/NahidaImpact.Protocol/RegionSimpleInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +message RegionSimpleInfo { + string dispatch_url = 4; + string name = 1; + string title = 2; + string type = 3; +} diff --git a/NahidaImpact.Protocol/Reliquary.proto b/NahidaImpact.Protocol/Reliquary.proto new file mode 100644 index 0000000..958e134 --- /dev/null +++ b/NahidaImpact.Protocol/Reliquary.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +message Reliquary { + repeated uint32 append_prop_id_list = 5; + uint32 main_prop_id = 4; + uint32 exp = 2; + uint32 promote_level = 3; + uint32 level = 1; +} diff --git a/NahidaImpact.Protocol/ReplayCustomDungeonReq.proto b/NahidaImpact.Protocol/ReplayCustomDungeonReq.proto new file mode 100644 index 0000000..fcaaa79 --- /dev/null +++ b/NahidaImpact.Protocol/ReplayCustomDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 1660 +// Obf: HNIAPOCKIMO +message ReplayCustomDungeonReq { +} diff --git a/NahidaImpact.Protocol/ReportReasonType.proto b/NahidaImpact.Protocol/ReportReasonType.proto new file mode 100644 index 0000000..5fb892a --- /dev/null +++ b/NahidaImpact.Protocol/ReportReasonType.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +// Obf: MLEODELMDAD +enum ReportReasonType { + REPORT_REASON_NONE = 0; + REPORT_REASON_DECEPTIVE_ADS = 1; + REPORT_REASON_ABUSING = 2; + REPORT_REASON_CHEAT = 3; + REPORT_REASON_POLITICAL = 4; + REPORT_REASON_OTHER = 5; + REPORT_REASON_HOME = 6; +} diff --git a/NahidaImpact.Protocol/ResVersionConfig.proto b/NahidaImpact.Protocol/ResVersionConfig.proto new file mode 100644 index 0000000..1684ffe --- /dev/null +++ b/NahidaImpact.Protocol/ResVersionConfig.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +message ResVersionConfig { + string next_script_version = 7; + string branch = 6; + string version_suffix = 5; + string md5 = 3; + string release_total_size = 4; + bool relogin = 2; + uint32 version = 1; +} diff --git a/NahidaImpact.Protocol/ResinCostType.proto b/NahidaImpact.Protocol/ResinCostType.proto new file mode 100644 index 0000000..48bbc43 --- /dev/null +++ b/NahidaImpact.Protocol/ResinCostType.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +// Obf: CJJHKGNDKMK +enum ResinCostType { + RESIN_COST_TYPE_NONE = 0; + RESIN_COST_TYPE_NORMAL = 1; + RESIN_COST_TYPE_CONDENSE = 2; + RESIN_COST_TYPE_REUNION_PRIVILEGE = 3; + RESIN_COST_TYPE_OP_ACTIVITY = 4; + RESIN_COST_TYPE_MATERIAL = 5; +} diff --git a/NahidaImpact.Protocol/RestartEffigyChallengeReq.proto b/NahidaImpact.Protocol/RestartEffigyChallengeReq.proto new file mode 100644 index 0000000..f2d3e6f --- /dev/null +++ b/NahidaImpact.Protocol/RestartEffigyChallengeReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 8574 +// Obf: ALOIGODPJPJ +message RestartEffigyChallengeReq { +} diff --git a/NahidaImpact.Protocol/Retcode.cs b/NahidaImpact.Protocol/Retcode.cs new file mode 100644 index 0000000..62a0852 --- /dev/null +++ b/NahidaImpact.Protocol/Retcode.cs @@ -0,0 +1,1377 @@ +namespace NahidaImpact.Protocol; +public static class Retcode +{ + public const int RET_SUCC = 0; + public const int RET_FAIL = -1; + public const int RET_SVR_ERROR = 1; + public const int RET_UNKNOWN_ERROR = 2; + public const int RET_FREQUENT = 3; + public const int RET_NODE_FORWARD_ERROR = 4; + public const int RET_NOT_FOUND_CONFIG = 5; + public const int RET_SYSTEM_BUSY = 6; + public const int RET_GM_UID_BIND = 7; + public const int RET_FORBIDDEN = 8; + public const int RET_STOP_REGISTER = 10; + public const int RET_STOP_SERVER = 11; + public const int RET_ACCOUNT_VEIRFY_ERROR = 12; + public const int RET_ACCOUNT_FREEZE = 13; + public const int RET_REPEAT_LOGIN = 14; + public const int RET_CLIENT_VERSION_ERROR = 15; + public const int RET_TOKEN_ERROR = 16; + public const int RET_ACCOUNT_NOT_EXIST = 17; + public const int RET_WAIT_OTHER_LOGIN = 18; + public const int RET_ANOTHER_LOGIN = 19; + public const int RET_CLIENT_FORCE_UPDATE = 20; + public const int RET_BLACK_UID = 21; + public const int RET_LOGIN_DB_FAIL = 22; + public const int RET_LOGIN_INIT_FAIL = 23; + public const int RET_MYSQL_DUPLICATE = 24; + public const int RET_MAX_PLAYER = 25; + public const int RET_ANTI_ADDICT = 26; + public const int RET_PS_PLAYER_WITHOUT_ONLINE_ID = 27; + public const int RET_ONLINE_ID_NOT_FOUND = 28; + public const int RET_ONLNE_ID_NOT_MATCH = 29; + public const int RET_REGISTER_IS_FULL = 30; + public const int RET_CHECKSUM_INVALID = 31; + public const int RET_BLACK_REGISTER_IP = 32; + public const int RET_EXCEED_REGISTER_RATE = 33; + public const int RET_UNKNOWN_PLATFORM = 34; + public const int RET_TOKEN_PARAM_ERROR = 35; + public const int RET_ANTI_OFFLINE_ERROR = 36; + public const int RET_BLACK_LOGIN_IP = 37; + public const int RET_GET_TOKEN_SESSION_HAS_UID = 38; + public const int RET_ENVIRONMENT_ERROR = 39; + public const int RET_CHECK_CLIENT_VERSION_HASH_FAIL = 40; + public const int RET_MINOR_REGISTER_FOBIDDEN = 41; + public const int RET_SECURITY_LIBRARY_ERROR = 42; + public const int RET_GATE_TICKET_CHECK_ERROR = 43; + public const int RET_PROTO_MIX_VERSION_NOT_MATCH = 44; + public const int RET_AVATAR_IN_CD = 101; + public const int RET_AVATAR_NOT_ALIVE = 102; + public const int RET_AVATAR_NOT_ON_SCENE = 103; + public const int RET_CAN_NOT_FIND_AVATAR = 104; + public const int RET_CAN_NOT_DEL_CUR_AVATAR = 105; + public const int RET_DUPLICATE_AVATAR = 106; + public const int RET_AVATAR_IS_SAME_ONE = 107; + public const int RET_AVATAR_LEVEL_LESS_THAN = 108; + public const int RET_AVATAR_CAN_NOT_CHANGE_ELEMENT = 109; + public const int RET_AVATAR_BREAK_LEVEL_LESS_THAN = 110; + public const int RET_AVATAR_ON_MAX_BREAK_LEVEL = 111; + public const int RET_AVATAR_ID_ALREADY_EXIST = 112; + public const int RET_AVATAR_NOT_DEAD = 113; + public const int RET_AVATAR_IS_REVIVING = 114; + public const int RET_AVATAR_ID_ERROR = 115; + public const int RET_REPEAT_SET_PLAYER_BORN_DATA = 116; + public const int RET_PLAYER_LEVEL_LESS_THAN = 117; + public const int RET_AVATAR_LIMIT_LEVEL_ERROR = 118; + public const int RET_CUR_AVATAR_NOT_ALIVE = 119; + public const int RET_CAN_NOT_FIND_TEAM = 120; + public const int RET_CAN_NOT_FIND_CUR_TEAM = 121; + public const int RET_AVATAR_NOT_EXIST_IN_TEAM = 122; + public const int RET_CAN_NOT_REMOVE_CUR_AVATAR_FROM_TEAM = 123; + public const int RET_CAN_NOT_USE_REVIVE_ITEM_FOR_CUR_AVATAR = 124; + public const int RET_TEAM_COST_EXCEED_LIMIT = 125; + public const int RET_TEAM_AVATAR_IN_EXPEDITION = 126; + public const int RET_TEAM_CAN_NOT_CHOSE_REPLACE_USE = 127; + public const int RET_AVATAR_IN_COMBAT = 128; + public const int RET_NICKNAME_UTF8_ERROR = 130; + public const int RET_NICKNAME_TOO_LONG = 131; + public const int RET_NICKNAME_WORD_ILLEGAL = 132; + public const int RET_NICKNAME_TOO_MANY_DIGITS = 133; + public const int RET_NICKNAME_IS_EMPTY = 134; + public const int RET_NICKNAME_MONTHLY_LIMIT = 135; + public const int RET_NICKNAME_NOT_CHANGED = 136; + public const int RET_PLAYER_NOT_ONLINE = 140; + public const int RET_OPEN_STATE_NOT_OPEN = 141; + public const int RET_FEATURE_CLOSED = 142; + public const int RET_AVATAR_EXPEDITION_AVATAR_DIE = 152; + public const int RET_AVATAR_EXPEDITION_COUNT_LIMIT = 153; + public const int RET_AVATAR_EXPEDITION_MAIN_FORBID = 154; + public const int RET_AVATAR_EXPEDITION_TRIAL_FORBID = 155; + public const int RET_TEAM_NAME_ILLEGAL = 156; + public const int RET_IS_NOT_IN_STANDBY = 157; + public const int RET_IS_IN_DUNGEON = 158; + public const int RET_IS_IN_LOCK_AVATAR_QUEST = 159; + public const int RET_IS_USING_TRIAL_AVATAR = 160; + public const int RET_IS_USING_TEMP_AVATAR = 161; + public const int RET_NOT_HAS_FLYCLOAK = 162; + public const int RET_FETTER_REWARD_ALREADY_GOT = 163; + public const int RET_FETTER_REWARD_LEVEL_NOT_ENOUGH = 164; + public const int RET_WORLD_LEVEL_ADJUST_MIN_LEVEL = 165; + public const int RET_WORLD_LEVEL_ADJUST_CD = 166; + public const int RET_NOT_HAS_COSTUME = 167; + public const int RET_COSTUME_AVATAR_ERROR = 168; + public const int RET_FLYCLOAK_PLATFORM_TYPE_ERR = 169; + public const int RET_IN_TRANSFER = 170; + public const int RET_IS_IN_LOCK_AVATAR = 171; + public const int RET_FULL_BACKUP_TEAM = 172; + public const int RET_BACKUP_TEAM_ID_NOT_VALID = 173; + public const int RET_BACKUP_TEAM_IS_CUR_TEAM = 174; + public const int RET_AVATAR_RENAME_IN_CD = 175; + public const int RET_AVATAR_RENAME_IN_AUDIT = 176; + public const int RET_AVATAR_RENAME_IN_IP_BLACK_LIST = 177; + public const int RET_TEAM_AVATAR_IS_LOCKED = 178; + public const int RET_PLAYER_HAS_TRIAL_AVATAR = 179; + public const int RET_FLOAT_ERROR = 201; + public const int RET_NPC_NOT_EXIST = 301; + public const int RET_NPC_TOO_FAR = 302; + public const int RET_NOT_CURRENT_TALK = 303; + public const int RET_NPC_CREATE_FAIL = 304; + public const int RET_NPC_MOVE_FAIL = 305; + public const int RET_QUEST_NOT_EXIST = 401; + public const int RET_QUEST_IS_FAIL = 402; + public const int RET_QUEST_CONTENT_ERROR = 403; + public const int RET_BARGAIN_NOT_ACTIVATED = 404; + public const int RET_BARGAIN_FINISHED = 405; + public const int RET_INFERENCE_ASSOCIATE_WORD_ERROR = 406; + public const int RET_INFERENCE_SUBMIT_WORD_NO_CONCLUSION = 407; + public const int RET_SUBMIT_QUEST_EVENTS_NOT_RIGHT = 408; + public const int RET_POINT_NOT_UNLOCKED = 501; + public const int RET_POINT_TOO_FAR = 502; + public const int RET_POINT_ALREAY_UNLOCKED = 503; + public const int RET_ENTITY_NOT_EXIST = 504; + public const int RET_ENTER_SCENE_FAIL = 505; + public const int RET_PLAYER_IS_ENTER_SCENE = 506; + public const int RET_CITY_MAX_LEVEL = 507; + public const int RET_AREA_LOCKED = 508; + public const int RET_JOIN_OTHER_WAIT = 509; + public const int RET_WEATHER_AREA_NOT_FOUND = 510; + public const int RET_WEATHER_IS_LOCKED = 511; + public const int RET_NOT_IN_SELF_SCENE = 512; + public const int RET_GROUP_NOT_EXIST = 513; + public const int RET_MARK_NAME_ILLEGAL = 514; + public const int RET_MARK_ALREADY_EXISTS = 515; + public const int RET_MARK_OVERFLOW = 516; + public const int RET_MARK_NOT_EXISTS = 517; + public const int RET_MARK_UNKNOWN_TYPE = 518; + public const int RET_MARK_NAME_TOO_LONG = 519; + public const int RET_DISTANCE_LONG = 520; + public const int RET_ENTER_SCENE_TOKEN_INVALID = 521; + public const int RET_NOT_IN_WORLD_SCENE = 522; + public const int RET_ANY_GALLERY_STARTED = 523; + public const int RET_GALLERY_NOT_START = 524; + public const int RET_GALLERY_INTERRUPT_ONLY_ON_SINGLE_MODE = 525; + public const int RET_GALLERY_CANNOT_INTERRUPT = 526; + public const int RET_GALLERY_WORLD_NOT_MEET = 527; + public const int RET_GALLERY_SCENE_NOT_MEET = 528; + public const int RET_CUR_PLAY_CANNOT_TRANSFER = 529; + public const int RET_CANT_USE_WIDGET_IN_HOME_SCENE = 530; + public const int RET_SCENE_GROUP_NOT_MATCH = 531; + public const int RET_POS_ROT_INVALID = 551; + public const int RET_MARK_INVALID_SCENE_ID = 552; + public const int RET_INVALID_SCENE_TO_USE_ANCHOR_POINT = 553; + public const int RET_ENTER_HOME_SCENE_FAIL = 554; + public const int RET_CUR_SCENE_IS_NULL = 555; + public const int RET_GROUP_ID_ERROR = 556; + public const int RET_GALLERY_INTERRUPT_NOT_OWNER = 557; + public const int RET_NO_SPRING_IN_AREA = 558; + public const int RET_AREA_NOT_IN_SCENE = 559; + public const int RET_INVALID_CITY_ID = 560; + public const int RET_INVALID_SCENE_ID = 561; + public const int RET_DEST_SCENE_IS_NOT_ALLOW = 562; + public const int RET_LEVEL_TAG_SWITCH_IN_CD = 563; + public const int RET_LEVEL_TAG_ALREADY_EXIST = 564; + public const int RET_INVALID_AREA_ID = 565; + public const int RET_GALLERY_ONGOING_FORBID = 566; + public const int RET_NOT_IN_PLAYER_WORLD = 567; + public const int RET_MAP_LAYER_GROUP_ALREADY_SHOWN = 568; + public const int RET_INVALID_MAP_LAYER = 569; + public const int RET_ITEM_NOT_EXIST = 601; + public const int RET_PACK_EXCEED_MAX_WEIGHT = 602; + public const int RET_ITEM_NOT_DROPABLE = 603; + public const int RET_ITEM_NOT_USABLE = 604; + public const int RET_ITEM_INVALID_USE_COUNT = 605; + public const int RET_ITEM_INVALID_DROP_COUNT = 606; + public const int RET_ITEM_ALREADY_EXIST = 607; + public const int RET_ITEM_IN_COOLDOWN = 608; + public const int RET_ITEM_COUNT_NOT_ENOUGH = 609; + public const int RET_ITEM_INVALID_TARGET = 610; + public const int RET_RECIPE_NOT_EXIST = 611; + public const int RET_RECIPE_LOCKED = 612; + public const int RET_RECIPE_UNLOCKED = 613; + public const int RET_COMPOUND_QUEUE_FULL = 614; + public const int RET_COMPOUND_NOT_FINISH = 615; + public const int RET_MAIL_ITEM_NOT_GET = 616; + public const int RET_ITEM_EXCEED_LIMIT = 617; + public const int RET_AVATAR_CAN_NOT_USE = 618; + public const int RET_ITEM_NEED_PLAYER_LEVEL = 619; + public const int RET_RECIPE_NOT_AUTO_QTE = 620; + public const int RET_COMPOUND_BUSY_QUEUE = 621; + public const int RET_NEED_MORE_SCOIN = 622; + public const int RET_SKILL_DEPOT_NOT_FOUND = 623; + public const int RET_HCOIN_NOT_ENOUGH = 624; + public const int RET_SCOIN_NOT_ENOUGH = 625; + public const int RET_HCOIN_EXCEED_LIMIT = 626; + public const int RET_SCOIN_EXCEED_LIMIT = 627; + public const int RET_MAIL_EXPIRED = 628; + public const int RET_REWARD_HAS_TAKEN = 629; + public const int RET_COMBINE_COUNT_TOO_LARGE = 630; + public const int RET_GIVING_ITEM_WRONG = 631; + public const int RET_GIVING_IS_FINISHED = 632; + public const int RET_GIVING_NOT_ACTIVED = 633; + public const int RET_FORGE_QUEUE_FULL = 634; + public const int RET_FORGE_QUEUE_CAPACITY = 635; + public const int RET_FORGE_QUEUE_NOT_FOUND = 636; + public const int RET_FORGE_QUEUE_EMPTY = 637; + public const int RET_NOT_SUPPORT_ITEM = 638; + public const int RET_ITEM_EMPTY = 639; + public const int RET_VIRTUAL_EXCEED_LIMIT = 640; + public const int RET_MATERIAL_EXCEED_LIMIT = 641; + public const int RET_EQUIP_EXCEED_LIMIT = 642; + public const int RET_ITEM_SHOULD_HAVE_NO_LEVEL = 643; + public const int RET_WEAPON_PROMOTE_LEVEL_EXCEED_LIMIT = 644; + public const int RET_WEAPON_LEVEL_INVALID = 645; + public const int RET_UNKNOW_ITEM_TYPE = 646; + public const int RET_ITEM_COUNT_IS_ZERO = 647; + public const int RET_ITEM_IS_EXPIRED = 648; + public const int RET_ITEM_EXCEED_OUTPUT_LIMIT = 649; + public const int RET_EQUIP_LEVEL_HIGHER = 650; + public const int RET_EQUIP_CAN_NOT_WAKE_OFF_WEAPON = 651; + public const int RET_EQUIP_HAS_BEEN_WEARED = 652; + public const int RET_EQUIP_WEARED_CANNOT_DROP = 653; + public const int RET_AWAKEN_LEVEL_MAX = 654; + public const int RET_MCOIN_NOT_ENOUGH = 655; + public const int RET_MCOIN_EXCEED_LIMIT = 656; + public const int RET_RESIN_NOT_ENOUGH = 660; + public const int RET_RESIN_EXCEED_LIMIT = 661; + public const int RET_RESIN_OPENSTATE_OFF = 662; + public const int RET_RESIN_BOUGHT_COUNT_EXCEEDED = 663; + public const int RET_RESIN_CARD_DAILY_REWARD_HAS_TAKEN = 664; + public const int RET_RESIN_CARD_EXPIRED = 665; + public const int RET_AVATAR_CAN_NOT_COOK = 666; + public const int RET_ATTACH_AVATAR_CD = 667; + public const int RET_AUTO_RECOVER_OPENSTATE_OFF = 668; + public const int RET_AUTO_RECOVER_BOUGHT_COUNT_EXCEEDED = 669; + public const int RET_RESIN_GAIN_FAILED = 670; + public const int RET_WIDGET_ORNAMENTS_TYPE_ERROR = 671; + public const int RET_ALL_TARGET_SATIATION_FULL = 672; + public const int RET_FORGE_WORLD_LEVEL_NOT_MATCH = 673; + public const int RET_FORGE_POINT_NOT_ENOUGH = 674; + public const int RET_WIDGET_ANCHOR_POINT_FULL = 675; + public const int RET_WIDGET_ANCHOR_POINT_NOT_FOUND = 676; + public const int RET_ALL_BONFIRE_EXCEED_MAX_COUNT = 677; + public const int RET_BONFIRE_EXCEED_MAX_COUNT = 678; + public const int RET_LUNCH_BOX_DATA_ERROR = 679; + public const int RET_INVALID_QUICK_USE_WIDGET = 680; + public const int RET_INVALID_REPLACE_RESIN_COUNT = 681; + public const int RET_PREV_DETECTED_GATHER_NOT_FOUND = 682; + public const int RET_GOT_ALL_ONEOFF_GAHTER = 683; + public const int RET_INVALID_WIDGET_MATERIAL_ID = 684; + public const int RET_WIDGET_DETECTOR_NO_HINT_TO_CLEAR = 685; + public const int RET_WIDGET_ALREADY_WITHIN_NEARBY_RADIUS = 686; + public const int RET_WIDGET_CLIENT_COLLECTOR_NEED_POINTS = 687; + public const int RET_WIDGET_IN_COMBAT = 688; + public const int RET_WIDGET_NOT_SET_QUICK_USE = 689; + public const int RET_ALREADY_ATTACH_WIDGET = 690; + public const int RET_EQUIP_IS_LOCKED = 691; + public const int RET_FORGE_IS_LOCKED = 692; + public const int RET_COMBINE_IS_LOCKED = 693; + public const int RET_FORGE_OUTPUT_STACK_LIMIT = 694; + public const int RET_ALREADY_DETTACH_WIDGET = 695; + public const int RET_GADGET_BUILDER_EXCEED_MAX_COUNT = 696; + public const int RET_REUNION_PRIVILEGE_RESIN_TYPE_IS_NORMAL = 697; + public const int RET_BONUS_COUNT_EXCEED_DOUBLE_LIMIT = 698; + public const int RET_RELIQUARY_DECOMPOSE_PARAM_ERROR = 699; + public const int RET_ITEM_COMBINE_COUNT_NOT_ENOUGH = 700; + public const int RET_GOODS_NOT_EXIST = 701; + public const int RET_GOODS_MATERIAL_NOT_ENOUGH = 702; + public const int RET_GOODS_NOT_IN_TIME = 703; + public const int RET_GOODS_BUY_NUM_NOT_ENOUGH = 704; + public const int RET_GOODS_BUY_NUM_ERROR = 705; + public const int RET_SHOP_NOT_OPEN = 706; + public const int RET_SHOP_CONTENT_NOT_MATCH = 707; + public const int RET_SHOP_BATCH_BUY_SHOP_LIMIT = 708; + public const int RET_SHOP_BATCH_BUY_COUNT_LIMIT = 709; + public const int RET_CHAT_FORBIDDEN = 798; + public const int RET_CHAT_CD = 799; + public const int RET_CHAT_FREQUENTLY = 800; + public const int RET_GADGET_NOT_EXIST = 801; + public const int RET_GADGET_NOT_INTERACTIVE = 802; + public const int RET_GADGET_NOT_GATHERABLE = 803; + public const int RET_CHEST_IS_LOCKED = 804; + public const int RET_GADGET_CREATE_FAIL = 805; + public const int RET_WORKTOP_OPTION_NOT_EXIST = 806; + public const int RET_GADGET_STATUE_NOT_ACTIVE = 807; + public const int RET_GADGET_STATUE_OPENED = 808; + public const int RET_BOSS_CHEST_NO_QUALIFICATION = 809; + public const int RET_BOSS_CHEST_LIFE_TIME_OVER = 810; + public const int RET_BOSS_CHEST_WEEK_NUM_LIMIT = 811; + public const int RET_BOSS_CHEST_GUEST_WORLD_LEVEL = 812; + public const int RET_BOSS_CHEST_HAS_TAKEN = 813; + public const int RET_BLOSSOM_CHEST_NO_QUALIFICATION = 814; + public const int RET_BLOSSOM_CHEST_LIFE_TIME_OVER = 815; + public const int RET_BLOSSOM_CHEST_HAS_TAKEN = 816; + public const int RET_BLOSSOM_CHEST_GUEST_WORLD_LEVEL = 817; + public const int RET_MP_PLAY_REWARD_NO_QUALIFICATION = 818; + public const int RET_MP_PLAY_REWARD_HAS_TAKEN = 819; + public const int RET_GENERAL_REWARD_NO_QUALIFICATION = 820; + public const int RET_GENERAL_REWARD_LIFE_TIME_OVER = 821; + public const int RET_GENERAL_REWARD_HAS_TAKEN = 822; + public const int RET_GADGET_NOT_VEHICLE = 823; + public const int RET_VEHICLE_SLOT_OCCUPIED = 824; + public const int RET_NOT_IN_VEHICLE = 825; + public const int RET_CREATE_VEHICLE_IN_CD = 826; + public const int RET_CREATE_VEHICLE_POS_INVALID = 827; + public const int RET_VEHICLE_POINT_NOT_UNLOCK = 828; + public const int RET_GADGET_INTERACT_COND_NOT_MEET = 829; + public const int RET_GADGET_INTERACT_PARAM_ERROR = 830; + public const int RET_GADGET_CUSTOM_COMBINATION_INVALID = 831; + public const int RET_DESHRET_OBELISK_DUPLICATE_INTERACT = 832; + public const int RET_DESHRET_OBELISK_NO_AVAIL_CHEST = 833; + public const int RET_VEHICLE_SORUSH_NOT_REPLACE = 834; + public const int RET_VEHICLE_SORUSH_NOT_UNLOAD = 835; + public const int RET_VEHICLE_SORUSH_STATE_NOT_MATCH = 836; + public const int RET_ACTIVITY_CLOSE = 860; + public const int RET_ACTIVITY_ITEM_ERROR = 861; + public const int RET_ACTIVITY_CONTRIBUTION_NOT_ENOUGH = 862; + public const int RET_SEA_LAMP_PHASE_NOT_FINISH = 863; + public const int RET_SEA_LAMP_FLY_NUM_LIMIT = 864; + public const int RET_SEA_LAMP_FLY_LAMP_WORD_ILLEGAL = 865; + public const int RET_ACTIVITY_WATCHER_REWARD_TAKEN = 866; + public const int RET_ACTIVITY_WATCHER_REWARD_NOT_FINISHED = 867; + public const int RET_SALESMAN_ALREADY_DELIVERED = 868; + public const int RET_SALESMAN_REWARD_COUNT_NOT_ENOUGH = 869; + public const int RET_SALESMAN_POSITION_INVALID = 870; + public const int RET_DELIVER_NOT_FINISH_ALL_QUEST = 871; + public const int RET_DELIVER_ALREADY_TAKE_DAILY_REWARD = 872; + public const int RET_ASTER_PROGRESS_EXCEED_LIMIT = 873; + public const int RET_ASTER_CREDIT_EXCEED_LIMIT = 874; + public const int RET_ASTER_TOKEN_EXCEED_LIMIT = 875; + public const int RET_ASTER_CREDIT_NOT_ENOUGH = 876; + public const int RET_ASTER_TOKEN_NOT_ENOUGH = 877; + public const int RET_ASTER_SPECIAL_REWARD_HAS_TAKEN = 878; + public const int RET_FLIGHT_GROUP_ACTIVITY_NOT_STARTED = 879; + public const int RET_ASTER_MID_PREVIOUS_BATTLE_NOT_FINISHED = 880; + public const int RET_DRAGON_SPINE_SHIMMERING_ESSENCE_EXCEED_LIMIT = 881; + public const int RET_DRAGON_SPINE_WARM_ESSENCE_EXCEED_LIMIT = 882; + public const int RET_DRAGON_SPINE_WONDROUS_ESSENCE_EXCEED_LIMIT = 883; + public const int RET_DRAGON_SPINE_SHIMMERING_ESSENCE_NOT_ENOUGH = 884; + public const int RET_DRAGON_SPINE_WARM_ESSENCE_NOT_ENOUGH = 885; + public const int RET_DRAGON_SPINE_WONDROUS_ESSENCE_NOT_ENOUGH = 886; + public const int RET_EFFIGY_FIRST_PASS_REWARD_HAS_TAKEN = 891; + public const int RET_EFFIGY_REWARD_HAS_TAKEN = 892; + public const int RET_TREASURE_MAP_ADD_TOKEN_EXCEED_LIMIT = 893; + public const int RET_TREASURE_MAP_TOKEN_NOT_ENOUGHT = 894; + public const int RET_SEA_LAMP_COIN_EXCEED_LIMIT = 895; + public const int RET_SEA_LAMP_COIN_NOT_ENOUGH = 896; + public const int RET_SEA_LAMP_POPULARITY_EXCEED_LIMIT = 897; + public const int RET_ACTIVITY_AVATAR_REWARD_NOT_OPEN = 898; + public const int RET_ACTIVITY_AVATAR_REWARD_HAS_TAKEN = 899; + public const int RET_ARENA_ACTIVITY_ALREADY_STARTED = 900; + public const int RET_TALENT_ALREAY_UNLOCKED = 901; + public const int RET_PREV_TALENT_NOT_UNLOCKED = 902; + public const int RET_BIG_TALENT_POINT_NOT_ENOUGH = 903; + public const int RET_SMALL_TALENT_POINT_NOT_ENOUGH = 904; + public const int RET_PROUD_SKILL_ALREADY_GOT = 905; + public const int RET_PREV_PROUD_SKILL_NOT_GET = 906; + public const int RET_PROUD_SKILL_MAX_LEVEL = 907; + public const int RET_CANDIDATE_SKILL_DEPOT_ID_NOT_FIND = 910; + public const int RET_SKILL_DEPOT_IS_THE_SAME = 911; + public const int RET_MONSTER_NOT_EXIST = 1001; + public const int RET_MONSTER_CREATE_FAIL = 1002; + public const int RET_DUNGEON_ENTER_FAIL = 1101; + public const int RET_DUNGEON_QUIT_FAIL = 1102; + public const int RET_DUNGEON_ENTER_EXCEED_DAY_COUNT = 1103; + public const int RET_DUNGEON_REVIVE_EXCEED_MAX_COUNT = 1104; + public const int RET_DUNGEON_REVIVE_FAIL = 1105; + public const int RET_DUNGEON_NOT_SUCCEED = 1106; + public const int RET_DUNGEON_CAN_NOT_CANCEL = 1107; + public const int RET_DEST_DUNGEON_SETTLED = 1108; + public const int RET_DUNGEON_CANDIDATE_TEAM_IS_FULL = 1109; + public const int RET_DUNGEON_CANDIDATE_TEAM_IS_DISMISS = 1110; + public const int RET_DUNGEON_CANDIDATE_TEAM_NOT_ALL_READY = 1111; + public const int RET_DUNGEON_CANDIDATE_TEAM_HAS_REPEAT_AVATAR = 1112; + public const int RET_DUNGEON_CANDIDATE_NOT_SINGEL_PASS = 1113; + public const int RET_DUNGEON_REPLAY_NEED_ALL_PLAYER_DIE = 1114; + public const int RET_DUNGEON_REPLAY_HAS_REVIVE_COUNT = 1115; + public const int RET_DUNGEON_OTHERS_LEAVE = 1116; + public const int RET_DUNGEON_ENTER_LEVEL_LIMIT = 1117; + public const int RET_DUNGEON_CANNOT_ENTER_PLOT_IN_MP = 1118; + public const int RET_DUNGEON_DROP_SUBFIELD_LIMIT = 1119; + public const int RET_DUNGEON_BE_INVITE_PLAYER_AVATAR_ALL_DIE = 1120; + public const int RET_DUNGEON_CANNOT_KICK = 1121; + public const int RET_DUNGEON_CANDIDATE_TEAM_SOMEONE_LEVEL_LIMIT = 1122; + public const int RET_DUNGEON_IN_FORCE_QUIT = 1123; + public const int RET_DUNGEON_GUEST_QUIT_DUNGEON = 1124; + public const int RET_DUNGEON_TICKET_FAIL = 1125; + public const int RET_CUR_DUNGEON_SETTLED = 1126; + public const int RET_CUR_DUNGEON_NOT_PLOT = 1127; + public const int RET_CUR_DUNGEON_NOT_ALLOW_SWITCH_TEAM = 1128; + public const int RET_MP_NOT_IN_MY_WORLD = 1201; + public const int RET_MP_IN_MP_MODE = 1202; + public const int RET_MP_SCENE_IS_FULL = 1203; + public const int RET_MP_MODE_NOT_AVAILABLE = 1204; + public const int RET_MP_PLAYER_NOT_ENTERABLE = 1205; + public const int RET_MP_QUEST_BLOCK_MP = 1206; + public const int RET_MP_IN_ROOM_SCENE = 1207; + public const int RET_MP_WORLD_IS_FULL = 1208; + public const int RET_MP_PLAYER_NOT_ALLOW_ENTER = 1209; + public const int RET_MP_PLAYER_DISCONNECTED = 1210; + public const int RET_MP_NOT_IN_MP_MODE = 1211; + public const int RET_MP_OWNER_NOT_ENTER = 1212; + public const int RET_MP_ALLOW_ENTER_PLAYER_FULL = 1213; + public const int RET_MP_TARGET_PLAYER_IN_TRANSFER = 1214; + public const int RET_MP_TARGET_ENTERING_OTHER = 1215; + public const int RET_MP_OTHER_ENTERING = 1216; + public const int RET_MP_ENTER_MAIN_PLAYER_IN_PLOT = 1217; + public const int RET_MP_NOT_PS_PLAYER = 1218; + public const int RET_MP_PLAY_NOT_ACTIVE = 1219; + public const int RET_MP_PLAY_REMAIN_REWARDS = 1220; + public const int RET_MP_PLAY_NO_REWARD = 1221; + public const int RET_MP_OPEN_STATE_FAIL = 1223; + public const int RET_MP_PLAYER_IN_BLACKLIST = 1224; + public const int RET_MP_REPLY_TIMEOUT = 1225; + public const int RET_MP_IS_BLOCK = 1226; + public const int RET_MP_ENTER_MAIN_PLAYER_IN_MP_PLAY = 1227; + public const int RET_MP_IN_MP_PLAY_BATTLE = 1228; + public const int RET_MP_GUEST_HAS_REWARD_REMAINED = 1229; + public const int RET_MP_QUIT_MP_INVALID = 1230; + public const int RET_MP_OTHER_DATA_VERSION_NOT_LATEST = 1231; + public const int RET_MP_DATA_VERSION_NOT_LATEST = 1232; + public const int RET_MP_CUR_WORLD_NOT_ENTERABLE = 1233; + public const int RET_MP_ANY_GALLERY_STARTED = 1234; + public const int RET_MP_HAS_ACTIVE_DRAFT = 1235; + public const int RET_MP_PLAYER_IN_DUNGEON = 1236; + public const int RET_MP_MATCH_FULL = 1237; + public const int RET_MP_MATCH_LIMIT = 1238; + public const int RET_MP_MATCH_IN_PUNISH = 1239; + public const int RET_MP_IS_IN_MULTISTAGE = 1240; + public const int RET_MP_MATCH_PLAY_NOT_OPEN = 1241; + public const int RET_MP_ONLY_MP_WITH_PS_PLAYER = 1242; + public const int RET_MP_GUEST_LOADING_FIRST_ENTER = 1243; + public const int RET_MP_SUMMER_TIME_SPRINT_BOAT_ONGOING = 1244; + public const int RET_MP_BLITZ_RUSH_PARKOUR_CHALLENGE_ONGOING = 1245; + public const int RET_MP_MUSIC_GAME_ONGOING = 1246; + public const int RET_MP_IN_MPING_MODE = 1247; + public const int RET_MP_OWNER_IN_SINGLE_SCENE = 1248; + public const int RET_MP_IN_SINGLE_SCENE = 1249; + public const int RET_MP_REPLY_NO_VALID_AVATAR = 1250; + public const int RET_MP_IS_NOT_IN_TRANSFER_GUARD = 1251; + public const int RET_MP_CANNOT_EXEC_GIVING_IN_SINGLE_MODE_QUEST = 1252; + public const int RET_MP_EFFIGY_CHALLENGE_V4_IN_PREPARE = 1253; + public const int RET_MP_SHUFFLE_BOARD_ONGOING = 1254; + public const int RET_MP_FLIGHT_GEAR_ONGOING = 1255; + public const int RET_MP_TOY_BATTLE_QTE_ONGOING = 1256; + public const int RET_MAIL_PARA_ERR = 1301; + public const int RET_MAIL_MAX_NUM = 1302; + public const int RET_MAIL_ITEM_NUM_EXCEED = 1303; + public const int RET_MAIL_TITLE_LEN_EXCEED = 1304; + public const int RET_MAIL_CONTENT_LEN_EXCEED = 1305; + public const int RET_MAIL_SENDER_LEN_EXCEED = 1306; + public const int RET_MAIL_PARSE_PACKET_FAIL = 1307; + public const int RET_OFFLINE_MSG_MAX_NUM = 1308; + public const int RET_OFFLINE_MSG_SAME_TICKET = 1309; + public const int RET_MAIL_EXCEL_MAIL_TYPE_ERROR = 1310; + public const int RET_MAIL_CANNOT_SEND_MCOIN = 1311; + public const int RET_MAIL_HCOIN_EXCEED_LIMIT = 1312; + public const int RET_MAIL_SCOIN_EXCEED_LIMIT = 1313; + public const int RET_MAIL_MATERIAL_ID_INVALID = 1314; + public const int RET_MAIL_AVATAR_EXCEED_LIMIT = 1315; + public const int RET_MAIL_GACHA_TICKET_ETC_EXCEED_LIMIT = 1316; + public const int RET_MAIL_ITEM_EXCEED_CEHUA_LIMIT = 1317; + public const int RET_MAIL_SPACE_OR_REST_NUM_NOT_ENOUGH = 1318; + public const int RET_MAIL_TICKET_IS_EMPTY = 1319; + public const int RET_MAIL_TRANSACTION_IS_EMPTY = 1320; + public const int RET_MAIL_DELETE_COLLECTED = 1321; + public const int RET_MAIL_COLLECTION_IS_FULL = 1322; + public const int RET_DAILY_TASK_NOT_FINISH = 1330; + public const int RET_DAILY_TAKS_HAS_TAKEN = 1331; + public const int RET_SOCIAL_OFFLINE_MSG_NUM_EXCEED = 1332; + public const int RET_DAILY_TASK_FILTER_CITY_NOT_OPEN = 1333; + public const int RET_GACHA_INAVAILABLE = 1401; + public const int RET_GACHA_RANDOM_NOT_MATCH = 1402; + public const int RET_GACHA_SCHEDULE_NOT_MATCH = 1403; + public const int RET_GACHA_INVALID_TIMES = 1404; + public const int RET_GACHA_COST_ITEM_NOT_ENOUGH = 1405; + public const int RET_GACHA_TIMES_LIMIT = 1406; + public const int RET_GACHA_WISH_SAME_ITEM = 1407; + public const int RET_GACHA_WISH_INVALID_ITEM = 1408; + public const int RET_GACHA_MINORS_TIMES_LIMIT = 1409; + public const int RET_GACHA_GENERAL_TIMES_LIMIT = 1410; + public const int RET_INVESTIGAITON_NOT_IN_PROGRESS = 1501; + public const int RET_INVESTIGAITON_UNCOMPLETE = 1502; + public const int RET_INVESTIGAITON_REWARD_TAKEN = 1503; + public const int RET_INVESTIGAITON_TARGET_STATE_ERROR = 1504; + public const int RET_PUSH_TIPS_NOT_FOUND = 1505; + public const int RET_SIGN_IN_RECORD_NOT_FOUND = 1506; + public const int RET_ALREADY_HAVE_SIGNED_IN = 1507; + public const int RET_SIGN_IN_COND_NOT_SATISFIED = 1508; + public const int RET_BONUS_ACTIVITY_NOT_UNREWARDED = 1509; + public const int RET_SIGN_IN_REWARDED = 1510; + public const int RET_TOWER_NOT_OPEN = 1521; + public const int RET_TOWER_HAVE_DAILY_RECORD = 1522; + public const int RET_TOWER_NOT_RECORD = 1523; + public const int RET_TOWER_HAVE_RECORD = 1524; + public const int RET_TOWER_TEAM_NUM_ERROR = 1525; + public const int RET_TOWER_FLOOR_NOT_OPEN = 1526; + public const int RET_TOWER_NO_FLOOR_STAR_RECORD = 1527; + public const int RET_ALREADY_HAS_TOWER_BUFF = 1528; + public const int RET_DUPLICATE_ENTER_LEVEL = 1529; + public const int RET_NOT_IN_TOWER_LEVEL = 1530; + public const int RET_IN_TOWER_LEVEL = 1531; + public const int RET_TOWER_PREV_FLOOR_NOT_FINISH = 1532; + public const int RET_TOWER_STAR_NOT_ENOUGH = 1533; + public const int RET_BATTLE_PASS_NO_SCHEDULE = 1541; + public const int RET_BATTLE_PASS_HAS_BUYED = 1542; + public const int RET_BATTLE_PASS_LEVEL_OVERFLOW = 1543; + public const int RET_BATTLE_PASS_PRODUCT_EXPIRED = 1544; + public const int RET_MATCH_HOST_QUIT = 1561; + public const int RET_MATCH_ALREADY_IN_MATCH = 1562; + public const int RET_MATCH_NOT_IN_MATCH = 1563; + public const int RET_MATCH_APPLYING_ENTER_MP = 1564; + public const int RET_MATCH_INCORRECT_SCENE = 1565; + public const int RET_WIDGET_TREASURE_SPOT_NOT_FOUND = 1581; + public const int RET_WIDGET_TREASURE_ENTITY_EXISTS = 1582; + public const int RET_WIDGET_TREASURE_SPOT_FAR_AWAY = 1583; + public const int RET_WIDGET_TREASURE_FINISHED_TODAY = 1584; + public const int RET_WIDGET_QUICK_USE_REQ_PARAM_ERROR = 1585; + public const int RET_WIDGET_CAMERA_SCAN_ID_ERROR = 1586; + public const int RET_WIDGET_NOT_ACTIVE = 1587; + public const int RET_WIDGET_FEATHER_NOT_ACTIVE = 1588; + public const int RET_WIDGET_FEATHER_GADGET_TOO_FAR_AWAY = 1589; + public const int RET_WIDGET_CAPTURE_ANIMAL_NOT_EXIST = 1590; + public const int RET_WIDGET_CAPTURE_ANIMAL_DROP_BAG_LIMIT = 1591; + public const int RET_WIDGET_CAPTURE_ANIMAL_CAN_NOT_CAPTURE = 1592; + public const int RET_WIDGET_SKY_CRYSTAL_ALL_COLLECTED = 1593; + public const int RET_WIDGET_SKY_CRYSTAL_HINT_ALREADY_EXIST = 1594; + public const int RET_WIDGET_SKY_CRYSTAL_NOT_FOUND = 1595; + public const int RET_WIDGET_SKY_CRYSTAL_NO_HINT_TO_CLEAR = 1596; + public const int RET_WIDGET_LIGHT_STONE_ENERGY_NOT_ENOUGH = 1597; + public const int RET_WIDGET_TOY_CRYSTAL_ENERGY_NOT_ENOUGH = 1598; + public const int RET_WIDGET_LIGHT_STONE_LEVEL_NOT_ENOUGH = 1599; + public const int RET_WIDGET_QUICK_SLOT_NOT_IN_WIDGET_PANEL = 1600; + public const int RET_UID_NOT_EXIST = 2001; + public const int RET_PARSE_BIN_ERROR = 2002; + public const int RET_ACCOUNT_INFO_NOT_EXIST = 2003; + public const int RET_ORDER_INFO_NOT_EXIST = 2004; + public const int RET_SNAPSHOT_INDEX_ERROR = 2005; + public const int RET_MAIL_HAS_BEEN_SENT = 2006; + public const int RET_PRODUCT_NOT_EXIST = 2007; + public const int RET_UNFINISH_ORDER = 2008; + public const int RET_ID_NOT_EXIST = 2009; + public const int RET_ORDER_TRADE_EARLY = 2010; + public const int RET_ORDER_FINISHED = 2011; + public const int RET_GAMESERVER_VERSION_WRONG = 2012; + public const int RET_OFFLINE_OP_FULL_LENGTH = 2013; + public const int RET_CONCERT_PRODUCT_OBTAIN_LIMIT = 2014; + public const int RET_CONCERT_PRODUCT_TICKET_DUPLICATED = 2015; + public const int RET_CONCERT_PRODUCT_TICKET_EMPTY = 2016; + public const int RET_REDIS_MODIFIED = 5001; + public const int RET_REDIS_UID_NOT_EXIST = 5002; + public const int RET_PATHFINDING_DATA_NOT_EXIST = 6001; + public const int RET_PATHFINDING_DESTINATION_NOT_EXIST = 6002; + public const int RET_PATHFINDING_ERROR_SCENE = 6003; + public const int RET_PATHFINDING_SCENE_DATA_LOADING = 6004; + public const int RET_TOTHEMOON_ERROR_SCENE = 6301; + public const int RET_TOTHEMOON_PLAYER_NOT_EXIST = 6302; + public const int RET_FRIEND_COUNT_EXCEEDED = 7001; + public const int RET_PLAYER_NOT_EXIST = 7002; + public const int RET_ALREADY_SENT_ADD_REQUEST = 7003; + public const int RET_ASK_FRIEND_LIST_FULL = 7004; + public const int RET_PLAYER_ALREADY_IS_FRIEND = 7005; + public const int RET_PLAYER_NOT_ASK_FRIEND = 7006; + public const int RET_TARGET_FRIEND_COUNT_EXCEED = 7007; + public const int RET_NOT_FRIEND = 7008; + public const int RET_BIRTHDAY_CANNOT_BE_SET_TWICE = 7009; + public const int RET_CANNOT_ADD_SELF_FRIEND = 7010; + public const int RET_SIGNATURE_ILLEGAL = 7011; + public const int RET_PS_PLAYER_CANNOT_ADD_FRIENDS = 7012; + public const int RET_PS_PLAYER_CANNOT_REMOVE_FRIENDS = 7013; + public const int RET_NAME_CARD_NOT_UNLOCKED = 7014; + public const int RET_ALREADY_IN_BLACKLIST = 7015; + public const int RET_PS_PALEYRS_CANNOT_ADD_BLACKLIST = 7016; + public const int RET_PLAYER_BLACKLIST_FULL = 7017; + public const int RET_PLAYER_NOT_IN_BLACKLIST = 7018; + public const int RET_BLACKLIST_PLAYER_CANNOT_ADD_FRIEND = 7019; + public const int RET_IN_TARGET_BLACKLIST = 7020; + public const int RET_CANNOT_ADD_TARGET_FRIEND = 7021; + public const int RET_BIRTHDAY_FORMAT_ERROR = 7022; + public const int RET_ONLINE_ID_NOT_EXISTS = 7023; + public const int RET_FIRST_SHARE_REWARD_HAS_TAKEN = 7024; + public const int RET_PS_PLAYER_CANNOT_REMOVE_BLACKLIST = 7025; + public const int RET_REPORT_CD = 7026; + public const int RET_REPORT_CONTENT_ILLEGAL = 7027; + public const int RET_REMARK_WORD_ILLEGAL = 7028; + public const int RET_REMARK_TOO_LONG = 7029; + public const int RET_REMARK_UTF8_ERROR = 7030; + public const int RET_REMARK_IS_EMPTY = 7031; + public const int RET_ASK_ADD_FRIEND_CD = 7032; + public const int RET_SHOW_AVATAR_INFO_NOT_EXIST = 7033; + public const int RET_PLAYER_NOT_SHOW_AVATAR = 7034; + public const int RET_SOCIAL_UPDATE_SHOW_LIST_REPEAT_ID = 7035; + public const int RET_PSN_ID_NOT_FOUND = 7036; + public const int RET_EMOJI_COLLECTION_NUM_EXCEED_LIMIT = 7037; + public const int RET_REMARK_EMPTY = 7038; + public const int RET_IN_TARGET_PSN_BLACKLIST = 7039; + public const int RET_SIGNATURE_NOT_CHANGED = 7040; + public const int RET_SIGNATURE_MONTHLY_LIMIT = 7041; + public const int RET_REQ_FRIEND_AVATAR_FREQUENTLY = 7042; + public const int RET_PSN_GET_PLAYER_SOCIAL_DETAIL_FAIL = 7043; + public const int RET_OFFERING_NOT_OPEN = 7081; + public const int RET_OFFERING_LEVEL_LIMIT = 7082; + public const int RET_OFFERING_LEVEL_NOT_REACH = 7083; + public const int RET_OFFERING_LEVEL_HAS_TAKEN = 7084; + public const int RET_OFFERING_PARI_SEARCH_NOT_OPEN = 7085; + public const int RET_OFFERING_PARI_NOT_FINISH = 7086; + public const int RET_OFFERING_PARI_FINISH_REWARD_HAS_TAKEN = 7087; + public const int RET_OFFERING_PARI_SEARCH_ALL_FINISH = 7088; + public const int RET_CITY_REPUTATION_NOT_OPEN = 7101; + public const int RET_CITY_REPUTATION_LEVEL_TAKEN = 7102; + public const int RET_CITY_REPUTATION_LEVEL_NOT_REACH = 7103; + public const int RET_CITY_REPUTATION_PARENT_QUEST_TAKEN = 7104; + public const int RET_CITY_REPUTATION_PARENT_QUEST_UNFINISH = 7105; + public const int RET_CITY_REPUTATION_ACCEPT_REQUEST = 7106; + public const int RET_CITY_REPUTATION_NOT_ACCEPT_REQUEST = 7107; + public const int RET_CITY_REPUTATION_ACCEPT_REQUEST_LIMIT = 7108; + public const int RET_CITY_REPUTATION_ENTRANCE_NOT_OPEN = 7109; + public const int RET_CITY_REPUTATION_TAKEN_REQUEST_REWARD = 7110; + public const int RET_CITY_REPUTATION_SWITCH_CLOSE = 7111; + public const int RET_CITY_REPUTATION_ENTRACE_SWITCH_CLOSE = 7112; + public const int RET_CITY_REPUTATION_TAKEN_EXPLORE_REWARD = 7113; + public const int RET_CITY_REPUTATION_EXPLORE_NOT_REACH = 7114; + public const int RET_MECHANICUS_NOT_OPEN = 7120; + public const int RET_MECHANICUS_GEAR_UNLOCK = 7121; + public const int RET_MECHANICUS_GEAR_LOCK = 7122; + public const int RET_MECHANICUS_GEAR_LEVEL_LIMIT = 7123; + public const int RET_MECHANICUS_COIN_NOT_ENOUGH = 7124; + public const int RET_MECHANICUS_NO_SEQUENCE = 7125; + public const int RET_MECHANICUS_SEQUENCE_LIMIT_LEVEL = 7126; + public const int RET_MECHANICUS_SEQUENCE_LIMIT_OPEN = 7127; + public const int RET_MECHANICUS_DIFFICULT_NOT_SUPPORT = 7128; + public const int RET_MECHANICUS_TICKET_NOT_ENOUGH = 7129; + public const int RET_MECHANICUS_TEACH_NOT_FINISH = 7130; + public const int RET_MECHANICUS_TEACH_FINISHED = 7131; + public const int RET_MECHANICUS_PREV_DIFFICULT_LEVEL_BLOCK = 7132; + public const int RET_MECHANICUS_PLAYER_LIMIT = 7133; + public const int RET_MECHANICUS_PUNISH_TIME = 7134; + public const int RET_MECHANICUS_SWITCH_CLOSE = 7135; + public const int RET_MECHANICUS_BATTLE_NOT_IN_DUNGEON = 7150; + public const int RET_MECHANICUS_BATTLE_PLAY_NOT_FOUND = 7151; + public const int RET_MECHANICUS_BATTLE_DUPLICATE_PICK_CARD = 7152; + public const int RET_MECHANICUS_BATTLE_PLAYER_NOT_IN_PLAY = 7153; + public const int RET_MECHANICUS_BATTLE_CARD_NOT_AVAILABLE = 7154; + public const int RET_MECHANICUS_BATTLE_NOT_IN_CARD_STAGE = 7155; + public const int RET_MECHANICUS_BATTLE_CARD_IS_WAITING = 7156; + public const int RET_MECHANICUS_BATTLE_CARD_ALL_CONFIRMED = 7157; + public const int RET_MECHANICUS_BATTLE_CARD_ALREADY_CONFIRMED = 7158; + public const int RET_MECHANICUS_BATTLE_CARD_CONFIRMED_BY_OTHER = 7159; + public const int RET_MECHANICUS_BATTLE_CARD_NOT_ENOUGH_POINTS = 7160; + public const int RET_MECHANICUS_BATTLE_CARD_ALREADY_SKIPPED = 7161; + public const int RET_LEGENDARY_KEY_NOT_ENOUGH = 8001; + public const int RET_LEGENDARY_KEY_EXCEED_LIMIT = 8002; + public const int RET_DAILY_TASK_NOT_ENOUGH_TO_REDEEM = 8003; + public const int RET_PERSONAL_LINE_OPEN_STATE_OFF = 8004; + public const int RET_PERSONAL_LINE_LEVEL_NOT_ENOUGH = 8005; + public const int RET_PERSONAL_LINE_NOT_OPEN = 8006; + public const int RET_PERSONAL_LINE_PRE_QUEST_NOT_FINISH = 8007; + public const int RET_HUNTING_ALREADY_FINISH_OFFER_LIMIT = 8201; + public const int RET_HUNTING_HAS_UNFINISHED_OFFER = 8202; + public const int RET_HUNTING_FAILED_OFFER_NOT_CD_READY = 8203; + public const int RET_HUNTING_NOT_TAKE_OFFER = 8204; + public const int RET_HUNTING_CANNOT_TAKE_TWICE = 8205; + public const int RET_RPIVATE_CHAT_INVALID_CONTENT_TYPE = 8901; + public const int RET_PRIVATE_CHAT_TARGET_IS_NOT_FRIEND = 8902; + public const int RET_PRIVATE_CHAT_CONTENT_NOT_SUPPORTED = 8903; + public const int RET_PRIVATE_CHAT_CONTENT_TOO_LONG = 8904; + public const int RET_PRIVATE_CHAT_PULL_TOO_FAST = 8905; + public const int RET_PRIVATE_CHAT_REPEAT_READ = 8906; + public const int RET_PRIVATE_CHAT_READ_NOT_FRIEND = 8907; + public const int RET_REUNION_FINISHED = 9001; + public const int RET_REUNION_NOT_ACTIVATED = 9002; + public const int RET_REUNION_ALREADY_TAKE_FIRST_REWARD = 9003; + public const int RET_REUNION_SIGN_IN_REWARDED = 9004; + public const int RET_REUNION_WATCHER_REWARDED = 9005; + public const int RET_REUNION_WATCHER_NOT_FINISH = 9006; + public const int RET_REUNION_MISSION_REWARDED = 9007; + public const int RET_REUNION_MISSION_NOT_FINISH = 9008; + public const int RET_REUNION_WATCHER_REWARD_NOT_UNLOCKED = 9009; + public const int RET_BLESSING_CONTENT_CLOSED = 9101; + public const int RET_BLESSING_NOT_ACTIVE = 9102; + public const int RET_BLESSING_NOT_TODAY_ENTITY = 9103; + public const int RET_BLESSING_ENTITY_EXCEED_SCAN_NUM_LIMIT = 9104; + public const int RET_BLESSING_DAILY_SCAN_NUM_EXCEED_LIMIT = 9105; + public const int RET_BLESSING_REDEEM_REWARD_NUM_EXCEED_LIMIT = 9106; + public const int RET_BLESSING_REDEEM_PIC_NUM_NOT_ENOUGH = 9107; + public const int RET_BLESSING_PIC_NOT_ENOUGH = 9108; + public const int RET_BLESSING_PIC_HAS_RECEIVED = 9109; + public const int RET_BLESSING_TARGET_RECV_NUM_EXCEED = 9110; + public const int RET_FLEUR_FAIR_CREDIT_EXCEED_LIMIT = 9111; + public const int RET_FLEUR_FAIR_CREDIT_NOT_ENOUGH = 9112; + public const int RET_FLEUR_FAIR_TOKEN_EXCEED_LIMIT = 9113; + public const int RET_FLEUR_FAIR_TOKEN_NOT_ENOUGH = 9114; + public const int RET_FLEUR_FAIR_MINIGAME_NOT_OPEN = 9115; + public const int RET_FLEUR_FAIR_MUSIC_GAME_DIFFICULTY_NOT_UNLOCK = 9116; + public const int RET_FLEUR_FAIR_DUNGEON_LOCKED = 9117; + public const int RET_FLEUR_FAIR_DUNGEON_PUNISH_TIME = 9118; + public const int RET_FLEUR_FAIR_ONLY_OWNER_CAN_RESTART_MINIGAM = 9119; + public const int RET_WATER_SPIRIT_COIN_EXCEED_LIMIT = 9120; + public const int RET_WATER_SPIRIT_COIN_NOT_ENOUGH = 9121; + public const int RET_REGION_SEARCH_NO_SEARCH = 9122; + public const int RET_REGION_SEARCH_STATE_ERROR = 9123; + public const int RET_CHANNELLER_SLAB_LOOP_DUNGEON_STAGE_NOT_OPEN = 9130; + public const int RET_CHANNELLER_SLAB_LOOP_DUNGEON_NOT_OPEN = 9131; + public const int RET_CHANNELLER_SLAB_LOOP_DUNGEON_FIRST_PASS_REWARD_HAS_TAKEN = 9132; + public const int RET_CHANNELLER_SLAB_LOOP_DUNGEON_SCORE_REWARD_HAS_TAKEN = 9133; + public const int RET_CHANNELLER_SLAB_INVALID_ONE_OFF_DUNGEON = 9134; + public const int RET_CHANNELLER_SLAB_ONE_OFF_DUNGEON_DONE = 9135; + public const int RET_CHANNELLER_SLAB_ONE_OFF_DUNGEON_STAGE_NOT_OPEN = 9136; + public const int RET_CHANNELLER_SLAB_TOKEN_EXCEED_LIMIT = 9137; + public const int RET_CHANNELLER_SLAB_TOKEN_NOT_ENOUGH = 9138; + public const int RET_CHANNELLER_SLAB_PLAYER_NOT_IN_ONE_OFF_DUNGEON = 9139; + public const int RET_MIST_TRIAL_SELECT_CHARACTER_NUM_NOT_ENOUGH = 9150; + public const int RET_MIST_TRIAL_ALREADY_USING_TRIAL_AVATAR = 9151; + public const int RET_HIDE_AND_SEEK_PLAY_NOT_OPEN = 9160; + public const int RET_HIDE_AND_SEEK_PLAY_MAP_NOT_OPEN = 9161; + public const int RET_HIDE_AND_SEEK_PLAY_MAP_NOT_CHOSEN = 9162; + public const int RET_SUMMER_TIME_DRAFT_WOORD_EXCEED_LIMIT = 9170; + public const int RET_SUMMER_TIME_DRAFT_WOORD_NOT_ENOUGH = 9171; + public const int RET_SUMMER_TIME_MINI_HARPASTUM_EXCEED_LIMIT = 9172; + public const int RET_SUMMER_TIME_MINI_HARPASTUMNOT_ENOUGH = 9173; + public const int RET_BOUNCE_CONJURING_COIN_EXCEED_LIMIT = 9180; + public const int RET_BOUNCE_CONJURING_COIN_NOT_ENOUGH = 9181; + public const int RET_CHESS_TEACH_MAP_FINISHED = 9183; + public const int RET_CHESS_TEACH_MAP_UNFINISHED = 9184; + public const int RET_CHESS_COIN_EXCEED_LIMIT = 9185; + public const int RET_CHESS_COIN_NOT_ENOUGH = 9186; + public const int RET_CHESS_IN_PUNISH_TIME = 9187; + public const int RET_CHESS_PREV_MAP_UNFINISHED = 9188; + public const int RET_CHESS_MAP_LOCKED = 9189; + public const int RET_BLITZ_RUSH_NOT_OPEN = 9192; + public const int RET_BLITZ_RUSH_DUNGEON_NOT_OPEN = 9193; + public const int RET_BLITZ_RUSH_COIN_A_EXCEED_LIMIT = 9194; + public const int RET_BLITZ_RUSH_COIN_B_EXCEED_LIMIT = 9195; + public const int RET_BLITZ_RUSH_COIN_A_NOT_ENOUGH = 9196; + public const int RET_BLITZ_RUSH_COIN_B_NOT_ENOUGH = 9197; + public const int RET_MIRACLE_RING_VALUE_NOT_ENOUGH = 9201; + public const int RET_MIRACLE_RING_CD = 9202; + public const int RET_MIRACLE_RING_REWARD_NOT_TAKEN = 9203; + public const int RET_MIRACLE_RING_NOT_DELIVER = 9204; + public const int RET_MIRACLE_RING_DELIVER_EXCEED = 9205; + public const int RET_MIRACLE_RING_HAS_CREATED = 9206; + public const int RET_MIRACLE_RING_HAS_NOT_CREATED = 9207; + public const int RET_MIRACLE_RING_NOT_YOURS = 9208; + public const int RET_GADGET_FOUNDATION_UNAUTHORIZED = 9251; + public const int RET_GADGET_FOUNDATION_SCENE_NOT_FOUND = 9252; + public const int RET_GADGET_FOUNDATION_NOT_IN_INIT_STATE = 9253; + public const int RET_GADGET_FOUNDATION_BILDING_POINT_NOT_ENOUGHT = 9254; + public const int RET_GADGET_FOUNDATION_NOT_IN_BUILT_STATE = 9255; + public const int RET_GADGET_FOUNDATION_OP_NOT_SUPPORTED = 9256; + public const int RET_GADGET_FOUNDATION_REQ_PLAYER_NOT_IN_SCENE = 9257; + public const int RET_GADGET_FOUNDATION_LOCKED_BY_ANOTHER_PLAYER = 9258; + public const int RET_GADGET_FOUNDATION_NOT_LOCKED = 9259; + public const int RET_GADGET_FOUNDATION_DUPLICATE_LOCK = 9260; + public const int RET_GADGET_FOUNDATION_PLAYER_NOT_FOUND = 9261; + public const int RET_GADGET_FOUNDATION_PLAYER_GEAR_NOT_FOUND = 9262; + public const int RET_GADGET_FOUNDATION_ROTAION_DISABLED = 9263; + public const int RET_GADGET_FOUNDATION_REACH_DUNGEON_GEAR_LIMIT = 9264; + public const int RET_GADGET_FOUNDATION_REACH_SINGLE_GEAR_LIMIT = 9265; + public const int RET_GADGET_FOUNDATION_ROTATION_ON_GOING = 9266; + public const int RET_OP_ACTIVITY_BONUS_NOT_FOUND = 9301; + public const int RET_OP_ACTIVITY_NOT_OPEN = 9302; + public const int RET_MULTISTAGE_PLAY_PLAYER_NOT_IN_SCENE = 9501; + public const int RET_MULTISTAGE_PLAY_NOT_FOUND = 9502; + public const int RET_MULTISTAGE_PLAY_IN_OTHER_STAGE = 9503; + public const int RET_COOP_CHAPTER_NOT_OPEN = 9601; + public const int RET_COOP_COND_NOT_MEET = 9602; + public const int RET_COOP_POINT_LOCKED = 9603; + public const int RET_COOP_NOT_HAVE_PROGRESS = 9604; + public const int RET_COOP_REWARD_HAS_TAKEN = 9605; + public const int RET_DRAFT_HAS_ACTIVE_DRAFT = 9651; + public const int RET_DRAFT_NOT_IN_MY_WORLD = 9652; + public const int RET_DRAFT_NOT_SUPPORT_MP = 9653; + public const int RET_DRAFT_PLAYER_NOT_ENOUGH = 9654; + public const int RET_DRAFT_INCORRECT_SCENE = 9655; + public const int RET_DRAFT_OTHER_PLAYER_ENTERING = 9656; + public const int RET_DRAFT_GUEST_IS_TRANSFERRING = 9657; + public const int RET_DRAFT_GUEST_NOT_IN_DRAFT_SCENE = 9658; + public const int RET_DRAFT_INVITE_OVER_TIME = 9659; + public const int RET_DRAFT_TWICE_CONFIRM_OVER_TIMER = 9660; + public const int RET_DRAFT_GUEST_NOT_IN_WORLD_SCENE = 9661; + public const int RET_HOME_UNKOWN = 9701; + public const int RET_HOME_INVALID_CLIENT_PARAM = 9702; + public const int RET_HOME_TARGE_PLAYER_HAS_NO_HOME = 9703; + public const int RET_HOME_NOT_ONLINE = 9704; + public const int RET_HOME_PLAYER_FULL = 9705; + public const int RET_HOME_BLOCKED = 9706; + public const int RET_HOME_ALREADY_IN_TARGET_HOME_WORLD = 9707; + public const int RET_HOME_IN_EDIT_MODE = 9708; + public const int RET_HOME_NOT_IN_EDIT_MODE = 9709; + public const int RET_HOME_HAS_GUEST = 9710; + public const int RET_HOME_CANT_ENTER_BY_IN_EDIT_MODE = 9711; + public const int RET_HOME_CLIENT_PARAM_INVALID = 9712; + public const int RET_HOME_PLAYER_NOT_IN_HOME_WORLD = 9713; + public const int RET_HOME_PLAYER_NOT_IN_SELF_HOME_WORLD = 9714; + public const int RET_HOME_NOT_FOUND_IN_MEM = 9715; + public const int RET_HOME_PLAYER_IN_HOME_ROOM_SCENE = 9716; + public const int RET_HOME_HOME_REFUSE_GUEST_ENTER = 9717; + public const int RET_HOME_OWNER_REFUSE_TO_ENTER_HOME = 9718; + public const int RET_HOME_OWNER_OFFLINE = 9719; + public const int RET_HOME_FURNITURE_EXCEED_LIMIT = 9720; + public const int RET_HOME_FURNITURE_COUNT_NOT_ENOUGH = 9721; + public const int RET_HOME_IN_TRY_ENTER_PROCESS = 9722; + public const int RET_HOME_ALREADY_IN_TARGET_SCENE = 9723; + public const int RET_HOME_COIN_EXCEED_LIMIT = 9724; + public const int RET_HOME_COIN_NOT_ENOUGH = 9725; + public const int RET_HOME_MODULE_NOT_UNLOCKED = 9726; + public const int RET_HOME_CUR_MODULE_CLOSED = 9727; + public const int RET_HOME_FURNITURE_SUITE_NOT_UNLOCKED = 9728; + public const int RET_HOME_IN_MATCH = 9729; + public const int RET_HOME_IN_COMBAT = 9730; + public const int RET_HOME_EDIT_MODE_CD = 9731; + public const int RET_HOME_UPDATE_FURNITURE_CD = 9732; + public const int RET_HOME_BLOCK_FURNITURE_LIMIT = 9733; + public const int RET_HOME_NOT_SUPPORT = 9734; + public const int RET_HOME_STATE_NOT_OPEN = 9735; + public const int RET_HOME_TARGET_STATE_NOT_OPEN = 9736; + public const int RET_HOME_APPLY_ENTER_OTHER_HOME_FAIL = 9737; + public const int RET_HOME_SAVE_NO_MAIN_HOUSE = 9738; + public const int RET_HOME_IN_DUNGEON = 9739; + public const int RET_HOME_ANY_GALLERY_STARTED = 9740; + public const int RET_HOME_QUEST_BLOCK_HOME = 9741; + public const int RET_HOME_WAITING_PRIOR_CHECK = 9742; + public const int RET_HOME_PERSISTENT_CHECK_FAIL = 9743; + public const int RET_HOME_FIND_ONLINE_HOME_FAIL = 9744; + public const int RET_HOME_JOIN_SCENE_FAIL = 9745; + public const int RET_HOME_MAX_PLAYER = 9746; + public const int RET_HOME_IN_TRANSFER = 9747; + public const int RET_HOME_ANY_HOME_GALLERY_STARTED = 9748; + public const int RET_HOME_CAN_NOT_ENTER_IN_AUDIT = 9749; + public const int RET_FURNITURE_MAKE_INDEX_ERROR = 9750; + public const int RET_FURNITURE_MAKE_LOCKED = 9751; + public const int RET_FURNITURE_MAKE_CONFIG_ERROR = 9752; + public const int RET_FURNITURE_MAKE_SLOT_FULL = 9753; + public const int RET_FURNITURE_MAKE_ADD_FURNITURE_FAIL = 9754; + public const int RET_FURNITURE_MAKE_UNFINISH = 9755; + public const int RET_FURNITURE_MAKE_IS_FINISH = 9756; + public const int RET_FURNITURE_MAKE_NOT_IN_CORRECT_HOME = 9757; + public const int RET_FURNITURE_MAKE_NO_COUNT = 9758; + public const int RET_FURNITURE_MAKE_ACCELERATE_LIMIT = 9759; + public const int RET_FURNITURE_MAKE_NO_MAKE_DATA = 9760; + public const int RET_HOME_LIMITED_SHOP_CLOSE = 9761; + public const int RET_HOME_AVATAR_NOT_SHOW = 9762; + public const int RET_HOME_EVENT_COND_NOT_SATISFIED = 9763; + public const int RET_HOME_INVALID_ARRANGE_ANIMAL_PARAM = 9764; + public const int RET_HOME_INVALID_ARRANGE_NPC_PARAM = 9765; + public const int RET_HOME_INVALID_ARRANGE_SUITE_PARAM = 9766; + public const int RET_HOME_INVALID_ARRANGE_MAIN_HOUSE_PARAM = 9767; + public const int RET_HOME_AVATAR_STATE_NOT_OPEN = 9768; + public const int RET_HOME_PLANT_FIELD_NOT_EMPTY = 9769; + public const int RET_HOME_PLANT_FIELD_EMPTY = 9770; + public const int RET_HOME_PLANT_FIELD_TYPE_ERROR = 9771; + public const int RET_HOME_PLANT_TIME_NOT_ENOUGH = 9772; + public const int RET_HOME_PLANT_SUB_FIELD_NUM_NOT_ENOUGH = 9773; + public const int RET_HOME_PLANT_FIELD_PARAM_ERROR = 9774; + public const int RET_HOME_FURNITURE_GUID_ERROR = 9775; + public const int RET_HOME_FURNITURE_ARRANGE_LIMIT = 9776; + public const int RET_HOME_FISH_FARMING_LIMIT = 9777; + public const int RET_HOME_FISH_COUNT_NOT_ENOUGH = 9778; + public const int RET_HOME_FURNITURE_COST_LIMIT = 9779; + public const int RET_HOME_CUSTOM_FURNITURE_INVALID = 9780; + public const int RET_HOME_INVALID_ARRANGE_GROUP_PARAM = 9781; + public const int RET_HOME_FURNITURE_ARRANGE_GROUP_LIMIT = 9782; + public const int RET_HOME_PICTURE_FRAME_COOP_CG_GENDER_ERROR = 9783; + public const int RET_HOME_PICTURE_FRAME_COOP_CG_NOT_UNLOCK = 9784; + public const int RET_HOME_FURNITURE_CANNOT_ARRANGE = 9785; + public const int RET_HOME_FURNITURE_IN_DUPLICATE_SUITE = 9786; + public const int RET_HOME_FURNITURE_CUSTOM_SUITE_TOO_SMALL = 9787; + public const int RET_HOME_FURNITURE_CUSTOM_SUITE_TOO_BIG = 9788; + public const int RET_HOME_FURNITURE_SUITE_EXCEED_LIMIT = 9789; + public const int RET_HOME_FURNITURE_CUSTOM_SUITE_EXCEED_LIMIT = 9790; + public const int RET_HOME_FURNITURE_CUSTOM_SUITE_INVALID_SURFACE_TYPE = 9791; + public const int RET_HOME_BGM_ID_NOT_FOUND = 9792; + public const int RET_HOME_BGM_NOT_UNLOCKED = 9793; + public const int RET_HOME_BGM_FURNITURE_NOT_FOUND = 9794; + public const int RET_HOME_BGM_NOT_SUPPORT_BY_CUR_SCENE = 9795; + public const int RET_HOME_LIMITED_SHOP_GOODS_DISABLE = 9796; + public const int RET_HOME_WORLD_WOOD_MATERIAL_EMPTY = 9797; + public const int RET_HOME_WORLD_WOOD_MATERIAL_NOT_FOUND = 9798; + public const int RET_HOME_WORLD_WOOD_MATERIAL_COUNT_INVALID = 9799; + public const int RET_HOME_WORLD_WOOD_EXCHANGE_EXCEED_LIMIT = 9800; + public const int RET_HOME_BLUEPRINT_SEARCH_SELF = 9801; + public const int RET_HOME_BLUEPRINT_SHARE_CODE_INVALID = 9802; + public const int RET_HOME_BLUEPRINT_NOT_EXIST = 9803; + public const int RET_HOME_BLUEPRINT_SLOT_HAS_EXIST_SHARE_CODE = 9804; + public const int RET_HOME_BLUEPRINT_SLOT_NOT_EXIST_SHARE_CODE = 9805; + public const int RET_HOME_BLUEPRINT_CAN_NOT_CREATE_IN_AUDIT = 9806; + public const int RET_HOME_BLOCK_NOT_UNLOCKED = 9807; + public const int RET_HOME_BLUEPRINT_CREATE_CD = 9808; + public const int RET_HOME_BLUEPRINT_SET_OPTION_CD = 9809; + public const int RET_HOME_BLUEPRINT_NOT_ALLOW_FRIEND_COPY = 9810; + public const int RET_HOME_FURNITURE_POS_UNDER_DIE_Y = 9811; + public const int RET_HOME_BLUEPRINT_GEN_SHARE_CODE_FAIL = 9812; + public const int RET_HOME_BLUEPRINT_SEARCH_CD = 9813; + public const int RET_HOME_BLUEPRINT_PREVIEW_CD = 9814; + public const int RET_HOME_BLUEPRINT_PREVIEW_SCENE_NOT_MATCH = 9815; + public const int RET_HOME_BLUEPRINT_SLOT_FULL = 9816; + public const int RET_HOME_BLUEPRINT_OWNER_REJECT_COPY = 9817; + public const int RET_HOME_BLUEPRINT_SAVE_TO_SLOT_CD = 9818; + public const int RET_HOME_BLUEPRINT_REPLY_TIMEOUT = 9819; + public const int RET_SUMO_ACTIVITY_STAGE_NOT_OPEN = 10000; + public const int RET_SUMO_ACTIVITY_SWITCH_TEAM_IN_CD = 10001; + public const int RET_SUMO_ACTIVITY_TEAM_NUM_INCORRECT = 10002; + public const int RET_LUNA_RITE_ACTIVITY_AREA_ID_ERROR = 10004; + public const int RET_LUNA_RITE_ACTIVITY_BATTLE_NOT_FINISH = 10005; + public const int RET_LUNA_RITE_ACTIVITY_ALREADY_SACRIFICE = 10006; + public const int RET_LUNA_RITE_ACTIVITY_ALREADY_TAKE_REWARD = 10007; + public const int RET_LUNA_RITE_ACTIVITY_SACRIFICE_NOT_ENOUGH = 10008; + public const int RET_LUNA_RITE_ACTIVITY_SEARCHING_COND_NOT_MEET = 10009; + public const int RET_DIG_GADGET_CONFIG_ID_NOT_MATCH = 10015; + public const int RET_DIG_FIND_NEAREST_POS_FAIL = 10016; + public const int RET_MUSIC_GAME_LEVEL_NOT_OPEN = 10021; + public const int RET_MUSIC_GAME_LEVEL_NOT_UNLOCK = 10022; + public const int RET_MUSIC_GAME_LEVEL_NOT_STARTED = 10023; + public const int RET_MUSIC_GAME_LEVEL_CONFIG_NOT_FOUND = 10024; + public const int RET_MUSIC_GAME_LEVEL_ID_NOT_MATCH = 10025; + public const int RET_ROGUELIKE_COIN_A_NOT_ENOUGH = 10031; + public const int RET_ROGUELIKE_COIN_B_NOT_ENOUGH = 10032; + public const int RET_ROGUELIKE_COIN_C_NOT_ENOUGH = 10033; + public const int RET_ROGUELIKE_COIN_A_EXCEED_LIMIT = 10034; + public const int RET_ROGUELIKE_COIN_B_EXCEED_LIMIT = 10035; + public const int RET_ROGUELIKE_COIN_C_EXCEED_LIMIT = 10036; + public const int RET_ROGUELIKE_RUNE_COUNT_NOT_ENOUGH = 10037; + public const int RET_ROGUELIKE_NOT_IN_ROGUE_DUNGEON = 10038; + public const int RET_ROGUELIKE_CELL_NOT_FOUND = 10039; + public const int RET_ROGUELIKE_CELL_TYPE_INCORRECT = 10040; + public const int RET_ROGUELIKE_CELL_ALREADY_FINISHED = 10041; + public const int RET_ROGUELIKE_DUNGEON_HAVE_UNFINISHED_PROGRESS = 10042; + public const int RET_ROGUELIKE_STAGE_NOT_FINISHED = 10043; + public const int RET_ROGUELIKE_STAGE_FIRST_PASS_REWARD_HAS_TAKEN = 10045; + public const int RET_ROGUELIKE_ACTIVITY_CONTENT_CLOSED = 10046; + public const int RET_ROGUELIKE_DUNGEON_PRE_QUEST_NOT_FINISHED = 10047; + public const int RET_ROGUELIKE_DUNGEON_NOT_OPEN = 10048; + public const int RET_ROGUELIKE_SPRINT_IS_BANNED = 10049; + public const int RET_ROGUELIKE_DUNGEON_PRE_STAGE_NOT_FINISHED = 10050; + public const int RET_ROGUELIKE_ALL_AVATAR_DIE_CANNOT_RESUME = 10051; + public const int RET_PLANT_FLOWER_ALREADY_TAKE_SEED = 10056; + public const int RET_PLANT_FLOWER_FRIEND_HAVE_FLOWER_LIMIT = 10057; + public const int RET_PLANT_FLOWER_CAN_GIVE_FLOWER_NOT_ENOUGH = 10058; + public const int RET_PLANT_FLOWER_WISH_FLOWER_KINDS_LIMIT = 10059; + public const int RET_PLANT_FLOWER_HAVE_FLOWER_NOT_ENOUGH = 10060; + public const int RET_PLANT_FLOWER_FLOWER_COMBINATION_INVALID = 10061; + public const int RET_HACHI_DUNGEON_NOT_VALID = 10052; + public const int RET_HACHI_DUNGEON_STAGE_NOT_OPEN = 10053; + public const int RET_HACHI_DUNGEON_TEAMMATE_NOT_PASS = 10054; + public const int RET_WINTER_CAMP_COIN_A_NOT_ENOUGH = 10071; + public const int RET_WINTER_CAMP_COIN_B_NOT_ENOUGH = 10072; + public const int RET_WINTER_CAMP_COIN_A_EXCEED_LIMIT = 10073; + public const int RET_WINTER_CAMP_COIN_B_EXCEED_LIMIT = 10074; + public const int RET_WINTER_CAMP_WISH_ID_INVALID = 10075; + public const int RET_WINTER_CAMP_NOT_FOUND_RECV_ITEM_DATA = 10076; + public const int RET_WINTER_CAMP_FRIEND_ITEM_COUNT_OVERFLOW = 10077; + public const int RET_WINTER_CAMP_SELECT_ITEM_DATA_INVALID = 10078; + public const int RET_WINTER_CAMP_ITEM_LIST_EMPTY = 10079; + public const int RET_WINTER_CAMP_REWARD_ALREADY_TAKEN = 10080; + public const int RET_WINTER_CAMP_STAGE_NOT_FINISH = 10081; + public const int RET_WINTER_CAMP_GADGET_INVALID = 10082; + public const int RET_LANTERN_RITE_COIN_A_NOT_ENOUGH = 10090; + public const int RET_LANTERN_RITE_COIN_B_NOT_ENOUGH = 10091; + public const int RET_LANTERN_RITE_COIN_C_NOT_ENOUGH = 10092; + public const int RET_LANTERN_RITE_COIN_A_EXCEED_LIMIT = 10093; + public const int RET_LANTERN_RITE_COIN_B_EXCEED_LIMIT = 10094; + public const int RET_LANTERN_RITE_COIN_C_EXCEED_LIMIT = 10095; + public const int RET_LANTERN_RITE_PROJECTION_CONTENT_CLOSED = 10096; + public const int RET_LANTERN_RITE_PROJECTION_CAN_NOT_START = 10097; + public const int RET_LANTERN_RITE_DUNGEON_NOT_OPEN = 10098; + public const int RET_LANTERN_RITE_HAS_TAKEN_SKIN_REWARD = 10099; + public const int RET_LANTERN_RITE_NOT_FINISHED_SKIN_WATCHERS = 10100; + public const int RET_LANTERN_RITE_FIREWORKS_CONTENT_CLOSED = 10101; + public const int RET_LANTERN_RITE_FIREWORKS_CHALLENGE_NOT_START = 10102; + public const int RET_LANTERN_RITE_FIREWORKS_REFORM_PARAM_ERROR = 10103; + public const int RET_LANTERN_RITE_FIREWORKS_REFORM_SKILL_LOCK = 10104; + public const int RET_LANTERN_RITE_FIREWORKS_REFORM_STAMINA_NOT_ENOUGH = 10105; + public const int RET_POTION_ACTIVITY_STAGE_NOT_OPEN = 10110; + public const int RET_POTION_ACTIVITY_LEVEL_HAVE_PASS = 10111; + public const int RET_POTION_ACTIVITY_TEAM_NUM_INCORRECT = 10112; + public const int RET_POTION_ACTIVITY_AVATAR_IN_CD = 10113; + public const int RET_POTION_ACTIVITY_BUFF_IN_CD = 10114; + public const int RET_IRODORI_POETRY_INVALID_LINE_ID = 10120; + public const int RET_IRODORI_POETRY_INVALID_THEME_ID = 10121; + public const int RET_IRODORI_POETRY_NOT_GET_ALL_INSPIRATION = 10122; + public const int RET_IRODORI_POETRY_INSPIRATION_REACH_LIMIE = 10123; + public const int RET_IRODORI_POETRY_ENTITY_ALREADY_SCANNED = 10124; + public const int RET_ACTIVITY_BANNER_ALREADY_CLEARED = 10300; + public const int RET_IRODORI_CHESS_NOT_OPEN = 10301; + public const int RET_IRODORI_CHESS_LEVEL_NOT_OPEN = 10302; + public const int RET_IRODORI_CHESS_MAP_NOT_OPEN = 10303; + public const int RET_IRODORI_CHESS_MAP_CARD_ALREADY_EQUIPED = 10304; + public const int RET_IRODORI_CHESS_EQUIP_CARD_EXCEED_LIMIT = 10305; + public const int RET_IRODORI_CHESS_MAP_CARD_NOT_EQUIPED = 10306; + public const int RET_IRODORI_CHESS_ENTER_FAIL_CARD_EXCEED_LIMIT = 10307; + public const int RET_ACTIVITY_FRIEND_HAVE_GIFT_LIMIT = 10310; + public const int RET_GACHA_ACTIVITY_HAVE_REWARD_LIMIT = 10315; + public const int RET_GACHA_ACTIVITY_HAVE_ROBOT_LIMIT = 10316; + public const int RET_SUMMER_TIME_V2_COIN_EXCEED_LIMIT = 10317; + public const int RET_SUMMER_TIME_V2_COIN_NOT_ENOUGH = 10318; + public const int RET_SUMMER_TIME_V2_DUNGEON_STAGE_NOT_OPEN = 10319; + public const int RET_SUMMER_TIME_V2_PREV_DUNGEON_NOT_COMPLETE = 10320; + public const int RET_ROGUE_DIARY_AVATAR_DEATH = 10350; + public const int RET_ROGUE_DIARY_AVATAR_TIRED = 10351; + public const int RET_ROGUE_DIARY_AVATAR_DUPLICATED = 10352; + public const int RET_ROGUE_DIARY_COIN_NOT_ENOUGH = 10353; + public const int RET_ROGUE_DIARY_VIRTUAL_COIN_EXCEED_LIMIT = 10354; + public const int RET_ROGUE_DIARY_VIRTUAL_COIN_NOT_ENOUGH = 10355; + public const int RET_ROGUE_DIARY_CONTENT_CLOSED = 10366; + public const int RET_GRAVEN_INNOCENCE_COIN_A_NOT_ENOUGH = 10380; + public const int RET_GRAVEN_INNOCENCE_COIN_B_NOT_ENOUGH = 10381; + public const int RET_GRAVEN_INNOCENCE_COIN_A_EXCEED_LIMIT = 10382; + public const int RET_GRAVEN_INNOCENCE_COIN_B_EXCEED_LIMIT = 10383; + public const int RET_ISLAND_PARTY_STAGE_NOT_OPEN = 10371; + public const int RET_WIND_FIELD_STAGE_NOT_OPEN = 10390; + public const int RET_VINTAGE_CONTENT_CLOSED = 10396; + public const int RET_VINTAGE_STORE_CONTENT_FINISHED = 10397; + public const int RET_VINTAGE_STORE_ATTR_TOO_SMALL = 10398; + public const int RET_VINTAGE_STORE_ATTR_TOO_LARGE = 10399; + public const int RET_VINTAGE_STORE_CONTENT_INTERRUPT = 10400; + public const int RET_VINTAGE_VIRTUAL_COIN_NOT_ENOUGH = 10401; + public const int RET_VINTAGE_STORE_ATTR_LESS_THAN_ZERO = 10402; + public const int RET_FUNGUS_FIGHTER_CAPTURE_COIN_NOT_ENOUGH = 10406; + public const int RET_FUNGUS_FIGHTER_TRAINING_COIN_NOT_ENOUGH = 10407; + public const int RET_FUNGUS_FIGHTER_CAPTURE_COIN_EXCEED_LIMIT = 10408; + public const int RET_FUNGUS_FIGHTER_TRAINING_COIN_EXCEED_LIMIT = 10409; + public const int RET_FUNGUS_FIGHTER_CONTENT_CLOSED = 10410; + public const int RET_FUNGUS_FIGHTER_PLOT_STAGE_NOT_OPEN = 10411; + public const int RET_FUNGUS_FIGHTER_FUNGUS_ID_CONFIG_NOT_VALID = 10412; + public const int RET_FUNGUS_FIGHTER_FUNGUS_NOT_CULTIVATED = 10413; + public const int RET_FUNGUS_FIGHTER_TRAINING_DUNGEON_NOT_OPEN = 10414; + public const int RET_EFFIGY_CHALLENGE_V2_COIN_NOT_ENOUGH = 10427; + public const int RET_EFFIGY_CHALLENGE_V2_COIN_EXCEED_LIMIT = 10428; + public const int RET_CHAR_AMUSEMENT_STAGE_NOT_OPEN = 10436; + public const int RET_COIN_COLLECT_LEVEL_NOT_OPEN = 10446; + public const int RET_COIN_COLLECT_NOT_EQUIP_WIDGET = 10447; + public const int RET_COIN_COLLECT_SCENE_NOT_MATCH = 10448; + public const int RET_COIN_COLLECT_CANT_ENTER_MP_MODE = 10449; + public const int RET_COIN_COLLECT_PLAYER_NUM_FAIL = 10450; + public const int RET_BRICK_BREAKER_PLAYER_NUM_FAIL = 10456; + public const int RET_BRICK_BREAKER_STAGE_NOT_UNLOCK = 10457; + public const int RET_BRICK_BREAKER_NORMAL_LEVEL_NOT_FINISH = 10458; + public const int RET_BRICK_BREAKER_PRE_LEVEL_NOT_FINISH = 10459; + public const int RET_BRICK_BREAKER_PRE_STAGE_NOT_FINISH = 10460; + public const int RET_BRICK_BREAKER_WORLD_LEVEL_NOT_UNLOCK = 10461; + public const int RET_BRICK_BREAKER_DUNGEON_LEVEL_NOT_UNLOCK = 10462; + public const int RET_BRICK_BREAKER_COIN_NOT_ENOUGH = 10463; + public const int RET_BRICK_BREAKER_COIN_EXCEED_LIMIT = 10464; + public const int RET_TEAMCHAIN_WORLD_IN_MP_MODE = 10466; + public const int RET_LAN_V3_BOAT_PLAYER_NUM_NOT_VALID = 10481; + public const int RET_LAN_V3_BOAT_PLAY_NOT_OPEN = 10482; + public const int RET_LAN_V3_BOAT_NOT_IN_WORLD_SCENE = 10483; + public const int RET_FLEUR_FAIR_V2_PACMAN_PLAY_NOT_OPEN = 10500; + public const int RET_FLEUR_FAIR_V2_PACMAN_PLAYER_NUM_INCORRECT = 10501; + public const int RET_FLEUR_FAIR_V2_COIN_NOT_ENOUGH = 10502; + public const int RET_FLEUR_FAIR_V2_COIN_EXCEED_LIMIT = 10503; + public const int RET_AKA_FES_RHYTHM_LEVEL_NOT_OPEN = 10521; + public const int RET_AKA_FES_RHYTHM_GALLERY_INIT_FAIL = 10522; + public const int RET_AKA_FES_RHYTHM_NOT_IN_EXPECTED_DUNGEON = 10533; + public const int RET_AKA_FES_REASONING_LEVEL_NOT_OPEN = 10531; + public const int RET_AKA_FES_ASTROLABE_LEVEL_NOT_OPEN = 10541; + public const int RET_AKA_FES_ASTROLABE_PRE_LEVEL_NOT_FINISH = 10542; + public const int RET_EFFIGY_CHALLENGE_V4_LEVEL_NOT_OPEN = 10551; + public const int RET_EFFIGY_CHALLENGE_V4_GUEST_NOT_READY = 10552; + public const int RET_EFFIGY_CHALLENGE_V4_DUPLICATE_AVATAR = 10553; + public const int RET_JOURNEY_ACTIVITY_PICK_PARAM_ERROR = 10561; + public const int RET_JOURNEY_ACTIVITY_PICK_COND_NOT_MEET = 10562; + public const int RET_JOURNEY_ACTIVITY_COIN_NOT_ENOUGH = 10563; + public const int RET_JOURNEY_ACTIVITY_COIN_EXCEED_LIMIT = 10564; + public const int RET_ACTIVITY_CONTENT_CLOSED = 10901; + public const int RET_NOT_IN_FISHING = 11001; + public const int RET_FISH_STATE_ERROR = 11002; + public const int RET_FISH_BAIT_LIMIT = 11003; + public const int RET_FISHING_MAX_DISTANCE = 11004; + public const int RET_FISHING_IN_COMBAT = 11005; + public const int RET_FISHING_BATTLE_TOO_SHORT = 11006; + public const int RET_FISH_GONE_AWAY = 11007; + public const int RET_CAN_NOT_EDIT_OTHER_DUNGEON = 11051; + public const int RET_CUSTOM_DUNGEON_DISMATCH = 11052; + public const int RET_NO_CUSTOM_DUNGEON_DATA = 11053; + public const int RET_BUILD_CUSTOM_DUNGEON_FAIL = 11054; + public const int RET_CUSTOM_DUNGEON_ROOM_CHECK_FAIL = 11055; + public const int RET_CUSTOM_DUNGEON_SAVE_MAY_FAIL = 11056; + public const int RET_NOT_IN_CUSTOM_DUNGEON = 11057; + public const int RET_CUSTOM_DUNGEON_INTERNAL_FAIL = 11058; + public const int RET_CUSTOM_DUNGEON_CAN_NOT_TRY = 11059; + public const int RET_CUSTOM_DUNGEON_NO_START_ROOM = 11060; + public const int RET_CUSTOM_DUNGEON_NO_ROOM_DATA = 11061; + public const int RET_CUSTOM_DUNGEON_SAVE_TOO_FREQUENT = 11062; + public const int RET_CUSTOM_DUNGEON_NOT_SELF_PASS = 11063; + public const int RET_CUSTOM_DUNGEON_LACK_COIN = 11064; + public const int RET_CUSTOM_DUNGEON_NO_FINISH_BRICK = 11065; + public const int RET_CUSTOM_DUNGEON_MULTI_FINISH = 11066; + public const int RET_CUSTOM_DUNGEON_NOT_PUBLISHED = 11067; + public const int RET_CUSTOM_DUNGEON_FULL_STORE = 11068; + public const int RET_CUSTOM_DUNGEON_STORE_REPEAT = 11069; + public const int RET_CUSTOM_DUNGEON_CAN_NOT_STORE_SELF = 11070; + public const int RET_CUSTOM_DUNGEON_NOT_SAVE_SUCC = 11071; + public const int RET_CUSTOM_DUNGEON_CAN_NOT_LIKE_SELF = 11072; + public const int RET_CUSTOM_DUNGEON_NOT_FOUND = 11073; + public const int RET_CUSTOM_DUNGEON_INVALID_SETTING = 11074; + public const int RET_CUSTOM_DUNGEON_NO_FINISH_SETTING = 11075; + public const int RET_CUSTOM_DUNGEON_SAVE_NOTHING = 11076; + public const int RET_CUSTOM_DUNGEON_NOT_IN_GROUP = 11077; + public const int RET_CUSTOM_DUNGEON_NOT_OFFICIAL = 11078; + public const int RET_CUSTOM_DUNGEON_LIFE_NUM_ERROR = 11079; + public const int RET_CUSTOM_DUNGEON_NO_OPEN_ROOM = 11080; + public const int RET_CUSTOM_DUNGEON_BRICK_EXCEED_LIMIT = 11081; + public const int RET_CUSTOM_DUNGEON_OFFICIAL_NOT_UNLOCK = 11082; + public const int RET_CAN_NOT_EDIT_OFFICIAL_SETTING = 11083; + public const int RET_CUSTOM_DUNGEON_BAN_PUBLISH = 11084; + public const int RET_CUSTOM_DUNGEON_CAN_NOT_REPLAY = 11085; + public const int RET_CUSTOM_DUNGEON_NOT_OPEN_GROUP = 11086; + public const int RET_CUSTOM_DUNGEON_MAX_EDIT_NUM = 11087; + public const int RET_CUSTOM_DUNGEON_CAN_NOT_OUT_STUCK = 11088; + public const int RET_CUSTOM_DUNGEON_MAX_TAG = 11089; + public const int RET_CUSTOM_DUNGEON_INVALID_TAG = 11090; + public const int RET_CUSTOM_DUNGEON_MAX_COST = 11091; + public const int RET_CUSTOM_DUNGEON_REQUEST_TOO_FREQUENT = 11092; + public const int RET_CUSTOM_DUNGEON_NOT_OPEN = 11093; + public const int RET_SHARE_CD_ID_ERROR = 11101; + public const int RET_SHARE_CD_INDEX_ERROR = 11102; + public const int RET_SHARE_CD_IN_CD = 11103; + public const int RET_SHARE_CD_TOKEN_NOT_ENOUGH = 11104; + public const int RET_UGC_DISMATCH = 11151; + public const int RET_UGC_DATA_NOT_FOUND = 11152; + public const int RET_UGC_BRIEF_NOT_FOUND = 11153; + public const int RET_UGC_DISABLED = 11154; + public const int RET_UGC_LIMITED = 11155; + public const int RET_UGC_LOCKED = 11156; + public const int RET_UGC_NOT_AUTH = 11157; + public const int RET_UGC_NOT_OPEN = 11158; + public const int RET_UGC_BAN_PUBLISH = 11159; + public const int RET_UGC_MUSIC_EXCEED_LIMIT = 11160; + public const int RET_UGC_MUSIC_SAVE_TOO_FREQUENT = 11161; + public const int RET_COMPOUND_BOOST_ITEM_NOT_EXIST = 11201; + public const int RET_COMPOUND_BOOST_TARGET_NOT_EXIST = 11202; + public const int RET_QUICK_HIT_TREE_EMPTY_TREES = 11211; + public const int RET_GCG_FIND_GAME_MODE_FAIL = 12000; + public const int RET_GCG_OPERATION_PARAM_ERROR = 12001; + public const int RET_GCG_GAME_NOT_RUNNING = 12002; + public const int RET_GCG_OP_NOT_ALLOW = 12003; + public const int RET_GCG_OP_NOT_MATCH_PHASE = 12004; + public const int RET_GCG_SELECT_HAND_CARD_GUID_ERROR = 12005; + public const int RET_GCG_DICE_INDEX_INVALID = 12006; + public const int RET_GCG_CHARACTER_GUID_INVALID = 12007; + public const int RET_GCG_CHARACTER_ALREADY_DIE = 12008; + public const int RET_GCG_CHARACTER_ALREADY_ON_STAGE = 12009; + public const int RET_GCG_CHARACTER_FORBIDDEN_ATTACK = 12010; + public const int RET_GCG_SELECT_DICE_NOT_MATCH = 12011; + public const int RET_GCG_FIND_SKILL_FAIL = 12012; + public const int RET_GCG_SKILL_CAN_NOT_ACTIVE_USE = 12013; + public const int RET_GCG_ENERGY_NOT_ENOUGH = 12014; + public const int RET_GCG_PLAY_CARD_TARGET_NOT_MATCH = 12015; + public const int RET_GCG_PLAY_CARD_ZONE_CANNOT_ADD = 12016; + public const int RET_GCG_REBOOT_SELECT_DICE_INVALID = 12017; + public const int RET_GCG_REBOOT_SELECT_CARD_INVALID = 12018; + public const int RET_GCG_PLAY_CARD_CONDITION_CHECK_FAIL = 12019; + public const int RET_GCG_PLAY_CARD_PARAM_INVALID = 12020; + public const int RET_GCG_MAX_GAME = 12021; + public const int RET_GCG_SEND_PACKET_FAIL = 12022; + public const int RET_GCG_ALREADY_SETTLE = 12023; + public const int RET_GCG_PLAY_CARD_LEGEND_ALREADY_USED = 12024; + public const int RET_GCG_COST_LEGEND_NOT_ENOUGH = 12025; + public const int RET_GCG_WATCH_IN_BLACK_LIST = 12026; + public const int RET_GCG_WATCH_FORBID_SWITCH = 12027; + public const int RET_GCG_WATCH_ALREADY_JOINED = 12028; + public const int RET_GCG_WATCH_KICK_NO_SPECTATOR = 12029; + public const int RET_GCG_WATCH_TARGET_NOT_IN_DUEL = 12030; + public const int RET_GCG_WATCH_TARGET_NOT_FRIEND = 12031; + public const int RET_GCG_WATCH_TARGET_PSN_ONLY = 12032; + public const int RET_GCG_WATCH_FORBID_BUSINESS_TYPE = 12033; + public const int RET_GCG_WATCH_OPTION_REFUSE = 12034; + public const int RET_GCG_WATCH_NO_PLAYER = 12035; + public const int RET_GCG_WATCH_TARGET_STATE_NOT_OPEN = 12036; + public const int RET_GCG_WATCH_SPECTATOR_LIMIT = 12037; + public const int RET_GCG_WATCH_FORBIDDEN_WATCH_GAME = 12038; + public const int RET_GCG_WATCH_NOT_SPECTATOR = 12039; + public const int RET_GCG_WATCH_ALREADY_IN_DUEL = 12040; + public const int RET_GCG_WATCH_CLIENT_DATA_VERSOIN_FORBID = 12041; + public const int RET_GCG_COIN_EXCEED_LIMIT = 12101; + public const int RET_GCG_COIN_NOT_ENOUGH = 12102; + public const int RET_GCG_NOT_IN_SELF_WORLD = 12103; + public const int RET_GCG_ALREADY_IN_DUEL = 12104; + public const int RET_GCG_NOT_IN_PLAYER_WORLD = 12105; + public const int RET_GCG_GALLERY_STARTED = 12106; + public const int RET_GCG_INVITE_TARGET_IS_SELF = 12107; + public const int RET_GCG_INVITE_TARGET_NOT_IN_WORLD = 12108; + public const int RET_GCG_APPLY_INVITE_NOT_ALLOW = 12109; + public const int RET_GCG_APPLY_INVITE_TIMEOUT = 12110; + public const int RET_GCG_CUR_DECK_INVALID = 12111; + public const int RET_GCG_NEED_RESOURCE_COMPLETE = 12112; + public const int RET_GCG_OPPONENT_PLAYER_IS_SELF = 12113; + public const int RET_GCG_GAME_ID_INVALID = 12114; + public const int RET_GCG_MATCH_IN_PUNISH = 12115; + public const int RET_GCG_SETTLE_STILL_IN_DUEL = 12116; + public const int RET_GCG_SETTLE_NOT_IN_DUNGEON = 12117; + public const int RET_GCG_UNSUPPORT_SETTLE_OPTION = 12118; + public const int RET_GCG_NOT_IN_GCG_DUNGEON = 12119; + public const int RET_GCG_WORLD_LEVEL_LOCKED = 12120; + public const int RET_GCG_BOSS_LEVEL_LOCKED = 12121; + public const int RET_GCG_NOT_IN_TAVERN = 12122; + public const int RET_GCG_WEEK_NPC_NOT_EXIST = 12123; + public const int RET_GCG_ENTER_GAME_FREQUENT = 12124; + public const int RET_GCG_BREAK_LEVEL_QUEST_NOT_UNFINISHED = 12125; + public const int RET_GCG_GUIDE_LEVEL_ALREADY_FINISHED = 12126; + public const int RET_GCG_LEVEL_CANNOT_RESTART = 12127; + public const int RET_GCG_TARGET_CHECK_ENTER_FAIL = 12128; + public const int RET_GCG_ALREADY_IN_DUNGEON = 12129; + public const int RET_GCG_BACK_DUEL_NO_GAME = 12130; + public const int RET_GCG_CONST_LEVEL_LOCKED = 12131; + public const int RET_GCG_QUEST_ID_ERROR = 12132; + public const int RET_GCG_QUEST_NEED_UNFINISHED = 12133; + public const int RET_GCG_IN_MATCH = 12134; + public const int RET_GCG_DATA_VERSION_NOT_LATEST = 12135; + public const int RET_GCG_INVITE_TARGET_ENTER_GAME_FREQUENT = 12136; + public const int RET_GCG_INVITE_TARGET_NEED_RESOURCE_COMPLETE = 12137; + public const int RET_GCG_INVITE_TARGET_SCENE_IS_NULL = 12138; + public const int RET_GCG_INVITE_TARGET_IN_TRANSFER = 12139; + public const int RET_GCG_INVITE_TARGET_DATA_VERSION_NOT_LATEST = 12140; + public const int RET_GCG_INVITE_TARGET_CUR_DECK_INVALID = 12141; + public const int RET_GCG_CLIENT_DATA_VERSION_NOT_MATCH = 12142; + public const int RET_GCG_CLIENT_DATA_VERSOIN_FORBID = 12143; + public const int RET_GCG_MP_CANT_MATCH = 12144; + public const int RET_GCG_INVITE_TARGET_STATE_NOT_OPEN = 12145; + public const int RET_GCG_CREATE_TIME_OUT = 12146; + public const int RET_GCG_BAN_MATCH = 12147; + public const int RET_GCG_BAN_INVITE = 12148; + public const int RET_GCG_TARGET_BAN_INVITE = 12149; + public const int RET_GCG_INVITE_ALREADY_INVITE = 12150; + public const int RET_GCG_FESTIVAL_MODE_NOT_OPEN = 12151; + public const int RET_GCG_TARGET_FESTIVAL_MODE_NOT_OPEN = 12152; + public const int RET_GCG_BACK_DUEL_PS_TO_OTHER = 12153; + public const int RET_GCG_BACK_DUEL_OTHER_TO_PS = 12154; + public const int RET_GCG_DS_DECK_LOCKED = 12201; + public const int RET_GCG_DS_DECK_NAME_INVALID = 12202; + public const int RET_GCG_DS_DECK_CHAR_CARD_NUM_INVALID = 12204; + public const int RET_GCG_DS_DECK_CARD_NUM_INVALID = 12205; + public const int RET_GCG_DS_CARD_NUM_EXCEED_LIMIT = 12206; + public const int RET_GCG_DS_DECK_INVALID = 12207; + public const int RET_GCG_DS_CARD_ID_INVALID = 12208; + public const int RET_GCG_DS_CARD_FACE_ALREADY_UNLOCK = 12209; + public const int RET_GCG_DS_CARD_FACE_IS_LOCK = 12210; + public const int RET_GCG_DS_FIELD_LOCK = 12211; + public const int RET_GCG_DS_FIELD_ALREADY_UNLOCK = 12212; + public const int RET_GCG_DS_FIELD_ID_INVALID = 12213; + public const int RET_GCG_DS_CARD_BACK_LOCKED = 12214; + public const int RET_GCG_DS_CARD_BACK_ALREADY_UNLOCK = 12215; + public const int RET_GCG_DS_CARD_BACK_ID_INVALID = 12216; + public const int RET_GCG_DS_CARD_FACE_ID_INVALID = 12217; + public const int RET_GCG_DS_DECK_NAME_ILLEGAL = 12218; + public const int RET_GCG_DS_DECK_SAVE_CD = 12219; + public const int RET_GCG_DS_DECK_CHANGE_NAME_CD = 12220; + public const int RET_GCG_MATCH_DECK_INVALID = 12221; + public const int RET_GCG_DS_DECK_ALREADY_UNLOCKED = 12222; + public const int RET_GCG_DS_AT_LEAST_ONE_DECK = 12223; + public const int RET_GCG_TC_CHARACTERNOT_MATCH_LEVEL = 12251; + public const int RET_GCG_TC_MUST_IN_SELF_WORLD = 12252; + public const int RET_GCG_TC_MUST_IN_TAVERN = 12253; + public const int RET_GCG_TC_ALREADY_IN_GAME = 12254; + public const int RET_GCG_TC_ALREADY_IN_MATCH = 12255; + public const int RET_GCG_TC_UNLOCK_CHARACTER_QUEST_NOT_FINISH = 12256; + public const int RET_GCG_TC_LEVEL_LOCKED = 12257; + public const int RET_GCG_TC_NO_INVITE_DATA = 12258; + public const int RET_GCG_TC_CUR_DECK_INVALID = 12259; + public const int RET_GCG_TC_COND_QUEST = 12260; + public const int RET_GCG_LEVEL_REWARD_LEVEL_ERROR = 12301; + public const int RET_GCG_LEVEL_REWARD_ALREADY_TAKEN = 12302; + public const int RET_GCG_LEVEL_REWARD_NO_REWARD = 12303; + public const int RET_GCG_NOT_IN_REPLAY_DUNGEON = 12311; + public const int RET_GCG_INVALID_REPLAY = 12312; + public const int RET_GCG_SET_FAVORITE_LIMIT_NUM = 12313; + public const int RET_GCG_REPLAY_EXPIRE = 12314; + public const int RET_GCG_REPLAY_DUNGEON_SETTLED = 12315; + public const int RET_GCG_PICK_CUR_UID_NOT_MATCH = 12331; + public const int RET_GCG_PICK_SELECT_PARAM_ERROR = 12332; + public const int RET_GCG_PICK_CONFIRM_ERROR = 12333; + public const int RET_GCG_PICK_BACK_NO_GAME = 12334; + public const int RET_GCG_ARENA_SCHEDULE_INACTIVE = 12341; + public const int RET_GCG_ARENA_SCHEDULE_NOT_MATCH = 12342; + public const int RET_GCG_ARENA_DECK_NOT_SET = 12343; + public const int RET_GCG_ARENA_DECK_INVALID = 12344; + public const int RET_GCG_ARENA_IN_CHALLENGE_CANNOT_SET_DECK = 12345; + public const int RET_GCG_ARENA_START_CHALLENGE_IN_MP_MODE = 12346; + public const int RET_GCG_ARENA_START_MATCH_IN_MP_MODE = 12347; + public const int RET_UGC_DUNGEON_IN_DUNGEON = 13001; + public const int RET_UGC_DUNGEON_ROOM_NUM_LIMIT = 13002; + public const int RET_UGC_DUNGEON_NOT_IN_EDIT_STATE = 13003; + public const int RET_UGC_DUNGEON_NOT_IN_EDIT_DUNGEON = 13004; + public const int RET_UGC_DUNGEON_NOT_EXIST = 13005; + public const int RET_UGC_DUNGEON_NOT_SAVE = 13006; + public const int RET_UGC_DUNGEON_SCORE_CONDTION_BUT_NO_MONSTER = 13007; + public const int RET_UGC_DUNGEON_SCORE_CONDTION_BUT_NO_COIN = 13008; + public const int RET_UGC_DUNGEON_SCORE_CONDTION_BUT_NO_CHEST = 13009; + public const int RET_UGC_DUNGEON_SCORE_CONDTION_BUT_NO_ROOM_SETTLE = 13010; + public const int RET_UGC_DUNGEON_TARGET_SCORE_EXCEED_LIMIT = 13011; + public const int RET_UGC_DUNGEON_TIME_SETTLE_TARGET_SCORE_NOT_ZERO = 13012; + public const int RET_UGC_DUNGEON_ALLOW_AVATAR_NOT_ENOUGH = 13013; + public const int RET_UGC_DUNGEON_HEART_BLOOD_WHILE_MONSTER_DEPLOY = 13014; + public const int RET_UGC_DUNGEON_ROOM_NO_EXIT_GADGET = 13015; + public const int RET_UGC_DUNGEON_ROOM_HOST_ENTER_GADGET_NUM = 13016; + public const int RET_UGC_DUNGEON_ROOM_GUEST_ENTER_GADGET_NOT_ENOUGH = 13017; + public const int RET_UGC_DUNGEON_ROOM_SETTING_COIN_NUM_TOO_LARGE = 13018; + public const int RET_UGC_DUNGEON_ROOM_SETTING_MONSTER_NUM_TOO_LARGE = 13019; + public const int RET_UGC_DUNGEON_ROOM_SETTING_NO_SETTLE_CONFIG = 13020; + public const int RET_UGC_DUNGEON_ROOM_SWITCH_INVITE_IN_PROCESS = 13021; + public const int RET_UGC_DUNGEON_ROOM_DEPLOYMENT_COST_LIMIT = 13022; + public const int RET_UGC_DUNGEON_ROOM_TRIGGER_DUPLICATE_GUID = 13023; + public const int RET_UGC_DUNGEON_ROOM_TRIGGER_PARAM_ERROR = 13024; + public const int RET_UGC_DUNGEON_SCORE_SETTLE_TARGET_SCORE_ZERO = 13025; + public const int RET_UGC_DUNGEON_STATE_CAN_NOT_AUDIT = 13026; + public const int RET_UGC_DUNGEON_AUDIT_VERSION_NOT_MATCH = 13027; + public const int RET_UGC_DUNGEON_IN_AUDIT = 13028; + public const int RET_UGC_DUNGEON_STATE_CAN_NOT_PUBLISH = 13029; + public const int RET_UGC_DUNGEON_REQUEST_TOO_FREQUENT = 13030; + public const int RET_UGC_DUNGEON_CAN_NOT_PUBLISH_NO_EDIT = 13031; + public const int RET_UGC_DUNGEON_NOT_ALLOW_IMPORT = 13032; + public const int RET_UGC_DUNGEON_IMPORT_ROOM_HAS_MONSTER = 13033; + public const int RET_UGC_DUNGEON_SEARCH_NOT_EXIST = 13034; + public const int RET_UGC_DUNGEON_ROOM_SWITCH_LAST_ROOM = 13035; + public const int RET_UGC_DUNGEON_ROOM_GADGET_NUM_LIMIT = 13036; + public const int RET_UGC_DUNGEON_ROOM_MONSTER_NUM_LIMIT = 13037; + public const int RET_UGC_DUNGEON_NO_TRIAL_SUCC_RECORD = 13038; + public const int RET_UGC_DUNGEON_NUM_LIMIT = 13039; + public const int RET_UGC_DUNGEON_IN_EDIT_DUNGEON = 13040; + public const int RET_UGC_DUNGEON_NOT_IN_DUNGEON = 13041; + public const int RET_UGC_DUNGEON_CHANGE_SETTING_TOO_FREQUENT = 13042; + public const int RET_UGC_DUNGEON_NOT_OWNER = 13043; + public const int RET_UGC_DUNGEON_NOT_PUBLISHED = 13044; + public const int RET_UGC_DUNGEON_SHARE_CODE_GEN_FAIL = 13045; + public const int RET_UGC_DUNGEON_ROOM_LIMIT = 13046; + public const int RET_UGC_DUNGEON_SHARE_CODE_INVALID = 13047; + public const int RET_UGC_DUNGEON_ROOM_SUITE_NUM_LIMIT = 13048; + public const int RET_UGC_DUNGEON_TOWER_HAS_BEEN_PURCHASED = 13101; + public const int RET_UGC_DUNGEON_PLAYER_ADD_ITEM_OVER_STACK = 13102; + public const int RET_UGC_DUNGEON_PLAYER_TOWER_LEVEL_UP_LIMITED = 13103; + public const int RET_UGC_DUNGEON_PLAYER_CONSUME_ITEM_NOT_ENOUGH = 13104; + public const int RET_UGC_DUNGEON_PLAYER_TOWER_ALREADY_LEVEL_UP = 13105; + public const int RET_UGC_DUNGEON_PLAYER_UGC_TARGET_IS_NOT_EXIST = 13106; + public const int RET_UGC_DUNGEON_PLAYER_UGC_TARGET_IS_NOT_ACTIVE = 13107; + public const int RET_UGC_DUNGEON_CHECK_LAYOUT_FAILED = 13108; + public const int RET_UGC_DUNGEON_PLAYER_TOWER_ALREADY_REMOVED = 13109; + public const int RET_UGC_DUNGEON_PLAYER_ADD_ITEM_OVER_LIMIT = 13110; + public const int RET_UGC_DUNGEON_PLAYER_GRANT_AVATAR_OVER_LIMIT = 13111; + public const int RET_UGC_DUNGEON_DUPLICATE_STAR = 13131; + public const int RET_UGC_DUNGEON_CANCEL_STAR_NOT_EXIST = 13132; + public const int RET_UGC_DUNGEON_STAR_REACH_LIMIT = 13133; + public const int RET_UGC_DUNGEON_INTERNAL_FAIL = 13134; + public const int RET_UGC_DUNGEON_PLAYER_PUBLISH_BANNED = 13135; + public const int RET_UGC_DUNGEON_CUSTOM_EDIT_IS_NOT_OPEN = 13151; + public const int RET_UGC_DUNGEON_OFFICIAL_LEVEL_IS_NOT_OPEN = 13152; + public const int RET_UGC_DUNGEON_TEMPLATE_IMPORT_IS_NOT_OPEN = 13153; + public const int RET_TARGET_SHOOTING_LEVEL_NOT_OPEN = 13161; + public const int RET_TARGET_SHOOTING_PLAYER_NUM_NOT_VALID = 13162; + public const int RET_TARGET_SHOOTING_PLAY_NOT_OPEN = 13163; + public const int RET_TARGET_SHOOTING_CONFIG_NOT_FOUND = 13164; + public const int RET_SHUFFLE_BOARD_LEVEL_NOT_OPEN = 13172; + public const int RET_SHUFFLE_BOARD_NOT_IN_PENUMBRA_SCENE = 13173; + public const int RET_SHUFFLE_BOARD_LEVEL_MISMATCH = 13174; + public const int RET_SHUFFLE_BOARD_ALREADY_PLAYING = 13175; + public const int RET_RAFFLE_TICKET_INVALID_BONUS_ID = 13176; + public const int RET_RAFFLE_TICKET_PREREQUISITE_NOT_MET = 13177; + public const int RET_RAFFLE_TICKET_NOT_ENOUGH = 13178; + public const int RET_FLIGHT_GEAR_LEVEL_NOT_OPEN = 13191; + public const int RET_FLIGHT_GEAR_IN_MP_MODE = 13192; + public const int RET_ANIMAL_VIEW_AVATAR_IS_CLOSING_TO_ANIMAL = 13212; + public const int RET_ANIMAL_VIEW_NOT_EQUIP_WIDGET = 13213; + public const int RET_COMBINE_POINT_NOT_ENOUGH = 13221; + public const int RET_TOY_BATTLE_CURRENT_LEVEL_NOT_OPEN = 13251; + public const int RET_TOY_BATTLE_CURRENT_NOT_PLAYING = 13252; + public const int RET_FONTAINE_GATHER_INVALID_GATHER_TRACKING = 13261; + public const int RET_FONTAINE_GATHER_INVALID_MONSTER_TRACKING = 13262; +} diff --git a/NahidaImpact.Protocol/Retcode.proto b/NahidaImpact.Protocol/Retcode.proto new file mode 100644 index 0000000..5fe1f25 --- /dev/null +++ b/NahidaImpact.Protocol/Retcode.proto @@ -0,0 +1,1209 @@ +syntax = "proto3"; + + + +enum Retcode { + RET_SUCC = 0; + RET_FAIL = -1; + RET_SVR_ERROR = 1; + RET_UNKNOWN_ERROR = 2; + RET_FREQUENT = 3; + RET_NODE_FORWARD_ERROR = 4; + RET_NOT_FOUND_CONFIG = 5; + RET_SYSTEM_BUSY = 6; + RET_GM_UID_BIND = 7; + RET_FORBIDDEN = 8; + RET_STOP_REGISTER = 10; + RET_STOP_SERVER = 11; + RET_ACCOUNT_VEIRFY_ERROR = 12; + RET_ACCOUNT_FREEZE = 13; + RET_REPEAT_LOGIN = 14; + RET_CLIENT_VERSION_ERROR = 15; + RET_TOKEN_ERROR = 16; + RET_ACCOUNT_NOT_EXIST = 17; + RET_WAIT_OTHER_LOGIN = 18; + RET_ANOTHER_LOGIN = 19; + RET_CLIENT_FORCE_UPDATE = 20; + RET_BLACK_UID = 21; + RET_LOGIN_DB_FAIL = 22; + RET_LOGIN_INIT_FAIL = 23; + RET_MYSQL_DUPLICATE = 24; + RET_MAX_PLAYER = 25; + RET_ANTI_ADDICT = 26; + RET_PS_PLAYER_WITHOUT_ONLINE_ID = 27; + RET_ONLINE_ID_NOT_FOUND = 28; + RET_ONLNE_ID_NOT_MATCH = 29; + RET_REGISTER_IS_FULL = 30; + RET_CHECKSUM_INVALID = 31; + RET_BLACK_REGISTER_IP = 32; + RET_EXCEED_REGISTER_RATE = 33; + RET_UNKNOWN_PLATFORM = 34; + RET_TOKEN_PARAM_ERROR = 35; + RET_ANTI_OFFLINE_ERROR = 36; + RET_BLACK_LOGIN_IP = 37; + RET_GET_TOKEN_SESSION_HAS_UID = 38; + RET_ENVIRONMENT_ERROR = 39; + RET_CHECK_CLIENT_VERSION_HASH_FAIL = 40; + RET_MINOR_REGISTER_FOBIDDEN = 41; + RET_SECURITY_LIBRARY_ERROR = 42; + RET_AVATAR_IN_CD = 101; + RET_AVATAR_NOT_ALIVE = 102; + RET_AVATAR_NOT_ON_SCENE = 103; + RET_CAN_NOT_FIND_AVATAR = 104; + RET_CAN_NOT_DEL_CUR_AVATAR = 105; + RET_DUPLICATE_AVATAR = 106; + RET_AVATAR_IS_SAME_ONE = 107; + RET_AVATAR_LEVEL_LESS_THAN = 108; + RET_AVATAR_CAN_NOT_CHANGE_ELEMENT = 109; + RET_AVATAR_BREAK_LEVEL_LESS_THAN = 110; + RET_AVATAR_ON_MAX_BREAK_LEVEL = 111; + RET_AVATAR_ID_ALREADY_EXIST = 112; + RET_AVATAR_NOT_DEAD = 113; + RET_AVATAR_IS_REVIVING = 114; + RET_AVATAR_ID_ERROR = 115; + RET_REPEAT_SET_PLAYER_BORN_DATA = 116; + RET_PLAYER_LEVEL_LESS_THAN = 117; + RET_AVATAR_LIMIT_LEVEL_ERROR = 118; + RET_CUR_AVATAR_NOT_ALIVE = 119; + RET_CAN_NOT_FIND_TEAM = 120; + RET_CAN_NOT_FIND_CUR_TEAM = 121; + RET_AVATAR_NOT_EXIST_IN_TEAM = 122; + RET_CAN_NOT_REMOVE_CUR_AVATAR_FROM_TEAM = 123; + RET_CAN_NOT_USE_REVIVE_ITEM_FOR_CUR_AVATAR = 124; + RET_TEAM_COST_EXCEED_LIMIT = 125; + RET_TEAM_AVATAR_IN_EXPEDITION = 126; + RET_TEAM_CAN_NOT_CHOSE_REPLACE_USE = 127; + RET_AVATAR_IN_COMBAT = 128; + RET_NICKNAME_UTF8_ERROR = 130; + RET_NICKNAME_TOO_LONG = 131; + RET_NICKNAME_WORD_ILLEGAL = 132; + RET_NICKNAME_TOO_MANY_DIGITS = 133; + RET_NICKNAME_IS_EMPTY = 134; + RET_NICKNAME_MONTHLY_LIMIT = 135; + RET_NICKNAME_NOT_CHANGED = 136; + RET_PLAYER_NOT_ONLINE = 140; + RET_OPEN_STATE_NOT_OPEN = 141; + RET_FEATURE_CLOSED = 142; + RET_AVATAR_EXPEDITION_AVATAR_DIE = 152; + RET_AVATAR_EXPEDITION_COUNT_LIMIT = 153; + RET_AVATAR_EXPEDITION_MAIN_FORBID = 154; + RET_AVATAR_EXPEDITION_TRIAL_FORBID = 155; + RET_TEAM_NAME_ILLEGAL = 156; + RET_IS_NOT_IN_STANDBY = 157; + RET_IS_IN_DUNGEON = 158; + RET_IS_IN_LOCK_AVATAR_QUEST = 159; + RET_IS_USING_TRIAL_AVATAR = 160; + RET_IS_USING_TEMP_AVATAR = 161; + RET_NOT_HAS_FLYCLOAK = 162; + RET_FETTER_REWARD_ALREADY_GOT = 163; + RET_FETTER_REWARD_LEVEL_NOT_ENOUGH = 164; + RET_WORLD_LEVEL_ADJUST_MIN_LEVEL = 165; + RET_WORLD_LEVEL_ADJUST_CD = 166; + RET_NOT_HAS_COSTUME = 167; + RET_COSTUME_AVATAR_ERROR = 168; + RET_FLYCLOAK_PLATFORM_TYPE_ERR = 169; + RET_IN_TRANSFER = 170; + RET_IS_IN_LOCK_AVATAR = 171; + RET_FULL_BACKUP_TEAM = 172; + RET_BACKUP_TEAM_ID_NOT_VALID = 173; + RET_BACKUP_TEAM_IS_CUR_TEAM = 174; + RET_AVATAR_RENAME_IN_CD = 175; + RET_AVATAR_RENAME_IN_AUDIT = 176; + RET_AVATAR_RENAME_IN_IP_BLACK_LIST = 177; + RET_FLOAT_ERROR = 201; + RET_NPC_NOT_EXIST = 301; + RET_NPC_TOO_FAR = 302; + RET_NOT_CURRENT_TALK = 303; + RET_NPC_CREATE_FAIL = 304; + RET_NPC_MOVE_FAIL = 305; + RET_QUEST_NOT_EXIST = 401; + RET_QUEST_IS_FAIL = 402; + RET_QUEST_CONTENT_ERROR = 403; + RET_BARGAIN_NOT_ACTIVATED = 404; + RET_BARGAIN_FINISHED = 405; + RET_INFERENCE_ASSOCIATE_WORD_ERROR = 406; + RET_INFERENCE_SUBMIT_WORD_NO_CONCLUSION = 407; + RET_POINT_NOT_UNLOCKED = 501; + RET_POINT_TOO_FAR = 502; + RET_POINT_ALREAY_UNLOCKED = 503; + RET_ENTITY_NOT_EXIST = 504; + RET_ENTER_SCENE_FAIL = 505; + RET_PLAYER_IS_ENTER_SCENE = 506; + RET_CITY_MAX_LEVEL = 507; + RET_AREA_LOCKED = 508; + RET_JOIN_OTHER_WAIT = 509; + RET_WEATHER_AREA_NOT_FOUND = 510; + RET_WEATHER_IS_LOCKED = 511; + RET_NOT_IN_SELF_SCENE = 512; + RET_GROUP_NOT_EXIST = 513; + RET_MARK_NAME_ILLEGAL = 514; + RET_MARK_ALREADY_EXISTS = 515; + RET_MARK_OVERFLOW = 516; + RET_MARK_NOT_EXISTS = 517; + RET_MARK_UNKNOWN_TYPE = 518; + RET_MARK_NAME_TOO_LONG = 519; + RET_DISTANCE_LONG = 520; + RET_ENTER_SCENE_TOKEN_INVALID = 521; + RET_NOT_IN_WORLD_SCENE = 522; + RET_ANY_GALLERY_STARTED = 523; + RET_GALLERY_NOT_START = 524; + RET_GALLERY_INTERRUPT_ONLY_ON_SINGLE_MODE = 525; + RET_GALLERY_CANNOT_INTERRUPT = 526; + RET_GALLERY_WORLD_NOT_MEET = 527; + RET_GALLERY_SCENE_NOT_MEET = 528; + RET_CUR_PLAY_CANNOT_TRANSFER = 529; + RET_CANT_USE_WIDGET_IN_HOME_SCENE = 530; + RET_SCENE_GROUP_NOT_MATCH = 531; + RET_POS_ROT_INVALID = 551; + RET_MARK_INVALID_SCENE_ID = 552; + RET_INVALID_SCENE_TO_USE_ANCHOR_POINT = 553; + RET_ENTER_HOME_SCENE_FAIL = 554; + RET_CUR_SCENE_IS_NULL = 555; + RET_GROUP_ID_ERROR = 556; + RET_GALLERY_INTERRUPT_NOT_OWNER = 557; + RET_NO_SPRING_IN_AREA = 558; + RET_AREA_NOT_IN_SCENE = 559; + RET_INVALID_CITY_ID = 560; + RET_INVALID_SCENE_ID = 561; + RET_DEST_SCENE_IS_NOT_ALLOW = 562; + RET_LEVEL_TAG_SWITCH_IN_CD = 563; + RET_LEVEL_TAG_ALREADY_EXIST = 564; + RET_INVALID_AREA_ID = 565; + RET_GALLERY_ONGOING_FORBID = 566; + RET_ITEM_NOT_EXIST = 601; + RET_PACK_EXCEED_MAX_WEIGHT = 602; + RET_ITEM_NOT_DROPABLE = 603; + RET_ITEM_NOT_USABLE = 604; + RET_ITEM_INVALID_USE_COUNT = 605; + RET_ITEM_INVALID_DROP_COUNT = 606; + RET_ITEM_ALREADY_EXIST = 607; + RET_ITEM_IN_COOLDOWN = 608; + RET_ITEM_COUNT_NOT_ENOUGH = 609; + RET_ITEM_INVALID_TARGET = 610; + RET_RECIPE_NOT_EXIST = 611; + RET_RECIPE_LOCKED = 612; + RET_RECIPE_UNLOCKED = 613; + RET_COMPOUND_QUEUE_FULL = 614; + RET_COMPOUND_NOT_FINISH = 615; + RET_MAIL_ITEM_NOT_GET = 616; + RET_ITEM_EXCEED_LIMIT = 617; + RET_AVATAR_CAN_NOT_USE = 618; + RET_ITEM_NEED_PLAYER_LEVEL = 619; + RET_RECIPE_NOT_AUTO_QTE = 620; + RET_COMPOUND_BUSY_QUEUE = 621; + RET_NEED_MORE_SCOIN = 622; + RET_SKILL_DEPOT_NOT_FOUND = 623; + RET_HCOIN_NOT_ENOUGH = 624; + RET_SCOIN_NOT_ENOUGH = 625; + RET_HCOIN_EXCEED_LIMIT = 626; + RET_SCOIN_EXCEED_LIMIT = 627; + RET_MAIL_EXPIRED = 628; + RET_REWARD_HAS_TAKEN = 629; + RET_COMBINE_COUNT_TOO_LARGE = 630; + RET_GIVING_ITEM_WRONG = 631; + RET_GIVING_IS_FINISHED = 632; + RET_GIVING_NOT_ACTIVED = 633; + RET_FORGE_QUEUE_FULL = 634; + RET_FORGE_QUEUE_CAPACITY = 635; + RET_FORGE_QUEUE_NOT_FOUND = 636; + RET_FORGE_QUEUE_EMPTY = 637; + RET_NOT_SUPPORT_ITEM = 638; + RET_ITEM_EMPTY = 639; + RET_VIRTUAL_EXCEED_LIMIT = 640; + RET_MATERIAL_EXCEED_LIMIT = 641; + RET_EQUIP_EXCEED_LIMIT = 642; + RET_ITEM_SHOULD_HAVE_NO_LEVEL = 643; + RET_WEAPON_PROMOTE_LEVEL_EXCEED_LIMIT = 644; + RET_WEAPON_LEVEL_INVALID = 645; + RET_UNKNOW_ITEM_TYPE = 646; + RET_ITEM_COUNT_IS_ZERO = 647; + RET_ITEM_IS_EXPIRED = 648; + RET_ITEM_EXCEED_OUTPUT_LIMIT = 649; + RET_EQUIP_LEVEL_HIGHER = 650; + RET_EQUIP_CAN_NOT_WAKE_OFF_WEAPON = 651; + RET_EQUIP_HAS_BEEN_WEARED = 652; + RET_EQUIP_WEARED_CANNOT_DROP = 653; + RET_AWAKEN_LEVEL_MAX = 654; + RET_MCOIN_NOT_ENOUGH = 655; + RET_MCOIN_EXCEED_LIMIT = 656; + RET_RESIN_NOT_ENOUGH = 660; + RET_RESIN_EXCEED_LIMIT = 661; + RET_RESIN_OPENSTATE_OFF = 662; + RET_RESIN_BOUGHT_COUNT_EXCEEDED = 663; + RET_RESIN_CARD_DAILY_REWARD_HAS_TAKEN = 664; + RET_RESIN_CARD_EXPIRED = 665; + RET_AVATAR_CAN_NOT_COOK = 666; + RET_ATTACH_AVATAR_CD = 667; + RET_AUTO_RECOVER_OPENSTATE_OFF = 668; + RET_AUTO_RECOVER_BOUGHT_COUNT_EXCEEDED = 669; + RET_RESIN_GAIN_FAILED = 670; + RET_WIDGET_ORNAMENTS_TYPE_ERROR = 671; + RET_ALL_TARGET_SATIATION_FULL = 672; + RET_FORGE_WORLD_LEVEL_NOT_MATCH = 673; + RET_FORGE_POINT_NOT_ENOUGH = 674; + RET_WIDGET_ANCHOR_POINT_FULL = 675; + RET_WIDGET_ANCHOR_POINT_NOT_FOUND = 676; + RET_ALL_BONFIRE_EXCEED_MAX_COUNT = 677; + RET_BONFIRE_EXCEED_MAX_COUNT = 678; + RET_LUNCH_BOX_DATA_ERROR = 679; + RET_INVALID_QUICK_USE_WIDGET = 680; + RET_INVALID_REPLACE_RESIN_COUNT = 681; + RET_PREV_DETECTED_GATHER_NOT_FOUND = 682; + RET_GOT_ALL_ONEOFF_GAHTER = 683; + RET_INVALID_WIDGET_MATERIAL_ID = 684; + RET_WIDGET_DETECTOR_NO_HINT_TO_CLEAR = 685; + RET_WIDGET_ALREADY_WITHIN_NEARBY_RADIUS = 686; + RET_WIDGET_CLIENT_COLLECTOR_NEED_POINTS = 687; + RET_WIDGET_IN_COMBAT = 688; + RET_WIDGET_NOT_SET_QUICK_USE = 689; + RET_ALREADY_ATTACH_WIDGET = 690; + RET_EQUIP_IS_LOCKED = 691; + RET_FORGE_IS_LOCKED = 692; + RET_COMBINE_IS_LOCKED = 693; + RET_FORGE_OUTPUT_STACK_LIMIT = 694; + RET_ALREADY_DETTACH_WIDGET = 695; + RET_GADGET_BUILDER_EXCEED_MAX_COUNT = 696; + RET_REUNION_PRIVILEGE_RESIN_TYPE_IS_NORMAL = 697; + RET_BONUS_COUNT_EXCEED_DOUBLE_LIMIT = 698; + RET_RELIQUARY_DECOMPOSE_PARAM_ERROR = 699; + RET_ITEM_COMBINE_COUNT_NOT_ENOUGH = 700; + RET_GOODS_NOT_EXIST = 701; + RET_GOODS_MATERIAL_NOT_ENOUGH = 702; + RET_GOODS_NOT_IN_TIME = 703; + RET_GOODS_BUY_NUM_NOT_ENOUGH = 704; + RET_GOODS_BUY_NUM_ERROR = 705; + RET_SHOP_NOT_OPEN = 706; + RET_SHOP_CONTENT_NOT_MATCH = 707; + RET_SHOP_BATCH_BUY_SHOP_LIMIT = 708; + RET_SHOP_BATCH_BUY_COUNT_LIMIT = 709; + RET_CHAT_FORBIDDEN = 798; + RET_CHAT_CD = 799; + RET_CHAT_FREQUENTLY = 800; + RET_GADGET_NOT_EXIST = 801; + RET_GADGET_NOT_INTERACTIVE = 802; + RET_GADGET_NOT_GATHERABLE = 803; + RET_CHEST_IS_LOCKED = 804; + RET_GADGET_CREATE_FAIL = 805; + RET_WORKTOP_OPTION_NOT_EXIST = 806; + RET_GADGET_STATUE_NOT_ACTIVE = 807; + RET_GADGET_STATUE_OPENED = 808; + RET_BOSS_CHEST_NO_QUALIFICATION = 809; + RET_BOSS_CHEST_LIFE_TIME_OVER = 810; + RET_BOSS_CHEST_WEEK_NUM_LIMIT = 811; + RET_BOSS_CHEST_GUEST_WORLD_LEVEL = 812; + RET_BOSS_CHEST_HAS_TAKEN = 813; + RET_BLOSSOM_CHEST_NO_QUALIFICATION = 814; + RET_BLOSSOM_CHEST_LIFE_TIME_OVER = 815; + RET_BLOSSOM_CHEST_HAS_TAKEN = 816; + RET_BLOSSOM_CHEST_GUEST_WORLD_LEVEL = 817; + RET_MP_PLAY_REWARD_NO_QUALIFICATION = 818; + RET_MP_PLAY_REWARD_HAS_TAKEN = 819; + RET_GENERAL_REWARD_NO_QUALIFICATION = 820; + RET_GENERAL_REWARD_LIFE_TIME_OVER = 821; + RET_GENERAL_REWARD_HAS_TAKEN = 822; + RET_GADGET_NOT_VEHICLE = 823; + RET_VEHICLE_SLOT_OCCUPIED = 824; + RET_NOT_IN_VEHICLE = 825; + RET_CREATE_VEHICLE_IN_CD = 826; + RET_CREATE_VEHICLE_POS_INVALID = 827; + RET_VEHICLE_POINT_NOT_UNLOCK = 828; + RET_GADGET_INTERACT_COND_NOT_MEET = 829; + RET_GADGET_INTERACT_PARAM_ERROR = 830; + RET_GADGET_CUSTOM_COMBINATION_INVALID = 831; + RET_DESHRET_OBELISK_DUPLICATE_INTERACT = 832; + RET_DESHRET_OBELISK_NO_AVAIL_CHEST = 833; + RET_ACTIVITY_CLOSE = 860; + RET_ACTIVITY_ITEM_ERROR = 861; + RET_ACTIVITY_CONTRIBUTION_NOT_ENOUGH = 862; + RET_SEA_LAMP_PHASE_NOT_FINISH = 863; + RET_SEA_LAMP_FLY_NUM_LIMIT = 864; + RET_SEA_LAMP_FLY_LAMP_WORD_ILLEGAL = 865; + RET_ACTIVITY_WATCHER_REWARD_TAKEN = 866; + RET_ACTIVITY_WATCHER_REWARD_NOT_FINISHED = 867; + RET_SALESMAN_ALREADY_DELIVERED = 868; + RET_SALESMAN_REWARD_COUNT_NOT_ENOUGH = 869; + RET_SALESMAN_POSITION_INVALID = 870; + RET_DELIVER_NOT_FINISH_ALL_QUEST = 871; + RET_DELIVER_ALREADY_TAKE_DAILY_REWARD = 872; + RET_ASTER_PROGRESS_EXCEED_LIMIT = 873; + RET_ASTER_CREDIT_EXCEED_LIMIT = 874; + RET_ASTER_TOKEN_EXCEED_LIMIT = 875; + RET_ASTER_CREDIT_NOT_ENOUGH = 876; + RET_ASTER_TOKEN_NOT_ENOUGH = 877; + RET_ASTER_SPECIAL_REWARD_HAS_TAKEN = 878; + RET_FLIGHT_GROUP_ACTIVITY_NOT_STARTED = 879; + RET_ASTER_MID_PREVIOUS_BATTLE_NOT_FINISHED = 880; + RET_DRAGON_SPINE_SHIMMERING_ESSENCE_EXCEED_LIMIT = 881; + RET_DRAGON_SPINE_WARM_ESSENCE_EXCEED_LIMIT = 882; + RET_DRAGON_SPINE_WONDROUS_ESSENCE_EXCEED_LIMIT = 883; + RET_DRAGON_SPINE_SHIMMERING_ESSENCE_NOT_ENOUGH = 884; + RET_DRAGON_SPINE_WARM_ESSENCE_NOT_ENOUGH = 885; + RET_DRAGON_SPINE_WONDROUS_ESSENCE_NOT_ENOUGH = 886; + RET_EFFIGY_FIRST_PASS_REWARD_HAS_TAKEN = 891; + RET_EFFIGY_REWARD_HAS_TAKEN = 892; + RET_TREASURE_MAP_ADD_TOKEN_EXCEED_LIMIT = 893; + RET_TREASURE_MAP_TOKEN_NOT_ENOUGHT = 894; + RET_SEA_LAMP_COIN_EXCEED_LIMIT = 895; + RET_SEA_LAMP_COIN_NOT_ENOUGH = 896; + RET_SEA_LAMP_POPULARITY_EXCEED_LIMIT = 897; + RET_ACTIVITY_AVATAR_REWARD_NOT_OPEN = 898; + RET_ACTIVITY_AVATAR_REWARD_HAS_TAKEN = 899; + RET_ARENA_ACTIVITY_ALREADY_STARTED = 900; + RET_TALENT_ALREAY_UNLOCKED = 901; + RET_PREV_TALENT_NOT_UNLOCKED = 902; + RET_BIG_TALENT_POINT_NOT_ENOUGH = 903; + RET_SMALL_TALENT_POINT_NOT_ENOUGH = 904; + RET_PROUD_SKILL_ALREADY_GOT = 905; + RET_PREV_PROUD_SKILL_NOT_GET = 906; + RET_PROUD_SKILL_MAX_LEVEL = 907; + RET_CANDIDATE_SKILL_DEPOT_ID_NOT_FIND = 910; + RET_SKILL_DEPOT_IS_THE_SAME = 911; + RET_MONSTER_NOT_EXIST = 1001; + RET_MONSTER_CREATE_FAIL = 1002; + RET_DUNGEON_ENTER_FAIL = 1101; + RET_DUNGEON_QUIT_FAIL = 1102; + RET_DUNGEON_ENTER_EXCEED_DAY_COUNT = 1103; + RET_DUNGEON_REVIVE_EXCEED_MAX_COUNT = 1104; + RET_DUNGEON_REVIVE_FAIL = 1105; + RET_DUNGEON_NOT_SUCCEED = 1106; + RET_DUNGEON_CAN_NOT_CANCEL = 1107; + RET_DEST_DUNGEON_SETTLED = 1108; + RET_DUNGEON_CANDIDATE_TEAM_IS_FULL = 1109; + RET_DUNGEON_CANDIDATE_TEAM_IS_DISMISS = 1110; + RET_DUNGEON_CANDIDATE_TEAM_NOT_ALL_READY = 1111; + RET_DUNGEON_CANDIDATE_TEAM_HAS_REPEAT_AVATAR = 1112; + RET_DUNGEON_CANDIDATE_NOT_SINGEL_PASS = 1113; + RET_DUNGEON_REPLAY_NEED_ALL_PLAYER_DIE = 1114; + RET_DUNGEON_REPLAY_HAS_REVIVE_COUNT = 1115; + RET_DUNGEON_OTHERS_LEAVE = 1116; + RET_DUNGEON_ENTER_LEVEL_LIMIT = 1117; + RET_DUNGEON_CANNOT_ENTER_PLOT_IN_MP = 1118; + RET_DUNGEON_DROP_SUBFIELD_LIMIT = 1119; + RET_DUNGEON_BE_INVITE_PLAYER_AVATAR_ALL_DIE = 1120; + RET_DUNGEON_CANNOT_KICK = 1121; + RET_DUNGEON_CANDIDATE_TEAM_SOMEONE_LEVEL_LIMIT = 1122; + RET_DUNGEON_IN_FORCE_QUIT = 1123; + RET_DUNGEON_GUEST_QUIT_DUNGEON = 1124; + RET_DUNGEON_TICKET_FAIL = 1125; + RET_CUR_DUNGEON_SETTLED = 1126; + RET_MP_NOT_IN_MY_WORLD = 1201; + RET_MP_IN_MP_MODE = 1202; + RET_MP_SCENE_IS_FULL = 1203; + RET_MP_MODE_NOT_AVAILABLE = 1204; + RET_MP_PLAYER_NOT_ENTERABLE = 1205; + RET_MP_QUEST_BLOCK_MP = 1206; + RET_MP_IN_ROOM_SCENE = 1207; + RET_MP_WORLD_IS_FULL = 1208; + RET_MP_PLAYER_NOT_ALLOW_ENTER = 1209; + RET_MP_PLAYER_DISCONNECTED = 1210; + RET_MP_NOT_IN_MP_MODE = 1211; + RET_MP_OWNER_NOT_ENTER = 1212; + RET_MP_ALLOW_ENTER_PLAYER_FULL = 1213; + RET_MP_TARGET_PLAYER_IN_TRANSFER = 1214; + RET_MP_TARGET_ENTERING_OTHER = 1215; + RET_MP_OTHER_ENTERING = 1216; + RET_MP_ENTER_MAIN_PLAYER_IN_PLOT = 1217; + RET_MP_NOT_PS_PLAYER = 1218; + RET_MP_PLAY_NOT_ACTIVE = 1219; + RET_MP_PLAY_REMAIN_REWARDS = 1220; + RET_MP_PLAY_NO_REWARD = 1221; + RET_MP_OPEN_STATE_FAIL = 1223; + RET_MP_PLAYER_IN_BLACKLIST = 1224; + RET_MP_REPLY_TIMEOUT = 1225; + RET_MP_IS_BLOCK = 1226; + RET_MP_ENTER_MAIN_PLAYER_IN_MP_PLAY = 1227; + RET_MP_IN_MP_PLAY_BATTLE = 1228; + RET_MP_GUEST_HAS_REWARD_REMAINED = 1229; + RET_MP_QUIT_MP_INVALID = 1230; + RET_MP_OTHER_DATA_VERSION_NOT_LATEST = 1231; + RET_MP_DATA_VERSION_NOT_LATEST = 1232; + RET_MP_CUR_WORLD_NOT_ENTERABLE = 1233; + RET_MP_ANY_GALLERY_STARTED = 1234; + RET_MP_HAS_ACTIVE_DRAFT = 1235; + RET_MP_PLAYER_IN_DUNGEON = 1236; + RET_MP_MATCH_FULL = 1237; + RET_MP_MATCH_LIMIT = 1238; + RET_MP_MATCH_IN_PUNISH = 1239; + RET_MP_IS_IN_MULTISTAGE = 1240; + RET_MP_MATCH_PLAY_NOT_OPEN = 1241; + RET_MP_ONLY_MP_WITH_PS_PLAYER = 1242; + RET_MP_GUEST_LOADING_FIRST_ENTER = 1243; + RET_MP_SUMMER_TIME_SPRINT_BOAT_ONGOING = 1244; + RET_MP_BLITZ_RUSH_PARKOUR_CHALLENGE_ONGOING = 1245; + RET_MP_MUSIC_GAME_ONGOING = 1246; + RET_MP_IN_MPING_MODE = 1247; + RET_MP_OWNER_IN_SINGLE_SCENE = 1248; + RET_MP_IN_SINGLE_SCENE = 1249; + RET_MP_REPLY_NO_VALID_AVATAR = 1250; + RET_MP_IS_NOT_IN_TRANSFER_GUARD = 1251; + RET_MAIL_PARA_ERR = 1301; + RET_MAIL_MAX_NUM = 1302; + RET_MAIL_ITEM_NUM_EXCEED = 1303; + RET_MAIL_TITLE_LEN_EXCEED = 1304; + RET_MAIL_CONTENT_LEN_EXCEED = 1305; + RET_MAIL_SENDER_LEN_EXCEED = 1306; + RET_MAIL_PARSE_PACKET_FAIL = 1307; + RET_OFFLINE_MSG_MAX_NUM = 1308; + RET_OFFLINE_MSG_SAME_TICKET = 1309; + RET_MAIL_EXCEL_MAIL_TYPE_ERROR = 1310; + RET_MAIL_CANNOT_SEND_MCOIN = 1311; + RET_MAIL_HCOIN_EXCEED_LIMIT = 1312; + RET_MAIL_SCOIN_EXCEED_LIMIT = 1313; + RET_MAIL_MATERIAL_ID_INVALID = 1314; + RET_MAIL_AVATAR_EXCEED_LIMIT = 1315; + RET_MAIL_GACHA_TICKET_ETC_EXCEED_LIMIT = 1316; + RET_MAIL_ITEM_EXCEED_CEHUA_LIMIT = 1317; + RET_MAIL_SPACE_OR_REST_NUM_NOT_ENOUGH = 1318; + RET_MAIL_TICKET_IS_EMPTY = 1319; + RET_MAIL_TRANSACTION_IS_EMPTY = 1320; + RET_MAIL_DELETE_COLLECTED = 1321; + RET_DAILY_TASK_NOT_FINISH = 1330; + RET_DAILY_TAKS_HAS_TAKEN = 1331; + RET_SOCIAL_OFFLINE_MSG_NUM_EXCEED = 1332; + RET_DAILY_TASK_FILTER_CITY_NOT_OPEN = 1333; + RET_GACHA_INAVAILABLE = 1401; + RET_GACHA_RANDOM_NOT_MATCH = 1402; + RET_GACHA_SCHEDULE_NOT_MATCH = 1403; + RET_GACHA_INVALID_TIMES = 1404; + RET_GACHA_COST_ITEM_NOT_ENOUGH = 1405; + RET_GACHA_TIMES_LIMIT = 1406; + RET_GACHA_WISH_SAME_ITEM = 1407; + RET_GACHA_WISH_INVALID_ITEM = 1408; + RET_GACHA_MINORS_TIMES_LIMIT = 1409; + RET_GACHA_GENERAL_TIMES_LIMIT = 1410; + RET_INVESTIGAITON_NOT_IN_PROGRESS = 1501; + RET_INVESTIGAITON_UNCOMPLETE = 1502; + RET_INVESTIGAITON_REWARD_TAKEN = 1503; + RET_INVESTIGAITON_TARGET_STATE_ERROR = 1504; + RET_PUSH_TIPS_NOT_FOUND = 1505; + RET_SIGN_IN_RECORD_NOT_FOUND = 1506; + RET_ALREADY_HAVE_SIGNED_IN = 1507; + RET_SIGN_IN_COND_NOT_SATISFIED = 1508; + RET_BONUS_ACTIVITY_NOT_UNREWARDED = 1509; + RET_SIGN_IN_REWARDED = 1510; + RET_TOWER_NOT_OPEN = 1521; + RET_TOWER_HAVE_DAILY_RECORD = 1522; + RET_TOWER_NOT_RECORD = 1523; + RET_TOWER_HAVE_RECORD = 1524; + RET_TOWER_TEAM_NUM_ERROR = 1525; + RET_TOWER_FLOOR_NOT_OPEN = 1526; + RET_TOWER_NO_FLOOR_STAR_RECORD = 1527; + RET_ALREADY_HAS_TOWER_BUFF = 1528; + RET_DUPLICATE_ENTER_LEVEL = 1529; + RET_NOT_IN_TOWER_LEVEL = 1530; + RET_IN_TOWER_LEVEL = 1531; + RET_TOWER_PREV_FLOOR_NOT_FINISH = 1532; + RET_TOWER_STAR_NOT_ENOUGH = 1533; + RET_BATTLE_PASS_NO_SCHEDULE = 1541; + RET_BATTLE_PASS_HAS_BUYED = 1542; + RET_BATTLE_PASS_LEVEL_OVERFLOW = 1543; + RET_BATTLE_PASS_PRODUCT_EXPIRED = 1544; + RET_MATCH_HOST_QUIT = 1561; + RET_MATCH_ALREADY_IN_MATCH = 1562; + RET_MATCH_NOT_IN_MATCH = 1563; + RET_MATCH_APPLYING_ENTER_MP = 1564; + RET_MATCH_INCORRECT_SCENE = 1565; + RET_WIDGET_TREASURE_SPOT_NOT_FOUND = 1581; + RET_WIDGET_TREASURE_ENTITY_EXISTS = 1582; + RET_WIDGET_TREASURE_SPOT_FAR_AWAY = 1583; + RET_WIDGET_TREASURE_FINISHED_TODAY = 1584; + RET_WIDGET_QUICK_USE_REQ_PARAM_ERROR = 1585; + RET_WIDGET_CAMERA_SCAN_ID_ERROR = 1586; + RET_WIDGET_NOT_ACTIVE = 1587; + RET_WIDGET_FEATHER_NOT_ACTIVE = 1588; + RET_WIDGET_FEATHER_GADGET_TOO_FAR_AWAY = 1589; + RET_WIDGET_CAPTURE_ANIMAL_NOT_EXIST = 1590; + RET_WIDGET_CAPTURE_ANIMAL_DROP_BAG_LIMIT = 1591; + RET_WIDGET_CAPTURE_ANIMAL_CAN_NOT_CAPTURE = 1592; + RET_WIDGET_SKY_CRYSTAL_ALL_COLLECTED = 1593; + RET_WIDGET_SKY_CRYSTAL_HINT_ALREADY_EXIST = 1594; + RET_WIDGET_SKY_CRYSTAL_NOT_FOUND = 1595; + RET_WIDGET_SKY_CRYSTAL_NO_HINT_TO_CLEAR = 1596; + RET_WIDGET_LIGHT_STONE_ENERGY_NOT_ENOUGH = 1597; + RET_WIDGET_TOY_CRYSTAL_ENERGY_NOT_ENOUGH = 1598; + RET_WIDGET_LIGHT_STONE_LEVEL_NOT_ENOUGH = 1599; + RET_UID_NOT_EXIST = 2001; + RET_PARSE_BIN_ERROR = 2002; + RET_ACCOUNT_INFO_NOT_EXIST = 2003; + RET_ORDER_INFO_NOT_EXIST = 2004; + RET_SNAPSHOT_INDEX_ERROR = 2005; + RET_MAIL_HAS_BEEN_SENT = 2006; + RET_PRODUCT_NOT_EXIST = 2007; + RET_UNFINISH_ORDER = 2008; + RET_ID_NOT_EXIST = 2009; + RET_ORDER_TRADE_EARLY = 2010; + RET_ORDER_FINISHED = 2011; + RET_GAMESERVER_VERSION_WRONG = 2012; + RET_OFFLINE_OP_FULL_LENGTH = 2013; + RET_CONCERT_PRODUCT_OBTAIN_LIMIT = 2014; + RET_CONCERT_PRODUCT_TICKET_DUPLICATED = 2015; + RET_CONCERT_PRODUCT_TICKET_EMPTY = 2016; + RET_REDIS_MODIFIED = 5001; + RET_REDIS_UID_NOT_EXIST = 5002; + RET_PATHFINDING_DATA_NOT_EXIST = 6001; + RET_PATHFINDING_DESTINATION_NOT_EXIST = 6002; + RET_PATHFINDING_ERROR_SCENE = 6003; + RET_PATHFINDING_SCENE_DATA_LOADING = 6004; + RET_FRIEND_COUNT_EXCEEDED = 7001; + RET_PLAYER_NOT_EXIST = 7002; + RET_ALREADY_SENT_ADD_REQUEST = 7003; + RET_ASK_FRIEND_LIST_FULL = 7004; + RET_PLAYER_ALREADY_IS_FRIEND = 7005; + RET_PLAYER_NOT_ASK_FRIEND = 7006; + RET_TARGET_FRIEND_COUNT_EXCEED = 7007; + RET_NOT_FRIEND = 7008; + RET_BIRTHDAY_CANNOT_BE_SET_TWICE = 7009; + RET_CANNOT_ADD_SELF_FRIEND = 7010; + RET_SIGNATURE_ILLEGAL = 7011; + RET_PS_PLAYER_CANNOT_ADD_FRIENDS = 7012; + RET_PS_PLAYER_CANNOT_REMOVE_FRIENDS = 7013; + RET_NAME_CARD_NOT_UNLOCKED = 7014; + RET_ALREADY_IN_BLACKLIST = 7015; + RET_PS_PALEYRS_CANNOT_ADD_BLACKLIST = 7016; + RET_PLAYER_BLACKLIST_FULL = 7017; + RET_PLAYER_NOT_IN_BLACKLIST = 7018; + RET_BLACKLIST_PLAYER_CANNOT_ADD_FRIEND = 7019; + RET_IN_TARGET_BLACKLIST = 7020; + RET_CANNOT_ADD_TARGET_FRIEND = 7021; + RET_BIRTHDAY_FORMAT_ERROR = 7022; + RET_ONLINE_ID_NOT_EXISTS = 7023; + RET_FIRST_SHARE_REWARD_HAS_TAKEN = 7024; + RET_PS_PLAYER_CANNOT_REMOVE_BLACKLIST = 7025; + RET_REPORT_CD = 7026; + RET_REPORT_CONTENT_ILLEGAL = 7027; + RET_REMARK_WORD_ILLEGAL = 7028; + RET_REMARK_TOO_LONG = 7029; + RET_REMARK_UTF8_ERROR = 7030; + RET_REMARK_IS_EMPTY = 7031; + RET_ASK_ADD_FRIEND_CD = 7032; + RET_SHOW_AVATAR_INFO_NOT_EXIST = 7033; + RET_PLAYER_NOT_SHOW_AVATAR = 7034; + RET_SOCIAL_UPDATE_SHOW_LIST_REPEAT_ID = 7035; + RET_PSN_ID_NOT_FOUND = 7036; + RET_EMOJI_COLLECTION_NUM_EXCEED_LIMIT = 7037; + RET_REMARK_EMPTY = 7038; + RET_IN_TARGET_PSN_BLACKLIST = 7039; + RET_SIGNATURE_NOT_CHANGED = 7040; + RET_SIGNATURE_MONTHLY_LIMIT = 7041; + RET_REQ_FRIEND_AVATAR_FREQUENTLY = 7042; + RET_PSN_GET_PLAYER_SOCIAL_DETAIL_FAIL = 7043; + RET_OFFERING_NOT_OPEN = 7081; + RET_OFFERING_LEVEL_LIMIT = 7082; + RET_OFFERING_LEVEL_NOT_REACH = 7083; + RET_OFFERING_LEVEL_HAS_TAKEN = 7084; + RET_CITY_REPUTATION_NOT_OPEN = 7101; + RET_CITY_REPUTATION_LEVEL_TAKEN = 7102; + RET_CITY_REPUTATION_LEVEL_NOT_REACH = 7103; + RET_CITY_REPUTATION_PARENT_QUEST_TAKEN = 7104; + RET_CITY_REPUTATION_PARENT_QUEST_UNFINISH = 7105; + RET_CITY_REPUTATION_ACCEPT_REQUEST = 7106; + RET_CITY_REPUTATION_NOT_ACCEPT_REQUEST = 7107; + RET_CITY_REPUTATION_ACCEPT_REQUEST_LIMIT = 7108; + RET_CITY_REPUTATION_ENTRANCE_NOT_OPEN = 7109; + RET_CITY_REPUTATION_TAKEN_REQUEST_REWARD = 7110; + RET_CITY_REPUTATION_SWITCH_CLOSE = 7111; + RET_CITY_REPUTATION_ENTRACE_SWITCH_CLOSE = 7112; + RET_CITY_REPUTATION_TAKEN_EXPLORE_REWARD = 7113; + RET_CITY_REPUTATION_EXPLORE_NOT_REACH = 7114; + RET_MECHANICUS_NOT_OPEN = 7120; + RET_MECHANICUS_GEAR_UNLOCK = 7121; + RET_MECHANICUS_GEAR_LOCK = 7122; + RET_MECHANICUS_GEAR_LEVEL_LIMIT = 7123; + RET_MECHANICUS_COIN_NOT_ENOUGH = 7124; + RET_MECHANICUS_NO_SEQUENCE = 7125; + RET_MECHANICUS_SEQUENCE_LIMIT_LEVEL = 7126; + RET_MECHANICUS_SEQUENCE_LIMIT_OPEN = 7127; + RET_MECHANICUS_DIFFICULT_NOT_SUPPORT = 7128; + RET_MECHANICUS_TICKET_NOT_ENOUGH = 7129; + RET_MECHANICUS_TEACH_NOT_FINISH = 7130; + RET_MECHANICUS_TEACH_FINISHED = 7131; + RET_MECHANICUS_PREV_DIFFICULT_LEVEL_BLOCK = 7132; + RET_MECHANICUS_PLAYER_LIMIT = 7133; + RET_MECHANICUS_PUNISH_TIME = 7134; + RET_MECHANICUS_SWITCH_CLOSE = 7135; + RET_MECHANICUS_BATTLE_NOT_IN_DUNGEON = 7150; + RET_MECHANICUS_BATTLE_PLAY_NOT_FOUND = 7151; + RET_MECHANICUS_BATTLE_DUPLICATE_PICK_CARD = 7152; + RET_MECHANICUS_BATTLE_PLAYER_NOT_IN_PLAY = 7153; + RET_MECHANICUS_BATTLE_CARD_NOT_AVAILABLE = 7154; + RET_MECHANICUS_BATTLE_NOT_IN_CARD_STAGE = 7155; + RET_MECHANICUS_BATTLE_CARD_IS_WAITING = 7156; + RET_MECHANICUS_BATTLE_CARD_ALL_CONFIRMED = 7157; + RET_MECHANICUS_BATTLE_CARD_ALREADY_CONFIRMED = 7158; + RET_MECHANICUS_BATTLE_CARD_CONFIRMED_BY_OTHER = 7159; + RET_MECHANICUS_BATTLE_CARD_NOT_ENOUGH_POINTS = 7160; + RET_MECHANICUS_BATTLE_CARD_ALREADY_SKIPPED = 7161; + RET_LEGENDARY_KEY_NOT_ENOUGH = 8001; + RET_LEGENDARY_KEY_EXCEED_LIMIT = 8002; + RET_DAILY_TASK_NOT_ENOUGH_TO_REDEEM = 8003; + RET_PERSONAL_LINE_OPEN_STATE_OFF = 8004; + RET_PERSONAL_LINE_LEVEL_NOT_ENOUGH = 8005; + RET_PERSONAL_LINE_NOT_OPEN = 8006; + RET_PERSONAL_LINE_PRE_QUEST_NOT_FINISH = 8007; + RET_HUNTING_ALREADY_FINISH_OFFER_LIMIT = 8201; + RET_HUNTING_HAS_UNFINISHED_OFFER = 8202; + RET_HUNTING_FAILED_OFFER_NOT_CD_READY = 8203; + RET_HUNTING_NOT_TAKE_OFFER = 8204; + RET_HUNTING_CANNOT_TAKE_TWICE = 8205; + RET_RPIVATE_CHAT_INVALID_CONTENT_TYPE = 8901; + RET_PRIVATE_CHAT_TARGET_IS_NOT_FRIEND = 8902; + RET_PRIVATE_CHAT_CONTENT_NOT_SUPPORTED = 8903; + RET_PRIVATE_CHAT_CONTENT_TOO_LONG = 8904; + RET_PRIVATE_CHAT_PULL_TOO_FAST = 8905; + RET_PRIVATE_CHAT_REPEAT_READ = 8906; + RET_PRIVATE_CHAT_READ_NOT_FRIEND = 8907; + RET_REUNION_FINISHED = 9001; + RET_REUNION_NOT_ACTIVATED = 9002; + RET_REUNION_ALREADY_TAKE_FIRST_REWARD = 9003; + RET_REUNION_SIGN_IN_REWARDED = 9004; + RET_REUNION_WATCHER_REWARDED = 9005; + RET_REUNION_WATCHER_NOT_FINISH = 9006; + RET_REUNION_MISSION_REWARDED = 9007; + RET_REUNION_MISSION_NOT_FINISH = 9008; + RET_REUNION_WATCHER_REWARD_NOT_UNLOCKED = 9009; + RET_BLESSING_CONTENT_CLOSED = 9101; + RET_BLESSING_NOT_ACTIVE = 9102; + RET_BLESSING_NOT_TODAY_ENTITY = 9103; + RET_BLESSING_ENTITY_EXCEED_SCAN_NUM_LIMIT = 9104; + RET_BLESSING_DAILY_SCAN_NUM_EXCEED_LIMIT = 9105; + RET_BLESSING_REDEEM_REWARD_NUM_EXCEED_LIMIT = 9106; + RET_BLESSING_REDEEM_PIC_NUM_NOT_ENOUGH = 9107; + RET_BLESSING_PIC_NOT_ENOUGH = 9108; + RET_BLESSING_PIC_HAS_RECEIVED = 9109; + RET_BLESSING_TARGET_RECV_NUM_EXCEED = 9110; + RET_FLEUR_FAIR_CREDIT_EXCEED_LIMIT = 9111; + RET_FLEUR_FAIR_CREDIT_NOT_ENOUGH = 9112; + RET_FLEUR_FAIR_TOKEN_EXCEED_LIMIT = 9113; + RET_FLEUR_FAIR_TOKEN_NOT_ENOUGH = 9114; + RET_FLEUR_FAIR_MINIGAME_NOT_OPEN = 9115; + RET_FLEUR_FAIR_MUSIC_GAME_DIFFICULTY_NOT_UNLOCK = 9116; + RET_FLEUR_FAIR_DUNGEON_LOCKED = 9117; + RET_FLEUR_FAIR_DUNGEON_PUNISH_TIME = 9118; + RET_FLEUR_FAIR_ONLY_OWNER_CAN_RESTART_MINIGAM = 9119; + RET_WATER_SPIRIT_COIN_EXCEED_LIMIT = 9120; + RET_WATER_SPIRIT_COIN_NOT_ENOUGH = 9121; + RET_REGION_SEARCH_NO_SEARCH = 9122; + RET_REGION_SEARCH_STATE_ERROR = 9123; + RET_CHANNELLER_SLAB_LOOP_DUNGEON_STAGE_NOT_OPEN = 9130; + RET_CHANNELLER_SLAB_LOOP_DUNGEON_NOT_OPEN = 9131; + RET_CHANNELLER_SLAB_LOOP_DUNGEON_FIRST_PASS_REWARD_HAS_TAKEN = 9132; + RET_CHANNELLER_SLAB_LOOP_DUNGEON_SCORE_REWARD_HAS_TAKEN = 9133; + RET_CHANNELLER_SLAB_INVALID_ONE_OFF_DUNGEON = 9134; + RET_CHANNELLER_SLAB_ONE_OFF_DUNGEON_DONE = 9135; + RET_CHANNELLER_SLAB_ONE_OFF_DUNGEON_STAGE_NOT_OPEN = 9136; + RET_CHANNELLER_SLAB_TOKEN_EXCEED_LIMIT = 9137; + RET_CHANNELLER_SLAB_TOKEN_NOT_ENOUGH = 9138; + RET_CHANNELLER_SLAB_PLAYER_NOT_IN_ONE_OFF_DUNGEON = 9139; + RET_MIST_TRIAL_SELECT_CHARACTER_NUM_NOT_ENOUGH = 9150; + RET_MIST_TRIAL_ALREADY_USING_TRIAL_AVATAR = 9151; + RET_HIDE_AND_SEEK_PLAY_NOT_OPEN = 9160; + RET_HIDE_AND_SEEK_PLAY_MAP_NOT_OPEN = 9161; + RET_HIDE_AND_SEEK_PLAY_MAP_NOT_CHOSEN = 9162; + RET_SUMMER_TIME_DRAFT_WOORD_EXCEED_LIMIT = 9170; + RET_SUMMER_TIME_DRAFT_WOORD_NOT_ENOUGH = 9171; + RET_SUMMER_TIME_MINI_HARPASTUM_EXCEED_LIMIT = 9172; + RET_SUMMER_TIME_MINI_HARPASTUMNOT_ENOUGH = 9173; + RET_BOUNCE_CONJURING_COIN_EXCEED_LIMIT = 9180; + RET_BOUNCE_CONJURING_COIN_NOT_ENOUGH = 9181; + RET_CHESS_TEACH_MAP_FINISHED = 9183; + RET_CHESS_TEACH_MAP_UNFINISHED = 9184; + RET_CHESS_COIN_EXCEED_LIMIT = 9185; + RET_CHESS_COIN_NOT_ENOUGH = 9186; + RET_CHESS_IN_PUNISH_TIME = 9187; + RET_CHESS_PREV_MAP_UNFINISHED = 9188; + RET_CHESS_MAP_LOCKED = 9189; + RET_BLITZ_RUSH_NOT_OPEN = 9192; + RET_BLITZ_RUSH_DUNGEON_NOT_OPEN = 9193; + RET_BLITZ_RUSH_COIN_A_EXCEED_LIMIT = 9194; + RET_BLITZ_RUSH_COIN_B_EXCEED_LIMIT = 9195; + RET_BLITZ_RUSH_COIN_A_NOT_ENOUGH = 9196; + RET_BLITZ_RUSH_COIN_B_NOT_ENOUGH = 9197; + RET_MIRACLE_RING_VALUE_NOT_ENOUGH = 9201; + RET_MIRACLE_RING_CD = 9202; + RET_MIRACLE_RING_REWARD_NOT_TAKEN = 9203; + RET_MIRACLE_RING_NOT_DELIVER = 9204; + RET_MIRACLE_RING_DELIVER_EXCEED = 9205; + RET_MIRACLE_RING_HAS_CREATED = 9206; + RET_MIRACLE_RING_HAS_NOT_CREATED = 9207; + RET_MIRACLE_RING_NOT_YOURS = 9208; + RET_GADGET_FOUNDATION_UNAUTHORIZED = 9251; + RET_GADGET_FOUNDATION_SCENE_NOT_FOUND = 9252; + RET_GADGET_FOUNDATION_NOT_IN_INIT_STATE = 9253; + RET_GADGET_FOUNDATION_BILDING_POINT_NOT_ENOUGHT = 9254; + RET_GADGET_FOUNDATION_NOT_IN_BUILT_STATE = 9255; + RET_GADGET_FOUNDATION_OP_NOT_SUPPORTED = 9256; + RET_GADGET_FOUNDATION_REQ_PLAYER_NOT_IN_SCENE = 9257; + RET_GADGET_FOUNDATION_LOCKED_BY_ANOTHER_PLAYER = 9258; + RET_GADGET_FOUNDATION_NOT_LOCKED = 9259; + RET_GADGET_FOUNDATION_DUPLICATE_LOCK = 9260; + RET_GADGET_FOUNDATION_PLAYER_NOT_FOUND = 9261; + RET_GADGET_FOUNDATION_PLAYER_GEAR_NOT_FOUND = 9262; + RET_GADGET_FOUNDATION_ROTAION_DISABLED = 9263; + RET_GADGET_FOUNDATION_REACH_DUNGEON_GEAR_LIMIT = 9264; + RET_GADGET_FOUNDATION_REACH_SINGLE_GEAR_LIMIT = 9265; + RET_GADGET_FOUNDATION_ROTATION_ON_GOING = 9266; + RET_OP_ACTIVITY_BONUS_NOT_FOUND = 9301; + RET_OP_ACTIVITY_NOT_OPEN = 9302; + RET_MULTISTAGE_PLAY_PLAYER_NOT_IN_SCENE = 9501; + RET_MULTISTAGE_PLAY_NOT_FOUND = 9502; + RET_MULTISTAGE_PLAY_IN_OTHER_STAGE = 9503; + RET_COOP_CHAPTER_NOT_OPEN = 9601; + RET_COOP_COND_NOT_MEET = 9602; + RET_COOP_POINT_LOCKED = 9603; + RET_COOP_NOT_HAVE_PROGRESS = 9604; + RET_COOP_REWARD_HAS_TAKEN = 9605; + RET_DRAFT_HAS_ACTIVE_DRAFT = 9651; + RET_DRAFT_NOT_IN_MY_WORLD = 9652; + RET_DRAFT_NOT_SUPPORT_MP = 9653; + RET_DRAFT_PLAYER_NOT_ENOUGH = 9654; + RET_DRAFT_INCORRECT_SCENE = 9655; + RET_DRAFT_OTHER_PLAYER_ENTERING = 9656; + RET_DRAFT_GUEST_IS_TRANSFERRING = 9657; + RET_DRAFT_GUEST_NOT_IN_DRAFT_SCENE = 9658; + RET_DRAFT_INVITE_OVER_TIME = 9659; + RET_DRAFT_TWICE_CONFIRM_OVER_TIMER = 9660; + RET_DRAFT_GUEST_NOT_IN_WORLD_SCENE = 9661; + RET_HOME_UNKOWN = 9701; + RET_HOME_INVALID_CLIENT_PARAM = 9702; + RET_HOME_TARGE_PLAYER_HAS_NO_HOME = 9703; + RET_HOME_NOT_ONLINE = 9704; + RET_HOME_PLAYER_FULL = 9705; + RET_HOME_BLOCKED = 9706; + RET_HOME_ALREADY_IN_TARGET_HOME_WORLD = 9707; + RET_HOME_IN_EDIT_MODE = 9708; + RET_HOME_NOT_IN_EDIT_MODE = 9709; + RET_HOME_HAS_GUEST = 9710; + RET_HOME_CANT_ENTER_BY_IN_EDIT_MODE = 9711; + RET_HOME_CLIENT_PARAM_INVALID = 9712; + RET_HOME_PLAYER_NOT_IN_HOME_WORLD = 9713; + RET_HOME_PLAYER_NOT_IN_SELF_HOME_WORLD = 9714; + RET_HOME_NOT_FOUND_IN_MEM = 9715; + RET_HOME_PLAYER_IN_HOME_ROOM_SCENE = 9716; + RET_HOME_HOME_REFUSE_GUEST_ENTER = 9717; + RET_HOME_OWNER_REFUSE_TO_ENTER_HOME = 9718; + RET_HOME_OWNER_OFFLINE = 9719; + RET_HOME_FURNITURE_EXCEED_LIMIT = 9720; + RET_HOME_FURNITURE_COUNT_NOT_ENOUGH = 9721; + RET_HOME_IN_TRY_ENTER_PROCESS = 9722; + RET_HOME_ALREADY_IN_TARGET_SCENE = 9723; + RET_HOME_COIN_EXCEED_LIMIT = 9724; + RET_HOME_COIN_NOT_ENOUGH = 9725; + RET_HOME_MODULE_NOT_UNLOCKED = 9726; + RET_HOME_CUR_MODULE_CLOSED = 9727; + RET_HOME_FURNITURE_SUITE_NOT_UNLOCKED = 9728; + RET_HOME_IN_MATCH = 9729; + RET_HOME_IN_COMBAT = 9730; + RET_HOME_EDIT_MODE_CD = 9731; + RET_HOME_UPDATE_FURNITURE_CD = 9732; + RET_HOME_BLOCK_FURNITURE_LIMIT = 9733; + RET_HOME_NOT_SUPPORT = 9734; + RET_HOME_STATE_NOT_OPEN = 9735; + RET_HOME_TARGET_STATE_NOT_OPEN = 9736; + RET_HOME_APPLY_ENTER_OTHER_HOME_FAIL = 9737; + RET_HOME_SAVE_NO_MAIN_HOUSE = 9738; + RET_HOME_IN_DUNGEON = 9739; + RET_HOME_ANY_GALLERY_STARTED = 9740; + RET_HOME_QUEST_BLOCK_HOME = 9741; + RET_HOME_WAITING_PRIOR_CHECK = 9742; + RET_HOME_PERSISTENT_CHECK_FAIL = 9743; + RET_HOME_FIND_ONLINE_HOME_FAIL = 9744; + RET_HOME_JOIN_SCENE_FAIL = 9745; + RET_HOME_MAX_PLAYER = 9746; + RET_HOME_IN_TRANSFER = 9747; + RET_HOME_ANY_HOME_GALLERY_STARTED = 9748; + RET_HOME_CAN_NOT_ENTER_IN_AUDIT = 9749; + RET_FURNITURE_MAKE_INDEX_ERROR = 9750; + RET_FURNITURE_MAKE_LOCKED = 9751; + RET_FURNITURE_MAKE_CONFIG_ERROR = 9752; + RET_FURNITURE_MAKE_SLOT_FULL = 9753; + RET_FURNITURE_MAKE_ADD_FURNITURE_FAIL = 9754; + RET_FURNITURE_MAKE_UNFINISH = 9755; + RET_FURNITURE_MAKE_IS_FINISH = 9756; + RET_FURNITURE_MAKE_NOT_IN_CORRECT_HOME = 9757; + RET_FURNITURE_MAKE_NO_COUNT = 9758; + RET_FURNITURE_MAKE_ACCELERATE_LIMIT = 9759; + RET_FURNITURE_MAKE_NO_MAKE_DATA = 9760; + RET_HOME_LIMITED_SHOP_CLOSE = 9761; + RET_HOME_AVATAR_NOT_SHOW = 9762; + RET_HOME_EVENT_COND_NOT_SATISFIED = 9763; + RET_HOME_INVALID_ARRANGE_ANIMAL_PARAM = 9764; + RET_HOME_INVALID_ARRANGE_NPC_PARAM = 9765; + RET_HOME_INVALID_ARRANGE_SUITE_PARAM = 9766; + RET_HOME_INVALID_ARRANGE_MAIN_HOUSE_PARAM = 9767; + RET_HOME_AVATAR_STATE_NOT_OPEN = 9768; + RET_HOME_PLANT_FIELD_NOT_EMPTY = 9769; + RET_HOME_PLANT_FIELD_EMPTY = 9770; + RET_HOME_PLANT_FIELD_TYPE_ERROR = 9771; + RET_HOME_PLANT_TIME_NOT_ENOUGH = 9772; + RET_HOME_PLANT_SUB_FIELD_NUM_NOT_ENOUGH = 9773; + RET_HOME_PLANT_FIELD_PARAM_ERROR = 9774; + RET_HOME_FURNITURE_GUID_ERROR = 9775; + RET_HOME_FURNITURE_ARRANGE_LIMIT = 9776; + RET_HOME_FISH_FARMING_LIMIT = 9777; + RET_HOME_FISH_COUNT_NOT_ENOUGH = 9778; + RET_HOME_FURNITURE_COST_LIMIT = 9779; + RET_HOME_CUSTOM_FURNITURE_INVALID = 9780; + RET_HOME_INVALID_ARRANGE_GROUP_PARAM = 9781; + RET_HOME_FURNITURE_ARRANGE_GROUP_LIMIT = 9782; + RET_HOME_PICTURE_FRAME_COOP_CG_GENDER_ERROR = 9783; + RET_HOME_PICTURE_FRAME_COOP_CG_NOT_UNLOCK = 9784; + RET_HOME_FURNITURE_CANNOT_ARRANGE = 9785; + RET_HOME_FURNITURE_IN_DUPLICATE_SUITE = 9786; + RET_HOME_FURNITURE_CUSTOM_SUITE_TOO_SMALL = 9787; + RET_HOME_FURNITURE_CUSTOM_SUITE_TOO_BIG = 9788; + RET_HOME_FURNITURE_SUITE_EXCEED_LIMIT = 9789; + RET_HOME_FURNITURE_CUSTOM_SUITE_EXCEED_LIMIT = 9790; + RET_HOME_FURNITURE_CUSTOM_SUITE_INVALID_SURFACE_TYPE = 9791; + RET_HOME_BGM_ID_NOT_FOUND = 9792; + RET_HOME_BGM_NOT_UNLOCKED = 9793; + RET_HOME_BGM_FURNITURE_NOT_FOUND = 9794; + RET_HOME_BGM_NOT_SUPPORT_BY_CUR_SCENE = 9795; + RET_HOME_LIMITED_SHOP_GOODS_DISABLE = 9796; + RET_HOME_WORLD_WOOD_MATERIAL_EMPTY = 9797; + RET_HOME_WORLD_WOOD_MATERIAL_NOT_FOUND = 9798; + RET_HOME_WORLD_WOOD_MATERIAL_COUNT_INVALID = 9799; + RET_HOME_WORLD_WOOD_EXCHANGE_EXCEED_LIMIT = 9800; + RET_HOME_BLUEPRINT_SEARCH_SELF = 9801; + RET_HOME_BLUEPRINT_SHARE_CODE_INVALID = 9802; + RET_HOME_BLUEPRINT_NOT_EXIST = 9803; + RET_HOME_BLUEPRINT_SLOT_HAS_EXIST_SHARE_CODE = 9804; + RET_HOME_BLUEPRINT_SLOT_NOT_EXIST_SHARE_CODE = 9805; + RET_HOME_BLUEPRINT_CAN_NOT_CREATE_IN_AUDIT = 9806; + RET_HOME_BLOCK_NOT_UNLOCKED = 9807; + RET_HOME_BLUEPRINT_CREATE_CD = 9808; + RET_HOME_BLUEPRINT_SET_OPTION_CD = 9809; + RET_HOME_BLUEPRINT_NOT_ALLOW_FRIEND_COPY = 9810; + RET_HOME_FURNITURE_POS_UNDER_DIE_Y = 9811; + RET_HOME_BLUEPRINT_GEN_SHARE_CODE_FAIL = 9812; + RET_HOME_BLUEPRINT_SEARCH_CD = 9813; + RET_HOME_BLUEPRINT_PREVIEW_CD = 9814; + RET_HOME_BLUEPRINT_PREVIEW_SCENE_NOT_MATCH = 9815; + RET_SUMO_ACTIVITY_STAGE_NOT_OPEN = 10000; + RET_SUMO_ACTIVITY_SWITCH_TEAM_IN_CD = 10001; + RET_SUMO_ACTIVITY_TEAM_NUM_INCORRECT = 10002; + RET_LUNA_RITE_ACTIVITY_AREA_ID_ERROR = 10004; + RET_LUNA_RITE_ACTIVITY_BATTLE_NOT_FINISH = 10005; + RET_LUNA_RITE_ACTIVITY_ALREADY_SACRIFICE = 10006; + RET_LUNA_RITE_ACTIVITY_ALREADY_TAKE_REWARD = 10007; + RET_LUNA_RITE_ACTIVITY_SACRIFICE_NOT_ENOUGH = 10008; + RET_LUNA_RITE_ACTIVITY_SEARCHING_COND_NOT_MEET = 10009; + RET_DIG_GADGET_CONFIG_ID_NOT_MATCH = 10015; + RET_DIG_FIND_NEAREST_POS_FAIL = 10016; + RET_MUSIC_GAME_LEVEL_NOT_OPEN = 10021; + RET_MUSIC_GAME_LEVEL_NOT_UNLOCK = 10022; + RET_MUSIC_GAME_LEVEL_NOT_STARTED = 10023; + RET_MUSIC_GAME_LEVEL_CONFIG_NOT_FOUND = 10024; + RET_MUSIC_GAME_LEVEL_ID_NOT_MATCH = 10025; + RET_ROGUELIKE_COIN_A_NOT_ENOUGH = 10031; + RET_ROGUELIKE_COIN_B_NOT_ENOUGH = 10032; + RET_ROGUELIKE_COIN_C_NOT_ENOUGH = 10033; + RET_ROGUELIKE_COIN_A_EXCEED_LIMIT = 10034; + RET_ROGUELIKE_COIN_B_EXCEED_LIMIT = 10035; + RET_ROGUELIKE_COIN_C_EXCEED_LIMIT = 10036; + RET_ROGUELIKE_RUNE_COUNT_NOT_ENOUGH = 10037; + RET_ROGUELIKE_NOT_IN_ROGUE_DUNGEON = 10038; + RET_ROGUELIKE_CELL_NOT_FOUND = 10039; + RET_ROGUELIKE_CELL_TYPE_INCORRECT = 10040; + RET_ROGUELIKE_CELL_ALREADY_FINISHED = 10041; + RET_ROGUELIKE_DUNGEON_HAVE_UNFINISHED_PROGRESS = 10042; + RET_ROGUELIKE_STAGE_NOT_FINISHED = 10043; + RET_ROGUELIKE_STAGE_FIRST_PASS_REWARD_HAS_TAKEN = 10045; + RET_ROGUELIKE_ACTIVITY_CONTENT_CLOSED = 10046; + RET_ROGUELIKE_DUNGEON_PRE_QUEST_NOT_FINISHED = 10047; + RET_ROGUELIKE_DUNGEON_NOT_OPEN = 10048; + RET_ROGUELIKE_SPRINT_IS_BANNED = 10049; + RET_ROGUELIKE_DUNGEON_PRE_STAGE_NOT_FINISHED = 10050; + RET_ROGUELIKE_ALL_AVATAR_DIE_CANNOT_RESUME = 10051; + RET_PLANT_FLOWER_ALREADY_TAKE_SEED = 10056; + RET_PLANT_FLOWER_FRIEND_HAVE_FLOWER_LIMIT = 10057; + RET_PLANT_FLOWER_CAN_GIVE_FLOWER_NOT_ENOUGH = 10058; + RET_PLANT_FLOWER_WISH_FLOWER_KINDS_LIMIT = 10059; + RET_PLANT_FLOWER_HAVE_FLOWER_NOT_ENOUGH = 10060; + RET_PLANT_FLOWER_FLOWER_COMBINATION_INVALID = 10061; + RET_HACHI_DUNGEON_NOT_VALID = 10052; + RET_HACHI_DUNGEON_STAGE_NOT_OPEN = 10053; + RET_HACHI_DUNGEON_TEAMMATE_NOT_PASS = 10054; + RET_WINTER_CAMP_COIN_A_NOT_ENOUGH = 10071; + RET_WINTER_CAMP_COIN_B_NOT_ENOUGH = 10072; + RET_WINTER_CAMP_COIN_A_EXCEED_LIMIT = 10073; + RET_WINTER_CAMP_COIN_B_EXCEED_LIMIT = 10074; + RET_WINTER_CAMP_WISH_ID_INVALID = 10075; + RET_WINTER_CAMP_NOT_FOUND_RECV_ITEM_DATA = 10076; + RET_WINTER_CAMP_FRIEND_ITEM_COUNT_OVERFLOW = 10077; + RET_WINTER_CAMP_SELECT_ITEM_DATA_INVALID = 10078; + RET_WINTER_CAMP_ITEM_LIST_EMPTY = 10079; + RET_WINTER_CAMP_REWARD_ALREADY_TAKEN = 10080; + RET_WINTER_CAMP_STAGE_NOT_FINISH = 10081; + RET_WINTER_CAMP_GADGET_INVALID = 10082; + RET_LANTERN_RITE_COIN_A_NOT_ENOUGH = 10090; + RET_LANTERN_RITE_COIN_B_NOT_ENOUGH = 10091; + RET_LANTERN_RITE_COIN_C_NOT_ENOUGH = 10092; + RET_LANTERN_RITE_COIN_A_EXCEED_LIMIT = 10093; + RET_LANTERN_RITE_COIN_B_EXCEED_LIMIT = 10094; + RET_LANTERN_RITE_COIN_C_EXCEED_LIMIT = 10095; + RET_LANTERN_RITE_PROJECTION_CONTENT_CLOSED = 10096; + RET_LANTERN_RITE_PROJECTION_CAN_NOT_START = 10097; + RET_LANTERN_RITE_DUNGEON_NOT_OPEN = 10098; + RET_LANTERN_RITE_HAS_TAKEN_SKIN_REWARD = 10099; + RET_LANTERN_RITE_NOT_FINISHED_SKIN_WATCHERS = 10100; + RET_LANTERN_RITE_FIREWORKS_CONTENT_CLOSED = 10101; + RET_LANTERN_RITE_FIREWORKS_CHALLENGE_NOT_START = 10102; + RET_LANTERN_RITE_FIREWORKS_REFORM_PARAM_ERROR = 10103; + RET_LANTERN_RITE_FIREWORKS_REFORM_SKILL_LOCK = 10104; + RET_LANTERN_RITE_FIREWORKS_REFORM_STAMINA_NOT_ENOUGH = 10105; + RET_POTION_ACTIVITY_STAGE_NOT_OPEN = 10110; + RET_POTION_ACTIVITY_LEVEL_HAVE_PASS = 10111; + RET_POTION_ACTIVITY_TEAM_NUM_INCORRECT = 10112; + RET_POTION_ACTIVITY_AVATAR_IN_CD = 10113; + RET_POTION_ACTIVITY_BUFF_IN_CD = 10114; + RET_IRODORI_POETRY_INVALID_LINE_ID = 10120; + RET_IRODORI_POETRY_INVALID_THEME_ID = 10121; + RET_IRODORI_POETRY_NOT_GET_ALL_INSPIRATION = 10122; + RET_IRODORI_POETRY_INSPIRATION_REACH_LIMIE = 10123; + RET_IRODORI_POETRY_ENTITY_ALREADY_SCANNED = 10124; + RET_ACTIVITY_BANNER_ALREADY_CLEARED = 10300; + RET_IRODORI_CHESS_NOT_OPEN = 10301; + RET_IRODORI_CHESS_LEVEL_NOT_OPEN = 10302; + RET_IRODORI_CHESS_MAP_NOT_OPEN = 10303; + RET_IRODORI_CHESS_MAP_CARD_ALREADY_EQUIPED = 10304; + RET_IRODORI_CHESS_EQUIP_CARD_EXCEED_LIMIT = 10305; + RET_IRODORI_CHESS_MAP_CARD_NOT_EQUIPED = 10306; + RET_IRODORI_CHESS_ENTER_FAIL_CARD_EXCEED_LIMIT = 10307; + RET_ACTIVITY_FRIEND_HAVE_GIFT_LIMIT = 10310; + RET_GACHA_ACTIVITY_HAVE_REWARD_LIMIT = 10315; + RET_GACHA_ACTIVITY_HAVE_ROBOT_LIMIT = 10316; + RET_SUMMER_TIME_V2_COIN_EXCEED_LIMIT = 10317; + RET_SUMMER_TIME_V2_COIN_NOT_ENOUGH = 10318; + RET_SUMMER_TIME_V2_DUNGEON_STAGE_NOT_OPEN = 10319; + RET_SUMMER_TIME_V2_PREV_DUNGEON_NOT_COMPLETE = 10320; + RET_ROGUE_DIARY_AVATAR_DEATH = 10350; + RET_ROGUE_DIARY_AVATAR_TIRED = 10351; + RET_ROGUE_DIARY_AVATAR_DUPLICATED = 10352; + RET_ROGUE_DIARY_COIN_NOT_ENOUGH = 10353; + RET_ROGUE_DIARY_VIRTUAL_COIN_EXCEED_LIMIT = 10354; + RET_ROGUE_DIARY_VIRTUAL_COIN_NOT_ENOUGH = 10355; + RET_ROGUE_DIARY_CONTENT_CLOSED = 10366; + RET_GRAVEN_INNOCENCE_COIN_A_NOT_ENOUGH = 10380; + RET_GRAVEN_INNOCENCE_COIN_B_NOT_ENOUGH = 10381; + RET_GRAVEN_INNOCENCE_COIN_A_EXCEED_LIMIT = 10382; + RET_GRAVEN_INNOCENCE_COIN_B_EXCEED_LIMIT = 10383; + RET_ISLAND_PARTY_STAGE_NOT_OPEN = 10371; + RET_WIND_FIELD_STAGE_NOT_OPEN = 10390; + RET_VINTAGE_CONTENT_CLOSED = 10396; + RET_VINTAGE_STORE_CONTENT_FINISHED = 10397; + RET_VINTAGE_STORE_ATTR_TOO_SMALL = 10398; + RET_VINTAGE_STORE_ATTR_TOO_LARGE = 10399; + RET_VINTAGE_STORE_CONTENT_INTERRUPT = 10400; + RET_VINTAGE_VIRTUAL_COIN_NOT_ENOUGH = 10401; + RET_VINTAGE_STORE_ATTR_LESS_THAN_ZERO = 10402; + RET_FUNGUS_FIGHTER_CAPTURE_COIN_NOT_ENOUGH = 10406; + RET_FUNGUS_FIGHTER_TRAINING_COIN_NOT_ENOUGH = 10407; + RET_FUNGUS_FIGHTER_CAPTURE_COIN_EXCEED_LIMIT = 10408; + RET_FUNGUS_FIGHTER_TRAINING_COIN_EXCEED_LIMIT = 10409; + RET_FUNGUS_FIGHTER_CONTENT_CLOSED = 10410; + RET_FUNGUS_FIGHTER_PLOT_STAGE_NOT_OPEN = 10411; + RET_FUNGUS_FIGHTER_FUNGUS_ID_CONFIG_NOT_VALID = 10412; + RET_FUNGUS_FIGHTER_FUNGUS_NOT_CULTIVATED = 10413; + RET_FUNGUS_FIGHTER_TRAINING_DUNGEON_NOT_OPEN = 10414; + RET_EFFIGY_CHALLENGE_V2_COIN_NOT_ENOUGH = 10427; + RET_EFFIGY_CHALLENGE_V2_COIN_EXCEED_LIMIT = 10428; + RET_CHAR_AMUSEMENT_STAGE_NOT_OPEN = 10436; + RET_COIN_COLLECT_LEVEL_NOT_OPEN = 10446; + RET_COIN_COLLECT_NOT_EQUIP_WIDGET = 10447; + RET_COIN_COLLECT_SCENE_NOT_MATCH = 10448; + RET_COIN_COLLECT_CANT_ENTER_MP_MODE = 10449; + RET_COIN_COLLECT_PLAYER_NUM_FAIL = 10450; + RET_BRICK_BREAKER_PLAYER_NUM_FAIL = 10456; + RET_BRICK_BREAKER_STAGE_NOT_UNLOCK = 10457; + RET_BRICK_BREAKER_NORMAL_LEVEL_NOT_FINISH = 10458; + RET_BRICK_BREAKER_PRE_LEVEL_NOT_FINISH = 10459; + RET_BRICK_BREAKER_PRE_STAGE_NOT_FINISH = 10460; + RET_BRICK_BREAKER_WORLD_LEVEL_NOT_UNLOCK = 10461; + RET_BRICK_BREAKER_DUNGEON_LEVEL_NOT_UNLOCK = 10462; + RET_BRICK_BREAKER_COIN_NOT_ENOUGH = 10463; + RET_BRICK_BREAKER_COIN_EXCEED_LIMIT = 10464; + RET_TEAMCHAIN_WORLD_IN_MP_MODE = 10466; + RET_LAN_V3_BOAT_PLAYER_NUM_NOT_VALID = 10481; + RET_LAN_V3_BOAT_PLAY_NOT_OPEN = 10482; + RET_LAN_V3_BOAT_NOT_IN_WORLD_SCENE = 10483; + RET_ACTIVITY_CONTENT_CLOSED = 10901; + RET_NOT_IN_FISHING = 11001; + RET_FISH_STATE_ERROR = 11002; + RET_FISH_BAIT_LIMIT = 11003; + RET_FISHING_MAX_DISTANCE = 11004; + RET_FISHING_IN_COMBAT = 11005; + RET_FISHING_BATTLE_TOO_SHORT = 11006; + RET_FISH_GONE_AWAY = 11007; + RET_CAN_NOT_EDIT_OTHER_DUNGEON = 11051; + RET_CUSTOM_DUNGEON_DISMATCH = 11052; + RET_NO_CUSTOM_DUNGEON_DATA = 11053; + RET_BUILD_CUSTOM_DUNGEON_FAIL = 11054; + RET_CUSTOM_DUNGEON_ROOM_CHECK_FAIL = 11055; + RET_CUSTOM_DUNGEON_SAVE_MAY_FAIL = 11056; + RET_NOT_IN_CUSTOM_DUNGEON = 11057; + RET_CUSTOM_DUNGEON_INTERNAL_FAIL = 11058; + RET_CUSTOM_DUNGEON_CAN_NOT_TRY = 11059; + RET_CUSTOM_DUNGEON_NO_START_ROOM = 11060; + RET_CUSTOM_DUNGEON_NO_ROOM_DATA = 11061; + RET_CUSTOM_DUNGEON_SAVE_TOO_FREQUENT = 11062; + RET_CUSTOM_DUNGEON_NOT_SELF_PASS = 11063; + RET_CUSTOM_DUNGEON_LACK_COIN = 11064; + RET_CUSTOM_DUNGEON_NO_FINISH_BRICK = 11065; + RET_CUSTOM_DUNGEON_MULTI_FINISH = 11066; + RET_CUSTOM_DUNGEON_NOT_PUBLISHED = 11067; + RET_CUSTOM_DUNGEON_FULL_STORE = 11068; + RET_CUSTOM_DUNGEON_STORE_REPEAT = 11069; + RET_CUSTOM_DUNGEON_CAN_NOT_STORE_SELF = 11070; + RET_CUSTOM_DUNGEON_NOT_SAVE_SUCC = 11071; + RET_CUSTOM_DUNGEON_CAN_NOT_LIKE_SELF = 11072; + RET_CUSTOM_DUNGEON_NOT_FOUND = 11073; + RET_CUSTOM_DUNGEON_INVALID_SETTING = 11074; + RET_CUSTOM_DUNGEON_NO_FINISH_SETTING = 11075; + RET_CUSTOM_DUNGEON_SAVE_NOTHING = 11076; + RET_CUSTOM_DUNGEON_NOT_IN_GROUP = 11077; + RET_CUSTOM_DUNGEON_NOT_OFFICIAL = 11078; + RET_CUSTOM_DUNGEON_LIFE_NUM_ERROR = 11079; + RET_CUSTOM_DUNGEON_NO_OPEN_ROOM = 11080; + RET_CUSTOM_DUNGEON_BRICK_EXCEED_LIMIT = 11081; + RET_CUSTOM_DUNGEON_OFFICIAL_NOT_UNLOCK = 11082; + RET_CAN_NOT_EDIT_OFFICIAL_SETTING = 11083; + RET_CUSTOM_DUNGEON_BAN_PUBLISH = 11084; + RET_CUSTOM_DUNGEON_CAN_NOT_REPLAY = 11085; + RET_CUSTOM_DUNGEON_NOT_OPEN_GROUP = 11086; + RET_CUSTOM_DUNGEON_MAX_EDIT_NUM = 11087; + RET_CUSTOM_DUNGEON_CAN_NOT_OUT_STUCK = 11088; + RET_CUSTOM_DUNGEON_MAX_TAG = 11089; + RET_CUSTOM_DUNGEON_INVALID_TAG = 11090; + RET_CUSTOM_DUNGEON_MAX_COST = 11091; + RET_CUSTOM_DUNGEON_REQUEST_TOO_FREQUENT = 11092; + RET_CUSTOM_DUNGEON_NOT_OPEN = 11093; + RET_SHARE_CD_ID_ERROR = 11101; + RET_SHARE_CD_INDEX_ERROR = 11102; + RET_SHARE_CD_IN_CD = 11103; + RET_SHARE_CD_TOKEN_NOT_ENOUGH = 11104; + RET_UGC_DISMATCH = 11151; + RET_UGC_DATA_NOT_FOUND = 11152; + RET_UGC_BRIEF_NOT_FOUND = 11153; + RET_UGC_DISABLED = 11154; + RET_UGC_LIMITED = 11155; + RET_UGC_LOCKED = 11156; + RET_UGC_NOT_AUTH = 11157; + RET_UGC_NOT_OPEN = 11158; + RET_UGC_BAN_PUBLISH = 11159; + RET_COMPOUND_BOOST_ITEM_NOT_EXIST = 11201; + RET_COMPOUND_BOOST_TARGET_NOT_EXIST = 11202; + RET_QUICK_HIT_TREE_EMPTY_TREES = 11211; + RET_GCG_FIND_GAME_MODE_FAIL = 12000; + RET_GCG_OPERATION_PARAM_ERROR = 12001; + RET_GCG_GAME_NOT_RUNNING = 12002; + RET_GCG_OP_NOT_ALLOW = 12003; + RET_GCG_OP_NOT_MATCH_PHASE = 12004; + RET_GCG_SELECT_HAND_CARD_GUID_ERROR = 12005; + RET_GCG_DICE_INDEX_INVALID = 12006; + RET_GCG_CHARACTER_GUID_INVALID = 12007; + RET_GCG_CHARACTER_ALREADY_DIE = 12008; + RET_GCG_CHARACTER_ALREADY_ON_STAGE = 12009; + RET_GCG_CHARACTER_FORBIDDEN_ATTACK = 12010; + RET_GCG_SELECT_DICE_NOT_MATCH = 12011; + RET_GCG_FIND_SKILL_FAIL = 12012; + RET_GCG_SKILL_CAN_NOT_ACTIVE_USE = 12013; + RET_GCG_ENERGY_NOT_ENOUGH = 12014; + RET_GCG_PLAY_CARD_TARGET_NOT_MATCH = 12015; + RET_GCG_PLAY_CARD_ZONE_CANNOT_ADD = 12016; + RET_GCG_REBOOT_SELECT_DICE_INVALID = 12017; + RET_GCG_REBOOT_SELECT_CARD_INVALID = 12018; + RET_GCG_PLAY_CARD_CONDITION_CHECK_FAIL = 12019; + RET_GCG_PLAY_CARD_PARAM_INVALID = 12020; + RET_GCG_MAX_GAME = 12021; + RET_GCG_SEND_PACKET_FAIL = 12022; + RET_GCG_ALREADY_SETTLE = 12023; + RET_GCG_COIN_EXCEED_LIMIT = 12101; + RET_GCG_COIN_NOT_ENOUGH = 12102; + RET_GCG_NOT_IN_SELF_WORLD = 12103; + RET_GCG_ALREADY_IN_DUEL = 12104; + RET_GCG_NOT_IN_PLAYER_WORLD = 12105; + RET_GCG_GALLERY_STARTED = 12106; + RET_GCG_INVITE_TARGET_IS_SELF = 12107; + RET_GCG_INVITE_TARGET_NOT_IN_WORLD = 12108; + RET_GCG_APPLY_INVITE_NOT_ALLOW = 12109; + RET_GCG_APPLY_INVITE_TIMEOUT = 12110; + RET_GCG_CUR_DECK_INVALID = 12111; + RET_GCG_NEED_RESOURCE_COMPLETE = 12112; + RET_GCG_OPPONENT_PLAYER_IS_SELF = 12113; + RET_GCG_GAME_ID_INVALID = 12114; + RET_GCG_MATCH_IN_PUNISH = 12115; + RET_GCG_SETTLE_STILL_IN_DUEL = 12116; + RET_GCG_SETTLE_NOT_IN_DUNGEON = 12117; + RET_GCG_UNSUPPORT_SETTLE_OPTION = 12118; + RET_GCG_NOT_IN_GCG_DUNGEON = 12119; + RET_GCG_WORLD_LEVEL_LOCKED = 12120; + RET_GCG_BOSS_LEVEL_LOCKED = 12121; + RET_GCG_NOT_IN_TAVERN = 12122; + RET_GCG_WEEK_NPC_NOT_EXIST = 12123; + RET_GCG_ENTER_GAME_FREQUENT = 12124; + RET_GCG_BREAK_LEVEL_QUEST_NOT_UNFINISHED = 12125; + RET_GCG_GUIDE_LEVEL_ALREADY_FINISHED = 12126; + RET_GCG_LEVEL_CANNOT_RESTART = 12127; + RET_GCG_TARGET_CHECK_ENTER_FAIL = 12128; + RET_GCG_ALREADY_IN_DUNGEON = 12129; + RET_GCG_BACK_DUEL_NO_GAME = 12130; + RET_GCG_CONST_LEVEL_LOCKED = 12131; + RET_GCG_QUEST_ID_ERROR = 12132; + RET_GCG_QUEST_NEED_UNFINISHED = 12133; + RET_GCG_IN_MATCH = 12134; + RET_GCG_DATA_VERSION_NOT_LATEST = 12135; + RET_GCG_INVITE_TARGET_ENTER_GAME_FREQUENT = 12136; + RET_GCG_INVITE_TARGET_NEED_RESOURCE_COMPLETE = 12137; + RET_GCG_INVITE_TARGET_SCENE_IS_NULL = 12138; + RET_GCG_INVITE_TARGET_IN_TRANSFER = 12139; + RET_GCG_INVITE_TARGET_DATA_VERSION_NOT_LATEST = 12140; + RET_GCG_INVITE_TARGET_CUR_DECK_INVALID = 12141; + RET_GCG_CLIENT_DATA_VERSION_NOT_MATCH = 12142; + RET_GCG_CLIENT_DATA_VERSOIN_FORBID = 12143; + RET_GCG_MP_CANT_MATCH = 12144; + RET_GCG_INVITE_TARGET_STATE_NOT_OPEN = 12145; + RET_GCG_CREATE_TIME_OUT = 12146; + RET_GCG_BAN_MATCH = 12147; + RET_GCG_BAN_INVITE = 12148; + RET_GCG_TARGET_BAN_INVITE = 12149; + RET_GCG_INVITE_ALREADY_INVITE = 12150; + RET_GCG_FESTIVAL_MODE_NOT_OPEN = 12151; + RET_GCG_TARGET_FESTIVAL_MODE_NOT_OPEN = 12152; + RET_GCG_BACK_DUEL_PS_TO_OTHER = 12153; + RET_GCG_BACK_DUEL_OTHER_TO_PS = 12154; + RET_GCG_DS_DECK_LOCKED = 12201; + RET_GCG_DS_DECK_NAME_INVALID = 12202; + RET_GCG_DS_DECK_CHAR_CARD_NUM_INVALID = 12204; + RET_GCG_DS_DECK_CARD_NUM_INVALID = 12205; + RET_GCG_DS_CARD_NUM_EXCEED_LIMIT = 12206; + RET_GCG_DS_DECK_INVALID = 12207; + RET_GCG_DS_CARD_ID_INVALID = 12208; + RET_GCG_DS_CARD_FACE_ALREADY_UNLOCK = 12209; + RET_GCG_DS_CARD_FACE_IS_LOCK = 12210; + RET_GCG_DS_FIELD_LOCK = 12211; + RET_GCG_DS_FIELD_ALREADY_UNLOCK = 12212; + RET_GCG_DS_FIELD_ID_INVALID = 12213; + RET_GCG_DS_CARD_BACK_LOCKED = 12214; + RET_GCG_DS_CARD_BACK_ALREADY_UNLOCK = 12215; + RET_GCG_DS_CARD_BACK_ID_INVALID = 12216; + RET_GCG_DS_CARD_FACE_ID_INVALID = 12217; + RET_GCG_DS_DECK_NAME_ILLEGAL = 12218; + RET_GCG_DS_DECK_SAVE_CD = 12219; + RET_GCG_DS_DECK_CHANGE_NAME_CD = 12220; + RET_GCG_MATCH_DECK_INVALID = 12221; + RET_GCG_DS_DECK_ALREADY_UNLOCKED = 12222; + RET_GCG_DS_AT_LEAST_ONE_DECK = 12223; + RET_GCG_TC_CHARACTERNOT_MATCH_LEVEL = 12251; + RET_GCG_TC_MUST_IN_SELF_WORLD = 12252; + RET_GCG_TC_MUST_IN_TAVERN = 12253; + RET_GCG_TC_ALREADY_IN_GAME = 12254; + RET_GCG_TC_ALREADY_IN_MATCH = 12255; + RET_GCG_TC_UNLOCK_CHARACTER_QUEST_NOT_FINISH = 12256; + RET_GCG_TC_LEVEL_LOCKED = 12257; + RET_GCG_TC_NO_INVITE_DATA = 12258; + RET_GCG_TC_CUR_DECK_INVALID = 12259; + RET_GCG_TC_COND_QUEST = 12260; + RET_GCG_LEVEL_REWARD_LEVEL_ERROR = 12301; + RET_GCG_LEVEL_REWARD_ALREADY_TAKEN = 12302; + RET_GCG_LEVEL_REWARD_NO_REWARD = 12303; +} diff --git a/NahidaImpact.Protocol/RetryCurRogueDiaryDungeonReq.proto b/NahidaImpact.Protocol/RetryCurRogueDiaryDungeonReq.proto new file mode 100644 index 0000000..e317ce1 --- /dev/null +++ b/NahidaImpact.Protocol/RetryCurRogueDiaryDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 9419 +// Obf: GOIMDLOHIDB +message RetryCurRogueDiaryDungeonReq { +} diff --git a/NahidaImpact.Protocol/ReunionBriefInfoReq.proto b/NahidaImpact.Protocol/ReunionBriefInfoReq.proto new file mode 100644 index 0000000..41d387e --- /dev/null +++ b/NahidaImpact.Protocol/ReunionBriefInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 27557 +// Obf: KPHAJMCKDFC +message ReunionBriefInfoReq { +} diff --git a/NahidaImpact.Protocol/ReunionSettleNotify.proto b/NahidaImpact.Protocol/ReunionSettleNotify.proto new file mode 100644 index 0000000..288f9e4 --- /dev/null +++ b/NahidaImpact.Protocol/ReunionSettleNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 28864 +// Obf: CCOAMGKAFMI +message ReunionSettleNotify { +} diff --git a/NahidaImpact.Protocol/Reward.proto b/NahidaImpact.Protocol/Reward.proto new file mode 100644 index 0000000..7978598 --- /dev/null +++ b/NahidaImpact.Protocol/Reward.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +import "ItemParam.proto"; +// Obf: HKODPBNKBHM +message Reward { + uint32 reward_id = 1; + repeated ItemParam item_list = 2; +} diff --git a/NahidaImpact.Protocol/RogueCellState.proto b/NahidaImpact.Protocol/RogueCellState.proto new file mode 100644 index 0000000..2b5a8ad --- /dev/null +++ b/NahidaImpact.Protocol/RogueCellState.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +// Obf: JEOOKNEBNDN +enum RogueCellState { + ROGUE_CELL_NONE = 0; + ROGUE_CELL_BATTLE = 1; + ROGUE_CELL_SUCCESS = 2; + ROGUE_CELL_FINISH = 3; + ROGUE_CELL_TAKEN_CHEST = 4; +} diff --git a/NahidaImpact.Protocol/RogueDiaryAvatarDisableStatus.proto b/NahidaImpact.Protocol/RogueDiaryAvatarDisableStatus.proto new file mode 100644 index 0000000..4881446 --- /dev/null +++ b/NahidaImpact.Protocol/RogueDiaryAvatarDisableStatus.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: LPHEHBBIBOG +enum RogueDiaryAvatarDisableStatus { + ROGUE_DIARY_AVATAR_DISABLE_NONE = 0; + ROGUE_DIARY_AVATAR_DISABLE_DEATH = 1; + ROGUE_DIARY_AVATAR_DISABLE_TIRED = 2; + ROGUE_DIARY_AVATAR_DISABLE_DUPLICATED = 3; +} diff --git a/NahidaImpact.Protocol/RogueEliteCellDifficultyType.proto b/NahidaImpact.Protocol/RogueEliteCellDifficultyType.proto new file mode 100644 index 0000000..02df1af --- /dev/null +++ b/NahidaImpact.Protocol/RogueEliteCellDifficultyType.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: ICMLDBMKFPC +enum RogueEliteCellDifficultyType { + ROGUE_ELITE_NORMAL = 0; + ROGUE_ELITE_HARD = 1; +} diff --git a/NahidaImpact.Protocol/RoguelikeGadgetInfo.proto b/NahidaImpact.Protocol/RoguelikeGadgetInfo.proto new file mode 100644 index 0000000..9200871 --- /dev/null +++ b/NahidaImpact.Protocol/RoguelikeGadgetInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +message RoguelikeGadgetInfo { + uint32 cell_config_id = 1; + uint32 cell_state = 3; + uint32 cell_id = 4; + uint32 cell_type = 2; +} diff --git a/NahidaImpact.Protocol/RoguelikeMistClearNotify.proto b/NahidaImpact.Protocol/RoguelikeMistClearNotify.proto new file mode 100644 index 0000000..37250e6 --- /dev/null +++ b/NahidaImpact.Protocol/RoguelikeMistClearNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 27988 +// Obf: GJEHOHLDKCF +message RoguelikeMistClearNotify { +} diff --git a/NahidaImpact.Protocol/Route.proto b/NahidaImpact.Protocol/Route.proto new file mode 100644 index 0000000..3d2df0a --- /dev/null +++ b/NahidaImpact.Protocol/Route.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + + +import "RoutePoint.proto"; + +message Route { + repeated RoutePoint route_points = 1; + uint32 route_type = 2; +} diff --git a/NahidaImpact.Protocol/RoutePoint.proto b/NahidaImpact.Protocol/RoutePoint.proto new file mode 100644 index 0000000..fcd5661 --- /dev/null +++ b/NahidaImpact.Protocol/RoutePoint.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + + +import "Vector.proto"; +import "MathQuaternion.proto"; + +message RoutePoint { + oneof move_params { + float velocity = 11; + float time = 12; + } + oneof rotate_params { + Vector rotation = 21; + MathQuaternion rotation_speed = 22; + MathQuaternion axis_speed = 23; + } + Vector position = 1; + float arrive_range = 2; + bool has_reach_event = 3; +} diff --git a/NahidaImpact.Protocol/SalesmanStatusType.proto b/NahidaImpact.Protocol/SalesmanStatusType.proto new file mode 100644 index 0000000..d764d12 --- /dev/null +++ b/NahidaImpact.Protocol/SalesmanStatusType.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: IGGCOLMGDPL +enum SalesmanStatusType { + SALESMAN_STATUS_NONE = 0; + SALESMAN_STATUS_UNSTARTED = 1; + SALESMAN_STATUS_STARTED = 2; + SALESMAN_STATUS_DELIVERED = 3; +} diff --git a/NahidaImpact.Protocol/SalvageEscortStopReason.proto b/NahidaImpact.Protocol/SalvageEscortStopReason.proto new file mode 100644 index 0000000..a2505a0 --- /dev/null +++ b/NahidaImpact.Protocol/SalvageEscortStopReason.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +// Obf: IEFIFHKIGNC +enum SalvageEscortStopReason { + SALVAGE_ESCORT_STOP_NONE = 0; + SALVAGE_ESCORT_STOP_SUCCESS = 1; + SALVAGE_ESCORT_STOP_DUMP = 2; + SALVAGE_ESCORT_STOP_TIME = 3; + SALVAGE_ESCORT_STOP_INTERRUPT = 4; + SALVAGE_ESCORT_STOP_LEAVE = 5; + SALVAGE_ESCORT_STOP_FULL = 6; +} diff --git a/NahidaImpact.Protocol/SalvagePreventStopReason.proto b/NahidaImpact.Protocol/SalvagePreventStopReason.proto new file mode 100644 index 0000000..39475aa --- /dev/null +++ b/NahidaImpact.Protocol/SalvagePreventStopReason.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +// Obf: MPKIGDOAHIH +enum SalvagePreventStopReason { + SALVAGE_PREVENT_STOP_NONE = 0; + SALVAGE_PREVENT_STOP_SUCCESS = 1; + SALVAGE_PREVENT_STOP_ARRIVAL = 2; + SALVAGE_PREVENT_STOP_INTERRUPT = 3; + SALVAGE_PREVENT_STOP_LEAVE = 4; + SALVAGE_PREVENT_STOP_FULL = 5; + SALVAGE_PREVENT_STOP_AWAY = 6; +} diff --git a/NahidaImpact.Protocol/SceneAvatarInfo.proto b/NahidaImpact.Protocol/SceneAvatarInfo.proto new file mode 100644 index 0000000..339e0e6 --- /dev/null +++ b/NahidaImpact.Protocol/SceneAvatarInfo.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; + + +import "SceneWeaponInfo.proto"; +import "SceneReliquaryInfo.proto"; +import "ServerBuff.proto"; +import "AvatarExcelInfo.proto"; +import "CurVehicleInfo.proto"; + +message SceneAvatarInfo { + repeated SceneReliquaryInfo reliquary_list = 9; + repeated uint32 inherent_proud_skill_list = 12; + SceneWeaponInfo weapon = 8; + map proud_skill_extra_level_map = 14; + repeated uint32 equip_id_list = 5; + map skill_level_map = 13; + repeated uint32 talent_id_list = 7; + repeated ServerBuff server_buff_list = 15; + repeated uint32 team_resonance_list = 16; + AvatarExcelInfo excel_info = 21; + CurVehicleInfo cur_vehicle_info = 20; + uint32 costume_id = 19; + uint32 peer_id = 4; + uint32 avatar_id = 2; + uint32 anim_hash = 22; + uint32 skill_depot_id = 6; + uint32 born_time = 18; + uint32 wearing_flycloak_id = 17; + uint32 core_proud_skill_level = 11; + uint32 uid = 1; + uint64 guid = 3; +} diff --git a/NahidaImpact.Protocol/SceneDataNotify.proto b/NahidaImpact.Protocol/SceneDataNotify.proto new file mode 100644 index 0000000..3e4e6c5 --- /dev/null +++ b/NahidaImpact.Protocol/SceneDataNotify.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// CmdId: 27173 +// Obf: FMCKLLIGMCJ +message SceneDataNotify { + repeated string level_config_name_list = 14; + repeated uint32 scene_tag_id_list = 4; +} diff --git a/NahidaImpact.Protocol/SceneEntityAiInfo.proto b/NahidaImpact.Protocol/SceneEntityAiInfo.proto new file mode 100644 index 0000000..5f3a377 --- /dev/null +++ b/NahidaImpact.Protocol/SceneEntityAiInfo.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + + +import "ServantInfo.proto"; +import "Vector.proto"; + +message SceneEntityAiInfo { + map ai_threat_map = 5; + ServantInfo servant_info = 4; + map skill_group_cd_map = 6; + Vector born_pos = 2; + map skill_cd_map = 3; + bool is_ai_open = 1; + uint32 cur_tactic = 7; +} diff --git a/NahidaImpact.Protocol/SceneEntityAppearNotify.proto b/NahidaImpact.Protocol/SceneEntityAppearNotify.proto new file mode 100644 index 0000000..3d535cd --- /dev/null +++ b/NahidaImpact.Protocol/SceneEntityAppearNotify.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + + +import "SceneEntityInfo.proto"; +import "VisionType.proto"; + +message SceneEntityAppearNotify { + // CMD_ID = 21994 + repeated SceneEntityInfo entity_list = 4; + uint32 param = 8; + VisionType appear_type = 11; +} diff --git a/NahidaImpact.Protocol/SceneEntityDisappearNotify.proto b/NahidaImpact.Protocol/SceneEntityDisappearNotify.proto new file mode 100644 index 0000000..ef8e5d4 --- /dev/null +++ b/NahidaImpact.Protocol/SceneEntityDisappearNotify.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +import "VisionType.proto"; +// CmdId: 1787 +// Obf: GLPMBMHBAKI +message SceneEntityDisappearNotify { + repeated uint32 entity_list = 12; + VisionType disappear_type = 3; + uint32 param = 7; +} diff --git a/NahidaImpact.Protocol/SceneEntityDrownReq.proto b/NahidaImpact.Protocol/SceneEntityDrownReq.proto new file mode 100644 index 0000000..d89d414 --- /dev/null +++ b/NahidaImpact.Protocol/SceneEntityDrownReq.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message SceneEntityDrownReq { + uint32 entity_id = 14; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/SceneEntityInfo.proto b/NahidaImpact.Protocol/SceneEntityInfo.proto new file mode 100644 index 0000000..111fd24 --- /dev/null +++ b/NahidaImpact.Protocol/SceneEntityInfo.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + + +import "MotionInfo.proto"; +import "SceneAvatarInfo.proto"; +import "SceneMonsterInfo.proto"; +import "SceneNpcInfo.proto"; +import "EntityClientData.proto"; +import "SceneGadgetInfo.proto"; +import "EntityAuthorityInfo.proto"; +import "FightPropPair.proto"; +import "EntityEnvironmentInfo.proto"; +import "PropPair.proto"; +import "AnimatorParameterValueInfoPair.proto"; +import "ServerBuff.proto"; +import "ProtEntityType.proto"; + +message SceneEntityInfo { + oneof entity { + SceneAvatarInfo avatar = 10; + SceneMonsterInfo monster = 11; + SceneNpcInfo npc = 12; + SceneGadgetInfo gadget = 13; + } + EntityAuthorityInfo entity_authority_info = 21; + repeated FightPropPair fight_prop_list = 6; + string name = 3; + MotionInfo motion_info = 4; + EntityClientData entity_client_data = 19; + repeated EntityEnvironmentInfo entity_environment_info_list = 20; + repeated PropPair prop_list = 5; + repeated string tag_list = 22; + repeated AnimatorParameterValueInfoPair animator_para_list = 9; + repeated ServerBuff server_buff_list = 23; + ProtEntityType entity_type = 1; + uint32 life_state = 7; + uint32 entity_id = 2; + uint32 last_move_scene_time_ms = 17; + uint32 last_move_reliable_seq = 18; +} diff --git a/NahidaImpact.Protocol/SceneFishInfo.proto b/NahidaImpact.Protocol/SceneFishInfo.proto new file mode 100644 index 0000000..a59a7a6 --- /dev/null +++ b/NahidaImpact.Protocol/SceneFishInfo.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + + +import "Vector.proto"; + +message SceneFishInfo { + Vector fish_pool_pos = 3; + uint32 fish_pool_entity_id = 2; + uint32 last_shock_time = 5; + uint32 fish_pool_gadget_id = 4; + uint32 fish_id = 1; +} diff --git a/NahidaImpact.Protocol/SceneGadgetInfo.proto b/NahidaImpact.Protocol/SceneGadgetInfo.proto new file mode 100644 index 0000000..e48cd49 --- /dev/null +++ b/NahidaImpact.Protocol/SceneGadgetInfo.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; + + +import "GatherGadgetInfo.proto"; +import "Item.proto"; +import "BossChestInfo.proto"; +import "OfferingInfo.proto"; +import "WorktopInfo.proto"; +import "ClientGadgetInfo.proto"; +import "WeatherInfo.proto"; +import "GadgetBornType.proto"; +import "AbilityGadgetInfo.proto"; +import "StatueGadgetInfo.proto"; +import "BlossomChestInfo.proto"; +import "FoundationInfo.proto"; +import "MpPlayRewardInfo.proto"; +import "GadgetGeneralRewardInfo.proto"; +import "VehicleInfo.proto"; +import "EchoShellInfo.proto"; +import "ScreenInfo.proto"; +import "FishPoolInfo.proto"; +import "CustomGadgetTreeInfo.proto"; +import "RoguelikeGadgetInfo.proto"; +import "NightCrowGadgetInfo.proto"; +import "DeshretObeliskGadgetInfo.proto"; +import "CoinCollectOperatorInfo.proto"; +import "GadgetPlayInfo.proto"; +import "PlatformInfo.proto"; + +message SceneGadgetInfo { + oneof content { + Item trifle_item = 12; + GatherGadgetInfo gather_gadget = 13; + WorktopInfo worktop = 14; + ClientGadgetInfo client_gadget = 15; + WeatherInfo weather = 17; + AbilityGadgetInfo ability_gadget = 18; + StatueGadgetInfo statue_gadget = 19; + BossChestInfo boss_chest = 20; + BlossomChestInfo blossom_chest = 41; + MpPlayRewardInfo mp_play_reward = 42; + GadgetGeneralRewardInfo general_reward = 43; + OfferingInfo offering_info = 44; + FoundationInfo foundation_info = 45; + VehicleInfo vehicle_info = 46; + EchoShellInfo shell_info = 47; + ScreenInfo screen_info = 48; + FishPoolInfo fish_pool_info = 59; + CustomGadgetTreeInfo custom_gadget_tree_info = 60; + RoguelikeGadgetInfo roguelike_gadget_info = 61; + NightCrowGadgetInfo night_crow_gadget_info = 62; + DeshretObeliskGadgetInfo deshret_obelisk_gadget_info = 63; + CoinCollectOperatorInfo coin_collect_operator_info = 64; + } + repeated uint32 interact_uid_list = 24; + GadgetPlayInfo play_info = 100; + PlatformInfo platform = 23; + uint32 prop_owner_entity_id = 22; + uint32 owner_entity_id = 4; + uint32 interact_id = 11; + uint32 mark_flag = 21; + uint32 group_id = 2; + uint32 gadget_type = 7; + uint32 authority_peer_id = 9; + uint32 config_id = 3; + bool is_enable_interact = 10; + bool is_show_cutscene = 8; + uint32 gadget_talk_state = 26; + uint32 gadget_state = 6; + uint32 draft_id = 25; + uint32 gadget_id = 1; + GadgetBornType born_type = 5; +} diff --git a/NahidaImpact.Protocol/SceneInitFinishReq.proto b/NahidaImpact.Protocol/SceneInitFinishReq.proto new file mode 100644 index 0000000..ed3dff2 --- /dev/null +++ b/NahidaImpact.Protocol/SceneInitFinishReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message SceneInitFinishReq { + // CMD_ID = 8917 + uint32 enter_scene_token = 5; +} diff --git a/NahidaImpact.Protocol/SceneInitFinishRsp.proto b/NahidaImpact.Protocol/SceneInitFinishRsp.proto new file mode 100644 index 0000000..182ad52 --- /dev/null +++ b/NahidaImpact.Protocol/SceneInitFinishRsp.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message SceneInitFinishRsp { + // CMD_ID = 9212 + int32 retcode = 1; + uint32 enter_scene_token = 4; +} diff --git a/NahidaImpact.Protocol/SceneMonsterInfo.proto b/NahidaImpact.Protocol/SceneMonsterInfo.proto new file mode 100644 index 0000000..68dc41a --- /dev/null +++ b/NahidaImpact.Protocol/SceneMonsterInfo.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + + +import "SceneFishInfo.proto"; +import "SceneWeaponInfo.proto"; +import "FishtankFishInfo.proto"; +import "MonsterRoute.proto"; +import "MonsterBornType.proto"; + +message SceneMonsterInfo { + oneof content { + SceneFishInfo fish_info = 50; + FishtankFishInfo fishtank_fish_info = 51; + } + repeated uint32 affix_list = 6; + map summon_tag_map = 10; + repeated SceneWeaponInfo weapon_list = 4; + MonsterRoute monster_route = 18; + uint32 owner_entity_id = 8; + uint32 attack_target_id = 17; + uint32 pose_id = 11; + uint32 summoned_tag = 9; + uint32 group_id = 2; + uint32 monster_id = 1; + uint32 mark_flag = 14; + uint32 level_route_id = 20; + uint32 ai_config_id = 19; + uint32 title_id = 15; + uint32 special_name_id = 16; + uint32 kill_num = 23; + uint32 config_id = 3; + MonsterBornType born_type = 12; + bool is_elite = 7; + bool is_light = 22; + uint32 block_id = 13; + uint32 init_pose_id = 21; + uint32 authority_peer_id = 5; +} diff --git a/NahidaImpact.Protocol/SceneNpcInfo.proto b/NahidaImpact.Protocol/SceneNpcInfo.proto new file mode 100644 index 0000000..ceb0db2 --- /dev/null +++ b/NahidaImpact.Protocol/SceneNpcInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +message SceneNpcInfo { + uint32 room_id = 2; + uint32 parent_quest_id = 3; + uint32 npc_id = 1; + uint32 block_id = 4; +} diff --git a/NahidaImpact.Protocol/ScenePointUnlockNotify.proto b/NahidaImpact.Protocol/ScenePointUnlockNotify.proto new file mode 100644 index 0000000..e1aa723 --- /dev/null +++ b/NahidaImpact.Protocol/ScenePointUnlockNotify.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +// CmdId: 5431 +// Obf: CBIBGAOCEHP +message ScenePointUnlockNotify { + repeated uint32 point_list = 7; + repeated uint32 LLLMNLAJJCO = 15; + repeated uint32 GBLBKADHGDM = 4; + repeated uint32 HJEKKPGBJBM = 12; + uint32 scene_id = 13; +} diff --git a/NahidaImpact.Protocol/SceneReliquaryInfo.proto b/NahidaImpact.Protocol/SceneReliquaryInfo.proto new file mode 100644 index 0000000..251dd0e --- /dev/null +++ b/NahidaImpact.Protocol/SceneReliquaryInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +message SceneReliquaryInfo { + uint32 level = 3; + uint32 item_id = 1; + uint32 promote_level = 4; + uint64 guid = 2; +} diff --git a/NahidaImpact.Protocol/SceneTeamAvatar.proto b/NahidaImpact.Protocol/SceneTeamAvatar.proto new file mode 100644 index 0000000..8ee868e --- /dev/null +++ b/NahidaImpact.Protocol/SceneTeamAvatar.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + + +import "AbilitySyncStateInfo.proto"; +import "SceneAvatarInfo.proto"; +import "AbilityControlBlock.proto"; +import "ServerBuff.proto"; +import "AvatarInfo.proto"; +import "SceneEntityInfo.proto"; + +message SceneTeamAvatar { + SceneAvatarInfo scene_avatar_info = 3; + AbilityControlBlock ability_control_block = 6; + repeated ServerBuff server_buff_list = 9; + SceneEntityInfo scene_entity_info = 13; + AvatarInfo avatar_info = 7; + uint32 entity_id = 4; + uint32 weapon_entity_id = 2; + uint64 avatar_guid = 14; + uint64 weapon_guid = 1; + uint32 scene_id = 5; + uint32 player_uid = 8; +} diff --git a/NahidaImpact.Protocol/SceneTeamUpdateNotify.proto b/NahidaImpact.Protocol/SceneTeamUpdateNotify.proto new file mode 100644 index 0000000..4fd3d30 --- /dev/null +++ b/NahidaImpact.Protocol/SceneTeamUpdateNotify.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + + +import "SceneTeamAvatar.proto"; + +message SceneTeamUpdateNotify { + // CMD_ID = 5835 + repeated SceneTeamAvatar scene_team_avatar_list = 11; + bool is_in_mp = 14; +} diff --git a/NahidaImpact.Protocol/SceneTimeNotify.proto b/NahidaImpact.Protocol/SceneTimeNotify.proto new file mode 100644 index 0000000..ff43f3d --- /dev/null +++ b/NahidaImpact.Protocol/SceneTimeNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + + +message SceneTimeNotify { + uint32 scene_id = 2; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/SceneTransToPointReq.proto b/NahidaImpact.Protocol/SceneTransToPointReq.proto new file mode 100644 index 0000000..fd69aa9 --- /dev/null +++ b/NahidaImpact.Protocol/SceneTransToPointReq.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// CmdId: 26498 +// Obf: EBDJGELLMOF +message SceneTransToPointReq { + uint32 scene_id = 4; + uint32 point_id = 1; +} diff --git a/NahidaImpact.Protocol/SceneTransToPointRsp.proto b/NahidaImpact.Protocol/SceneTransToPointRsp.proto new file mode 100644 index 0000000..9de7a12 --- /dev/null +++ b/NahidaImpact.Protocol/SceneTransToPointRsp.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// CmdId: 28443 +// Obf: GNAGNBFBJEB +message SceneTransToPointRsp { + int32 retcode = 12; + uint32 point_id = 10; + uint32 scene_id = 4; +} diff --git a/NahidaImpact.Protocol/SceneWeaponInfo.proto b/NahidaImpact.Protocol/SceneWeaponInfo.proto new file mode 100644 index 0000000..9dcdd33 --- /dev/null +++ b/NahidaImpact.Protocol/SceneWeaponInfo.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + + +import "AbilitySyncStateInfo.proto"; +import "EntityRendererChangedInfo.proto"; + +message SceneWeaponInfo { + map affix_map = 8; + AbilitySyncStateInfo ability_info = 7; + EntityRendererChangedInfo renderer_changed_info = 9; + uint32 item_id = 3; + uint32 promote_level = 6; + uint32 entity_id = 1; + uint32 level = 5; + uint32 gadget_id = 2; + uint64 guid = 4; +} diff --git a/NahidaImpact.Protocol/ScreenInfo.proto b/NahidaImpact.Protocol/ScreenInfo.proto new file mode 100644 index 0000000..6aa684b --- /dev/null +++ b/NahidaImpact.Protocol/ScreenInfo.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message ScreenInfo { + uint32 projector_entity_id = 2; + uint32 live_id = 1; +} diff --git a/NahidaImpact.Protocol/SealBattleType.proto b/NahidaImpact.Protocol/SealBattleType.proto new file mode 100644 index 0000000..ccbcb91 --- /dev/null +++ b/NahidaImpact.Protocol/SealBattleType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: EAMEAGLMOEM +enum SealBattleType { + SEAL_BATTLE_KEEP_ALIVE = 0; + SEAL_BATTLE_KILL_MONSTER = 1; + SEAL_BATTLE_ENERGY_CHARGE = 2; +} diff --git a/NahidaImpact.Protocol/ServantInfo.proto b/NahidaImpact.Protocol/ServantInfo.proto new file mode 100644 index 0000000..6cd2147 --- /dev/null +++ b/NahidaImpact.Protocol/ServantInfo.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message ServantInfo { + uint32 master_entity_id = 1; + uint32 born_slot_index = 2; +} diff --git a/NahidaImpact.Protocol/ServerBuff.proto b/NahidaImpact.Protocol/ServerBuff.proto new file mode 100644 index 0000000..858a1ee --- /dev/null +++ b/NahidaImpact.Protocol/ServerBuff.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +message ServerBuff { + uint32 server_buff_type = 3; + uint32 instanced_modifier_id = 4; + uint32 server_buff_id = 2; + uint32 server_buff_uid = 1; + bool is_modifier_added = 5; +} diff --git a/NahidaImpact.Protocol/ServerGlobalValueChangeNotify.proto b/NahidaImpact.Protocol/ServerGlobalValueChangeNotify.proto new file mode 100644 index 0000000..6dd9f47 --- /dev/null +++ b/NahidaImpact.Protocol/ServerGlobalValueChangeNotify.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// CmdId: 28698 +// Obf: GKKPLLOCNMC +message ServerGlobalValueChangeNotify { + float value = 9; + uint32 key_hash = 13; + uint32 entity_id = 7; +} diff --git a/NahidaImpact.Protocol/ServerLogLevel.proto b/NahidaImpact.Protocol/ServerLogLevel.proto new file mode 100644 index 0000000..cb81c35 --- /dev/null +++ b/NahidaImpact.Protocol/ServerLogLevel.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +// Obf: AEKKKMKLLKD +enum ServerLogLevel { + LOG_LEVEL_NONE = 0; + LOG_LEVEL_DEBUG = 1; + LOG_LEVEL_INFO = 2; + LOG_LEVEL_WARNING = 3; + LOG_LEVEL_ERROR = 4; +} diff --git a/NahidaImpact.Protocol/ServerLogType.proto b/NahidaImpact.Protocol/ServerLogType.proto new file mode 100644 index 0000000..ba51d78 --- /dev/null +++ b/NahidaImpact.Protocol/ServerLogType.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +// Obf: DEJFCBNPEJO +enum ServerLogType { + SERVER_LOG_NONE = 0; + SERVER_LOG_ABILITY = 1; + SERVER_LOG_LEVEL = 2; + SERVER_LOG_ENTITY = 3; + SERVER_LOG_LUA = 4; +} diff --git a/NahidaImpact.Protocol/ServerMassiveEntity.proto b/NahidaImpact.Protocol/ServerMassiveEntity.proto new file mode 100644 index 0000000..85f73a8 --- /dev/null +++ b/NahidaImpact.Protocol/ServerMassiveEntity.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +import "MassiveWaterInfo.proto"; +import "MassiveGrassInfo.proto"; +import "MassiveBoxInfo.proto"; +// Obf: JEJIJKEBLHM +message ServerMassiveEntity { + uint32 entity_type = 1; + uint32 config_id = 2; + uint32 runtime_id = 3; + uint32 authority_peer_id = 4; + int64 obj_id = 5; + oneof entity_info { + MassiveWaterInfo water_info = 6; + MassiveGrassInfo grass_info = 7; + MassiveBoxInfo box_info = 8; + } +} diff --git a/NahidaImpact.Protocol/SetNameCardReq.proto b/NahidaImpact.Protocol/SetNameCardReq.proto new file mode 100644 index 0000000..f907434 --- /dev/null +++ b/NahidaImpact.Protocol/SetNameCardReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + + +message SetNameCardReq { + uint32 name_card_id = 12; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/SetNameCardRsp.proto b/NahidaImpact.Protocol/SetNameCardRsp.proto new file mode 100644 index 0000000..e8bc8f6 --- /dev/null +++ b/NahidaImpact.Protocol/SetNameCardRsp.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + + +message SetNameCardRsp { + uint32 name_card_id = 1; + int32 retcode = 14; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/SetOpenStateReq.proto b/NahidaImpact.Protocol/SetOpenStateReq.proto new file mode 100644 index 0000000..ac3465c --- /dev/null +++ b/NahidaImpact.Protocol/SetOpenStateReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message SetOpenStateReq { + uint32 key = 10; + uint32 value = 6; +} diff --git a/NahidaImpact.Protocol/SetOpenStateRsp.proto b/NahidaImpact.Protocol/SetOpenStateRsp.proto new file mode 100644 index 0000000..971719c --- /dev/null +++ b/NahidaImpact.Protocol/SetOpenStateRsp.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + + +message SetOpenStateRsp { + int32 retcode = 2; + uint32 key = 9; + uint32 value = 1; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/SetPlayerBornDataReq.proto b/NahidaImpact.Protocol/SetPlayerBornDataReq.proto new file mode 100644 index 0000000..1d7c19c --- /dev/null +++ b/NahidaImpact.Protocol/SetPlayerBornDataReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message SetPlayerBornDataReq { + string nick_name = 3; + uint32 avatar_id = 6; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/SetPlayerBornDataRsp.proto b/NahidaImpact.Protocol/SetPlayerBornDataRsp.proto new file mode 100644 index 0000000..77c04fe --- /dev/null +++ b/NahidaImpact.Protocol/SetPlayerBornDataRsp.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// CmdId: 22804 +// Obf: CGFIJAMAKEG +message SetPlayerBornDataRsp { + int32 retcode = 3; +} diff --git a/NahidaImpact.Protocol/SetPlayerNameReq.proto b/NahidaImpact.Protocol/SetPlayerNameReq.proto new file mode 100644 index 0000000..4667c08 --- /dev/null +++ b/NahidaImpact.Protocol/SetPlayerNameReq.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message SetPlayerNameReq { + string nick_name = 10; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/SetPlayerPropRsp.proto b/NahidaImpact.Protocol/SetPlayerPropRsp.proto new file mode 100644 index 0000000..586a7dd --- /dev/null +++ b/NahidaImpact.Protocol/SetPlayerPropRsp.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + + +message SetPlayerPropRsp { + int32 retcode = 4; +} diff --git a/NahidaImpact.Protocol/SetUpAvatarTeamReq.proto b/NahidaImpact.Protocol/SetUpAvatarTeamReq.proto new file mode 100644 index 0000000..cb10cc1 --- /dev/null +++ b/NahidaImpact.Protocol/SetUpAvatarTeamReq.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + + +message SetUpAvatarTeamReq { + uint32 team_id = 4; + repeated uint64 avatar_team_guid_list = 11; + uint64 cur_avatar_guid = 15; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/SetUpAvatarTeamRsp.proto b/NahidaImpact.Protocol/SetUpAvatarTeamRsp.proto new file mode 100644 index 0000000..dfb070f --- /dev/null +++ b/NahidaImpact.Protocol/SetUpAvatarTeamRsp.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +// CmdId: 8572 +// Obf: CPNEKEDGLHM +message SetUpAvatarTeamRsp { + uint32 team_id = 11; + uint64 cur_avatar_guid =5; + repeated uint64 avatar_team_guid_list = 10; + int32 retcode = 4; +} diff --git a/NahidaImpact.Protocol/SetWidgetSlotReq.proto b/NahidaImpact.Protocol/SetWidgetSlotReq.proto new file mode 100644 index 0000000..ca6f9c5 --- /dev/null +++ b/NahidaImpact.Protocol/SetWidgetSlotReq.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "WidgetSlotOp.proto"; +import "WidgetSlotTag.proto"; +message SetWidgetSlotReq { + uint32 material_id = 12; + WidgetSlotOp op = 9; + repeated WidgetSlotTag tag_list = 8; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/SetWidgetSlotRsp.proto b/NahidaImpact.Protocol/SetWidgetSlotRsp.proto new file mode 100644 index 0000000..6e80ad9 --- /dev/null +++ b/NahidaImpact.Protocol/SetWidgetSlotRsp.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +import "WidgetSlotTag.proto"; +import "WidgetSlotOp.proto"; + +message SetWidgetSlotRsp { + int32 retcode = 7; + repeated WidgetSlotTag tag_list = 5; + uint32 material_id = 8; + WidgetSlotOp op = 14; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/ShapeBox.proto b/NahidaImpact.Protocol/ShapeBox.proto new file mode 100644 index 0000000..13e895b --- /dev/null +++ b/NahidaImpact.Protocol/ShapeBox.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +import "Vector.proto"; +// Obf: BFCLKLDHKOM +message ShapeBox { + Vector center = 1; + Vector axis0 = 2; + Vector axis1 = 3; + Vector axis2 = 4; + Vector extents = 5; +} diff --git a/NahidaImpact.Protocol/ShapeSphere.proto b/NahidaImpact.Protocol/ShapeSphere.proto new file mode 100644 index 0000000..ae66792 --- /dev/null +++ b/NahidaImpact.Protocol/ShapeSphere.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +import "Vector.proto"; +// Obf: KJNACIDANGB +message ShapeSphere { + Vector center = 1; + float radius = 2; +} diff --git a/NahidaImpact.Protocol/ShopCardProduct.proto b/NahidaImpact.Protocol/ShopCardProduct.proto new file mode 100644 index 0000000..13979eb --- /dev/null +++ b/NahidaImpact.Protocol/ShopCardProduct.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +import "ItemParam.proto"; +// Obf: LJJFPCDLGIJ +message ShopCardProduct { + // Obf: JIBALNEIBIK + message ResinCard { + repeated ItemParam base_item_list = 1; + repeated ItemParam per_day_item_list = 2; + } + + string product_id = 1; + string price_tier = 2; + uint32 mcoin_base = 3; + uint32 hcoin_per_day = 4; + uint32 days = 5; + uint32 remain_reward_days = 6; + uint32 card_product_type = 7; + optional ResinCard resin_card = 101; +} diff --git a/NahidaImpact.Protocol/ShopConcertProduct.proto b/NahidaImpact.Protocol/ShopConcertProduct.proto new file mode 100644 index 0000000..c19d77e --- /dev/null +++ b/NahidaImpact.Protocol/ShopConcertProduct.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +// Obf: ABHPGEAODHI +message ShopConcertProduct { + string product_id = 1; + string price_tier = 2; + uint32 obtain_count = 3; + uint32 obtain_limit = 4; + uint32 begin_time = 5; + uint32 end_time = 6; + uint32 buy_times = 7; +} diff --git a/NahidaImpact.Protocol/ShopMcoinProduct.proto b/NahidaImpact.Protocol/ShopMcoinProduct.proto new file mode 100644 index 0000000..c8e1928 --- /dev/null +++ b/NahidaImpact.Protocol/ShopMcoinProduct.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +// Obf: BNMNBLNCBIG +message ShopMcoinProduct { + string product_id = 1; + string price_tier = 2; + uint32 mcoin_base = 3; + uint32 mcoin_non_first = 4; + uint32 mcoin_first = 5; + uint32 bought_num = 6; + bool is_audit = 7; +} diff --git a/NahidaImpact.Protocol/ShortAbilityHashPair.proto b/NahidaImpact.Protocol/ShortAbilityHashPair.proto new file mode 100644 index 0000000..d580a79 --- /dev/null +++ b/NahidaImpact.Protocol/ShortAbilityHashPair.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message ShortAbilityHashPair { + sfixed32 ability_config_hash = 14; + sfixed32 ability_name_hash = 13; +} diff --git a/NahidaImpact.Protocol/ShowAvatarInfo.proto b/NahidaImpact.Protocol/ShowAvatarInfo.proto new file mode 100644 index 0000000..ff2c1ae --- /dev/null +++ b/NahidaImpact.Protocol/ShowAvatarInfo.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +import "PropValue.proto"; +import "ShowEquip.proto"; +import "AvatarFetterInfo.proto"; +import "AvatarExcelInfo.proto"; +// Obf: BHNAGPHOKLL +message ShowAvatarInfo { + uint32 avatar_id = 1; + map prop_map = 2; + repeated uint32 talent_id_list = 3; + map fight_prop_map = 4; + uint32 skill_depot_id = 5; + uint32 core_proud_skill_level = 6; + repeated uint32 inherent_proud_skill_list = 7; + map skill_level_map = 8; + map proud_skill_extra_level_map = 9; + repeated ShowEquip equip_list = 10; + AvatarFetterInfo fetter_info = 11; + uint32 costume_id = 12; + AvatarExcelInfo excel_info = 13; +} diff --git a/NahidaImpact.Protocol/ShowEquip.proto b/NahidaImpact.Protocol/ShowEquip.proto new file mode 100644 index 0000000..ed55b64 --- /dev/null +++ b/NahidaImpact.Protocol/ShowEquip.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +import "Reliquary.proto"; +import "Weapon.proto"; +// Obf: OJMNHOEOFAN +message ShowEquip { + uint32 item_id = 1; + oneof detail { + Reliquary reliquary = 2; + Weapon weapon = 3; + } +} diff --git a/NahidaImpact.Protocol/SignInInfoReq.proto b/NahidaImpact.Protocol/SignInInfoReq.proto new file mode 100644 index 0000000..eb5cc2f --- /dev/null +++ b/NahidaImpact.Protocol/SignInInfoReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 1091 +// Obf: LEEKMMIELMG +message SignInInfoReq { +} diff --git a/NahidaImpact.Protocol/SocialDetail.proto b/NahidaImpact.Protocol/SocialDetail.proto new file mode 100644 index 0000000..36433cf --- /dev/null +++ b/NahidaImpact.Protocol/SocialDetail.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + + + + +import "Birthday.proto"; +import "FriendOnlineState.proto"; +import "SocialShowAvatarInfo.proto"; +import "FriendEnterHomeOption.proto"; +import "ProfilePicture.proto"; +message SocialDetail { + uint32 uid = 1; + string nickname = 2; + uint32 level = 3; + uint32 avatar_id = 4; + string signature = 5; + Birthday birthday = 6; + uint32 world_level = 7; + repeated uint32 reserved_list = 8; + FriendOnlineState online_state = 9; + uint32 param = 10; + bool is_friend = 11; + bool is_mp_mode_available = 12; + string online_id = 13; + uint32 name_card_id = 14; + bool is_in_blacklist = 15; + bool is_chat_no_disturb = 16; + string remark_name = 17; + uint32 finish_achievement_num = 18; + uint32 tower_floor_index = 19; + uint32 tower_level_index = 20; + bool is_show_avatar = 21; + repeated SocialShowAvatarInfo show_avatar_info_list = 22; + repeated uint32 show_name_card_id_list = 23; + FriendEnterHomeOption friend_enter_home_option = 24; + ProfilePicture profile_picture = 25; + string ip_code = 26; +} diff --git a/NahidaImpact.Protocol/SocialShowAvatarInfo.proto b/NahidaImpact.Protocol/SocialShowAvatarInfo.proto new file mode 100644 index 0000000..e292329 --- /dev/null +++ b/NahidaImpact.Protocol/SocialShowAvatarInfo.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + + + + +message SocialShowAvatarInfo { + uint32 avatar_id = 1; + uint32 level = 2; + uint32 costume_id = 3; +} diff --git a/NahidaImpact.Protocol/StatueGadgetInfo.proto b/NahidaImpact.Protocol/StatueGadgetInfo.proto new file mode 100644 index 0000000..0c3d3ae --- /dev/null +++ b/NahidaImpact.Protocol/StatueGadgetInfo.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message StatueGadgetInfo { + repeated uint32 opened_statue_uid_list = 1; +} diff --git a/NahidaImpact.Protocol/StopServerInfo.proto b/NahidaImpact.Protocol/StopServerInfo.proto new file mode 100644 index 0000000..df443b7 --- /dev/null +++ b/NahidaImpact.Protocol/StopServerInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +message StopServerInfo { + string content_msg = 4; + string url = 3; + uint32 stop_begin_time = 1; + uint32 stop_end_time = 2; +} diff --git a/NahidaImpact.Protocol/StoreType.proto b/NahidaImpact.Protocol/StoreType.proto new file mode 100644 index 0000000..643eca5 --- /dev/null +++ b/NahidaImpact.Protocol/StoreType.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + + + + +enum StoreType { + StoreType_StoreNone = 0; + StoreType_StorePack = 1; + StoreType_StoreDepot = 2; +} diff --git a/NahidaImpact.Protocol/StoreWeightLimitNotify.proto b/NahidaImpact.Protocol/StoreWeightLimitNotify.proto new file mode 100644 index 0000000..7232da7 --- /dev/null +++ b/NahidaImpact.Protocol/StoreWeightLimitNotify.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +import "StoreType.proto"; +// CmdId: 21113 +// Obf: FNKANKNBOBD +message StoreWeightLimitNotify { + uint32 weight_limit = 2; + StoreType store_type = 11; + uint32 WeaponCountLimit = 7; //MEGLBHDLMDJ + uint32 material_count_limit = 10; + uint32 reliquary_count_limit = 15; + uint32 furniture_count_limit = 9; +} diff --git a/NahidaImpact.Protocol/SummerTimeV2RestartDungeonReq.proto b/NahidaImpact.Protocol/SummerTimeV2RestartDungeonReq.proto new file mode 100644 index 0000000..3ed9d3f --- /dev/null +++ b/NahidaImpact.Protocol/SummerTimeV2RestartDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 212 +// Obf: KHLOFPMBOOF +message SummerTimeV2RestartDungeonReq { +} diff --git a/NahidaImpact.Protocol/SumoLeaveDungeonNotify.proto b/NahidaImpact.Protocol/SumoLeaveDungeonNotify.proto new file mode 100644 index 0000000..3336b93 --- /dev/null +++ b/NahidaImpact.Protocol/SumoLeaveDungeonNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 4886 +// Obf: FEIBGIGLAKF +message SumoLeaveDungeonNotify { +} diff --git a/NahidaImpact.Protocol/SumoRestartDungeonReq.proto b/NahidaImpact.Protocol/SumoRestartDungeonReq.proto new file mode 100644 index 0000000..a30ecc4 --- /dev/null +++ b/NahidaImpact.Protocol/SumoRestartDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 23088 +// Obf: GKBLOJIHPFF +message SumoRestartDungeonReq { +} diff --git a/NahidaImpact.Protocol/SvrMsgId.proto b/NahidaImpact.Protocol/SvrMsgId.proto new file mode 100644 index 0000000..15d81c3 --- /dev/null +++ b/NahidaImpact.Protocol/SvrMsgId.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +// Obf: MGJMJBMPFPG +enum SvrMsgId { + MSG_UNKNOWN = 0; + MSG_BLOCK_REFRESH_COUNTDOWN = 1; + MSG_AVATAR_REVIVE_BY_STATUE = 2; + MSG_DAILY_TASK_REWARD_MAX_NUM = 3; + MSG_ROUTINE_TYPE_NOT_OPEN = 4; + MSG_ROUTINE_TYPE_REWARD_MAX_NUM = 5; + MSG_MECHANICUS_COIN_LIMIT = 6; +} diff --git a/NahidaImpact.Protocol/TakeFirstShareRewardReq.proto b/NahidaImpact.Protocol/TakeFirstShareRewardReq.proto new file mode 100644 index 0000000..adf19c6 --- /dev/null +++ b/NahidaImpact.Protocol/TakeFirstShareRewardReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 21051 +// Obf: DIMKBDPNMOC +message TakeFirstShareRewardReq { +} diff --git a/NahidaImpact.Protocol/TakeReunionFirstGiftRewardReq.proto b/NahidaImpact.Protocol/TakeReunionFirstGiftRewardReq.proto new file mode 100644 index 0000000..17569a8 --- /dev/null +++ b/NahidaImpact.Protocol/TakeReunionFirstGiftRewardReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 24987 +// Obf: NKLKOJKDGEH +message TakeReunionFirstGiftRewardReq { +} diff --git a/NahidaImpact.Protocol/TeamChainTakeCostumeRewardReq.proto b/NahidaImpact.Protocol/TeamChainTakeCostumeRewardReq.proto new file mode 100644 index 0000000..49a8388 --- /dev/null +++ b/NahidaImpact.Protocol/TeamChainTakeCostumeRewardReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 24365 +// Obf: CHFPHEEGLHP +message TeamChainTakeCostumeRewardReq { +} diff --git a/NahidaImpact.Protocol/TeamEnterSceneInfo.proto b/NahidaImpact.Protocol/TeamEnterSceneInfo.proto new file mode 100644 index 0000000..5a5ff60 --- /dev/null +++ b/NahidaImpact.Protocol/TeamEnterSceneInfo.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + + +import "AbilityControlBlock.proto"; +import "AbilitySyncStateInfo.proto"; + +message TeamEnterSceneInfo { + AbilityControlBlock ability_control_block = 1; + AbilitySyncStateInfo team_ability_info = 15; + uint32 team_entity_id = 12; +} diff --git a/NahidaImpact.Protocol/ToTheMoonPingNotify.proto b/NahidaImpact.Protocol/ToTheMoonPingNotify.proto new file mode 100644 index 0000000..bebd042 --- /dev/null +++ b/NahidaImpact.Protocol/ToTheMoonPingNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 6154 +// Obf: FONBLBBMKAG +message ToTheMoonPingNotify { +} diff --git a/NahidaImpact.Protocol/TowerMiddleLevelChangeTeamNotify.proto b/NahidaImpact.Protocol/TowerMiddleLevelChangeTeamNotify.proto new file mode 100644 index 0000000..2397600 --- /dev/null +++ b/NahidaImpact.Protocol/TowerMiddleLevelChangeTeamNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 2027 +// Obf: NMHAKMEJMMM +message TowerMiddleLevelChangeTeamNotify { +} diff --git a/NahidaImpact.Protocol/TowerRecordHandbookReq.proto b/NahidaImpact.Protocol/TowerRecordHandbookReq.proto new file mode 100644 index 0000000..b8aadcd --- /dev/null +++ b/NahidaImpact.Protocol/TowerRecordHandbookReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 2953 +// Obf: CAOMBJNDNGD +message TowerRecordHandbookReq { +} diff --git a/NahidaImpact.Protocol/TowerSurrenderReq.proto b/NahidaImpact.Protocol/TowerSurrenderReq.proto new file mode 100644 index 0000000..630ec11 --- /dev/null +++ b/NahidaImpact.Protocol/TowerSurrenderReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 22082 +// Obf: IJLOHKDGPCG +message TowerSurrenderReq { +} diff --git a/NahidaImpact.Protocol/TrackingIOInfo.proto b/NahidaImpact.Protocol/TrackingIOInfo.proto new file mode 100644 index 0000000..643e5ea --- /dev/null +++ b/NahidaImpact.Protocol/TrackingIOInfo.proto @@ -0,0 +1,4 @@ +syntax = "proto3"; + +message TrackingIOInfo { +} diff --git a/NahidaImpact.Protocol/TransmitReason.proto b/NahidaImpact.Protocol/TransmitReason.proto new file mode 100644 index 0000000..cd5acf0 --- /dev/null +++ b/NahidaImpact.Protocol/TransmitReason.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: GDDBIDNNPNO +enum TransmitReason { + TRANSMIT_NONE = 0; + TRANSMIT_QUEST = 1; +} diff --git a/NahidaImpact.Protocol/TreasureMapGuideTaskDoneNotify.proto b/NahidaImpact.Protocol/TreasureMapGuideTaskDoneNotify.proto new file mode 100644 index 0000000..7d88503 --- /dev/null +++ b/NahidaImpact.Protocol/TreasureMapGuideTaskDoneNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 1567 +// Obf: HKPFGBDPCLI +message TreasureMapGuideTaskDoneNotify { +} diff --git a/NahidaImpact.Protocol/TreasureMapMpChallengeNotify.proto b/NahidaImpact.Protocol/TreasureMapMpChallengeNotify.proto new file mode 100644 index 0000000..9784de6 --- /dev/null +++ b/NahidaImpact.Protocol/TreasureMapMpChallengeNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 8790 +// Obf: OKLHGHMKKHI +message TreasureMapMpChallengeNotify { +} diff --git a/NahidaImpact.Protocol/TreasureMapPreTaskDoneNotify.proto b/NahidaImpact.Protocol/TreasureMapPreTaskDoneNotify.proto new file mode 100644 index 0000000..48d9d1a --- /dev/null +++ b/NahidaImpact.Protocol/TreasureMapPreTaskDoneNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 20410 +// Obf: HJHMFJBJDIC +message TreasureMapPreTaskDoneNotify { +} diff --git a/NahidaImpact.Protocol/TrialAvatarActivityRewardDetailInfo.proto b/NahidaImpact.Protocol/TrialAvatarActivityRewardDetailInfo.proto new file mode 100644 index 0000000..1ff76c9 --- /dev/null +++ b/NahidaImpact.Protocol/TrialAvatarActivityRewardDetailInfo.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: PPLODNCPDAI +message TrialAvatarActivityRewardDetailInfo { + uint32 reward_id = 10; + bool HOMJOOPMEKC = 13; + bool MOJAMAJMDDM = 15; + uint32 trial_avatar_index_id = 6; +} diff --git a/NahidaImpact.Protocol/TrialAvatarGrantRecord.proto b/NahidaImpact.Protocol/TrialAvatarGrantRecord.proto new file mode 100644 index 0000000..ecff2a4 --- /dev/null +++ b/NahidaImpact.Protocol/TrialAvatarGrantRecord.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message TrialAvatarGrantRecord { + uint32 grant_reason = 1; + uint32 from_parent_quest_id = 2; +} diff --git a/NahidaImpact.Protocol/TrialAvatarInfo.proto b/NahidaImpact.Protocol/TrialAvatarInfo.proto new file mode 100644 index 0000000..a543862 --- /dev/null +++ b/NahidaImpact.Protocol/TrialAvatarInfo.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + + +import "TrialAvatarGrantRecord.proto"; +import "Item.proto"; + +message TrialAvatarInfo { + repeated Item trial_equip_list = 2; + TrialAvatarGrantRecord grant_record = 3; + uint32 trial_avatar_id = 1; +} diff --git a/NahidaImpact.Protocol/TrifleGadget.proto b/NahidaImpact.Protocol/TrifleGadget.proto new file mode 100644 index 0000000..2480619 --- /dev/null +++ b/NahidaImpact.Protocol/TrifleGadget.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +import "Item.proto"; +// Obf: LEEAOCFCGJA +message TrifleGadget { + Item item = 1; + uint32 GAHBDCCFPGJ = 2; +} diff --git a/NahidaImpact.Protocol/TryCustomDungeonType.proto b/NahidaImpact.Protocol/TryCustomDungeonType.proto new file mode 100644 index 0000000..ecaf109 --- /dev/null +++ b/NahidaImpact.Protocol/TryCustomDungeonType.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +// Obf: LJENCJEGDKA +enum TryCustomDungeonType { + TRY_CUSTOM_DUNGEON_NONE = 0; + TRY_CUSTOM_DUNGEON_ROOM = 1; + TRY_CUSTOM_DUNGEON_ALL = 2; + TRY_CUSTOM_DUNGEON_OFFICIAL_PLAY = 3; +} diff --git a/NahidaImpact.Protocol/TryEnterNextRogueDiaryDungeonReq.proto b/NahidaImpact.Protocol/TryEnterNextRogueDiaryDungeonReq.proto new file mode 100644 index 0000000..d5fb7e6 --- /dev/null +++ b/NahidaImpact.Protocol/TryEnterNextRogueDiaryDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 619 +// Obf: OOIKACKGACB +message TryEnterNextRogueDiaryDungeonReq { +} diff --git a/NahidaImpact.Protocol/TryInterruptRogueDiaryDungeonReq.proto b/NahidaImpact.Protocol/TryInterruptRogueDiaryDungeonReq.proto new file mode 100644 index 0000000..21da6ab --- /dev/null +++ b/NahidaImpact.Protocol/TryInterruptRogueDiaryDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 23223 +// Obf: FKGINDOIJFP +message TryInterruptRogueDiaryDungeonReq { +} diff --git a/NahidaImpact.Protocol/UgcType.proto b/NahidaImpact.Protocol/UgcType.proto new file mode 100644 index 0000000..f15496a --- /dev/null +++ b/NahidaImpact.Protocol/UgcType.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: ACCJDILEKGK +enum UgcType { + UGC_TYPE_NONE = 0; + UGC_TYPE_MUSIC_GAME = 1; +} diff --git a/NahidaImpact.Protocol/Uint32Pair.proto b/NahidaImpact.Protocol/Uint32Pair.proto new file mode 100644 index 0000000..3407422 --- /dev/null +++ b/NahidaImpact.Protocol/Uint32Pair.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: CBDJBGDIJBB +message Uint32Pair { + uint32 key = 1; + uint32 value = 2; +} diff --git a/NahidaImpact.Protocol/UnionCmd.proto b/NahidaImpact.Protocol/UnionCmd.proto new file mode 100644 index 0000000..b31adf1 --- /dev/null +++ b/NahidaImpact.Protocol/UnionCmd.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message UnionCmd { + uint32 message_id = 6; + bytes body = 5; +} diff --git a/NahidaImpact.Protocol/UnionCmdNotify.proto b/NahidaImpact.Protocol/UnionCmdNotify.proto new file mode 100644 index 0000000..915803e --- /dev/null +++ b/NahidaImpact.Protocol/UnionCmdNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +import "UnionCmd.proto"; +message UnionCmdNotify { + repeated UnionCmd cmd_list = 8; +} diff --git a/NahidaImpact.Protocol/UnlockTransPointReq.proto b/NahidaImpact.Protocol/UnlockTransPointReq.proto new file mode 100644 index 0000000..653922c --- /dev/null +++ b/NahidaImpact.Protocol/UnlockTransPointReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message UnlockTransPointReq { + uint32 scene_id = 10; + uint32 point_id = 5; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/UnlockTransPointRsp.proto b/NahidaImpact.Protocol/UnlockTransPointRsp.proto new file mode 100644 index 0000000..2eeb9d6 --- /dev/null +++ b/NahidaImpact.Protocol/UnlockTransPointRsp.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + + +message UnlockTransPointRsp { + int32 retcode = 6; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/Vector.proto b/NahidaImpact.Protocol/Vector.proto new file mode 100644 index 0000000..16cf4ce --- /dev/null +++ b/NahidaImpact.Protocol/Vector.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message Vector { + float y = 2; + float z = 3; + float x = 1; +} diff --git a/NahidaImpact.Protocol/Vector3Int.proto b/NahidaImpact.Protocol/Vector3Int.proto new file mode 100644 index 0000000..72b796e --- /dev/null +++ b/NahidaImpact.Protocol/Vector3Int.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: KKPDGAEKGHF +message Vector3Int { + int32 x = 1; + int32 y = 2; + int32 z = 3; +} diff --git a/NahidaImpact.Protocol/VectorPlane.proto b/NahidaImpact.Protocol/VectorPlane.proto new file mode 100644 index 0000000..398a6f9 --- /dev/null +++ b/NahidaImpact.Protocol/VectorPlane.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: FOOALIEJOLM +message VectorPlane { + float x = 1; + float y = 2; +} diff --git a/NahidaImpact.Protocol/VehicleInfo.proto b/NahidaImpact.Protocol/VehicleInfo.proto new file mode 100644 index 0000000..1b7a3ac --- /dev/null +++ b/NahidaImpact.Protocol/VehicleInfo.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + + +import "VehicleMember.proto"; + +message VehicleInfo { + repeated VehicleMember member_list = 1; + uint32 owner_uid = 2; + float cur_stamina = 3; +} diff --git a/NahidaImpact.Protocol/VehicleInteractType.proto b/NahidaImpact.Protocol/VehicleInteractType.proto new file mode 100644 index 0000000..c27fd77 --- /dev/null +++ b/NahidaImpact.Protocol/VehicleInteractType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: HHAEHDABPEB +enum VehicleInteractType { + VEHICLE_INTERACT_TYPE_NONE = 0; + VEHICLE_INTERACT_TYPE_IN = 1; + VEHICLE_INTERACT_TYPE_OUT = 2; +} diff --git a/NahidaImpact.Protocol/VehicleMember.proto b/NahidaImpact.Protocol/VehicleMember.proto new file mode 100644 index 0000000..06a6ed1 --- /dev/null +++ b/NahidaImpact.Protocol/VehicleMember.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +message VehicleMember { + uint32 pos = 3; + uint32 uid = 1; + uint64 avatar_guid = 2; +} diff --git a/NahidaImpact.Protocol/VintageHuntingThirdStageInfo.proto b/NahidaImpact.Protocol/VintageHuntingThirdStageInfo.proto new file mode 100644 index 0000000..91038ca --- /dev/null +++ b/NahidaImpact.Protocol/VintageHuntingThirdStageInfo.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +// Obf: ALBKMPFFDDE +message VintageHuntingThirdStageInfo { +} diff --git a/NahidaImpact.Protocol/VisionType.proto b/NahidaImpact.Protocol/VisionType.proto new file mode 100644 index 0000000..2493ad4 --- /dev/null +++ b/NahidaImpact.Protocol/VisionType.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + + +enum VisionType { + VISION_TYPE_NONE = 0; + VISION_TYPE_MEET = 1; + VISION_TYPE_REBORN = 2; + VISION_TYPE_REPLACE = 3; + VISION_TYPE_WAYPOINT_REBORN = 4; + VISION_TYPE_MISS = 5; + VISION_TYPE_DIE = 6; + VISION_TYPE_GATHER_ESCAPE = 7; + VISION_TYPE_REFRESH = 8; + VISION_TYPE_TRANSPORT = 9; + VISION_TYPE_REPLACE_DIE = 10; + VISION_TYPE_REPLACE_NO_NOTIFY = 11; + VISION_TYPE_BORN = 12; + VISION_TYPE_PICKUP = 13; + VISION_TYPE_REMOVE = 14; + VISION_TYPE_CHANGE_COSTUME = 15; + VISION_TYPE_FISH_REFRESH = 16; + VISION_TYPE_FISH_BIG_SHOCK = 17; + VISION_TYPE_FISH_QTE_SUCC = 18; + VISION_TYPE_CAPTURE_DISAPPEAR = 19; +} diff --git a/NahidaImpact.Protocol/WaterSpritePhaseFinishNotify.proto b/NahidaImpact.Protocol/WaterSpritePhaseFinishNotify.proto new file mode 100644 index 0000000..d90e9cc --- /dev/null +++ b/NahidaImpact.Protocol/WaterSpritePhaseFinishNotify.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 22107 +// Obf: GDGFKLEKPHP +message WaterSpritePhaseFinishNotify { +} diff --git a/NahidaImpact.Protocol/Weapon.proto b/NahidaImpact.Protocol/Weapon.proto new file mode 100644 index 0000000..f2b9109 --- /dev/null +++ b/NahidaImpact.Protocol/Weapon.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +message Weapon { + map affix_map = 4; + uint32 promote_level = 3; + uint32 exp = 2; + uint32 level = 1; +} diff --git a/NahidaImpact.Protocol/WearEquipReq.proto b/NahidaImpact.Protocol/WearEquipReq.proto new file mode 100644 index 0000000..9520d0f --- /dev/null +++ b/NahidaImpact.Protocol/WearEquipReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message WearEquipReq { + uint64 equip_guid = 7; + uint64 avatar_guid = 10; +} diff --git a/NahidaImpact.Protocol/WearEquipRsp.proto b/NahidaImpact.Protocol/WearEquipRsp.proto new file mode 100644 index 0000000..06530d1 --- /dev/null +++ b/NahidaImpact.Protocol/WearEquipRsp.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + + + +message WearEquipRsp { + uint64 avatar_guid = 9; + int32 retcode = 8; + uint64 equip_guid = 5; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/WeatherInfo.proto b/NahidaImpact.Protocol/WeatherInfo.proto new file mode 100644 index 0000000..438b35f --- /dev/null +++ b/NahidaImpact.Protocol/WeatherInfo.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message WeatherInfo { + uint32 weather_area_id = 1; +} diff --git a/NahidaImpact.Protocol/WeeklyBossResinDiscountInfo.proto b/NahidaImpact.Protocol/WeeklyBossResinDiscountInfo.proto new file mode 100644 index 0000000..b557b96 --- /dev/null +++ b/NahidaImpact.Protocol/WeeklyBossResinDiscountInfo.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +message WeeklyBossResinDiscountInfo { + uint32 original_resin_cost = 4; + uint32 discount_num = 1; + uint32 discount_num_limit = 2; + uint32 resin_cost = 3; +} diff --git a/NahidaImpact.Protocol/WidgetCreatorOpType.proto b/NahidaImpact.Protocol/WidgetCreatorOpType.proto new file mode 100644 index 0000000..3bc48f6 --- /dev/null +++ b/NahidaImpact.Protocol/WidgetCreatorOpType.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +// Obf: GCEFDCIHAKA +enum WidgetCreatorOpType { + WIDGET_CREATOR_TYPE_NONE = 0; + WIDGET_CREATOR_TYPE_RETRACT = 1; + WIDGET_CREATOR_TYPE_RETRACT_AND_CREATE = 2; +} diff --git a/NahidaImpact.Protocol/WidgetDoBagReq.proto b/NahidaImpact.Protocol/WidgetDoBagReq.proto new file mode 100644 index 0000000..603b5ba --- /dev/null +++ b/NahidaImpact.Protocol/WidgetDoBagReq.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message WidgetDoBagReq { + uint32 material_id = 5; +} diff --git a/NahidaImpact.Protocol/WidgetDoBagRsp.proto b/NahidaImpact.Protocol/WidgetDoBagRsp.proto new file mode 100644 index 0000000..dced754 --- /dev/null +++ b/NahidaImpact.Protocol/WidgetDoBagRsp.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message WidgetDoBagRsp { + uint32 material_id = 2; + int32 retcode = 15; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/WidgetExtraCdType.proto b/NahidaImpact.Protocol/WidgetExtraCdType.proto new file mode 100644 index 0000000..399a1b9 --- /dev/null +++ b/NahidaImpact.Protocol/WidgetExtraCdType.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +// Obf: FHGCBFMFGMA +enum WidgetExtraCdType { + WIDGET_EXTRA_CD_TYPE_NONE = 0; + WIDGET_EXTRA_CD_TYPE_E_SKILL_SHARED = 1; +} diff --git a/NahidaImpact.Protocol/WidgetSlotChangeNotify.proto b/NahidaImpact.Protocol/WidgetSlotChangeNotify.proto new file mode 100644 index 0000000..d1a0a08 --- /dev/null +++ b/NahidaImpact.Protocol/WidgetSlotChangeNotify.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +import "WidgetSlotData.proto"; +import "WidgetSlotOp.proto"; + +message WidgetSlotChangeNotify { + WidgetSlotData slot = 3; + WidgetSlotOp op = 8; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/WidgetSlotData.proto b/NahidaImpact.Protocol/WidgetSlotData.proto new file mode 100644 index 0000000..4ae4fcf --- /dev/null +++ b/NahidaImpact.Protocol/WidgetSlotData.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + + + +import "WidgetSlotTag.proto"; +message WidgetSlotData { + WidgetSlotTag tag = 5; + uint32 material_id = 9; + bool is_active = 12; + uint32 cd_over_time = 2; +} diff --git a/NahidaImpact.Protocol/WidgetSlotOp.proto b/NahidaImpact.Protocol/WidgetSlotOp.proto new file mode 100644 index 0000000..7abde15 --- /dev/null +++ b/NahidaImpact.Protocol/WidgetSlotOp.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +enum WidgetSlotOp { + WIDGET_SLOT_OP_ATTACH = 0; + WIDGET_SLOT_OP_DETACH = 1; +} \ No newline at end of file diff --git a/NahidaImpact.Protocol/WidgetSlotTag.proto b/NahidaImpact.Protocol/WidgetSlotTag.proto new file mode 100644 index 0000000..4eca3ee --- /dev/null +++ b/NahidaImpact.Protocol/WidgetSlotTag.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + + + + +enum WidgetSlotTag { + WIDGET_SLOT_TAG_QUICK_USE = 0; + WIDGET_SLOT_TAG_ATTACH_AVATAR = 1; +} diff --git a/NahidaImpact.Protocol/WindFieldDungeonFailReason.proto b/NahidaImpact.Protocol/WindFieldDungeonFailReason.proto new file mode 100644 index 0000000..c9e9ad9 --- /dev/null +++ b/NahidaImpact.Protocol/WindFieldDungeonFailReason.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +// Obf: EPFKHGDAOCP +enum WindFieldDungeonFailReason { + WIND_FIELD_DUNGEON_FAIL_NONE = 0; + WIND_FIELD_DUNGEON_FAIL_CANCEL = 1; + WIND_FIELD_DUNGEON_FAIL_TIMEOUT = 2; + WIND_FIELD_DUNGEON_FAIL_ALL_AVATAR_DIE = 3; + WIND_FIELD_DUNGEON_FAIL_LUA_INTERRUPT = 4; +} diff --git a/NahidaImpact.Protocol/WindFieldRestartDungeonReq.proto b/NahidaImpact.Protocol/WindFieldRestartDungeonReq.proto new file mode 100644 index 0000000..a414227 --- /dev/null +++ b/NahidaImpact.Protocol/WindFieldRestartDungeonReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 27756 +// Obf: ABNPNMDPANP +message WindFieldRestartDungeonReq { +} diff --git a/NahidaImpact.Protocol/WindSeedType1Notify.proto b/NahidaImpact.Protocol/WindSeedType1Notify.proto new file mode 100644 index 0000000..88d60ce --- /dev/null +++ b/NahidaImpact.Protocol/WindSeedType1Notify.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + + +message WindSeedType1Notify { + uint32 config_id = 10; + bytes payload = 3; +} diff --git a/NahidaImpact.Protocol/WinterCampAcceptAllGiveItemReq.proto b/NahidaImpact.Protocol/WinterCampAcceptAllGiveItemReq.proto new file mode 100644 index 0000000..6360a18 --- /dev/null +++ b/NahidaImpact.Protocol/WinterCampAcceptAllGiveItemReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 6397 +// Obf: HPLLPIMMLLJ +message WinterCampAcceptAllGiveItemReq { +} diff --git a/NahidaImpact.Protocol/WinterCampGetCanGiveFriendItemReq.proto b/NahidaImpact.Protocol/WinterCampGetCanGiveFriendItemReq.proto new file mode 100644 index 0000000..82527bf --- /dev/null +++ b/NahidaImpact.Protocol/WinterCampGetCanGiveFriendItemReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 130 +// Obf: KFEPKPFHJNO +message WinterCampGetCanGiveFriendItemReq { +} diff --git a/NahidaImpact.Protocol/WinterCampGetFriendWishListReq.proto b/NahidaImpact.Protocol/WinterCampGetFriendWishListReq.proto new file mode 100644 index 0000000..8ac63a6 --- /dev/null +++ b/NahidaImpact.Protocol/WinterCampGetFriendWishListReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 4914 +// Obf: DBDFLMPILFO +message WinterCampGetFriendWishListReq { +} diff --git a/NahidaImpact.Protocol/WinterCampGetRecvItemListReq.proto b/NahidaImpact.Protocol/WinterCampGetRecvItemListReq.proto new file mode 100644 index 0000000..7e339ae --- /dev/null +++ b/NahidaImpact.Protocol/WinterCampGetRecvItemListReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 25703 +// Obf: LGPFAFBIANE +message WinterCampGetRecvItemListReq { +} diff --git a/NahidaImpact.Protocol/WorktopInfo.proto b/NahidaImpact.Protocol/WorktopInfo.proto new file mode 100644 index 0000000..c20b892 --- /dev/null +++ b/NahidaImpact.Protocol/WorktopInfo.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message WorktopInfo { + repeated uint32 option_list = 1; + bool is_guest_can_operate = 2; +} diff --git a/NahidaImpact.Protocol/WorldDataNotify.proto b/NahidaImpact.Protocol/WorldDataNotify.proto new file mode 100644 index 0000000..1a28610 --- /dev/null +++ b/NahidaImpact.Protocol/WorldDataNotify.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +import "PropValue.proto"; +// CmdId: 2101 +// Obf: CJFCLNEAHME +message WorldDataNotify { + map world_prop_map = 14; +} diff --git a/NahidaImpact.Protocol/WorldPlayerInfoNotify.proto b/NahidaImpact.Protocol/WorldPlayerInfoNotify.proto new file mode 100644 index 0000000..e43b517 --- /dev/null +++ b/NahidaImpact.Protocol/WorldPlayerInfoNotify.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +import "PlayerWidgetInfo.proto"; +import "OnlinePlayerInfo.proto"; +// CmdId: 21934 +// Obf: ALKKKAANPAJ +message WorldPlayerInfoNotify { + repeated uint32 player_uid_list = 14; + repeated PlayerWidgetInfo player_widget_info_list = 3; + repeated OnlinePlayerInfo player_info_list = 12; +} diff --git a/NahidaImpact.Protocol/WorldPlayerReviveReq.proto b/NahidaImpact.Protocol/WorldPlayerReviveReq.proto new file mode 100644 index 0000000..9ab0f64 --- /dev/null +++ b/NahidaImpact.Protocol/WorldPlayerReviveReq.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +// CmdId: 2639 +// Obf: CLFPPNDBGLJ +message WorldPlayerReviveReq { +} diff --git a/NahidaImpact.Protocol/proto_4.2.5.zip b/NahidaImpact.Protocol/proto_4.2.5.zip new file mode 100644 index 0000000000000000000000000000000000000000..09d796994ccdbd4163b47f9973e1cdbbf19e7a57 GIT binary patch literal 253831 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

P&uW6&dm@gkx@H7uTNN%X|2tgomKW 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 N`W + + + Exe + net8.0 + enable + enable + + + + + + + diff --git a/NahidaImpact.Proxy/Program.cs b/NahidaImpact.Proxy/Program.cs new file mode 100644 index 0000000..3f998b8 --- /dev/null +++ b/NahidaImpact.Proxy/Program.cs @@ -0,0 +1,18 @@ +using NahidaImpact.Proxy; + +Console.Title = "NahidaImpact | Proxy"; + +ProxyService service = new(); + +Console.Clear(); +Console.WriteLine(" ddxocc:;lc:o \r\n lllooddocc;',ll:::llcdxxo:,l\r\n dllllooxO0KXXXKK00OOkkkko::;ccclc:olc\r\n llodkO0KK00K00KXXXKK0KKXNNNKx::ldOkxx:;ld\r\n l:coxxO0XXK00KK0kOKXXKOO0000KXXxodddxkkdcdocld\r\n oclxOOOKXK0KKXNXK0KNXXXXXKKXNXKKOxdooxxoddcdKOl:o\r\n dc:d000KXK0KXNNNXKKNNNNKOKNNX0KNNNOxdc:lxxdko:o00d:l\r\n dccxOOXNXKKXNNNNK0KNNNNNK0KXNNX0KN0kkdc,:oloOx:ldx0xccd\r\n xdco000NNXXNWWNWNKk0NNNNNNXXKXNNNXK0kxocc:::ccodlclox0Olcd\r\n xd:l0KKNNKXWMMMMWKxONWNNNNNNNKKNNNNKkxoclc::::cccll:;lkOOlcd\r\n d::k0KNX0XWMWWWN0xxKMMWWWWWWWXXWWNNNXK0kxddd::ldxooxc,coxOlcd\r\n xl:dkOKX0KWWNNNN0OxxXWWWWWWWMMNXWWXKXK0XNX0kOd:cxK0oodl:;:xOccd\r\n dclxk0X0KNNNNNNK0KddXNNXNNNWWWNKXNXO00dOXN0oodxocodddc;clccxkcc\r\n o;oO0X00NNNNNXKKX0dxKNNXXNNNNNX00N0x0XkdOKkko,::',cdkl'',,;ckx:l\r\n c;o0KKKNNNNNX0KKOxkxkXNKKXNNNNN0OKklxKkdoodOx;'..':xOxl;'..,oOd:o\r\n xolc;'l0KKXNNNXK0KKxkKNKOXN0OKNNNNN0xxdox0Kkkkllddc;'';dKKkdol:;:x0dcd\r\n dl:cl;;x0XNNNXXKKKOx0NMWXkOXKxOXNNNNKxod00O000XKdclddlcclONXkooooookkll\r\n ::dkxox0XXKK0OO0OdccddddddxkKOd0NNNNXkoO0Oxolldoddxkoddood0XNOoccloldlcd\r\n ;ck0xdOKKOO0KX0dolc'...',,,;oxxll0NNNXkkOc'';,...'okxokK0Oxx0NXxcccox0kcl\r\n :oxkdkNN0k0XXNXxc'.;:''dK0c'oK0xodOKXN0kd',xKO:.;:,'lx0NNX0odXN0l:ldxKKll\r\n :cc:oKN0coKXXNKo..:x:,cd0k:,xWWWNKOkO00Ox;,d0xl,,xl..c0NNXKl:ONXolxdkKKol\r\n ::;dXXl'dX0KNNKdcxKdo0OOkooKWWMWMWWNXXXKdokOO0do0OllONNKK0o;dXXxkOxOX0ll\r\n xd:oX0xdkKKOOXNX00XKO0K000KWMWWWWWWWWWWWX00KK0OOXX0KNKOkK0xxx00xOOkKXd:o\r\n d::xk0kx0KKkxkOOOO0K0KKXNWWWWWWWWWWWWWWWNXKKKK0OkOkxdxKXkk0xdddxk0XO\r\n ccc:dOXX0dllx0XNXXNNNWWWWWWWWWWWWWWWNNNXXXXKklldOXNOlloldkOO0Kk:\r\n xxl;cxKNKOocd0NNNNNWWWWWWNXXXNWWWWWWNNNNNKxclOKNXOookxdkKKK0d;\r\n xd:;coOXNKx;;ok0XNWWWWWWN000XWWWWWWNX0ko;,oKNXKx:,cxxddO0xl:\r\n o:clok0XN0l;,;lodxkO0XXXXXXXKOkxool:';cOXX0xllc;ldddddc,\r\n oc:looxkOOd:;;,...':codxdoc:,...,,,:dOkxdlldl:dOkl; PROXY\r\n xolccllll:,';oolll;',:::,';cllod:',:llldxxd:ckdl"); +Console.CursorTop = 0; +Console.CursorVisible = false; + +AppDomain.CurrentDomain.ProcessExit += (_, _) => +{ + Console.WriteLine("Shutting down..."); + service.Shutdown(); +}; + +Thread.Sleep(-1); \ No newline at end of file diff --git a/NahidaImpact.Proxy/ProxyService.cs b/NahidaImpact.Proxy/ProxyService.cs new file mode 100644 index 0000000..e075f33 --- /dev/null +++ b/NahidaImpact.Proxy/ProxyService.cs @@ -0,0 +1,94 @@ +using System.Net; +using System.Net.Security; +using Titanium.Web.Proxy; +using Titanium.Web.Proxy.EventArguments; +using Titanium.Web.Proxy.Models; + +namespace NahidaImpact.Proxy; +internal class ProxyService +{ + private static readonly string[] s_redirectDomains = + { + ".yuanshen.com", + ".hoyoverse.com", + ".mihoyo.com" + }; + + private readonly ProxyServer _server; + + public ProxyService() + { + _server = new ProxyServer(); + _server.CertificateManager.EnsureRootCertificate(); + + _server.BeforeRequest += BeforeRequest; + _server.ServerCertificateValidationCallback += OnCertValidation; + + ExplicitProxyEndPoint endPoint = new(IPAddress.Any, 8080, true); + endPoint.BeforeTunnelConnectRequest += BeforeTunnelConnectRequest; + + _server.AddEndPoint(endPoint); + _server.Start(); + + _server.SetAsSystemHttpProxy(endPoint); + _server.SetAsSystemHttpsProxy(endPoint); + } + + public void Shutdown() + { + _server.Stop(); + _server.Dispose(); + } + + private Task BeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs args) + { + string hostname = args.HttpClient.Request.RequestUri.Host; + args.DecryptSsl = ShouldRedirect(hostname); + + return Task.CompletedTask; + } + + private Task OnCertValidation(object sender, CertificateValidationEventArgs args) + { + if (args.SslPolicyErrors == SslPolicyErrors.None) + args.IsValid = true; + + return Task.CompletedTask; + } + + private Task BeforeRequest(object sender, SessionEventArgs args) + { + string hostname = args.HttpClient.Request.RequestUri.Host; + + if (ShouldRedirect(hostname)) + { + string requestUrl = args.HttpClient.Request.Url; + Uri local = new($"http://127.0.0.1:8888/"); + + string replacedUrl = new UriBuilder(requestUrl) + { + Scheme = local.Scheme, + Host = local.Host, + Port = local.Port + }.Uri.ToString(); + + replacedUrl = replacedUrl.Replace("hk4e_cn", "hk4e_global"); // cn -> global for CN builds + args.HttpClient.Request.Url = replacedUrl; + + Console.Title = "Redirecting: " + replacedUrl; + } + + return Task.CompletedTask; + } + + private static bool ShouldRedirect(string hostname) + { + foreach (string domain in s_redirectDomains) + { + if (hostname.EndsWith(domain)) + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/NahidaImpact.SDK/Handlers/AuthHandler.cs b/NahidaImpact.SDK/Handlers/AuthHandler.cs new file mode 100644 index 0000000..1e15d4a --- /dev/null +++ b/NahidaImpact.SDK/Handlers/AuthHandler.cs @@ -0,0 +1,50 @@ +using System.Text.Json; +using NahidaImpact.SDK.Models; + +namespace NahidaImpact.SDK.Handlers; + +public static class AuthHandler +{ + public static IResult OnPasswordLogin() + { + // TODO: account system + + ShieldApiAuthResponse response = new() + { + Data = new() + { + Account = new() + { + AreaCode = "**", + Country = "RU", + Email = "NahidaImpact", + IsEmailVerify = "1", + Token = "mostsecuretokenever", + Uid = "1337" + } + } + }; + + return JsonStringResult(JsonSerializer.Serialize(response)); + } + + public static async Task OnGranterLogin(HttpRequest httpRequest) + { + GranterLoginRequest? request = await httpRequest.ReadFromJsonAsync(); + if (request is null) return Results.BadRequest(); + + GranterLoginRequest.RequestData? data = JsonSerializer.Deserialize(request.Data); + if (data is null) return Results.BadRequest(); + + string? openId = data.OpenId; + string? token = data.Token; + + return JsonStringResult($$"""{"retcode":0,"message":"OK","data":{"combo_id":1,"open_id":{{openId}},"combo_token":"{{token}}","data":"{\"guest\":false}","heartbeat":false,"account_type":1,"fatigue_remind":null}"""); + } + + public static IResult OnCaptchaRequest() => + JsonStringResult("""{"data":{"id":"06611ed14c3131a676b19c0d34c0644b","action":"ACTION_NONE","geetest":null},"message":"OK","retcode":0}"""); + + private static IResult JsonStringResult(string jsonString) => + TypedResults.Text(jsonString, "application/json"); +} diff --git a/NahidaImpact.SDK/Handlers/RegionHandler.cs b/NahidaImpact.SDK/Handlers/RegionHandler.cs new file mode 100644 index 0000000..249497a --- /dev/null +++ b/NahidaImpact.SDK/Handlers/RegionHandler.cs @@ -0,0 +1,49 @@ +using System.Text.Json; +using NahidaImpact.Common.Security; +using NahidaImpact.Protocol; +using Google.Protobuf; + +namespace NahidaImpact.SDK.Handlers; + +public static class RegionHandler +{ + private const string CLIENT_CUSTOM_CONFIG = "{\"sdkenv\":\"2\",\"checkdevice\":\"false\",\"loadPatch\":\"false\",\"showexception\":\"false\",\"regionConfig\":\"pm|fk|add\",\"downloadMode\":\"0\"}"; + private static readonly string s_queryRegionListRsp; + private static readonly string s_queryCurRegionRsp; + + static RegionHandler() + { + s_queryRegionListRsp = BuildQueryRegionListResponse(); + s_queryCurRegionRsp = BuildQueryCurrentRegionResponse(); + } + + public static IResult OnQueryRegionList() => TypedResults.Text(s_queryRegionListRsp, "text/plain"); + public static IResult OnQueryCurRegion() => TypedResults.Text(s_queryCurRegionRsp, "application/json"); + + private static string BuildQueryCurrentRegionResponse() => "{\"ip\":\"127.0.0.1\"}"; + + private static string BuildQueryRegionListResponse() + { + byte[] clientCustomConfigEncrypted = MhySecurity.Xor(CLIENT_CUSTOM_CONFIG, MhySecurity.InitialKey); + + QueryRegionListHttpRsp rsp = new() + { + ClientCustomConfigEncrypted = ByteString.CopyFrom(clientCustomConfigEncrypted), + ClientSecretKey = ByteString.CopyFrom(MhySecurity.InitialKeyEc2b), + EnableLoginPc = true, + RegionList = + { + new RegionSimpleInfo + { + Type = "DEV_PUBLIC", + DispatchUrl = "http://127.0.0.1:8888/query_cur_region", + Name = "os_russia", + Title = "NahidaImpact" + } + }, + Retcode = 0 + }; + + return Convert.ToBase64String(rsp.ToByteArray()); + } +} diff --git a/NahidaImpact.SDK/Models/AuthAccountData.cs b/NahidaImpact.SDK/Models/AuthAccountData.cs new file mode 100644 index 0000000..fe65cd2 --- /dev/null +++ b/NahidaImpact.SDK/Models/AuthAccountData.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace NahidaImpact.SDK.Models; + +public record AuthAccountData +{ + [JsonPropertyName("area_code")] + public string? AreaCode { get; set; } + + [JsonPropertyName("email")] + public string? Email { get; set; } + + [JsonPropertyName("country")] + public string? Country { get; set; } + + [JsonPropertyName("is_email_verify")] + public string? IsEmailVerify { get; set; } + + [JsonPropertyName("token")] + public string? Token { get; set; } + + [JsonPropertyName("uid")] + public string? Uid { get; set; } +} diff --git a/NahidaImpact.SDK/Models/AuthSuccessData.cs b/NahidaImpact.SDK/Models/AuthSuccessData.cs new file mode 100644 index 0000000..b51a2db --- /dev/null +++ b/NahidaImpact.SDK/Models/AuthSuccessData.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace NahidaImpact.SDK.Models; + +public record AuthSuccessData +{ + [JsonPropertyName("account")] + public AuthAccountData? Account { get; set; } + + [JsonPropertyName("device_grant_required")] + public bool DeviceGrantRequired { get; set; } + + [JsonPropertyName("reactivate_required")] + public bool ReactivateRequired { get; set; } + + [JsonPropertyName("realperson_required")] + public bool RealPersonRequired { get; set; } + + [JsonPropertyName("safe_mobile_required")] + public bool SafeMobileRequired { get; set; } +} diff --git a/NahidaImpact.SDK/Models/GranterLoginRequest.cs b/NahidaImpact.SDK/Models/GranterLoginRequest.cs new file mode 100644 index 0000000..9656e31 --- /dev/null +++ b/NahidaImpact.SDK/Models/GranterLoginRequest.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; + +namespace NahidaImpact.SDK.Models; + +public record GranterLoginRequest +{ + [JsonPropertyName("data")] + public required string Data { get; set; } + + public record RequestData + { + [JsonPropertyName("uid")] + public string? OpenId { get; set; } + + [JsonPropertyName("token")] + public string? Token { get; set; } + } +} \ No newline at end of file diff --git a/NahidaImpact.SDK/Models/ShieldApiAuthResponse.cs b/NahidaImpact.SDK/Models/ShieldApiAuthResponse.cs new file mode 100644 index 0000000..7cb4f53 --- /dev/null +++ b/NahidaImpact.SDK/Models/ShieldApiAuthResponse.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace NahidaImpact.SDK.Models; + +public record ShieldApiAuthResponse +{ + [JsonPropertyName("data")] + public AuthSuccessData? Data { get; set; } + + [JsonPropertyName("message")] + public string Message { get; set; } = "OK"; + + [JsonPropertyName("retcode")] + public int Retcode { get; set; } +} diff --git a/NahidaImpact.SDK/NahidaImpact.SDK.csproj b/NahidaImpact.SDK/NahidaImpact.SDK.csproj new file mode 100644 index 0000000..3cdf34e --- /dev/null +++ b/NahidaImpact.SDK/NahidaImpact.SDK.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/NahidaImpact.SDK/Program.cs b/NahidaImpact.SDK/Program.cs new file mode 100644 index 0000000..d1a4c56 --- /dev/null +++ b/NahidaImpact.SDK/Program.cs @@ -0,0 +1,25 @@ +using NahidaImpact.SDK.Handlers; + +Console.Title = "NahidaImpact | SDK Server"; +Directory.SetCurrentDirectory(AppContext.BaseDirectory); + +Console.WriteLine(" ddxocc:;lc:o \r\n lllooddocc;',ll:::llcdxxo:,l\r\n dllllooxO0KXXXKK00OOkkkko::;ccclc:olc\r\n llodkO0KK00K00KXXXKK0KKXNNNKx::ldOkxx:;ld\r\n l:coxxO0XXK00KK0kOKXXKOO0000KXXxodddxkkdcdocld\r\n oclxOOOKXK0KKXNXK0KNXXXXXKKXNXKKOxdooxxoddcdKOl:o\r\n dc:d000KXK0KXNNNXKKNNNNKOKNNX0KNNNOxdc:lxxdko:o00d:l\r\n dccxOOXNXKKXNNNNK0KNNNNNK0KXNNX0KN0kkdc,:oloOx:ldx0xccd\r\n xdco000NNXXNWWNWNKk0NNNNNNXXKXNNNXK0kxocc:::ccodlclox0Olcd\r\n xd:l0KKNNKXWMMMMWKxONWNNNNNNNKKNNNNKkxoclc::::cccll:;lkOOlcd\r\n d::k0KNX0XWMWWWN0xxKMMWWWWWWWXXWWNNNXK0kxddd::ldxooxc,coxOlcd\r\n xl:dkOKX0KWWNNNN0OxxXWWWWWWWMMNXWWXKXK0XNX0kOd:cxK0oodl:;:xOccd\r\n dclxk0X0KNNNNNNK0KddXNNXNNNWWWNKXNXO00dOXN0oodxocodddc;clccxkcc\r\n o;oO0X00NNNNNXKKX0dxKNNXXNNNNNX00N0x0XkdOKkko,::',cdkl'',,;ckx:l\r\n c;o0KKKNNNNNX0KKOxkxkXNKKXNNNNN0OKklxKkdoodOx;'..':xOxl;'..,oOd:o\r\n xolc;'l0KKXNNNXK0KKxkKNKOXN0OKNNNNN0xxdox0Kkkkllddc;'';dKKkdol:;:x0dcd\r\n dl:cl;;x0XNNNXXKKKOx0NMWXkOXKxOXNNNNKxod00O000XKdclddlcclONXkooooookkll\r\n ::dkxox0XXKK0OO0OdccddddddxkKOd0NNNNXkoO0Oxolldoddxkoddood0XNOoccloldlcd\r\n ;ck0xdOKKOO0KX0dolc'...',,,;oxxll0NNNXkkOc'';,...'okxokK0Oxx0NXxcccox0kcl\r\n :oxkdkNN0k0XXNXxc'.;:''dK0c'oK0xodOKXN0kd',xKO:.;:,'lx0NNX0odXN0l:ldxKKll\r\n :cc:oKN0coKXXNKo..:x:,cd0k:,xWWWNKOkO00Ox;,d0xl,,xl..c0NNXKl:ONXolxdkKKol\r\n ::;dXXl'dX0KNNKdcxKdo0OOkooKWWMWMWWNXXXKdokOO0do0OllONNKK0o;dXXxkOxOX0ll\r\n xd:oX0xdkKKOOXNX00XKO0K000KWMWWWWWWWWWWWX00KK0OOXX0KNKOkK0xxx00xOOkKXd:o\r\n d::xk0kx0KKkxkOOOO0K0KKXNWWWWWWWWWWWWWWWNXKKKK0OkOkxdxKXkk0xdddxk0XO\r\n ccc:dOXX0dllx0XNXXNNNWWWWWWWWWWWWWWWNNNXXXXKklldOXNOlloldkOO0Kk:\r\n xxl;cxKNKOocd0NNNNNWWWWWWNXXXNWWWWWWNNNNNKxclOKNXOookxdkKKK0d;\r\n xd:;coOXNKx;;ok0XNWWWWWWN000XWWWWWWNX0ko;,oKNXKx:,cxxddO0xl:\r\n o:clok0XN0l;,;lodxkO0XXXXXXXKOkxool:';cOXX0xllc;ldddddc,\r\n oc:looxkOOd:;;,...':codxdoc:,...,,,:dOkxdlldl:dOkl; SDK SERVER\r\n xolccllll:,';oolll;',:::,';cllod:',:llldxxd:ckdl"); +Console.CursorTop = 0; +Console.CursorVisible = false; + +WebApplicationBuilder builder = WebApplication.CreateBuilder(args); + +builder.Logging.ClearProviders(); +builder.Services.AddLogging(); +builder.WebHost.UseUrls("http://*:8888"); + +WebApplication app = builder.Build(); + +app.MapGet("/query_region_list", RegionHandler.OnQueryRegionList); +app.MapGet("/query_cur_region", RegionHandler.OnQueryCurRegion); + +app.MapPost("/account/risky/api/check", AuthHandler.OnCaptchaRequest); +app.MapPost("/{product_name}/mdk/shield/api/login", AuthHandler.OnPasswordLogin); +app.MapPost("/{product_name}/combo/granter/login/v2/login", AuthHandler.OnGranterLogin); + +await app.RunAsync(); diff --git a/NahidaImpact.SDK/Properties/launchSettings.json b/NahidaImpact.SDK/Properties/launchSettings.json new file mode 100644 index 0000000..1285c25 --- /dev/null +++ b/NahidaImpact.SDK/Properties/launchSettings.json @@ -0,0 +1,28 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:2482", + "sslPort": 0 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5259", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/NahidaImpact.SDK/appsettings.Development.json b/NahidaImpact.SDK/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/NahidaImpact.SDK/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/NahidaImpact.SDK/appsettings.json b/NahidaImpact.SDK/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/NahidaImpact.SDK/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/NahidaImpact.sln b/NahidaImpact.sln new file mode 100644 index 0000000..faa7a82 --- /dev/null +++ b/NahidaImpact.sln @@ -0,0 +1,69 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34031.279 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{2F718EA6-A163-4DFF-B0FD-701D617528B1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Game Servers", "Game Servers", "{F40E8251-E7A9-4CAC-AEC8-010E20AE8703}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Framework", "Framework", "{6897BDD9-41F7-49AC-B96C-9BB5A0AFBB44}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NahidaImpact.Proxy", "NahidaImpact.Proxy\NahidaImpact.Proxy.csproj", "{DEFBDB9A-E58E-4A43-885C-BDFCC2E7F084}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NahidaImpact.SDK", "NahidaImpact.SDK\NahidaImpact.SDK.csproj", "{DC8CFA7E-4E34-4701-9A3A-0217BF7C0F17}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NahidaImpact.Protocol", "NahidaImpact.Protocol\NahidaImpact.Protocol.csproj", "{5B10318A-F3B4-43FC-B55E-33346590BA7C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NahidaImpact.Common", "NahidaImpact.Common\NahidaImpact.Common.csproj", "{92CD424D-9F3B-4071-99AD-A6E3A0C52538}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NahidaImpact.Gameserver", "NahidaImpact.Gameserver\NahidaImpact.Gameserver.csproj", "{D4EC1460-DC47-4B63-B64B-3F4BC7521238}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NahidaImpact.Kcp", "NahidaImpact.Kcp\NahidaImpact.Kcp.csproj", "{8A2BEC8F-8DD1-4CDC-9A2A-2EC9EF85BFD6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DEFBDB9A-E58E-4A43-885C-BDFCC2E7F084}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DEFBDB9A-E58E-4A43-885C-BDFCC2E7F084}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DEFBDB9A-E58E-4A43-885C-BDFCC2E7F084}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DEFBDB9A-E58E-4A43-885C-BDFCC2E7F084}.Release|Any CPU.Build.0 = Release|Any CPU + {DC8CFA7E-4E34-4701-9A3A-0217BF7C0F17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DC8CFA7E-4E34-4701-9A3A-0217BF7C0F17}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DC8CFA7E-4E34-4701-9A3A-0217BF7C0F17}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DC8CFA7E-4E34-4701-9A3A-0217BF7C0F17}.Release|Any CPU.Build.0 = Release|Any CPU + {5B10318A-F3B4-43FC-B55E-33346590BA7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5B10318A-F3B4-43FC-B55E-33346590BA7C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5B10318A-F3B4-43FC-B55E-33346590BA7C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5B10318A-F3B4-43FC-B55E-33346590BA7C}.Release|Any CPU.Build.0 = Release|Any CPU + {92CD424D-9F3B-4071-99AD-A6E3A0C52538}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {92CD424D-9F3B-4071-99AD-A6E3A0C52538}.Debug|Any CPU.Build.0 = Debug|Any CPU + {92CD424D-9F3B-4071-99AD-A6E3A0C52538}.Release|Any CPU.ActiveCfg = Release|Any CPU + {92CD424D-9F3B-4071-99AD-A6E3A0C52538}.Release|Any CPU.Build.0 = Release|Any CPU + {D4EC1460-DC47-4B63-B64B-3F4BC7521238}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4EC1460-DC47-4B63-B64B-3F4BC7521238}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4EC1460-DC47-4B63-B64B-3F4BC7521238}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4EC1460-DC47-4B63-B64B-3F4BC7521238}.Release|Any CPU.Build.0 = Release|Any CPU + {8A2BEC8F-8DD1-4CDC-9A2A-2EC9EF85BFD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A2BEC8F-8DD1-4CDC-9A2A-2EC9EF85BFD6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A2BEC8F-8DD1-4CDC-9A2A-2EC9EF85BFD6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A2BEC8F-8DD1-4CDC-9A2A-2EC9EF85BFD6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {DEFBDB9A-E58E-4A43-885C-BDFCC2E7F084} = {2F718EA6-A163-4DFF-B0FD-701D617528B1} + {DC8CFA7E-4E34-4701-9A3A-0217BF7C0F17} = {F40E8251-E7A9-4CAC-AEC8-010E20AE8703} + {5B10318A-F3B4-43FC-B55E-33346590BA7C} = {6897BDD9-41F7-49AC-B96C-9BB5A0AFBB44} + {92CD424D-9F3B-4071-99AD-A6E3A0C52538} = {6897BDD9-41F7-49AC-B96C-9BB5A0AFBB44} + {D4EC1460-DC47-4B63-B64B-3F4BC7521238} = {F40E8251-E7A9-4CAC-AEC8-010E20AE8703} + {8A2BEC8F-8DD1-4CDC-9A2A-2EC9EF85BFD6} = {6897BDD9-41F7-49AC-B96C-9BB5A0AFBB44} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {629BB9D5-7AED-4D5E-A5A1-0E9FD18A87B2} + EndGlobalSection +EndGlobal diff --git a/README.md b/README.md new file mode 100644 index 0000000..33e9d3e --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +

+ +--- +
+
+ +# FurinaImpact +Server backend reimplementation for some game. + +### Building +You can build it with .NET 7 SDK + +### Running +1. Launch FurinaImpact.SDK and FurinaImpact.Gameserver +2. Server is running. + +### Connecting +For connecting to FurinaImpact, you can use FurinaImpact.Proxy. Just launch it and setup your system proxy settings. SDK requests will be redirected. + +### Any questions? +Feel free to ask your questions in our [Discord Server](https://discord.gg/sHZuMpCpVw)