├── .gitignore ├── MMORPG ├── Start2.ps1 ├── GameServer │ ├── config.yaml │ ├── core │ │ ├── Task │ │ │ ├── Reward │ │ │ │ ├── IRewardHandler.cs │ │ │ │ ├── Impl │ │ │ │ │ ├── SkillRewardHandler.cs │ │ │ │ │ ├── SkillChainRewardHandler.cs │ │ │ │ │ └── ItemRewardHandler.cs │ │ │ │ └── TaskRewardParser.cs │ │ │ └── Condition │ │ │ │ ├── IConditionChecker.cs │ │ │ │ └── Impl │ │ │ │ ├── TalkNpcConditionChecker.cs │ │ │ │ ├── CastSkillConditionChecker.cs │ │ │ │ ├── CollectItemConditionChecker.cs │ │ │ │ ├── EnterGameConditionChecker.cs │ │ │ │ ├── TaskCompletedChecker.cs │ │ │ │ ├── LevelConditionChecker.cs │ │ │ │ ├── KillMonsterConditionChecker.cs │ │ │ │ └── ReachPositionConditionChecker.cs │ │ ├── Model │ │ │ ├── BaseItem │ │ │ │ ├── Sub │ │ │ │ │ ├── GameMaterialItem.cs │ │ │ │ │ └── GameConsumable.cs │ │ │ │ └── GameItem.cs │ │ │ └── GameCharacterManager.cs │ │ └── Chat │ │ │ └── ChatManager.cs │ ├── GameServer.csproj │ ├── Net │ │ ├── GameToken.cs │ │ └── GameTokenManager.cs │ ├── Hanle │ │ └── GameServerHandler.cs │ └── Utils │ │ └── Config.cs ├── LoginServer │ ├── config.yaml │ ├── Net │ │ ├── Session.cs │ │ ├── LoginToken.cs │ │ ├── LoginTokenManager.cs │ │ └── SessionManager.cs │ ├── LoginServer.csproj │ ├── Core │ │ └── LoginServerMonitor.cs │ ├── Utils │ │ └── Config.cs │ └── Handle │ │ └── LoginServerHandler.cs ├── SceneServer │ ├── config.yaml │ ├── config2.yaml │ ├── Core │ │ ├── Model │ │ │ ├── Actor │ │ │ │ └── SceneNpc.cs │ │ │ ├── Interactivo │ │ │ │ └── SceneInteractivo.cs │ │ │ ├── Item │ │ │ │ └── SceneItem.cs │ │ │ └── SceneEntity.cs │ │ ├── Combat │ │ │ ├── AI │ │ │ │ ├── WoodenDummy │ │ │ │ │ ├── Impl │ │ │ │ │ │ ├── WoodenDummyMonsterAIState_Death.cs │ │ │ │ │ │ ├── WoodenDummyMonsterAIState_Idle.cs │ │ │ │ │ │ ├── WoodenDummyMonsterAIState.cs │ │ │ │ │ │ └── WoodenDummyMonsterAIState_Hurt.cs │ │ │ │ │ └── WoodenDummyMonsterAI.cs │ │ │ │ ├── Boss │ │ │ │ │ └── Impl │ │ │ │ │ │ ├── BossMonsterAIState.cs │ │ │ │ │ │ ├── BossMonsterAIState_Death.cs │ │ │ │ │ │ ├── BossMonsterAIState_ReturnBrith.cs │ │ │ │ │ │ ├── BossMonsterAIState_Hurt.cs │ │ │ │ │ │ ├── BossMonsterAIState_Chase.cs │ │ │ │ │ │ ├── BossMonsterAIState_Attack.cs │ │ │ │ │ │ ├── BossMonsterAIState_Patrol.cs │ │ │ │ │ │ └── BossMonsterAIState_Flee.cs │ │ │ │ └── BaseMonsterAI.cs │ │ │ ├── Skill │ │ │ │ ├── SkillImpl │ │ │ │ │ ├── Skill_Invincible.cs │ │ │ │ │ └── Skill_Fengxingshu.cs │ │ │ │ ├── SCObject.cs │ │ │ │ ├── Missile.cs │ │ │ │ ├── SkillScanner.cs │ │ │ │ └── SkillManager.cs │ │ │ └── Buffs │ │ │ │ ├── BuffImplement │ │ │ │ └── InvincibleBuff.cs │ │ │ │ └── BuffScanner.cs │ │ ├── AOIMap │ │ │ └── Linked │ │ │ │ ├── SkipList │ │ │ │ ├── SkipListNode.cs │ │ │ │ └── SkipList.cs │ │ │ │ └── Base │ │ │ │ ├── AoiNode.cs │ │ │ │ └── AoiEntity.cs │ │ └── Scene │ │ │ └── Component │ │ │ ├── SceneMonsterManager.cs │ │ │ ├── SpawnManager.cs │ │ │ ├── SceneItemManager.cs │ │ │ └── SceneEntityManager.cs │ ├── SceneServer.csproj │ ├── Net │ │ └── Session.cs │ ├── Handle │ │ ├── SceneServerHandler.cs │ │ ├── EnterGameWorldHanlder.cs │ │ └── CombatHandler.cs │ └── Utils │ │ └── Config.cs ├── ControlCenter │ ├── config.yaml │ ├── ControlCenter.csproj │ ├── Core │ │ └── ControlCenterHandler.cs │ └── Utils │ │ └── Config.cs ├── DBProxyServer │ ├── config.yaml │ ├── DBProxyServer.csproj │ ├── Core │ │ └── Conn │ │ │ └── MongodbConnection.cs │ ├── Handle │ │ ├── DBProxyServerHandler.cs │ │ └── WorldHandler.cs │ └── Utils │ │ └── Config.cs ├── GameGateServer │ ├── config.yaml │ ├── GameGateServer.csproj │ ├── Net │ │ ├── Session.cs │ │ └── SessionManager.cs │ ├── Handle │ │ ├── GameGateServerHandler.cs │ │ ├── SecurityHandler.cs │ │ └── ChatHandler.cs │ └── Utils │ │ └── Config.cs ├── LoginGateServer │ ├── config.yaml │ ├── LoginGateServer.csproj │ ├── Net │ │ ├── LoginGateToken.cs │ │ └── LoginGateTokenManager.cs │ ├── Handle │ │ ├── LoginGateHandler.cs │ │ ├── SecurityHandler.cs │ │ ├── EnterGameWorldHanlder.cs │ │ └── UserHandler.cs │ └── Utils │ │ └── Config.cs ├── GameGateMgrServer │ ├── config.yaml │ ├── GameGateMgrServer.csproj │ └── Utils │ │ └── Config.cs ├── MasterTimerServer │ ├── config.yaml │ ├── Core │ │ └── TimeMonitor.cs │ ├── MasterTimerServer.csproj │ ├── Handler │ │ └── TimeSyncHandler.cs │ ├── Utils │ │ └── Config.cs │ └── Net │ │ └── MasterTimerServersMgr.cs ├── EntryServer │ ├── Program.cs │ └── EntryServer.csproj ├── LogServer │ ├── Program.cs │ └── LogServer.csproj ├── LoginGateMgrServer │ ├── config.yaml │ ├── LoginGateMgrServer.csproj │ └── Utils │ │ └── Config.cs ├── PortalServer │ ├── Program.cs │ └── PortalServer.csproj ├── RedisServer │ ├── Program.cs │ └── RedisServer.csproj ├── Common │ ├── Summer │ │ ├── Tools │ │ │ ├── ObjectPool.cs │ │ │ ├── StateMachine │ │ │ │ ├── StateBase.cs │ │ │ │ └── StateMachine.cs │ │ │ ├── Singleton.cs │ │ │ ├── IdGenerator.cs │ │ │ ├── GameEvent │ │ │ │ └── CharacterEventSystem.cs │ │ │ ├── LogDemo.cs │ │ │ └── Varint.cs │ │ ├── Proto │ │ │ ├── Chat │ │ │ │ └── ProtoSource │ │ │ │ │ └── Chat.proto │ │ │ ├── Game │ │ │ │ └── ProtoSource │ │ │ │ │ ├── Game.proto │ │ │ │ │ ├── Backpack.proto │ │ │ │ │ ├── GameTask.proto │ │ │ │ │ ├── GameGateMgr.proto │ │ │ │ │ └── GameGate.proto │ │ │ ├── Combat │ │ │ │ └── ProtoSource │ │ │ │ │ ├── Buff.proto │ │ │ │ │ └── Skill.proto │ │ │ ├── Login │ │ │ │ └── ProtoSource │ │ │ │ │ ├── Login.proto │ │ │ │ │ ├── LoginGateMgr.proto │ │ │ │ │ └── LoginGate.proto │ │ │ ├── Scene │ │ │ │ └── ProtoSource │ │ │ │ │ ├── Scene.proto │ │ │ │ │ └── SceneEntity.proto │ │ │ ├── DBProxy │ │ │ │ └── ProtoSource │ │ │ │ │ ├── DBTask.proto │ │ │ │ │ ├── DBUser.proto │ │ │ │ │ ├── DBWorld.proto │ │ │ │ │ ├── DBCharacter.proto │ │ │ │ │ └── DBInventory .proto │ │ │ ├── TimeSync │ │ │ │ └── ProtoSource │ │ │ │ │ └── MasterTime.proto │ │ │ └── ControlCenter │ │ │ │ └── ProtoSource │ │ │ │ └── ControlCenter.proto │ │ ├── Core │ │ │ └── MyTime.cs │ │ ├── Net │ │ │ ├── TypeAttributeStore.cs │ │ │ └── New │ │ │ │ └── UserMessageHandlerMap.cs │ │ ├── Time │ │ │ └── HighPrecisionClock.cs │ │ ├── StaticData │ │ │ └── ErrorCode.cs │ │ ├── Security │ │ │ ├── EncryptionManager.cs │ │ │ ├── PasswordHasher.cs │ │ │ └── AesEncryption.cs │ │ └── CommonMgr.cs │ └── Common.csproj ├── HttpProxyServer │ ├── Program.cs │ └── HttpProxyServer.csproj ├── SlaveTimerServer │ ├── Program.cs │ └── SlaveTimerServer.csproj ├── Llua │ ├── lLua.csproj │ ├── lLua - Backup.csproj │ ├── Api │ │ ├── ConstsHelper.cs │ │ └── ILuaState.cs │ ├── State │ │ ├── LuaValue.cs │ │ └── LuaStack.cs │ └── VM │ │ └── Instruction.cs ├── .gitignore ├── Stop1.bat ├── Client │ └── TestClient.csproj └── Start1.bat └── README.assets ├── 小南梁界服务器架构.png ├── image-removebg.png ├── image-20250901002110044.png ├── image-20250921152545581.png ├── image-20250921152738108.png ├── image-20241031210804398-1731842150687-34.png ├── image-20241031211158387-1731842054803-6.png ├── image-20241031211158387-1731842150687-35.png ├── image-20241102120751826-1731842150688-36.png ├── image-20241102183824895-1731842150688-37.png ├── image-20241102183944857-1731842150688-38.png ├── image-20241102184013053-1731842150688-39.png ├── image-20241102192526343-1731842150688-42.png ├── image-20241102192553433-1731842150688-43.png └── image-20241102195034307-1731842150688-44.png /.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MMORPG/Start2.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Start2.ps1 -------------------------------------------------------------------------------- /MMORPG/GameServer/config.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/GameServer/config.yaml -------------------------------------------------------------------------------- /README.assets/小南梁界服务器架构.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/小南梁界服务器架构.png -------------------------------------------------------------------------------- /MMORPG/LoginServer/config.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/LoginServer/config.yaml -------------------------------------------------------------------------------- /MMORPG/SceneServer/config.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/SceneServer/config.yaml -------------------------------------------------------------------------------- /MMORPG/SceneServer/config2.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/SceneServer/config2.yaml -------------------------------------------------------------------------------- /MMORPG/ControlCenter/config.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/ControlCenter/config.yaml -------------------------------------------------------------------------------- /MMORPG/DBProxyServer/config.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/DBProxyServer/config.yaml -------------------------------------------------------------------------------- /MMORPG/GameGateServer/config.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/GameGateServer/config.yaml -------------------------------------------------------------------------------- /MMORPG/LoginGateServer/config.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/LoginGateServer/config.yaml -------------------------------------------------------------------------------- /README.assets/image-removebg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-removebg.png -------------------------------------------------------------------------------- /MMORPG/GameGateMgrServer/config.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/GameGateMgrServer/config.yaml -------------------------------------------------------------------------------- /MMORPG/MasterTimerServer/config.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/MasterTimerServer/config.yaml -------------------------------------------------------------------------------- /MMORPG/EntryServer/Program.cs: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/new-console-template for more information 2 | Console.WriteLine("Hello, World!"); 3 | -------------------------------------------------------------------------------- /MMORPG/LogServer/Program.cs: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/new-console-template for more information 2 | Console.WriteLine("Hello, World!"); 3 | -------------------------------------------------------------------------------- /MMORPG/LoginGateMgrServer/config.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/LoginGateMgrServer/config.yaml -------------------------------------------------------------------------------- /MMORPG/PortalServer/Program.cs: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/new-console-template for more information 2 | Console.WriteLine("Hello, World!"); 3 | -------------------------------------------------------------------------------- /MMORPG/RedisServer/Program.cs: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/new-console-template for more information 2 | Console.WriteLine("Hello, World!"); 3 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Tools/ObjectPool.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Tools/ObjectPool.cs -------------------------------------------------------------------------------- /MMORPG/HttpProxyServer/Program.cs: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/new-console-template for more information 2 | Console.WriteLine("Hello, World!"); 3 | -------------------------------------------------------------------------------- /MMORPG/SlaveTimerServer/Program.cs: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/new-console-template for more information 2 | Console.WriteLine("Hello, World!"); 3 | -------------------------------------------------------------------------------- /README.assets/image-20250901002110044.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-20250901002110044.png -------------------------------------------------------------------------------- /README.assets/image-20250921152545581.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-20250921152545581.png -------------------------------------------------------------------------------- /README.assets/image-20250921152738108.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-20250921152738108.png -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/Chat/ProtoSource/Chat.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/Chat/ProtoSource/Chat.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/Game/ProtoSource/Game.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/Game/ProtoSource/Game.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/Combat/ProtoSource/Buff.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/Combat/ProtoSource/Buff.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/Login/ProtoSource/Login.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/Login/ProtoSource/Login.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/Scene/ProtoSource/Scene.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/Scene/ProtoSource/Scene.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/Combat/ProtoSource/Skill.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/Combat/ProtoSource/Skill.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/DBProxy/ProtoSource/DBTask.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/DBProxy/ProtoSource/DBTask.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/DBProxy/ProtoSource/DBUser.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/DBProxy/ProtoSource/DBUser.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/Game/ProtoSource/Backpack.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/Game/ProtoSource/Backpack.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/Game/ProtoSource/GameTask.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/Game/ProtoSource/GameTask.proto -------------------------------------------------------------------------------- /README.assets/image-20241031210804398-1731842150687-34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-20241031210804398-1731842150687-34.png -------------------------------------------------------------------------------- /README.assets/image-20241031211158387-1731842054803-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-20241031211158387-1731842054803-6.png -------------------------------------------------------------------------------- /README.assets/image-20241031211158387-1731842150687-35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-20241031211158387-1731842150687-35.png -------------------------------------------------------------------------------- /README.assets/image-20241102120751826-1731842150688-36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-20241102120751826-1731842150688-36.png -------------------------------------------------------------------------------- /README.assets/image-20241102183824895-1731842150688-37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-20241102183824895-1731842150688-37.png -------------------------------------------------------------------------------- /README.assets/image-20241102183944857-1731842150688-38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-20241102183944857-1731842150688-38.png -------------------------------------------------------------------------------- /README.assets/image-20241102184013053-1731842150688-39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-20241102184013053-1731842150688-39.png -------------------------------------------------------------------------------- /README.assets/image-20241102192526343-1731842150688-42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-20241102192526343-1731842150688-42.png -------------------------------------------------------------------------------- /README.assets/image-20241102192553433-1731842150688-43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-20241102192553433-1731842150688-43.png -------------------------------------------------------------------------------- /README.assets/image-20241102195034307-1731842150688-44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/README.assets/image-20241102195034307-1731842150688-44.png -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/DBProxy/ProtoSource/DBWorld.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/DBProxy/ProtoSource/DBWorld.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/Game/ProtoSource/GameGateMgr.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/Game/ProtoSource/GameGateMgr.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/DBProxy/ProtoSource/DBCharacter.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/DBProxy/ProtoSource/DBCharacter.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/Login/ProtoSource/LoginGateMgr.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/Login/ProtoSource/LoginGateMgr.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/Scene/ProtoSource/SceneEntity.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/Scene/ProtoSource/SceneEntity.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/TimeSync/ProtoSource/MasterTime.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/TimeSync/ProtoSource/MasterTime.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/ControlCenter/ProtoSource/ControlCenter.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lianglllll/MMORPG-Server/HEAD/MMORPG/Common/Summer/Proto/ControlCenter/ProtoSource/ControlCenter.proto -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/DBProxy/ProtoSource/DBInventory .proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package HS.Protobuf.DBProxy.DBInventory; 3 | 4 | enum DBInventoryProtocol{ 5 | DBINVENTORY_PROTOCL_NONE = 0; 6 | } 7 | -------------------------------------------------------------------------------- /MMORPG/Llua/lLua.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /MMORPG/Llua/lLua - Backup.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /MMORPG/.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | .vscode/ 3 | bin/ 4 | obj/ 5 | 6 | *.userprefs 7 | *.unityproj 8 | *.DS_Store 9 | *.vsconfig 10 | 11 | /pids.txt 12 | 13 | # proto 14 | Common/Summer/Proto/**/ProtoClass 15 | 16 | # data 17 | Common/Summer/StaticData/Data/ 18 | Common/Summer/StaticData/DataDefine/ -------------------------------------------------------------------------------- /MMORPG/LogServer/LogServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Model/Actor/SceneNpc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SceneServer.Core.Model.Actor 8 | { 9 | public class SceneNpc : SceneActor 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MMORPG/EntryServer/EntryServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MMORPG/RedisServer/RedisServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MMORPG/PortalServer/PortalServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MMORPG/HttpProxyServer/HttpProxyServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Model/Interactivo/SceneInteractivo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SceneServer.Core.Model.Interactivo 8 | { 9 | internal class SceneInteractivo 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MMORPG/SlaveTimerServer/SlaveTimerServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/Login/ProtoSource/LoginGate.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package HS.Protobuf.LoginGate; 3 | 4 | enum LoginGateProtocl{ 5 | LOGINGATE_PROTOCL_NONE = 0; 6 | LOGINGATE_PROTOCL_GET_LOGINGATE_TOKEN_REQ = 21001; 7 | LOGINGATE_PROTOCL_GET_LOGINGATE_TOKEN_RESP = 21002; 8 | } 9 | 10 | message GetLoginGateTokenRequest{ 11 | } 12 | message GetLoginGateTokenResponse{ 13 | string loginGateToken = 1; 14 | } 15 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/WoodenDummy/Impl/WoodenDummyMonsterAIState_Death.cs: -------------------------------------------------------------------------------- 1 | using HS.Protobuf.SceneEntity; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace SceneServer.Core.Combat.AI.WoodenDummy.Impl 9 | { 10 | public class WoodenDummyMonsterAIState_Death : WoodenDummyMonsterAIState 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Reward/IRewardHandler.cs: -------------------------------------------------------------------------------- 1 | using GameServer.Core.Model; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Numerics; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace GameServer.Core.Task.Reward 10 | { 11 | public interface IRewardHandler 12 | { 13 | void GrantReward(RewardData rewardData, GameCharacter chr); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MMORPG/LoginServer/Net/Session.cs: -------------------------------------------------------------------------------- 1 | using HS.Protobuf.DBProxy.DBUser; 2 | 3 | namespace LoginServer.Net 4 | { 5 | /// 6 | /// 用户会话,代表玩家客户端,只有登录成功的用户才分配给他session 7 | /// 8 | public class Session 9 | { 10 | public string Id { get; private set; } 11 | public DBUserNode dbUser { get; set; } 12 | 13 | public Session(string sessionId) 14 | { 15 | Id = sessionId; 16 | } 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MMORPG/MasterTimerServer/Core/TimeMonitor.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Time; 2 | using Common.Summer.Tools; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MasterTimerServer.Core 10 | { 11 | public class TimeMonitor : Singleton 12 | { 13 | private HighPrecisionClock highPrecisionClock = new HighPrecisionClock(); 14 | public long GetUnixTimeMilliseconds => highPrecisionClock.GetUnixTimeMilliseconds(); 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Reward/Impl/SkillRewardHandler.cs: -------------------------------------------------------------------------------- 1 | using GameServer.Core.Model; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace GameServer.Core.Task.Reward.Impl 9 | { 10 | public class SkillRewardHandler : IRewardHandler 11 | { 12 | public void GrantReward(RewardData rewardData, GameCharacter chr) 13 | { 14 | int skillId = int.Parse(rewardData.Parameters[0]); 15 | // chr. 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/AOIMap/Linked/SkipList/SkipListNode.cs: -------------------------------------------------------------------------------- 1 | namespace SceneServer.Core.AOI 2 | { 3 | public class SkipListNode 4 | { 5 | public long Value; 6 | public T Obj; 7 | public SkipListNode Right; 8 | public SkipListNode Down; 9 | 10 | public SkipListNode Init(long v, T o, SkipListNode r, SkipListNode d) 11 | { 12 | Right = r; 13 | Down = d; 14 | Value = v; 15 | Obj = o; 16 | 17 | return this; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/WoodenDummy/Impl/WoodenDummyMonsterAIState_Idle.cs: -------------------------------------------------------------------------------- 1 | using HS.Protobuf.SceneEntity; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace SceneServer.Core.Combat.AI.WoodenDummy.Impl 9 | { 10 | public class WoodenDummyMonsterAIState_Idle : WoodenDummyMonsterAIState 11 | { 12 | public override void Enter() 13 | { 14 | monsterAI.Monster.ChangeActorStateAndSend(NetActorState.Idle); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Model/BaseItem/Sub/GameMaterialItem.cs: -------------------------------------------------------------------------------- 1 | using HS.Protobuf.Backpack; 2 | 3 | namespace GameServer.core.Model.BaseItem.Sub 4 | { 5 | 6 | /// 7 | /// 材料 8 | /// 9 | public class GameMaterialItem : GameItem 10 | { 11 | public GameMaterialItem(NetItemDataNode netItemDataNode) : base(netItemDataNode) 12 | { 13 | } 14 | 15 | public GameMaterialItem(ItemDefine define, int amount = 1, int position = 0) : base(define, amount, position) 16 | { 17 | } 18 | } 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Reward/Impl/SkillChainRewardHandler.cs: -------------------------------------------------------------------------------- 1 | using GameServer.Core.Model; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace GameServer.Core.Task.Reward.Impl 9 | { 10 | public class SkillChainRewardHandler : IRewardHandler 11 | { 12 | public void GrantReward(RewardData rewardData, GameCharacter chr) 13 | { 14 | int skillChainId = int.Parse(rewardData.Parameters[0]); 15 | // chr. 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /MMORPG/Llua/Api/ConstsHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace lLua.Api 8 | { 9 | public enum LuaDataType 10 | { 11 | LUA_TNONE = -1, 12 | LUA_TNIL, 13 | LUA_TBOOLEAN, 14 | LUA_TLIGHTUSERDATA, 15 | LUA_TNUMBER, 16 | LUA_TSTRING, 17 | LUA_TTABLE, 18 | LUA_TFUNCTION, 19 | LUA_TUSERDATA, 20 | LUA_TTHREAD 21 | } 22 | 23 | public class ConstsHelper 24 | { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MMORPG/LoginServer/LoginServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /MMORPG/ControlCenter/ControlCenter.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /MMORPG/GameGateServer/GameGateServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /MMORPG/GameGateMgrServer/GameGateMgrServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /MMORPG/LoginGateMgrServer/LoginGateMgrServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /MMORPG/MasterTimerServer/MasterTimerServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Model/BaseItem/Sub/GameConsumable.cs: -------------------------------------------------------------------------------- 1 | using GameServer.core.Model.BaseItem; 2 | using HS.Protobuf.Backpack; 3 | 4 | namespace GameServer.core.Model.BaseItem.Sub 5 | { 6 | /// 7 | /// 消耗品 8 | /// 9 | public class GameConsumable : GameItem 10 | { 11 | public GameConsumable(NetItemDataNode netItemDataNode) : base(netItemDataNode) 12 | { 13 | } 14 | 15 | public GameConsumable(ItemDefine define, int amount = 1, int position = 0) : base(define, amount, position) 16 | { 17 | } 18 | } 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/WoodenDummy/Impl/WoodenDummyMonsterAIState.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Tools; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace SceneServer.Core.Combat.AI.WoodenDummy.Impl 9 | { 10 | public class WoodenDummyMonsterAIState : StateBase 11 | { 12 | protected WoodenDummyMonsterAI monsterAI; 13 | 14 | public override void Init(IStateMachineOwner owner) 15 | { 16 | monsterAI = owner as WoodenDummyMonsterAI; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/Boss/Impl/BossMonsterAIState.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Tools; 2 | using SceneServer.Core.Model.Actor; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace SceneServer.Core.Combat.AI.MonsterAIStateImpl 10 | { 11 | public abstract class BossMonsterAIState : StateBase 12 | { 13 | protected BossMonsterAI monsterAI; 14 | 15 | public override void Init(IStateMachineOwner owner) 16 | { 17 | monsterAI = owner as BossMonsterAI; 18 | } 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Tools/StateMachine/StateBase.cs: -------------------------------------------------------------------------------- 1 | namespace Common.Summer.Tools 2 | { 3 | public class StateBase 4 | { 5 | public virtual void Init(IStateMachineOwner owner) 6 | { 7 | // 可能会使用对象池,所以需要每次添加到状态机时进行初始化 8 | } 9 | public virtual void UnInit() 10 | { 11 | // 反初始化,一般用于释放资源 12 | } 13 | public virtual void Enter() { } 14 | public virtual void Exit() { } 15 | public virtual void Update(float deltaTime) { } 16 | public virtual void FixedUpdate() { } 17 | public virtual void LateUpdate() { } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/Skill/SkillImpl/Skill_Invincible.cs: -------------------------------------------------------------------------------- 1 | using SceneServer.Core.Combat.Skills; 2 | using SceneServer.Core.Model.Actor; 3 | 4 | namespace SceneServer.Combat.Skills.SkillImpl 5 | { 6 | /// 7 | /// 无敌 8 | /// 9 | [SkillAttribute(2004)] 10 | public class Skill_Invincible : Skill 11 | { 12 | public Skill_Invincible(SceneActor owner, int skillId): base(owner, skillId) 13 | { 14 | 15 | } 16 | 17 | protected override void OnActive() 18 | { 19 | //Owner.buffManager.AddBuff(Owner); 20 | } 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /MMORPG/Stop1.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | rem 定义 pids.txt 文件路径 5 | set "PIDS_FILE=%~dp0pids.txt" 6 | 7 | rem 检查 pids.txt 是否存在 8 | if not exist "%PIDS_FILE%" ( 9 | echo File not found: %PIDS_FILE% 10 | exit /b 11 | ) 12 | 13 | rem 逐行读取文件并终止每个 PID 对应的进程 14 | for /f "usebackq delims=" %%A in ("%PIDS_FILE%") do ( 15 | echo Terminating process with PID: %%A 16 | taskkill /PID %%A /F >nul 2>&1 17 | if errorlevel 1 ( 18 | echo Failed to terminate PID %%A or it might already be closed. 19 | ) else ( 20 | echo Successfully terminated PID %%A. 21 | ) 22 | ) 23 | 24 | rem 删除 pids.txt 文件 25 | del "%PIDS_FILE%" >nul 2>&1 26 | 27 | endlocal -------------------------------------------------------------------------------- /MMORPG/GameServer/GameServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | PreserveNewest 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /MMORPG/DBProxyServer/DBProxyServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/Boss/Impl/BossMonsterAIState_Death.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SceneServer.Core.Combat.AI.MonsterAIStateImpl 8 | { 9 | public class BossMonsterAIState_Death : BossMonsterAIState 10 | { 11 | public override void Enter() 12 | { 13 | 14 | } 15 | public override void Update(float deltatime) 16 | { 17 | // 检测死亡状态退出 18 | if (!monsterAI.Monster.IsDeath) 19 | { 20 | monsterAI.ChangeState(MonsterAIState.Patrol); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/SceneServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | PreserveNewest 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /MMORPG/Client/TestClient.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /MMORPG/LoginGateServer/LoginGateServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | PreserveNewest 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /MMORPG/LoginGateServer/Net/LoginGateToken.cs: -------------------------------------------------------------------------------- 1 | using Google.Protobuf; 2 | using Common.Summer.Core; 3 | 4 | namespace LoginGateServer.Net 5 | { 6 | public class LoginGateToken 7 | { 8 | public string Id { get; private set; } 9 | public Connection Conn; //网络连接对象 10 | public float LastHeartTime { get; set; } //心跳时间 11 | 12 | public LoginGateToken(string sessionId, Connection connection) 13 | { 14 | Id = sessionId; 15 | Conn = connection; 16 | LastHeartTime = MyTime.time; 17 | } 18 | 19 | public void Send(IMessage message) 20 | { 21 | Conn?.Send(message); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Tools/Singleton.cs: -------------------------------------------------------------------------------- 1 | namespace Common.Summer.Tools 2 | { 3 | //泛型弄出了很多个不同的Singleton类,所以多个子类来继承这个Singleton的时候并不会发生使用同一个static属性的问题 4 | public class Singleton where T : new() 5 | { 6 | private static T instance; 7 | private static object lockObj = new object(); 8 | public static T Instance 9 | { 10 | get 11 | { 12 | if (instance != null) return instance; 13 | lock (lockObj) 14 | { 15 | if(instance == null) //防止极端情况 16 | { 17 | instance = new T(); 18 | } 19 | } 20 | return instance; 21 | } 22 | } 23 | 24 | // 防止外部实例化 25 | protected Singleton() { } 26 | 27 | // 可选初始化方法 28 | public virtual void Init() { } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/AOIMap/Linked/Base/AoiNode.cs: -------------------------------------------------------------------------------- 1 | namespace SceneServer.Core.AOI 2 | { 3 | public sealed class AoiNode 4 | { 5 | public float Value; 6 | public readonly int Layer; 7 | public readonly AoiEntity Entity; 8 | public AoiNode Left; 9 | public AoiNode Right; 10 | public AoiNode Top; 11 | public AoiNode Down; 12 | 13 | public AoiNode (int layer, float v = 0, AoiEntity entity = null, AoiNode left = null, AoiNode right = null, AoiNode top = null, AoiNode down = null) 14 | { 15 | Layer = layer; 16 | Left = left; 17 | Right = right; 18 | Top = top; 19 | Down = down; 20 | Value = v; 21 | Entity = entity; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/Skill/SkillImpl/Skill_Fengxingshu.cs: -------------------------------------------------------------------------------- 1 | using SceneServer.Core.Combat.Skills; 2 | using SceneServer.Core.Model.Actor; 3 | 4 | namespace SceneServer.Combat.Skills.SkillImpl 5 | { 6 | /// 7 | /// 风行术 8 | /// 9 | [SkillAttribute(2003)] 10 | public class Skill_Fengxingshu : Skill 11 | { 12 | public Skill_Fengxingshu(SceneActor owner, int skillId): base(owner, skillId) 13 | { 14 | 15 | } 16 | 17 | protected override void OnActive() 18 | { 19 | //Log.Information("风行术激活"); 20 | if(Target.RealObj is SceneActor actor) 21 | { 22 | //actor.buffManager.AddBuff(Owner); 23 | } 24 | 25 | } 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Net/Session.cs: -------------------------------------------------------------------------------- 1 | using Google.Protobuf; 2 | using Common.Summer.Core; 3 | using SceneServer.Core.Model.Actor; 4 | 5 | namespace SceneServer.Net 6 | { 7 | /// 8 | /// 用户会话,代表玩家客户端, 9 | /// 10 | public class Session 11 | { 12 | private string m_sessionId; 13 | private Connection m_conn; // 对应的网关连接 14 | public SceneCharacter Chr; 15 | 16 | public string SesssionId => m_sessionId; 17 | public Session(string sessionId, Connection conn) 18 | { 19 | m_sessionId = sessionId; 20 | m_conn = conn; 21 | } 22 | public void Send(IMessage message) 23 | { 24 | m_conn?.Send(message); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/Buffs/BuffImplement/InvincibleBuff.cs: -------------------------------------------------------------------------------- 1 | using SceneServer.Core.Model.Actor; 2 | using SceneServer.Utils; 3 | using System.Collections.Generic; 4 | 5 | namespace SceneServer.Core.Combat.Buffs.BuffImplement 6 | { 7 | // 无敌buff, 有这个buff的actor无法被攻击(也就是无法受到伤害) 8 | [BuffAttribute(5)] 9 | public class InvincibleBuff : BuffBase 10 | { 11 | public override BuffDefine GetBuffDefine() 12 | { 13 | return StaticDataManager.Instance.buffDefineDict.GetValueOrDefault(5); 14 | } 15 | public override void OnGet() 16 | { 17 | Owner.SetActorReciveDamageMode(false); 18 | } 19 | public override void OnLost() 20 | { 21 | Owner.SetActorReciveDamageMode(true); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Condition/IConditionChecker.cs: -------------------------------------------------------------------------------- 1 | using GameServer.Core.Model; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace GameServer.Core.Task.Condition 9 | { 10 | public interface IConditionChecker 11 | { 12 | public bool InitCondition(ConditionData condition, GameCharacter chr); 13 | public bool UnInitCondition(ConditionData condition, GameCharacter chr); 14 | public bool UpdateCondition(ConditionData condition, GameCharacter chr, Dictionary args); 15 | 16 | public bool IsNeedRegisterToScene() { return false; } 17 | public Dictionary ParseRemoteArgs(string args) 18 | { 19 | return null; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MMORPG/GameServer/Net/GameToken.cs: -------------------------------------------------------------------------------- 1 | using Google.Protobuf; 2 | using Common.Summer.Core; 3 | 4 | namespace GameServer.Net 5 | { 6 | public class GameToken 7 | { 8 | public string Id { get; private set; } 9 | public Connection Conn; //网络连接对象 10 | public float LastHeartTime { get; set; } //心跳时间 11 | public int ServerId { get; private set; } 12 | 13 | public GameToken(string sessionId, Connection connection, int serverId) 14 | { 15 | Id = sessionId; 16 | Conn = connection; 17 | ServerId = serverId; 18 | LastHeartTime = MyTime.time; 19 | } 20 | 21 | public void Send(IMessage message) 22 | { 23 | Conn?.Send(message); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/WoodenDummy/Impl/WoodenDummyMonsterAIState_Hurt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SceneServer.Core.Combat.AI.WoodenDummy.Impl 8 | { 9 | public class WoodenDummyMonsterAIState_Hurt : WoodenDummyMonsterAIState 10 | { 11 | private float hurtWaitTime = 2f; 12 | private float curWaitTime; 13 | 14 | public override void Enter() 15 | { 16 | curWaitTime = hurtWaitTime; 17 | } 18 | public override void Update(float deltaTime) 19 | { 20 | curWaitTime -= deltaTime; 21 | if (curWaitTime <= 0f) 22 | { 23 | monsterAI.ChangeState(MonsterAIState.Idle); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Condition/Impl/TalkNpcConditionChecker.cs: -------------------------------------------------------------------------------- 1 | using GameServer.Core.Model; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace GameServer.Core.Task.Condition.Impl 9 | { 10 | public class TalkNpcConditionChecker : IConditionChecker 11 | { 12 | public bool InitCondition(ConditionData condition, GameCharacter chr) 13 | { 14 | return true; 15 | } 16 | public bool UnInitCondition(ConditionData condition, GameCharacter chr) 17 | { 18 | return true; 19 | } 20 | 21 | public bool UpdateCondition(ConditionData condition, GameCharacter chr, Dictionary args) 22 | { 23 | throw new NotImplementedException(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Condition/Impl/CastSkillConditionChecker.cs: -------------------------------------------------------------------------------- 1 | using GameServer.Core.Model; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace GameServer.Core.Task.Condition.Impl 9 | { 10 | public class CastSkillConditionChecker : IConditionChecker 11 | { 12 | public bool InitCondition(ConditionData condition, GameCharacter chr) 13 | { 14 | return true; 15 | } 16 | 17 | public bool UnInitCondition(ConditionData condition, GameCharacter chr) 18 | { 19 | return true; 20 | } 21 | 22 | public bool UpdateCondition(ConditionData condition, GameCharacter chr, Dictionary args) 23 | { 24 | throw new NotImplementedException(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Condition/Impl/CollectItemConditionChecker.cs: -------------------------------------------------------------------------------- 1 | using GameServer.Core.Model; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace GameServer.Core.Task.Condition.Impl 9 | { 10 | public class CollectItemConditionChecker : IConditionChecker 11 | { 12 | public bool InitCondition(ConditionData condition, GameCharacter chr) 13 | { 14 | return true; 15 | } 16 | 17 | public bool UnInitCondition(ConditionData condition, GameCharacter chr) 18 | { 19 | return true; 20 | } 21 | 22 | public bool UpdateCondition(ConditionData condition, GameCharacter chr, Dictionary args) 23 | { 24 | throw new NotImplementedException(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Condition/Impl/EnterGameConditionChecker.cs: -------------------------------------------------------------------------------- 1 | using GameServer.Core.Model; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace GameServer.Core.Task.Condition.Impl 9 | { 10 | public class EnterGameConditionChecker : IConditionChecker 11 | { 12 | public bool InitCondition(ConditionData condition, GameCharacter chr) 13 | { 14 | return true; 15 | } 16 | 17 | public bool UnInitCondition(ConditionData condition, GameCharacter chr) 18 | { 19 | return true; 20 | } 21 | 22 | public bool UpdateCondition(ConditionData condition, GameCharacter chr, Dictionary args) 23 | { 24 | condition.CurValue++; 25 | return true; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /MMORPG/LoginServer/Net/LoginToken.cs: -------------------------------------------------------------------------------- 1 | using Google.Protobuf; 2 | using Common.Summer.Core; 3 | using HS.Protobuf.Common; 4 | 5 | namespace LoginGateServer.Net 6 | { 7 | public class LoginToken 8 | { 9 | public string Id { get; private set; } 10 | public Connection Conn; //网络连接对象 11 | public float LastHeartTime { get; set; } //心跳时间 12 | public ServerInfoNode ServerInfoNode { get; set; } 13 | 14 | public LoginToken(string sessionId, Connection connection , ServerInfoNode serverInfoNode) 15 | { 16 | Id = sessionId; 17 | Conn = connection; 18 | ServerInfoNode = serverInfoNode; 19 | LastHeartTime = MyTime.time; 20 | } 21 | 22 | public void Send(IMessage message) 23 | { 24 | Conn?.Send(message); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Condition/Impl/TaskCompletedChecker.cs: -------------------------------------------------------------------------------- 1 | using GameServer.Core.Model; 2 | using GameServer.Core.Task.Condition.Impl; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Numerics; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace GameServer.Core.Task.Condition.Impl 11 | { 12 | public class TaskCompletedChecker : IConditionChecker 13 | { 14 | public bool InitCondition(ConditionData condition, GameCharacter chr) 15 | { 16 | return true; 17 | } 18 | 19 | public bool UnInitCondition(ConditionData condition, GameCharacter chr) 20 | { 21 | return true; 22 | } 23 | 24 | public bool UpdateCondition(ConditionData condition, GameCharacter chr, Dictionary args) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Reward/Impl/ItemRewardHandler.cs: -------------------------------------------------------------------------------- 1 | using GameServer.Core.Model; 2 | using HS.Protobuf.Backpack; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Numerics; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace GameServer.Core.Task.Reward.Impl 11 | { 12 | public class ItemRewardHandler : IRewardHandler 13 | { 14 | public void GrantReward(RewardData rewardData, GameCharacter chr) 15 | { 16 | int itemId = int.Parse(rewardData.Parameters[0]); 17 | int count = int.Parse(rewardData.Parameters[1]); 18 | chr.BackPackManager.AddGameItem(itemId, count); 19 | 20 | // todo 21 | var resp = new GetItemInventoryDataResponse(); 22 | resp.SessionId = chr.SessionId; 23 | resp.Node = chr.BackPackManager.NetItemInventoryDataNode; 24 | chr.SendToGate(resp); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MMORPG/Llua/State/LuaValue.cs: -------------------------------------------------------------------------------- 1 | using lLua.Api; 2 | 3 | 4 | namespace lLua.State 5 | { 6 | public class LuaValue 7 | { 8 | public object Value { get; set; } 9 | public LuaValue() { } 10 | public LuaValue(object value) 11 | { 12 | Value = value; 13 | } 14 | } 15 | 16 | public class LuaDataTypeHelper 17 | { 18 | public static LuaDataType TypeOf(object val) 19 | { 20 | return val switch 21 | { 22 | null => LuaDataType.LUA_TNIL, 23 | bool => LuaDataType.LUA_TBOOLEAN, 24 | int => LuaDataType.LUA_TNUMBER, 25 | long => LuaDataType.LUA_TNUMBER, 26 | float => LuaDataType.LUA_TNUMBER, 27 | double => LuaDataType.LUA_TNUMBER, 28 | string => LuaDataType.LUA_TSTRING, 29 | _ => throw new NotImplementedException("Unhandled type!") 30 | }; 31 | } 32 | } 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /MMORPG/DBProxyServer/Core/Conn/MongodbConnection.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Tools; 2 | using MongoDB.Driver; 3 | using Serilog; 4 | 5 | namespace DBProxyServer.Core 6 | { 7 | public class MongoDBConnection:Singleton 8 | { 9 | private IMongoDatabase? m_database; 10 | 11 | public void Init(string connectionString, string databaseName) 12 | { 13 | var client = new MongoClient(connectionString); 14 | m_database = client.GetDatabase(databaseName); 15 | UserOperations.Instance.Init(this); 16 | CharacterOperations.Instance.Init(this); 17 | WorldOperations.Instance.Init(this); 18 | TaskOperations.Instance.Init(this); 19 | InventoryOperations.Instance.Init(this); 20 | Log.Information("Successfully connect to MongoDB"); 21 | } 22 | 23 | public IMongoCollection GetCollection(string collectionName) 24 | { 25 | return m_database.GetCollection(collectionName); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/Boss/Impl/BossMonsterAIState_ReturnBrith.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using HS.Protobuf.SceneEntity; 3 | using SceneServer.Core.Combat.AI.MonsterAIStateImpl; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace SceneServer.Core.Combat.AI.MonsterAi.MonsterAIStateImpl 11 | { 12 | public class BossMonsterAIState_ReturnBrith : BossMonsterAIState 13 | { 14 | public override void Enter() 15 | { 16 | monsterAI.Monster.StartMoveToPoint(monsterAI.Monster.m_initPosition, monsterAI.patrolSpeed); 17 | } 18 | 19 | public override void Update(float deltaTime) 20 | { 21 | // 接近到出生点就切换为巡逻状态 22 | if (Vector3.Distance(monsterAI.Monster.m_initPosition, monsterAI.Monster.Position) < 100) 23 | { 24 | monsterAI.ChangeState(MonsterAIState.Patrol); 25 | goto End; 26 | } 27 | 28 | End: 29 | return; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Reward/TaskRewardParser.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Tools; 2 | using GameServer.Core.Model; 3 | using GameServer.Core.Task.Reward.Impl; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Numerics; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace GameServer.Core.Task.Reward 12 | { 13 | public class TaskRewardParser : Singleton 14 | { 15 | private Dictionary _handlers = new Dictionary(); 16 | 17 | public void Init() 18 | { 19 | _handlers["Item"] = new ItemRewardHandler(); 20 | _handlers["SkillChain"] = new SkillChainRewardHandler(); 21 | _handlers["Skill"] = new SkillRewardHandler(); 22 | } 23 | 24 | public void GrantRewards(RewardData rewardData, GameCharacter chr) 25 | { 26 | if (_handlers.TryGetValue(rewardData.rewardType, out var handler)) 27 | { 28 | handler.GrantReward(rewardData, chr); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Model/Item/SceneItem.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using HS.Protobuf.Common; 3 | using HS.Protobuf.Backpack; 4 | using HS.Protobuf.SceneEntity; 5 | 6 | namespace SceneServer.Core.Model.Item 7 | { 8 | public class SceneItem : SceneEntity 9 | { 10 | private NetItemNode m_netItemNode; 11 | 12 | public NetItemNode NetItemNode => m_netItemNode; 13 | 14 | public void Init(NetItemDataNode itemDataNode, Vector3Int pos, Vector3Int dir, Vector3Int scale) 15 | { 16 | base.Init(pos, dir, scale); 17 | m_netItemNode = new NetItemNode(); 18 | m_netItemNode.NetItemDataNode = itemDataNode; 19 | 20 | var transform = new NetTransform(); 21 | m_netItemNode.Transform = transform; 22 | transform.Position = new NetVector3(); 23 | transform.Rotation = new NetVector3(); 24 | transform.Scale = new NetVector3(); 25 | m_netItemNode.Transform.Position = Position; 26 | m_netItemNode.Transform.Rotation = Rotation; 27 | m_netItemNode.Transform.Scale = Scale; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Core/MyTime.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Common.Summer.Core 4 | { 5 | //时间单位 6 | public enum TimeUnit 7 | { 8 | Milliseconds, 9 | Seconds, 10 | Minutes, 11 | Hours, 12 | Days 13 | } 14 | 15 | //时间 16 | public class MyTime 17 | { 18 | //游戏开始的时间戳 19 | private static long startTime = DateTimeOffset.Now.ToUnixTimeMilliseconds(); 20 | 21 | //游戏的运行时间(秒),帧开始的时间 22 | public static float time { get; private set; } 23 | 24 | //上一帧运行所用的时间 25 | public static float deltaTime { get; private set; } 26 | 27 | // 记录最后一次tick的时间 28 | private static long lastTick = 0; 29 | 30 | /// 31 | /// 由Schedule调用,请不要自行调用,除非你知道自己在做什么!!! 32 | /// 33 | public static void Tick() 34 | { 35 | long now = DateTimeOffset.Now.ToUnixTimeMilliseconds(); 36 | time = (now - startTime) * 0.001f; 37 | if (lastTick == 0) lastTick = now; 38 | deltaTime = (now - lastTick) * 0.001f;//deltaTime是以秒作为单位的 39 | lastTick = now; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /MMORPG/GameServer/Net/GameTokenManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using Common.Summer.Tools; 3 | using Common.Summer.Core; 4 | using System; 5 | 6 | namespace GameServer.Net 7 | { 8 | public class GameTokenManager : Singleton 9 | { 10 | private ConcurrentDictionary m_tokens = new ConcurrentDictionary(); 11 | 12 | public void Init() 13 | { 14 | } 15 | 16 | public GameToken NewToken(Connection connection, int serverId) 17 | { 18 | var token = new GameToken(Guid.NewGuid().ToString(), connection, serverId); 19 | m_tokens[token.Id] = token; 20 | return token; 21 | } 22 | public void RemoveToken(string tokenId) 23 | { 24 | m_tokens.TryRemove(tokenId, out var token); 25 | if (token != null) 26 | { 27 | token.Conn = null; 28 | } 29 | } 30 | public GameToken GetToken(string tokenId) 31 | { 32 | if (m_tokens.TryGetValue(tokenId, out var token)) 33 | { 34 | return token; 35 | } 36 | return null; 37 | } 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Scene/Component/SceneMonsterManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Common.Summer.Core; 3 | using SceneServer.Core.Model.Actor; 4 | 5 | namespace SceneServer.Core.Scene.Component 6 | { 7 | // 每个地图中都有一个怪物管理器 8 | public class SceneMonsterManager 9 | { 10 | public Dictionary monsterDict = new(); // 11 | 12 | public void Init() 13 | { 14 | 15 | } 16 | public void UnInit() 17 | { 18 | monsterDict.Clear(); 19 | } 20 | 21 | public SceneMonster Create(int professionId, int level, Spawner spawner) 22 | { 23 | // 怪物初始化 24 | SceneMonster monster = new SceneMonster(); 25 | SceneEntityManager.Instance.AddSceneEntity(monster); 26 | monster.Init(professionId, level, spawner); 27 | monster.NetActorNode.EntityId = monster.EntityId; 28 | 29 | // 添加到当前的mostermanager中管理 30 | monsterDict[monster.EntityId] = monster; 31 | 32 | // 显示到当前场景 33 | SceneManager.Instance.MonsterEnterScene(monster); 34 | 35 | monster.Init2(); 36 | return monster; 37 | } 38 | 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /MMORPG/LoginServer/Core/LoginServerMonitor.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Tools; 3 | using HS.Protobuf.Common; 4 | using LoginGateServer.Net; 5 | using Serilog; 6 | 7 | namespace LoginServer.Core 8 | { 9 | public class LoginServerMonitor : Singleton 10 | { 11 | public bool Init() 12 | { 13 | return true; 14 | } 15 | 16 | public string RegisterLoginGateInstance(Connection conn, ServerInfoNode serverInfoNode) 17 | { 18 | Log.Information("Register LoginGateInstance , {0}", serverInfoNode); 19 | // 分配一下连接token 20 | LoginToken token = LoginTokenManager.Instance.NewToken(conn, serverInfoNode); 21 | conn.Set(token); 22 | return token.Id; 23 | } 24 | public void HaveLoginGateInstanceDisconnect(Connection conn) 25 | { 26 | // token回收 27 | var token = conn.Get(); 28 | if (token != null) 29 | { 30 | Log.Error("disconnection LoginGateInstance , serverId = [{0}]", token.ServerInfoNode.ServerId); 31 | LoginTokenManager.Instance.RemoveToken(conn.Get().Id); 32 | } 33 | } 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Condition/Impl/LevelConditionChecker.cs: -------------------------------------------------------------------------------- 1 | using GameServer.Core.Model; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Numerics; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace GameServer.Core.Task.Condition.Impl 10 | { 11 | // 示例:检查玩家等级 12 | public class LevelConditionChecker : IConditionChecker 13 | { 14 | public bool InitCondition(ConditionData condition, GameCharacter chr) 15 | { 16 | int targetLevel = int.Parse(condition.Parameters[0]); 17 | if(chr.Level >= targetLevel) 18 | { 19 | condition.CurValue = 1; 20 | } 21 | return true; 22 | } 23 | 24 | public bool UnInitCondition(ConditionData condition, GameCharacter chr) 25 | { 26 | return true; 27 | } 28 | 29 | public bool UpdateCondition(ConditionData condition, GameCharacter chr, Dictionary args) 30 | { 31 | // Level:1 32 | int targetLevel = int.Parse(condition.Parameters[0]); 33 | if (chr.Level >= targetLevel) 34 | { 35 | condition.CurValue = 1; 36 | } 37 | return true; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /MMORPG/ControlCenter/Core/ControlCenterHandler.cs: -------------------------------------------------------------------------------- 1 | 2 | using Common.Summer.Core; 3 | using Common.Summer.Net; 4 | using Common.Summer.Tools; 5 | using HS.Protobuf.ControlCenter; 6 | 7 | namespace ControlCenter.Core 8 | { 9 | public class ControlCenterHandler : Singleton 10 | { 11 | public bool Init() 12 | { 13 | // 协议注册 14 | ProtoHelper.Instance.Register((int)ControlCenterProtocl.GetAllserverinfoReq); 15 | ProtoHelper.Instance.Register((int)ControlCenterProtocl.GetAllserverinfoResp); 16 | // 消息订阅 17 | MessageRouter.Instance.Subscribe(_HandleGetAllServerInfoRequest); 18 | 19 | return true; 20 | } 21 | public bool UnInit() 22 | { 23 | return true; 24 | } 25 | private void _HandleGetAllServerInfoRequest(Connection conn, GetAllServerInfoRequest message) 26 | { 27 | var resp = new GetAllServerInfoResponse(); 28 | var list = ServersMgr.Instance.GetAllServerInfoByServerType(message.ServerType); 29 | resp.ServerType = message.ServerType; 30 | resp.ServerInfoNodes.AddRange(list); 31 | conn.Send(resp); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Net/TypeAttributeStore.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Common.Summer.Net 4 | { 5 | /// 6 | /// 一个通用的属性存储(自定义的) 7 | /// 缺点:同一个类型只能存储一个 8 | /// 9 | public class TypeAttributeStore 10 | { 11 | private Dictionary _dict = new Dictionary(); 12 | 13 | /// 14 | /// 根据类型存放属性 15 | /// 16 | /// 17 | /// 18 | public void Set(T value) 19 | { 20 | string key = typeof(T).FullName; 21 | if (!_dict.ContainsKey(key)) 22 | { 23 | _dict.Add(key, value); 24 | } 25 | else 26 | { 27 | _dict[key] = value; 28 | } 29 | } 30 | 31 | /// 32 | /// 根据类型获取属性 33 | /// 34 | /// 35 | /// 36 | public T Get() 37 | { 38 | string key = typeof(T).FullName; 39 | if (_dict.ContainsKey(key)) 40 | { 41 | return (T)_dict[key]; 42 | } 43 | return default; 44 | } 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/AOIMap/Linked/Base/AoiEntity.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace SceneServer.Core.AOI 3 | { 4 | /// 5 | /// AOI结果,描述了哪个人,在哪,他身边有谁。 6 | /// 7 | public sealed class AoiEntity 8 | { 9 | public readonly long Key; // entityId 10 | public AoiNode X; 11 | public AoiNode Y; 12 | // todo ViewEntity极其容易被修改 13 | public HashSet ViewEntity; // 本次视野空间附近的人,不包括自己 14 | private HashSet ViewEntityBak; // 上次视野空间附近的人 15 | 16 | public IEnumerable Leave => ViewEntityBak.Except(ViewEntity); 17 | public IEnumerable Newly => ViewEntity.Except(ViewEntityBak); 18 | 19 | public AoiEntity(long key) 20 | { 21 | Key = key; 22 | ViewEntity = new HashSet(); 23 | ViewEntityBak = new HashSet(); 24 | } 25 | 26 | // tools 27 | public void RecordCurViewAndClear() 28 | { 29 | ViewEntityBak.Clear(); 30 | 31 | var t3 = ViewEntity; 32 | ViewEntity = ViewEntityBak; 33 | ViewEntityBak = t3; 34 | } 35 | public List GetViewEntityIds() 36 | { 37 | List ids = ViewEntity.ToList(); 38 | return ids; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Proto/Game/ProtoSource/GameGate.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | import "Common/ProtoSource/Common.proto"; 3 | package HS.Protobuf.GameGate; 4 | 5 | enum GameGateProtocl{ 6 | GAMEGATE_PROTOCL_NONE = 0; 7 | GAMEGATE_PROTOCL_REGISTER_SESSION_TO_GG_REQ = 31001; // [RegisterSessionToGGRequest] 8 | GAMEGATE_PROTOCL_REGISTER_SESSION_TO_GG_RESP = 31002; // [RegisterSessionToGGResponse] 9 | GAMEGATE_PROTOCL_REGISTER_SCENES_TO_GG_REQ = 31003; // [RegisterSceneToGGRequest] 10 | GAMEGATE_PROTOCL_REGISTER_SCENES_TO_GG_RESP = 31004; // [RegisterSceneToGGResponse] 11 | GAMEGATE_PROTOCL_VERIFY_SESSION_REQ = 31005; // [VerifySessionRequeest] 12 | GAMEGATE_PROTOCL_VERIFY_SESSION_RESP = 31006; // [VerifySessionResponse] 13 | } 14 | 15 | message RegisterSessionToGGRequest{ 16 | string sessionId = 1; 17 | string uId = 2; 18 | } 19 | message RegisterSessionToGGResponse{ 20 | int32 resultCode = 1; 21 | string resultMsg = 2; 22 | } 23 | 24 | message RegisterSceneToGGRequest{ 25 | repeated HS.Protobuf.Common.ServerInfoNode sceneInfos = 1; 26 | } 27 | message RegisterSceneToGGResponse{ 28 | int32 resultCode = 1; 29 | string resultMsg = 2; 30 | int32 serverId = 3; 31 | } 32 | 33 | message VerifySessionRequeest{ 34 | string sessionId = 1; 35 | } 36 | message VerifySessionResponse{ 37 | int32 resultCode = 1; 38 | string resultMsg = 2; 39 | } -------------------------------------------------------------------------------- /MMORPG/DBProxyServer/Handle/DBProxyServerHandler.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Tools; 4 | using DBProxyServer.Net; 5 | using HS.Protobuf.ControlCenter; 6 | using HS.Protobuf.Game; 7 | using Serilog; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Linq; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | 14 | namespace DBProxyServer.Handle 15 | { 16 | public class DBProxyServerHandler : Singleton 17 | { 18 | public override void Init() 19 | { 20 | // 协议注册 21 | ProtoHelper.Instance.Register((int)ControlCenterProtocl.ClusterEventResp); 22 | 23 | // 消息的订阅 24 | MessageRouter.Instance.Subscribe(_HandleClusterEventResponse); 25 | } 26 | 27 | private void _HandleClusterEventResponse(Connection conn, ClusterEventResponse message) 28 | { 29 | if (message.ClusterEventNode.EventType == ClusterEventType.MastertimeEnter) 30 | { 31 | Log.Debug("A new MT server has joined the cluster, {0}", message.ClusterEventNode.ServerInfoNode); 32 | DBProxyServersMgr.Instance.AddMTServerInfo(message.ClusterEventNode.ServerInfoNode); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MMORPG/LoginServer/Net/LoginTokenManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using Common.Summer.Tools; 3 | using Common.Summer.Core; 4 | using LoginServer.Net; 5 | using HS.Protobuf.Common; 6 | using HS.Protobuf.Login; 7 | using Common.Summer.Net; 8 | 9 | namespace LoginGateServer.Net 10 | { 11 | public class LoginTokenManager : Singleton 12 | { 13 | private ConcurrentDictionary m_tokens = new ConcurrentDictionary(); 14 | 15 | public void Init() 16 | { 17 | 18 | } 19 | 20 | public LoginToken NewToken(Connection connection, ServerInfoNode serverInfoNode) 21 | { 22 | var token = new LoginToken(Guid.NewGuid().ToString(), connection, serverInfoNode); 23 | m_tokens[token.Id] = token; 24 | return token; 25 | } 26 | public void RemoveToken(string tokenId) 27 | { 28 | m_tokens.TryRemove(tokenId, out var token); 29 | if (token != null) 30 | { 31 | token.Conn = null; 32 | } 33 | } 34 | public LoginToken GetToken(string tokenId) 35 | { 36 | if (m_tokens.TryGetValue(tokenId, out var token)) 37 | { 38 | return token; 39 | } 40 | return null; 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Scene/Component/SpawnManager.cs: -------------------------------------------------------------------------------- 1 | using SceneServer.Utils; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace SceneServer.Core.Scene.Component 9 | { 10 | //刷怪管理器,每个场景都会有一个 11 | public class SpawnManager 12 | { 13 | public List m_spawners = new List(); 14 | public void Init() 15 | { 16 | //根据当前场景加载对应的规则 17 | int sceneId = SceneManager.Instance.SceneId; 18 | var spawnDefines = StaticDataManager.Instance.spawnDefineDict.Values 19 | .Where(r => r.SpaceId == sceneId && r.SpawnNum > 0); 20 | foreach (var define in spawnDefines) 21 | { 22 | for (int i = 0; i < define.SpawnNum; i++) 23 | { 24 | var spawner = new Spawner(); 25 | spawner.Init(define); 26 | m_spawners.Add(spawner); 27 | } 28 | } 29 | } 30 | public void UnInit() 31 | { 32 | m_spawners.Clear(); 33 | } 34 | public void Update(float deltaTime) 35 | { 36 | foreach(var spawner in m_spawners) 37 | { 38 | spawner.Update(deltaTime); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Tools/IdGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace Common.Summer.Tools 10 | { 11 | /// 12 | /// id生成器 13 | /// 14 | public class IdGenerator 15 | { 16 | private int _currentMaxId; // 用于记录当前分配到的最大ID 17 | private ConcurrentBag _recycledIds; // 存储回收的ID,线程安全 18 | 19 | public IdGenerator() 20 | { 21 | _currentMaxId = 0; 22 | _recycledIds = new ConcurrentBag(); 23 | } 24 | 25 | // 获取新的ID 26 | public int GetId() 27 | { 28 | // 首先尝试从_recycledIds中获取一个可重复利用的ID 29 | if (_recycledIds.TryTake(out int recycledId)) 30 | { 31 | return recycledId; 32 | } 33 | 34 | // 如果没有可重复利用的ID,则生成一个新的ID 35 | // 使用Interlocked.Increment来确保操作的原子性,防止多线程下的数据竞争问题 36 | return Interlocked.Increment(ref _currentMaxId); 37 | } 38 | 39 | // 归还不再使用的ID,以便将来重复利用 40 | public void ReturnId(int id) 41 | { 42 | if (id <= 0) 43 | { 44 | throw new ArgumentException("ID must be greater than 0."); 45 | } 46 | 47 | _recycledIds.Add(id); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Handle/SceneServerHandler.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Tools; 4 | using HS.Protobuf.ControlCenter; 5 | using SceneServer.Net; 6 | using Serilog; 7 | 8 | namespace SceneServer.Handle 9 | { 10 | public class SceneServerHandler : Singleton 11 | { 12 | public void Init() 13 | { 14 | // 协议注册 15 | ProtoHelper.Instance.Register((int)ControlCenterProtocl.ClusterEventResp); 16 | // 消息的订阅 17 | MessageRouter.Instance.Subscribe(_HandleClusterEventResponse); 18 | } 19 | public void UnInit() 20 | { 21 | } 22 | private void _HandleClusterEventResponse(Connection sender, ClusterEventResponse message) 23 | { 24 | if (message.ClusterEventNode.EventType == ClusterEventType.DbproxyEnter) 25 | { 26 | Log.Debug("A new DBProxy Server has joined the cluster."); 27 | ServersMgr.Instance.AddDBServerInfo(message.ClusterEventNode.ServerInfoNode); 28 | } 29 | else if (message.ClusterEventNode.EventType == ClusterEventType.GamegatemgrEnter) 30 | { 31 | Log.Debug("A new GameGateMgr Server has joined the cluster."); 32 | ServersMgr.Instance.AddGGMServerInfo(message.ClusterEventNode.ServerInfoNode); 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /MMORPG/ControlCenter/Utils/Config.cs: -------------------------------------------------------------------------------- 1 | using YamlDotNet.Serialization; 2 | 3 | namespace ControlCenter.Utils 4 | { 5 | public class ServerConfig 6 | { 7 | [YamlMember(Alias = "ip")] 8 | public string ip { get; set; } 9 | 10 | [YamlMember(Alias = "port")] 11 | public int port { get; set; } 12 | 13 | [YamlMember(Alias = "workerCount")] 14 | public int workerCount { get; set; } 15 | 16 | [YamlMember(Alias = "updateHz")] 17 | public int updateHz { get; set; } 18 | 19 | [YamlMember(Alias = "heartBeatTimeOut")] 20 | public float heartBeatTimeOut { get; set; } 21 | 22 | [YamlMember(Alias = "heartBeatCheckInterval")] 23 | public float heartBeatCheckInterval { get; set; } 24 | } 25 | 26 | public class AppConfig 27 | { 28 | [YamlMember(Alias = "server")] 29 | public ServerConfig Server { get; set; } 30 | } 31 | 32 | public static class Config 33 | { 34 | private static AppConfig _config; 35 | public static void Init(string filePath = "config.yaml") 36 | { 37 | // 读取配置文件,当前项目根目录 38 | var yaml = File.ReadAllText(filePath); 39 | 40 | // 反序列化配置文件 41 | var deserializer = new DeserializerBuilder().Build(); 42 | _config = deserializer.Deserialize(yaml); 43 | } 44 | public static ServerConfig Server => _config?.Server; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /MMORPG/MasterTimerServer/Handler/TimeSyncHandler.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Tools; 4 | using HS.Protobuf.Login; 5 | using HS.Protobuf.MasterTime; 6 | using MasterTimerServer.Core; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | 13 | namespace MasterTimerServer.Handler 14 | { 15 | public class TimeSyncHandler : Singleton 16 | { 17 | public override void Init() 18 | { 19 | ProtoHelper.Instance.Register((int)MasterTimeProtocl.TimeSyncReq); 20 | ProtoHelper.Instance.Register((int)MasterTimeProtocl.TimeSyncResp); 21 | MessageRouter.Instance.Subscribe(_HandleTimeSyncRequest); 22 | } 23 | 24 | private void _HandleTimeSyncRequest(Connection conn, TimeSyncRequest message) 25 | { 26 | // 接收请求时记录精确时间戳 27 | var receiveTime = TimeMonitor.Instance.GetUnixTimeMilliseconds; 28 | 29 | // 构建响应包(包含三级时间标记) 30 | var resp = new TimeSyncResponse 31 | { 32 | ClientSendTime = message.ClientSendTime, 33 | ServerReceiveTime = receiveTime, 34 | ServerSendTime = TimeMonitor.Instance.GetUnixTimeMilliseconds // 发送响应时间 35 | }; 36 | 37 | conn.Send(resp); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Condition/Impl/KillMonsterConditionChecker.cs: -------------------------------------------------------------------------------- 1 | using GameServer.Core.Model; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace GameServer.Core.Task.Condition.Impl 9 | { 10 | public class KillMonsterConditionChecker : IConditionChecker 11 | { 12 | public bool InitCondition(ConditionData condition, GameCharacter chr) 13 | { 14 | // 主要是设置target 和 cur 15 | condition.CurValue = 0; 16 | condition.TargetValue = int.Parse(condition.Parameters[1]); 17 | return true; 18 | } 19 | 20 | public bool UnInitCondition(ConditionData condition, GameCharacter chr) 21 | { 22 | return true; 23 | } 24 | 25 | public bool UpdateCondition(ConditionData condition, GameCharacter chr, Dictionary args) 26 | { 27 | // KillMonster:1001=2 28 | int targetPid = int.Parse(condition.Parameters[0]); 29 | int curPid = (int)args["professionId"]; 30 | if(targetPid != curPid) 31 | { 32 | return false; 33 | } 34 | condition.CurValue += 1; 35 | return true; 36 | } 37 | 38 | bool IConditionChecker.InitCondition(ConditionData condition, GameCharacter chr) 39 | { 40 | throw new NotImplementedException(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/Boss/Impl/BossMonsterAIState_Hurt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SceneServer.Core.Combat.AI.MonsterAIStateImpl 8 | { 9 | public class BossMonsterAIState_Hurt : BossMonsterAIState 10 | { 11 | private float hurtWaitTime = 1f; 12 | private float curWaitTime; 13 | 14 | public override void Enter() 15 | { 16 | curWaitTime = hurtWaitTime; 17 | } 18 | public override void Update(float deltaTime) 19 | { 20 | curWaitTime -= deltaTime; 21 | if(curWaitTime <= 0f) 22 | { 23 | if (((float)monsterAI.Monster.CurHP / monsterAI.Monster.MaxHP) < 0.05f) 24 | { 25 | monsterAI.ChangeState(MonsterAIState.Flee); 26 | } 27 | else if(monsterAI.IsTargetInRange(monsterAI.maxAttackDistance)) 28 | { 29 | monsterAI.ChangeState(MonsterAIState.Attack); 30 | } 31 | else if (monsterAI.IsTargetInRange(monsterAI.maxChaseDistance)) 32 | { 33 | monsterAI.ChangeState(MonsterAIState.Attack); 34 | } 35 | else 36 | { 37 | monsterAI.ChangeState(MonsterAIState.Patrol); 38 | } 39 | } 40 | } 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Time/HighPrecisionClock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace Common.Summer.Time 5 | { 6 | public class HighPrecisionClock 7 | { 8 | private readonly DateTimeOffset _baseTime; 9 | private readonly long _baseTimestamp; 10 | private readonly double _tickToMilliFactor; // 这是每个stopwatch刻度的时间,单位是毫秒 11 | 12 | public HighPrecisionClock() 13 | { 14 | _baseTime = DateTimeOffset.UtcNow; 15 | _baseTimestamp = Stopwatch.GetTimestamp(); 16 | _tickToMilliFactor = 1000.0 / Stopwatch.Frequency; // == (1 / Stopwatch.Frequency) * 1000 17 | } 18 | 19 | /// 20 | /// 获取当前UTC时间的Unix时间戳(毫秒级) 21 | /// 22 | public long GetUnixTimeMilliseconds() 23 | { 24 | // 手动计算流逝时间 25 | long currentTicks = Stopwatch.GetTimestamp(); 26 | long elapsedTicks = currentTicks - _baseTimestamp; 27 | TimeSpan elapsed = new TimeSpan((long)(elapsedTicks * (TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency))); 28 | 29 | DateTimeOffset currentTime = _baseTime.Add(elapsed); 30 | return currentTime.ToUnixTimeMilliseconds(); 31 | } 32 | 33 | /// 34 | /// 获取程序启动后的流逝时间(毫秒) 35 | /// 36 | public long GetElapsedMilliseconds() 37 | { 38 | long elapsedTicks = Stopwatch.GetTimestamp() - _baseTimestamp; 39 | return (long)(elapsedTicks * _tickToMilliFactor); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /MMORPG/Common/Common.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/Boss/Impl/BossMonsterAIState_Chase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SceneServer.Core.Combat.AI.MonsterAIStateImpl 8 | { 9 | public class BossMonsterAIState_Chase : BossMonsterAIState 10 | { 11 | public override void Enter() 12 | { 13 | monsterAI.Monster.StartMoveToPoint(monsterAI.Target.Position, (int)(monsterAI.chaseSpeed)); 14 | } 15 | 16 | public override void Update(float deltaTime) 17 | { 18 | if (monsterAI.CheckExceedMaxBrithDistance()) 19 | { 20 | monsterAI.ChangeState(MonsterAIState.Rturn); 21 | goto End; 22 | } 23 | 24 | if (monsterAI.IsTargetInRange(monsterAI.maxAttackDistance)) 25 | { 26 | monsterAI.ChangeState(MonsterAIState.Attack); 27 | goto End; 28 | } 29 | 30 | if (!monsterAI.IsTargetInRange(monsterAI.maxChaseDistance)) 31 | { 32 | monsterAI.ChangeState(MonsterAIState.Patrol); 33 | monsterAI.ClearTarget(); 34 | goto End; 35 | } 36 | 37 | monsterAI.Monster.StartMoveToPoint(monsterAI.Target.Position, monsterAI.chaseSpeed); 38 | 39 | End: 40 | return; 41 | } 42 | 43 | public override void Exit() 44 | { 45 | monsterAI.Monster.StopMove(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /MMORPG/GameGateServer/Net/Session.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Google.Protobuf; 3 | using Serilog; 4 | using System.Collections.Concurrent; 5 | 6 | namespace GameGateServer.Net 7 | { 8 | /// 9 | /// 用户会话,代表玩家客户端,只有登录成功的用户才分配给他session 10 | /// 11 | public class Session 12 | { 13 | public string Id { get; private set; } 14 | public string m_uId; 15 | public string m_cId; 16 | public int curSceneId; 17 | public Connection Conn; 18 | 19 | public float LastHeartTime; // 用myTime 20 | private ConcurrentQueue msgBuffer = new ConcurrentQueue(); 21 | 22 | public Session(string sessionId, string Uid) 23 | { 24 | Id = sessionId; 25 | m_uId = Uid; 26 | LastHeartTime = Scheduler.UnixTime; 27 | } 28 | public void Send(IMessage message) 29 | { 30 | if (Conn != null) 31 | { 32 | while (msgBuffer.TryDequeue(out var msg)) 33 | { 34 | Log.Information("补发消息:" + msg); 35 | Conn.Send(msg); 36 | } 37 | Conn.Send(message); 38 | } 39 | else 40 | { 41 | //说明当前角色离线了,我们将数据写入缓存中 42 | msgBuffer.Enqueue(message); 43 | } 44 | } 45 | public void Send(ByteString message) 46 | { 47 | if(Conn != null) 48 | { 49 | Conn.Send(message); 50 | } 51 | } 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/Skill/SCObject.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using SceneServer.Core.Model; 3 | 4 | namespace SceneServer.Core.Combat.Skills 5 | { 6 | /// 7 | /// Server-Client-Object,用于代理(一个人和一个坐标) 8 | /// 9 | public abstract class SCObject 10 | { 11 | protected object realObj; 12 | public SCObject(object realobj) 13 | { 14 | realObj = realobj; 15 | } 16 | 17 | public int Id => GetId(); 18 | public object RealObj => GetRealObj(); 19 | public Vector3 Position => GetPosition(); 20 | public Vector3 Direction => GetDirection(); 21 | 22 | 23 | protected virtual int GetId() => 0; 24 | protected virtual object GetRealObj() => realObj; 25 | protected virtual Vector3 GetPosition() => Vector3.Zero; 26 | protected virtual Vector3 GetDirection() => Vector3.Zero; 27 | 28 | } 29 | 30 | //定义SCEntity类,继承自SCObject 31 | public class SCEntity : SCObject 32 | { 33 | private SceneEntity Obj { get => (SceneEntity)realObj; } 34 | public SCEntity(SceneEntity realobj) : base(realobj) 35 | { 36 | } 37 | 38 | protected override int GetId() => Obj.EntityId; 39 | protected override Vector3 GetDirection() => Obj.Rotation; 40 | protected override Vector3 GetPosition() => Obj.Position; 41 | 42 | } 43 | 44 | public class SCPosition : SCObject 45 | { 46 | public SCPosition(Vector3 realobj) : base(realobj) 47 | { 48 | } 49 | protected override Vector3 GetPosition() => (Vector3)realObj; 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /MMORPG/LoginGateServer/Net/LoginGateTokenManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using Common.Summer.Tools; 3 | using Common.Summer.Core; 4 | using HS.Protobuf.Login; 5 | using HS.Protobuf.LoginGate; 6 | using Common.Summer.Net; 7 | 8 | namespace LoginGateServer.Net 9 | { 10 | public class LoginGateTokenManager : Singleton 11 | { 12 | private ConcurrentDictionary m_tokens = new ConcurrentDictionary(); 13 | 14 | public void Init() 15 | { 16 | // 协议注册 17 | ProtoHelper.Instance.Register((int)LoginGateProtocl.GetLogingateTokenResp); 18 | 19 | } 20 | 21 | public LoginGateToken NewToken(Connection connection) 22 | { 23 | var token = new LoginGateToken(Guid.NewGuid().ToString(), connection); 24 | m_tokens[token.Id] = token; 25 | 26 | GetLoginGateTokenResponse resp = new GetLoginGateTokenResponse(); 27 | resp.LoginGateToken = token.Id; 28 | connection.Send(resp); 29 | 30 | return token; 31 | } 32 | public LoginGateToken GetToken(string tokenId) 33 | { 34 | if (m_tokens.TryGetValue(tokenId, out var token)) 35 | { 36 | return token; 37 | } 38 | return null; 39 | } 40 | public void RemoveToken(string tokenId) 41 | { 42 | m_tokens.TryRemove(tokenId, out var token); 43 | if (token != null) 44 | { 45 | token.Conn = null; 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /MMORPG/LoginServer/Net/SessionManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using Common.Summer.Tools; 3 | 4 | namespace LoginServer.Net 5 | { 6 | public class SessionManager : Singleton 7 | { 8 | //session字典 9 | private ConcurrentDictionary sessions1 = new ConcurrentDictionary(); 10 | // 11 | private ConcurrentDictionary sessions2 = new ConcurrentDictionary(); 12 | 13 | public void Init() 14 | { 15 | } 16 | public Session NewSession(string uId) 17 | { 18 | var session = new Session(Guid.NewGuid().ToString()); 19 | sessions1[session.Id] = session; 20 | sessions2[uId] = session; 21 | return session; 22 | } 23 | public Session GetSessionBySessionId(string sessionId) 24 | { 25 | if (sessions1.TryGetValue(sessionId, out var session)) 26 | { 27 | return session; 28 | } 29 | return null; 30 | } 31 | public Session GetSessionByUId(string uId) 32 | { 33 | if (sessions2.TryGetValue(uId, out var session)) 34 | { 35 | return session; 36 | } 37 | return null; 38 | } 39 | 40 | public void RemoveSession(string sessionId) 41 | { 42 | sessions1.TryRemove(sessionId, out var session); 43 | if(session != null) 44 | { 45 | sessions2.TryRemove(session.dbUser.UId, out _); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/StaticData/ErrorCode.cs: -------------------------------------------------------------------------------- 1 | using Serilog; 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | namespace Common.Summer.StaticData 6 | { 7 | public static class ErrorCode 8 | { 9 | private static Dictionary _codeMap = new(); 10 | private static Dictionary _descMap = new(); 11 | private static readonly string jsonFilePath = "ErrorCodeDefine.json"; 12 | 13 | static ErrorCode() 14 | { 15 | try 16 | { 17 | var errorCodes = StaticDataLoader.LoadByFilePath1(jsonFilePath).Values; 18 | 19 | _codeMap.Clear(); 20 | _descMap.Clear(); 21 | 22 | foreach (var item in errorCodes) 23 | { 24 | _codeMap[item.SID] = item.ID; 25 | _descMap[item.SID] = item.Desc; 26 | } 27 | } 28 | catch (Exception ex) 29 | { 30 | Log.Error($"加载错误码失败: {ex.Message}"); 31 | throw; 32 | } 33 | } 34 | 35 | public static int GetCode(string id) 36 | { 37 | if (_codeMap.TryGetValue(id, out int code)) 38 | { 39 | return code; 40 | } 41 | 42 | throw new KeyNotFoundException($"未找到错误码标识符: {id}"); 43 | } 44 | 45 | public static string GetDescription(string code) 46 | { 47 | if (_descMap.TryGetValue(code, out string desc)) 48 | { 49 | return desc; 50 | } 51 | 52 | return "未知错误码"; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /MMORPG/Llua/Api/ILuaState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace lLua.Api 8 | { 9 | public interface ILuaState 10 | { 11 | /* Basic stack manipulation */ 12 | int GetTop(); 13 | int AbsIndex(int idx); 14 | bool CheckStack(int n); 15 | void Pop(int n); 16 | void Copy(int fromIdx, int toIdx); 17 | void PushValue(int idx); 18 | void Replace(int idx); 19 | void Insert(int idx); 20 | void Remove(int idx); 21 | void Rotate(int idx, int n); 22 | void SetTop(int idx); 23 | 24 | /* Access functions (stack -> c#) */ 25 | string TypeName(LuaDataType tp); 26 | LuaDataType Type(int idx); 27 | bool IsNone(int idx); 28 | bool IsNil(int idx); 29 | bool IsNoneOrNil(int idx); 30 | bool IsBoolean(int idx); 31 | bool IsInteger(int idx); 32 | bool IsNumber(int idx); 33 | bool IsString(int idx); 34 | bool ToBoolean(int idx); 35 | long ToInteger(int idx); 36 | (long value, bool isValid) ToIntegerX(int idx); // Tuple for multi-value return 37 | double ToNumber(int idx); 38 | (double value, bool isValid) ToNumberX(int idx); // Tuple for multi-value return 39 | string ToString(int idx); 40 | (string value, bool isValid) ToStringX(int idx); // Tuple for multi-value return 41 | 42 | /* Push functions (c# -> stack) */ 43 | void PushNil(); 44 | void PushBoolean(bool b); 45 | void PushInteger(long n); 46 | void PushNumber(double n); 47 | void PushString(string s); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Net/New/UserMessageHandlerMap.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Tools; 2 | using Google.Protobuf; 3 | using System; 4 | using System.Collections.Concurrent; 5 | using static Common.Summer.Net.MessageRouter; 6 | 7 | namespace Common.Summer.Net 8 | { 9 | public class UserMessageHandlerArgs2 10 | { 11 | public int clientId; 12 | public int seqId; 13 | } 14 | 15 | public class UserMessageHandlerMap : Singleton 16 | { 17 | public delegate IMessage MessageHandler(UserMessageHandlerArgs2 args, T message); 18 | 19 | private readonly ConcurrentDictionary delegateMap = new ConcurrentDictionary(); 20 | 21 | public void Subscribe(MessageHandler handler) where T : IMessage 22 | { 23 | string type = typeof(T).FullName; 24 | if (!delegateMap.ContainsKey(type))//没有就创建一个空的 25 | { 26 | delegateMap[type] = null; 27 | } 28 | delegateMap[type] = (MessageHandler)delegateMap[type] + handler; 29 | } 30 | 31 | public void UnSubscribe(MessageHandler handler) where T : IMessage 32 | { 33 | string key = typeof(T).FullName; 34 | if (!delegateMap.ContainsKey(key)) 35 | {//频道不存在给你加一个 36 | delegateMap[key] = null; 37 | } 38 | //添加订阅者,因为这里它不知道是什么类型的委托,所以要转型 39 | delegateMap[key] = (MessageHandler)delegateMap[key] - handler; 40 | } 41 | 42 | public Delegate GetMessageHandler(string key) 43 | { 44 | delegateMap.TryGetValue(key, out var handler); 45 | return handler; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/Boss/Impl/BossMonsterAIState_Attack.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Serilog; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace SceneServer.Core.Combat.AI.MonsterAIStateImpl 10 | { 11 | public class BossMonsterAIState_Attack : BossMonsterAIState 12 | { 13 | public float attackInterval = 1f; 14 | public float remainAttackCD; 15 | 16 | public override void Enter() 17 | { 18 | TryAttack(); 19 | } 20 | 21 | public override void Update(float deltaTime) 22 | { 23 | if (!monsterAI.Monster.IsCanAttack()) 24 | { 25 | goto End; 26 | } 27 | 28 | remainAttackCD -= deltaTime; 29 | if (remainAttackCD <= 0) 30 | { 31 | if (!monsterAI.IsTargetInRange(monsterAI.maxAttackDistance)) 32 | { 33 | if (monsterAI.IsTargetInRange(monsterAI.maxChaseDistance)) 34 | { 35 | monsterAI.ChangeState(MonsterAIState.Chase); 36 | } 37 | else 38 | { 39 | monsterAI.ClearTarget(); 40 | monsterAI.ChangeState(MonsterAIState.Patrol); 41 | } 42 | goto End; 43 | } 44 | 45 | TryAttack(); 46 | } 47 | 48 | End: 49 | return; 50 | } 51 | 52 | private void TryAttack() 53 | { 54 | monsterAI.Monster.Attack(monsterAI.Target); 55 | remainAttackCD = attackInterval; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/BaseMonsterAI.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Tools; 2 | using SceneServer.Core.Combat.AI.MonsterAIStateImpl; 3 | using Serilog; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using YamlDotNet.Serialization; 10 | 11 | namespace SceneServer.Core.Combat.AI 12 | { 13 | public enum MonsterAIState 14 | { 15 | None, 16 | Patrol, 17 | Chase, 18 | Attack, 19 | Death, 20 | Flee, 21 | Hurt, 22 | Rturn, 23 | Idle 24 | } 25 | 26 | public class BaseMonsterAI : IStateMachineOwner 27 | { 28 | // AI 驱动频率 29 | private int m_fps; 30 | private float m_cumulativeTime; 31 | private float m_updateTime; 32 | 33 | // 状态机 34 | protected StateMachine m_stateMachine; 35 | protected MonsterAIState m_curState; 36 | 37 | public BaseMonsterAI(int fps) { 38 | m_fps = fps; 39 | m_cumulativeTime = 0; 40 | m_updateTime = 1.0f / fps; 41 | 42 | m_stateMachine = new StateMachine(); 43 | m_stateMachine.Init(this); 44 | } 45 | public void Update(float deltaTime) 46 | { 47 | m_cumulativeTime += deltaTime; 48 | if (m_cumulativeTime > m_updateTime) 49 | { 50 | m_stateMachine.Update(m_cumulativeTime); 51 | Dothing(m_cumulativeTime); 52 | m_cumulativeTime = 0; 53 | } 54 | } 55 | protected virtual void Dothing(float deltaTime) 56 | { 57 | } 58 | public virtual void ChangeState(MonsterAIState state, bool reCurrstate = false) { 59 | 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Tools/GameEvent/CharacterEventSystem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Common.Summer.Tools.GameEvent 8 | { 9 | public class CharacterEventSystem 10 | { 11 | private Dictionary>> m_eventListeners = new(); 12 | private static readonly Dictionary EmptyParameters = new(); 13 | 14 | public void Subscribe(string eventType, Action> handler) 15 | { 16 | if (!m_eventListeners.ContainsKey(eventType)) 17 | { 18 | m_eventListeners[eventType] = handler; 19 | } 20 | else 21 | { 22 | m_eventListeners[eventType] += handler; 23 | } 24 | } 25 | public void Unsubscribe(string eventType, Action> handler) 26 | { 27 | if (m_eventListeners.TryGetValue(eventType, out var currentHandler)) 28 | { 29 | // 从委托链中移除指定handler 30 | currentHandler -= handler; 31 | 32 | // 更新委托链 33 | if (currentHandler != null) 34 | m_eventListeners[eventType] = currentHandler; // 更新为移除后的委托 35 | else 36 | m_eventListeners.Remove(eventType); // 无剩余handler则移除事件类型 37 | } 38 | } 39 | public void Trigger(string eventType, Dictionary parameters = null) 40 | { 41 | if (m_eventListeners.ContainsKey(eventType)) 42 | { 43 | m_eventListeners[eventType]?.Invoke(parameters ?? EmptyParameters); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /MMORPG/GameGateServer/Net/SessionManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using Common.Summer.Core; 3 | using Common.Summer.Net; 4 | using Common.Summer.Tools; 5 | using HS.Protobuf.GameGate; 6 | using Serilog; 7 | 8 | namespace GameGateServer.Net 9 | { 10 | public class SessionManager : Singleton 11 | { 12 | private int SESSIONTIMEOUT = 120; 13 | //session字典 14 | private ConcurrentDictionary sessions = new ConcurrentDictionary(); 15 | 16 | public void Init() 17 | { 18 | Scheduler.Instance.AddTask(_CheckSession, 1000, 0); 19 | } 20 | 21 | public Session NewSession(RegisterSessionToGGRequest message) 22 | { 23 | var session = new Session(message.SessionId, message.UId); 24 | sessions[message.SessionId] = session; 25 | return session; 26 | } 27 | public void RemoveSessionById(string sessionId) 28 | { 29 | sessions.TryRemove(sessionId, out var session); 30 | } 31 | public Session GetSessionBySessionId(string sessionId) 32 | { 33 | if (sessions.TryGetValue(sessionId, out var session)) 34 | { 35 | return session; 36 | } 37 | return null; 38 | } 39 | private void _CheckSession() 40 | { 41 | foreach (var session in sessions.Values) { 42 | if(MyTime.time - session.LastHeartTime > SESSIONTIMEOUT) 43 | { 44 | Log.Debug("session超时"); 45 | ConnManager.Instance.CloseUserConnection(session.Conn); 46 | RemoveSessionById(session.Id); 47 | } 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /MMORPG/GameGateServer/Handle/GameGateServerHandler.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Tools; 4 | using HS.Protobuf.ControlCenter; 5 | using GameGateServer.Net; 6 | using Serilog; 7 | using HS.Protobuf.GameGate; 8 | 9 | namespace GameGateServer.Handle 10 | { 11 | public class GameGateServerHandler : Singleton 12 | { 13 | public void Init() 14 | { 15 | // 协议注册 16 | ProtoHelper.Instance.Register((int)ControlCenterProtocl.ClusterEventResp); 17 | ProtoHelper.Instance.Register((int)GameGateProtocl.RegisterScenesToGgReq); 18 | ProtoHelper.Instance.Register((int)GameGateProtocl.RegisterScenesToGgResp); 19 | 20 | // 消息的订阅 21 | MessageRouter.Instance.Subscribe(_HandleClusterEventResponse); 22 | MessageRouter.Instance.Subscribe(_HandleRegisterSceneToGGRequest); 23 | } 24 | 25 | public void UnInit() 26 | { 27 | } 28 | private void _HandleClusterEventResponse(Connection sender, ClusterEventResponse message) 29 | { 30 | if (message.ClusterEventNode.EventType == ClusterEventType.GamegatemgrEnter) 31 | { 32 | Log.Information("A new GameGateMgr server has joined the cluster, {0}", message.ClusterEventNode.ServerInfoNode); 33 | ServersMgr.Instance.AddGGMServerInfo(message.ClusterEventNode.ServerInfoNode); 34 | } 35 | } 36 | private void _HandleRegisterSceneToGGRequest(Connection conn, RegisterSceneToGGRequest message) 37 | { 38 | foreach(var node in message.SceneInfos) 39 | { 40 | ServersMgr.Instance.AddSServerInfo(node); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /MMORPG/Llua/VM/Instruction.cs: -------------------------------------------------------------------------------- 1 | namespace lLua.VM 2 | { 3 | public class Instruction 4 | { 5 | private readonly uint instructionValue; 6 | private const int MAXARG_Bx = 1 << 18 - 1; // 2^18-1 = 262143 7 | private const int MAXARG_sBx = MAXARG_Bx >> 1; 8 | 9 | public Instruction(uint value) 10 | { 11 | instructionValue = value; 12 | } 13 | 14 | private int Opcode() 15 | { 16 | //取低6位 17 | return (int)instructionValue & 0x3F; 18 | } 19 | 20 | public (int a, int b, int c) ABC() 21 | { 22 | int a = (int)((instructionValue >> 6) & 0xFF); 23 | int c = (int)((instructionValue >> 14) & 0x1FF); 24 | int b = (int)((instructionValue >> 23) & 0x1FF); 25 | return (a, b, c); 26 | } 27 | 28 | public (int a, int bx) ABx() 29 | { 30 | int a = (int)((instructionValue >> 6) & 0xFF); 31 | int bx = (int)(instructionValue >> 14); 32 | return (a, bx); 33 | } 34 | 35 | public (int a, int sbx) AsBx() 36 | { 37 | var (a, bx) = ABx(); 38 | int sbx = (int)bx - MAXARG_sBx; 39 | return (a, sbx); 40 | } 41 | 42 | public int Ax() 43 | { 44 | return (int)(instructionValue >> 6); 45 | } 46 | 47 | public string OpName() 48 | { 49 | return Opcodes.opcodes[Opcode()].Name; 50 | } 51 | 52 | public byte OpMode() 53 | { 54 | return Opcodes.opcodes[Opcode()].OpMode; 55 | } 56 | 57 | public byte ArgBMode() 58 | { 59 | return Opcodes.opcodes[Opcode()].ArgBMode; 60 | } 61 | 62 | public byte ArgCMode() 63 | { 64 | return Opcodes.opcodes[Opcode()].ArgCMode; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Chat/ChatManager.cs: -------------------------------------------------------------------------------- 1 | using Google.Protobuf.Collections; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using Common.Summer.Tools; 5 | using HS.Protobuf.Chat; 6 | using System.Net.NetworkInformation; 7 | using Common.Summer.Core; 8 | using System; 9 | 10 | namespace GameServer.Manager 11 | { 12 | public class ChatManager: Singleton 13 | { 14 | private int LocalMsgCacheNum = 60; 15 | private int MaxChatRecoredNums = 10; 16 | private List System = new(); 17 | private ConcurrentDictionary> sceneChatMessageQueues = new(); 18 | private List World = new(); 19 | private ConcurrentDictionary> Team = new(); 20 | private ConcurrentDictionary> Guild = new(); 21 | 22 | private ConcurrentQueue HandleChatMessageQueue = new(); 23 | public override void Init() 24 | { 25 | //Scheduler.Instance.Update(Update); 26 | } 27 | private void Update() 28 | { 29 | if (HandleChatMessageQueue.Count <= 0) return; 30 | 31 | foreach(var chatMsg in HandleChatMessageQueue) 32 | { 33 | HandleWorldChatMessage(chatMsg); 34 | } 35 | } 36 | private void HandleWorldChatMessage(ChatMessageV2 message) 37 | { 38 | 39 | } 40 | private void HandleSceneChatMessage(ChatMessageV2 message) 41 | { 42 | 43 | } 44 | 45 | public void AddWorldChatMessage(ChatMessageV2 message) 46 | { 47 | 48 | } 49 | public void AddSceneChatMessage(int sceneId, ChatMessageV2 message) { 50 | 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Security/EncryptionManager.cs: -------------------------------------------------------------------------------- 1 | namespace Common.Summer.Security 2 | { 3 | public class EncryptionManager 4 | { 5 | private AesEncryption aesEncryption; 6 | private RsaEncryption remoteRsaEncryption; 7 | private RsaEncryption localRsaEncryption; 8 | 9 | public void Init() 10 | { 11 | localRsaEncryption = new RsaEncryption(); 12 | remoteRsaEncryption = new RsaEncryption(); 13 | 14 | } 15 | public void UnInit() 16 | { 17 | aesEncryption = null; 18 | localRsaEncryption = null; 19 | remoteRsaEncryption = null; 20 | } 21 | public string AesEncrypt(string plainText) 22 | { 23 | return aesEncryption.Encrypt(plainText); 24 | } 25 | public string AesDecrypt(string cipherText) 26 | { 27 | return aesEncryption.Decrypt(cipherText); 28 | } 29 | public string RsaEncrypt(string plainText) 30 | { 31 | return remoteRsaEncryption.Encrypt(plainText); 32 | } 33 | public string RsaDecrypt(string cipherText) 34 | { 35 | return localRsaEncryption.Decrypt(cipherText); 36 | } 37 | public (string key, string iv) GenerateAesKeyAndIv() 38 | { 39 | return AesEncryption.GenerateAesKeyAndIv(); 40 | } 41 | public bool SetAesKeyAndIv(string key, string iv) 42 | { 43 | aesEncryption = new AesEncryption(key, iv); 44 | return true; 45 | } 46 | public bool SetRemoteRsaPublicKey(string key) 47 | { 48 | remoteRsaEncryption.ImportPublicKey(key); 49 | return true; 50 | } 51 | public string GetLocalRsaPublicKey() 52 | { 53 | return localRsaEncryption.GetPublicKey(); 54 | } 55 | 56 | //完整性验证 57 | //数字签名 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/WoodenDummy/WoodenDummyMonsterAI.cs: -------------------------------------------------------------------------------- 1 | using SceneServer.Core.Combat.AI.MonsterAi.MonsterAIStateImpl; 2 | using SceneServer.Core.Combat.AI.MonsterAIStateImpl; 3 | using SceneServer.Core.Combat.AI.WoodenDummy.Impl; 4 | using SceneServer.Core.Model.Actor; 5 | using Serilog; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace SceneServer.Core.Combat.AI.WoodenDummy 13 | { 14 | public class WoodenDummyMonsterAI : BaseMonsterAI 15 | { 16 | private SceneMonster m_owner; 17 | public WoodenDummyMonsterAI(SceneMonster owner, int fps = 10) : base(fps) 18 | { 19 | m_owner = owner; 20 | ChangeState(MonsterAIState.Idle); 21 | } 22 | 23 | public SceneMonster Monster => m_owner; 24 | 25 | public override void ChangeState(MonsterAIState state, bool reCurrstate = false) 26 | { 27 | if (m_curState == state && !reCurrstate) return; 28 | m_curState = state; 29 | 30 | Log.Information("[monsterState]:{0}", m_curState.ToString()); 31 | 32 | switch (m_curState) 33 | { 34 | case MonsterAIState.Idle: 35 | m_stateMachine.ChangeState(reCurrstate); 36 | break; 37 | case MonsterAIState.Hurt: 38 | m_stateMachine.ChangeState(reCurrstate); 39 | break; 40 | case MonsterAIState.Death: 41 | m_stateMachine.ChangeState(reCurrstate); 42 | break; 43 | default: 44 | m_stateMachine.ChangeState(reCurrstate); 45 | break; 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Tools/StateMachine/StateMachine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Common.Summer.Tools 5 | { 6 | public interface IStateMachineOwner { } 7 | 8 | public class StateMachine 9 | { 10 | private IStateMachineOwner owner; 11 | private StateBase curState; 12 | private Dictionary stateDict = new(); 13 | public StateBase CurState { get => curState; } 14 | 15 | public void Init(IStateMachineOwner owner) 16 | { 17 | this.owner = owner; 18 | } 19 | public void UnInit() 20 | { 21 | if (curState != null) 22 | { 23 | curState.Exit(); 24 | } 25 | foreach (var item in stateDict.Values) 26 | { 27 | item.UnInit(); 28 | } 29 | stateDict.Clear(); 30 | } 31 | private StateBase GetState() where T : StateBase, new() 32 | { 33 | Type type = typeof(T); 34 | if (!stateDict.TryGetValue(type, out var state)) 35 | { 36 | state = new T(); 37 | state.Init(owner); 38 | stateDict.Add(type, state); 39 | } 40 | return state; 41 | } 42 | public bool ChangeState(bool reCurrstate = false) where T : StateBase, new() 43 | { 44 | if (curState != null && curState.GetType() == typeof(T) && !reCurrstate) return false; 45 | 46 | //退出当前状态 47 | if (curState != null) 48 | { 49 | curState.Exit(); 50 | } 51 | 52 | //进入新状态 53 | curState = GetState(); 54 | curState.Enter(); 55 | 56 | return false; 57 | } 58 | public virtual void Update(float deltaTime) 59 | { 60 | curState?.Update(deltaTime); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /MMORPG/LoginGateServer/Handle/LoginGateHandler.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Tools; 4 | using HS.Protobuf.ControlCenter; 5 | using HS.Protobuf.LoginGate; 6 | using LoginGateServer.Net; 7 | using Serilog; 8 | 9 | namespace LoginGateServer.Handle 10 | { 11 | public class LoginGateHandler : Singleton 12 | { 13 | public void Init() 14 | { 15 | // 协议注册 16 | ProtoHelper.Instance.Register((int)ControlCenterProtocl.ClusterEventResp); 17 | ProtoHelper.Instance.Register((int)LoginGateProtocl.GetLogingateTokenReq); 18 | ProtoHelper.Instance.Register((int)LoginGateProtocl.GetLogingateTokenResp); 19 | // 消息的订阅 20 | MessageRouter.Instance.Subscribe(_HandleClusterEventResponse); 21 | MessageRouter.Instance.Subscribe(_HandleGetLoginGateTokenRequest); 22 | } 23 | 24 | public void UnInit() 25 | { 26 | } 27 | private void _HandleClusterEventResponse(Connection sender, ClusterEventResponse message) 28 | { 29 | if (message.ClusterEventNode.EventType == ClusterEventType.LogingatemgrEnter) 30 | { 31 | Log.Information("A new LoginGateMgr server has joined the cluster, {0}", message.ClusterEventNode.ServerInfoNode); 32 | ServersMgr.Instance.AddLGMServerInfo(message.ClusterEventNode.ServerInfoNode); 33 | } 34 | } 35 | private void _HandleGetLoginGateTokenRequest(Connection conn, GetLoginGateTokenRequest message) 36 | { 37 | string tokenId = conn.Get().Id; 38 | GetLoginGateTokenResponse resp = new GetLoginGateTokenResponse(); 39 | resp.LoginGateToken = tokenId; 40 | conn.Send(resp); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Tools/LogDemo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | #nullable enable 7 | 8 | 9 | 10 | /// 11 | /// 日志模块的流程 12 | /// 13 | namespace Tools 14 | { 15 | 16 | #region 演示日志模块 17 | /* public class Log 18 | { 19 | public const int DEBUG = 0; //调试信息 20 | public const int INFO = 1; //普通信息 21 | public const int WARN = 2; //警告信息 22 | public const int ERROR = 3; //错误信息 23 | 24 | public static int Level = INFO; //默认当前日志级别 25 | 26 | static string[] levelName = { "DEBUG", "INFO", "WARN", "ERROR" }; 27 | 28 | public delegate void PrintCallback(string text); 29 | public static event PrintCallback Print; 30 | 31 | //加委托 32 | static Log() 33 | { 34 | Log.Print += (text) => 35 | { 36 | Console.WriteLine(text); 37 | }; 38 | } 39 | 40 | 41 | private static void WriteLine(int lev, string text, params object?[]? args) 42 | { 43 | if (Level <= lev)//用于隐藏不需要的信息 44 | { 45 | text = String.Format(text, args); 46 | text = String.Format("[{0}]\t-{1}", levelName[lev], text); 47 | Print?.Invoke(text); 48 | } 49 | } 50 | 51 | public static void Debug(string text,params object?[]? args) { 52 | WriteLine(1, text, args); 53 | } 54 | 55 | public static void Info(string text, params object?[]? args) 56 | { 57 | WriteLine(2, text, args); 58 | } 59 | 60 | public static void Warn(string text, params object?[]? args) 61 | { 62 | WriteLine(3, text, args); 63 | } 64 | 65 | public static void Error(string text, params object?[]? args) 66 | { 67 | WriteLine(4, text, args); 68 | } 69 | }*/ 70 | #endregion 71 | } 72 | -------------------------------------------------------------------------------- /MMORPG/LoginServer/Utils/Config.cs: -------------------------------------------------------------------------------- 1 | using YamlDotNet.Serialization; 2 | 3 | namespace LoginServer.Utils 4 | { 5 | public class ServerConfig 6 | { 7 | [YamlMember(Alias = "ip")] 8 | public string ip { get; set; } 9 | 10 | [YamlMember(Alias = "port")] 11 | public int port { get; set; } 12 | 13 | [YamlMember(Alias = "workerCount")] 14 | public int workerCount { get; set; } 15 | 16 | [YamlMember(Alias = "updateHz")] 17 | public int updateHz { get; set; } 18 | 19 | [YamlMember(Alias = "heartBeatTimeOut")] 20 | public float heartBeatTimeOut { get; set; } 21 | 22 | [YamlMember(Alias = "heartBeatCheckInterval")] 23 | public float heartBeatCheckInterval { get; set; } 24 | 25 | [YamlMember(Alias = "heartBeatSendInterval")] 26 | public float heartBeatSendInterval { get; set; } 27 | } 28 | 29 | public class CCConfig 30 | { 31 | [YamlMember(Alias = "ip")] 32 | public string ip { get; set; } 33 | 34 | [YamlMember(Alias = "port")] 35 | public int port { get; set; } 36 | } 37 | 38 | public class AppConfig 39 | { 40 | [YamlMember(Alias = "server")] 41 | public ServerConfig Server { get; set; } 42 | 43 | [YamlMember(Alias = "cc")] 44 | public CCConfig CCServer { get; set; } 45 | } 46 | 47 | public static class Config 48 | { 49 | private static AppConfig _config; 50 | 51 | public static void Init(string filePath = "config.yaml") 52 | { 53 | // 读取配置文件,当前项目根目录 54 | var yaml = File.ReadAllText(filePath); 55 | //Log.Information("LoadYamlText:\r\n {Yaml}", yaml); 56 | 57 | // 反序列化配置文件 58 | var deserializer = new DeserializerBuilder().Build(); 59 | _config = deserializer.Deserialize(yaml); 60 | } 61 | public static ServerConfig Server => _config?.Server; 62 | public static CCConfig CCConfig => _config?.CCServer; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /MMORPG/GameGateMgrServer/Utils/Config.cs: -------------------------------------------------------------------------------- 1 | using YamlDotNet.Serialization; 2 | 3 | namespace GameGateMgrServer.Utils 4 | { 5 | public class ServerConfig 6 | { 7 | [YamlMember(Alias = "ip")] 8 | public string ip { get; set; } 9 | 10 | [YamlMember(Alias = "port")] 11 | public int port { get; set; } 12 | 13 | [YamlMember(Alias = "workerCount")] 14 | public int workerCount { get; set; } 15 | 16 | [YamlMember(Alias = "updateHz")] 17 | public int updateHz { get; set; } 18 | 19 | [YamlMember(Alias = "heartBeatTimeOut")] 20 | public float heartBeatTimeOut { get; set; } 21 | 22 | [YamlMember(Alias = "heartBeatCheckInterval")] 23 | public float heartBeatCheckInterval { get; set; } 24 | 25 | [YamlMember(Alias = "heartBeatSendInterval")] 26 | public float heartBeatSendInterval { get; set; } 27 | } 28 | 29 | public class CCConfig 30 | { 31 | [YamlMember(Alias = "ip")] 32 | public string ip { get; set; } 33 | 34 | [YamlMember(Alias = "port")] 35 | public int port { get; set; } 36 | } 37 | 38 | public class AppConfig 39 | { 40 | [YamlMember(Alias = "server")] 41 | public ServerConfig Server { get; set; } 42 | 43 | [YamlMember(Alias = "cc")] 44 | public CCConfig CCServer { get; set; } 45 | } 46 | 47 | public static class Config 48 | { 49 | private static AppConfig _config; 50 | 51 | public static void Init(string filePath = "config.yaml") 52 | { 53 | // 读取配置文件,当前项目根目录 54 | var yaml = File.ReadAllText(filePath); 55 | //Log.Information("LoadYamlText:\r\n {Yaml}", yaml); 56 | 57 | // 反序列化配置文件 58 | var deserializer = new DeserializerBuilder().Build(); 59 | _config = deserializer.Deserialize(yaml); 60 | } 61 | 62 | public static ServerConfig Server => _config?.Server; 63 | public static CCConfig CCConfig => _config?.CCServer; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /MMORPG/LoginGateMgrServer/Utils/Config.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using YamlDotNet.Serialization; 3 | 4 | namespace LoginServer.Utils 5 | { 6 | public class ServerConfig 7 | { 8 | [YamlMember(Alias = "ip")] 9 | public string ip { get; set; } 10 | 11 | [YamlMember(Alias = "port")] 12 | public int port { get; set; } 13 | 14 | [YamlMember(Alias = "workerCount")] 15 | public int workerCount { get; set; } 16 | 17 | [YamlMember(Alias = "updateHz")] 18 | public int updateHz { get; set; } 19 | 20 | [YamlMember(Alias = "heartBeatTimeOut")] 21 | public float heartBeatTimeOut { get; set; } 22 | 23 | [YamlMember(Alias = "heartBeatCheckInterval")] 24 | public float heartBeatCheckInterval { get; set; } 25 | 26 | [YamlMember(Alias = "heartBeatSendInterval")] 27 | public float heartBeatSendInterval { get; set; } 28 | } 29 | 30 | public class CCConfig 31 | { 32 | [YamlMember(Alias = "ip")] 33 | public string ip { get; set; } 34 | 35 | [YamlMember(Alias = "port")] 36 | public int port { get; set; } 37 | } 38 | 39 | public class AppConfig 40 | { 41 | [YamlMember(Alias = "server")] 42 | public ServerConfig Server { get; set; } 43 | 44 | [YamlMember(Alias = "cc")] 45 | public CCConfig CCServer { get; set; } 46 | } 47 | 48 | public static class Config 49 | { 50 | private static AppConfig _config; 51 | 52 | public static void Init(string filePath = "config.yaml") 53 | { 54 | // 读取配置文件,当前项目根目录 55 | var yaml = File.ReadAllText(filePath); 56 | //Log.Information("LoadYamlText:\r\n {Yaml}", yaml); 57 | 58 | // 反序列化配置文件 59 | var deserializer = new DeserializerBuilder().Build(); 60 | _config = deserializer.Deserialize(yaml); 61 | } 62 | 63 | public static ServerConfig Server => _config?.Server; 64 | public static CCConfig CCConfig => _config?.CCServer; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Task/Condition/Impl/ReachPositionConditionChecker.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using GameServer.Core.Model; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace GameServer.Core.Task.Condition.Impl 10 | { 11 | public class ReachPositionConditionChecker : IConditionChecker 12 | { 13 | public bool InitCondition(ConditionData condition, GameCharacter chr) 14 | { 15 | return true; 16 | } 17 | public bool UnInitCondition(ConditionData condition, GameCharacter chr) 18 | { 19 | return true; 20 | } 21 | public bool UpdateCondition(ConditionData condition, GameCharacter chr, Dictionary args) 22 | { 23 | if(condition.CurValue == 1) 24 | { 25 | goto End; 26 | } 27 | Vector3 curPosition = (Vector3)args["Position"]; 28 | Vector3 targetPosition = new Vector3() 29 | { 30 | x = int.Parse(condition.Parameters[0]), 31 | y = int.Parse(condition.Parameters[1]), 32 | z = int.Parse(condition.Parameters[2]), 33 | }; 34 | var dist = Vector3.Distance(curPosition, targetPosition); 35 | if(dist < 5) 36 | { 37 | condition.CurValue = condition.TargetValue; 38 | } 39 | End: 40 | return true; 41 | } 42 | public bool IsNeedRegisterToScene() { return true; } 43 | public Dictionary ParseRemoteArgs(string args) 44 | { 45 | // "100,1,100" 46 | var parts = args.Split(','); 47 | Vector3 position = new Vector3() 48 | { 49 | x = float.Parse(parts[0]), 50 | y = float.Parse(parts[1]), 51 | z = float.Parse(parts[2]), 52 | }; 53 | return new Dictionary { { "Position", position } }; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /MMORPG/MasterTimerServer/Utils/Config.cs: -------------------------------------------------------------------------------- 1 | using YamlDotNet.Serialization; 2 | 3 | namespace MasterTimerServer.Utils 4 | { 5 | public class ServerConfig 6 | { 7 | [YamlMember(Alias = "ip")] 8 | public string ip { get; set; } 9 | 10 | [YamlMember(Alias = "serverPort")] 11 | public int serverPort { get; set; } 12 | 13 | [YamlMember(Alias = "workerCount")] 14 | public int workerCount { get; set; } 15 | 16 | [YamlMember(Alias = "updateHz")] 17 | public int updateHz { get; set; } 18 | 19 | [YamlMember(Alias = "heartBeatTimeOut")] 20 | public float heartBeatTimeOut { get; set; } 21 | 22 | [YamlMember(Alias = "heartBeatCheckInterval")] 23 | public float heartBeatCheckInterval { get; set; } 24 | 25 | [YamlMember(Alias = "heartBeatSendInterval")] 26 | public float heartBeatSendInterval { get; set; } 27 | } 28 | 29 | public class CCConfig 30 | { 31 | [YamlMember(Alias = "ip")] 32 | public string ip { get; set; } 33 | 34 | [YamlMember(Alias = "port")] 35 | public int port { get; set; } 36 | } 37 | 38 | public class AppConfig 39 | { 40 | 41 | [YamlMember(Alias = "server")] 42 | public ServerConfig Server { get; set; } 43 | 44 | [YamlMember(Alias = "cc")] 45 | public CCConfig CCServer { get; set; } 46 | } 47 | 48 | public static class Config 49 | { 50 | private static AppConfig _config; 51 | 52 | public static void Init(string filePath = "config.yaml") 53 | { 54 | // 读取配置文件,当前项目根目录 55 | var yaml = File.ReadAllText(filePath); 56 | //Log.Information("LoadYamlText:\r\n {Yaml}", yaml); 57 | 58 | // 反序列化配置文件 59 | var deserializer = new DeserializerBuilder().Build(); 60 | _config = deserializer.Deserialize(yaml); 61 | } 62 | 63 | public static ServerConfig Server => _config?.Server; 64 | public static CCConfig CCConfig => _config?.CCServer; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /MMORPG/Llua/State/LuaStack.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace lLua.State 8 | { 9 | public class LuaStack 10 | { 11 | private List slots; 12 | private int top; 13 | 14 | public LuaStack(int size) 15 | { 16 | slots = new List(new LuaValue[size]); 17 | top = 0; 18 | } 19 | 20 | public void Push(LuaValue val) 21 | { 22 | if (top == slots.Count) 23 | { 24 | throw new InvalidOperationException("stack overflow!"); 25 | } 26 | slots[top] = val; 27 | top++; 28 | } 29 | 30 | public LuaValue Pop() 31 | { 32 | if (top < 1) 33 | { 34 | throw new InvalidOperationException("stack underflow!"); 35 | } 36 | top--; 37 | var val = slots[top]; 38 | slots[top] = null; // 将槽位设置为 null,释放引用。 39 | return val; 40 | } 41 | 42 | public int AbsIndex(int idx) 43 | { 44 | if (idx >= 0) 45 | { 46 | return idx; 47 | } 48 | return idx + top + 1; 49 | } 50 | 51 | public bool IsValid(int idx) 52 | { 53 | int absIdx = AbsIndex(idx); 54 | return absIdx > 0 && absIdx <= top; 55 | } 56 | 57 | public LuaValue Get(int idx) 58 | { 59 | int absIdx = AbsIndex(idx); 60 | if (absIdx > 0 && absIdx <= top) 61 | { 62 | return slots[absIdx - 1]; 63 | } 64 | return null; 65 | } 66 | 67 | public void Set(int idx, LuaValue val) 68 | { 69 | int absIdx = AbsIndex(idx); 70 | if (absIdx > 0 && absIdx <= top) 71 | { 72 | slots[absIdx - 1] = val; 73 | return; 74 | } 75 | throw new InvalidOperationException("Invalid index!"); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Security/PasswordHasher.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Tools; 2 | using System; 3 | using System.Security.Cryptography; 4 | 5 | namespace Common.Summer.Security 6 | { 7 | public class PasswordHasher :Singleton 8 | { 9 | private const int SaltSize = 16; // 128 bit 10 | private const int KeySize = 32; // 256 bit 11 | private const int Iterations = 10000; // Recommended is at least 10,000 12 | 13 | public string HashPassword(string password) 14 | { 15 | using var algorithm = new Rfc2898DeriveBytes( 16 | password, 17 | SaltSize, 18 | Iterations, 19 | HashAlgorithmName.SHA256); 20 | 21 | var salt = algorithm.Salt; 22 | var hash = algorithm.GetBytes(KeySize); 23 | 24 | // Combine salt and hash into one byte array 25 | var hashBytes = new byte[SaltSize + KeySize]; 26 | Array.Copy(salt, 0, hashBytes, 0, SaltSize); 27 | Array.Copy(hash, 0, hashBytes, SaltSize, KeySize); 28 | 29 | // Convert the byte array to a base64 string 30 | return Convert.ToBase64String(hashBytes); 31 | } 32 | 33 | public bool VerifyPassword(string password, string hashedPassword) 34 | { 35 | var hashBytes = Convert.FromBase64String(hashedPassword); 36 | 37 | // Extract salt from the stored hash 38 | var salt = new byte[SaltSize]; 39 | Array.Copy(hashBytes, 0, salt, 0, SaltSize); 40 | 41 | using var algorithm = new Rfc2898DeriveBytes( 42 | password, 43 | salt, 44 | Iterations, 45 | HashAlgorithmName.SHA256); 46 | 47 | var hash = algorithm.GetBytes(KeySize); 48 | 49 | // Compare hash with the original hash from storage (skip the salt bytes) 50 | for (int i = 0; i < KeySize; i++) 51 | { 52 | if (hashBytes[i + SaltSize] != hash[i]) 53 | return false; 54 | } 55 | 56 | return true; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /MMORPG/GameGateServer/Utils/Config.cs: -------------------------------------------------------------------------------- 1 | using YamlDotNet.Serialization; 2 | 3 | namespace GameGateServer.Utils 4 | { 5 | public class ServerConfig 6 | { 7 | [YamlMember(Alias = "ip")] 8 | public string ip { get; set; } 9 | 10 | [YamlMember(Alias = "userPort")] 11 | public int userPort { get; set; } 12 | 13 | [YamlMember(Alias = "serverPort")] 14 | public int serverPort { get; set; } 15 | 16 | [YamlMember(Alias = "workerCount")] 17 | public int workerCount { get; set; } 18 | 19 | [YamlMember(Alias = "updateHz")] 20 | public int updateHz { get; set; } 21 | 22 | [YamlMember(Alias = "heartBeatTimeOut")] 23 | public float heartBeatTimeOut { get; set; } 24 | 25 | [YamlMember(Alias = "heartBeatCheckInterval")] 26 | public float heartBeatCheckInterval { get; set; } 27 | 28 | [YamlMember(Alias = "heartBeatSendInterval")] 29 | public float heartBeatSendInterval { get; set; } 30 | } 31 | 32 | public class CCConfig 33 | { 34 | [YamlMember(Alias = "ip")] 35 | public string ip { get; set; } 36 | 37 | [YamlMember(Alias = "port")] 38 | public int port { get; set; } 39 | } 40 | 41 | public class AppConfig 42 | { 43 | [YamlMember(Alias = "server")] 44 | public ServerConfig Server { get; set; } 45 | 46 | [YamlMember(Alias = "cc")] 47 | public CCConfig CCServer { get; set; } 48 | } 49 | 50 | public static class Config 51 | { 52 | private static AppConfig _config; 53 | 54 | public static void Init(string filePath = "config.yaml") 55 | { 56 | // 读取配置文件,当前项目根目录 57 | var yaml = File.ReadAllText(filePath); 58 | //Log.Information("LoadYamlText:\r\n {Yaml}", yaml); 59 | 60 | // 反序列化配置文件 61 | var deserializer = new DeserializerBuilder().Build(); 62 | _config = deserializer.Deserialize(yaml); 63 | } 64 | 65 | public static ServerConfig Server => _config?.Server; 66 | public static CCConfig CCConfig => _config?.CCServer; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /MMORPG/LoginGateServer/Utils/Config.cs: -------------------------------------------------------------------------------- 1 | using YamlDotNet.Serialization; 2 | 3 | namespace LoginGateServer.Utils 4 | { 5 | public class ServerConfig 6 | { 7 | [YamlMember(Alias = "ip")] 8 | public string ip { get; set; } 9 | 10 | [YamlMember(Alias = "userPort")] 11 | public int userPort { get; set; } 12 | 13 | [YamlMember(Alias = "serverPort")] 14 | public int serverPort { get; set; } 15 | 16 | [YamlMember(Alias = "workerCount")] 17 | public int workerCount { get; set; } 18 | 19 | [YamlMember(Alias = "updateHz")] 20 | public int updateHz { get; set; } 21 | 22 | [YamlMember(Alias = "heartBeatTimeOut")] 23 | public float heartBeatTimeOut { get; set; } 24 | 25 | [YamlMember(Alias = "heartBeatCheckInterval")] 26 | public float heartBeatCheckInterval { get; set; } 27 | 28 | [YamlMember(Alias = "heartBeatSendInterval")] 29 | public float heartBeatSendInterval { get; set; } 30 | } 31 | 32 | public class CCConfig 33 | { 34 | [YamlMember(Alias = "ip")] 35 | public string ip { get; set; } 36 | 37 | [YamlMember(Alias = "port")] 38 | public int port { get; set; } 39 | } 40 | 41 | public class AppConfig 42 | { 43 | [YamlMember(Alias = "server")] 44 | public ServerConfig Server { get; set; } 45 | 46 | [YamlMember(Alias = "cc")] 47 | public CCConfig CCServer { get; set; } 48 | } 49 | 50 | public static class Config 51 | { 52 | private static AppConfig _config; 53 | 54 | public static void Init(string filePath = "config.yaml") 55 | { 56 | // 读取配置文件,当前项目根目录 57 | var yaml = File.ReadAllText(filePath); 58 | //Log.Information("LoadYamlText:\r\n {Yaml}", yaml); 59 | 60 | // 反序列化配置文件 61 | var deserializer = new DeserializerBuilder().Build(); 62 | _config = deserializer.Deserialize(yaml); 63 | } 64 | 65 | public static ServerConfig Server => _config?.Server; 66 | public static CCConfig CCConfig => _config?.CCServer; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/Skill/Missile.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Tools; 3 | 4 | 5 | namespace SceneServer.Core.Combat.Skills 6 | { 7 | /// 8 | /// 投射物 9 | /// 10 | public class Missile 11 | { 12 | //对象池 13 | private static ObjectPool _pool = new(() => new Missile()); 14 | 15 | //所属技能 16 | public Skill Skill { get; private set; } 17 | //追击目标 18 | public SCObject Target { get; private set; } 19 | //初始位置 20 | public Vector3 InitPos { get; private set; } 21 | //飞行物当前位置 22 | public Vector3 curPosition; 23 | 24 | public void Init(Skill skill, Vector3 initPos, SCObject target) 25 | { 26 | Skill = skill; 27 | Target = target; 28 | InitPos = initPos; 29 | curPosition = initPos; 30 | } 31 | 32 | public void OnUpdate(float deltaTime) 33 | { 34 | var a = curPosition; 35 | var b = Target.Position; 36 | Vector3 direction = (b - a).normalized; 37 | var distance = Skill.Define.MissileSpeed * deltaTime; 38 | //判断本帧运算是否能到达目标点 39 | if (distance >= Vector3.Distance(a, b)) 40 | { 41 | curPosition = b; 42 | Skill.OnHitByMissile(Target); 43 | // todo 44 | // Space.fightManager.missiles.Remove(this); 45 | _pool.ReturnObject(this); 46 | } 47 | else 48 | { 49 | curPosition += direction * distance; 50 | } 51 | 52 | } 53 | 54 | /// 55 | /// 创建投射物 56 | /// 57 | /// 58 | /// 59 | /// 60 | /// 61 | public static Missile Create(Skill skill, Vector3 initPos, SCObject target) 62 | { 63 | var obj = _pool.GetObject(); 64 | obj.Init(skill, initPos, target); 65 | return obj; 66 | } 67 | 68 | 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /MMORPG/GameGateServer/Handle/SecurityHandler.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Tools; 4 | using HS.Protobuf.Common; 5 | 6 | namespace GameGateServer.Handle 7 | { 8 | public class SecurityHandler : Singleton 9 | { 10 | public bool Init() 11 | { 12 | ProtoHelper.Instance.Register((int)CommonProtocl.ExchangePublicKeyReq); 13 | ProtoHelper.Instance.Register((int)CommonProtocl.ExchangePublicKeyResp); 14 | ProtoHelper.Instance.Register((int)CommonProtocl.ExchangeCommunicationSecretKeyReq); 15 | ProtoHelper.Instance.Register((int)CommonProtocl.ExchangeCommunicationSecretKeyResp); 16 | 17 | MessageRouter.Instance.Subscribe(_HandleExchangePublicKeyRequest); 18 | MessageRouter.Instance.Subscribe(_HandleExchangeCommunicationSecretKeyRequest); 19 | 20 | 21 | return true; 22 | } 23 | public bool UnInit() 24 | { 25 | return true; 26 | } 27 | 28 | private void _HandleExchangePublicKeyRequest(Connection sender, ExchangePublicKeyRequest message) 29 | { 30 | sender.m_encryptionManager.SetRemoteRsaPublicKey(message.ClientPublicKey); 31 | ExchangePublicKeyResponse resp = new(); 32 | resp.ServerPublilcKey = sender.m_encryptionManager.GetLocalRsaPublicKey(); 33 | sender.Send(resp); 34 | } 35 | 36 | private void _HandleExchangeCommunicationSecretKeyRequest(Connection sender, ExchangeCommunicationSecretKeyRequest message) 37 | { 38 | string k1 = sender.m_encryptionManager.RsaDecrypt(message.Key1); 39 | string k2 = sender.m_encryptionManager.RsaDecrypt(message.Key2); 40 | sender.m_encryptionManager.SetAesKeyAndIv(k1, k2); 41 | 42 | ExchangeCommunicationSecretKeyResponse resp = new(); 43 | resp.ResultCode = 0; 44 | sender.Send(resp); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /MMORPG/LoginGateServer/Handle/SecurityHandler.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Tools; 4 | using HS.Protobuf.Common; 5 | 6 | namespace LoginGateServer.Handle 7 | { 8 | public class SecurityHandler : Singleton 9 | { 10 | public bool Init() 11 | { 12 | ProtoHelper.Instance.Register((int)CommonProtocl.ExchangePublicKeyReq); 13 | ProtoHelper.Instance.Register((int)CommonProtocl.ExchangePublicKeyResp); 14 | ProtoHelper.Instance.Register((int)CommonProtocl.ExchangeCommunicationSecretKeyReq); 15 | ProtoHelper.Instance.Register((int)CommonProtocl.ExchangeCommunicationSecretKeyResp); 16 | 17 | MessageRouter.Instance.Subscribe(_HandleExchangePublicKeyRequest); 18 | MessageRouter.Instance.Subscribe(_HandleExchangeCommunicationSecretKeyRequest); 19 | 20 | 21 | return true; 22 | } 23 | public bool UnInit() 24 | { 25 | return true; 26 | } 27 | 28 | private void _HandleExchangePublicKeyRequest(Connection sender, ExchangePublicKeyRequest message) 29 | { 30 | sender.m_encryptionManager.SetRemoteRsaPublicKey(message.ClientPublicKey); 31 | ExchangePublicKeyResponse resp = new(); 32 | resp.ServerPublilcKey = sender.m_encryptionManager.GetLocalRsaPublicKey(); 33 | sender.Send(resp); 34 | } 35 | 36 | private void _HandleExchangeCommunicationSecretKeyRequest(Connection sender, ExchangeCommunicationSecretKeyRequest message) 37 | { 38 | string k1 = sender.m_encryptionManager.RsaDecrypt(message.Key1); 39 | string k2 = sender.m_encryptionManager.RsaDecrypt(message.Key2); 40 | sender.m_encryptionManager.SetAesKeyAndIv(k1, k2); 41 | 42 | ExchangeCommunicationSecretKeyResponse resp = new(); 43 | resp.ResultCode = 0; 44 | sender.Send(resp); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Scene/Component/SceneItemManager.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using HS.Protobuf.Backpack; 3 | using SceneServer.Core.Model.Item; 4 | using System; 5 | using System.Collections.Concurrent; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Runtime.ConstrainedExecution; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | 12 | namespace SceneServer.Core.Scene.Component 13 | { 14 | public class SceneItemManager 15 | { 16 | public ConcurrentDictionary itemEntityDict = new(); // 17 | 18 | public void Init() 19 | { 20 | } 21 | public void UnInit() 22 | { 23 | itemEntityDict.Clear(); 24 | } 25 | 26 | public SceneItem CreateSceneItem(NetItemDataNode itemDataNode, Vector3Int pos, Vector3Int dir, Vector3Int scale) 27 | { 28 | var sceneItem = new SceneItem(); 29 | sceneItem.Init(itemDataNode, pos, dir, scale); 30 | 31 | // 添加到entityMananger中管理 32 | SceneEntityManager.Instance.AddSceneEntity(sceneItem); 33 | itemEntityDict[sceneItem.EntityId] = sceneItem; 34 | 35 | sceneItem.NetItemNode.EntityId = sceneItem.EntityId; 36 | sceneItem.NetItemNode.SceneId = SceneManager.Instance.SceneId; 37 | 38 | // 显示到当前场景 39 | SceneManager.Instance.ItemEnterScene(sceneItem); 40 | 41 | return sceneItem; 42 | } 43 | public SceneItem RemoveItem(int entityId) 44 | { 45 | SceneItem result = null; 46 | if (!itemEntityDict.ContainsKey(entityId)) 47 | { 48 | goto End; 49 | } 50 | 51 | SceneEntityManager.Instance.RemoveSceneEntity(entityId); 52 | itemEntityDict.Remove(entityId, out result); 53 | 54 | // 场景中移除 55 | SceneManager.Instance.ItemExitScene(result); 56 | 57 | End: 58 | return result; 59 | } 60 | 61 | public SceneItem GetEItemByEntityId(int entityId) 62 | { 63 | return itemEntityDict.GetValueOrDefault(entityId); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Utils/Config.cs: -------------------------------------------------------------------------------- 1 | using YamlDotNet.Serialization; 2 | 3 | namespace SceneServer.Utils 4 | { 5 | 6 | public class ServerConfig 7 | { 8 | [YamlMember(Alias = "ip")] 9 | public string ip { get; set; } 10 | 11 | [YamlMember(Alias = "serverPort")] 12 | public int serverPort { get; set; } 13 | 14 | [YamlMember(Alias = "workerCount")] 15 | public int workerCount { get; set; } 16 | 17 | [YamlMember(Alias = "aoiViewArea")] 18 | public float aoiViewArea { get; set; } 19 | 20 | [YamlMember(Alias = "updateHz")] 21 | public int updateHz { get; set; } 22 | 23 | [YamlMember(Alias = "heartBeatTimeOut")] 24 | public float heartBeatTimeOut { get; set; } 25 | 26 | [YamlMember(Alias = "heartBeatCheckInterval")] 27 | public float heartBeatCheckInterval { get; set; } 28 | 29 | [YamlMember(Alias = "heartBeatSendInterval")] 30 | public float heartBeatSendInterval { get; set; } 31 | } 32 | 33 | public class CCConfig 34 | { 35 | [YamlMember(Alias = "ip")] 36 | public string ip { get; set; } 37 | 38 | [YamlMember(Alias = "port")] 39 | public int port { get; set; } 40 | } 41 | 42 | public class AppConfig 43 | { 44 | 45 | [YamlMember(Alias = "server")] 46 | public ServerConfig Server { get; set; } 47 | 48 | [YamlMember(Alias = "cc")] 49 | public CCConfig CCServer { get; set; } 50 | } 51 | 52 | public static class Config 53 | { 54 | private static AppConfig _config; 55 | 56 | public static void Init(string filePath = "config.yaml") 57 | { 58 | // 读取配置文件,当前项目根目录 59 | var yaml = File.ReadAllText(filePath); 60 | //Log.Information("LoadYamlText:\r\n {Yaml}", yaml); 61 | 62 | // 反序列化配置文件 63 | var deserializer = new DeserializerBuilder().Build(); 64 | _config = deserializer.Deserialize(yaml); 65 | } 66 | 67 | public static ServerConfig Server => _config?.Server; 68 | public static CCConfig CCConfig => _config?.CCServer; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /MMORPG/LoginServer/Handle/LoginServerHandler.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Tools; 4 | using HS.Protobuf.ControlCenter; 5 | using HS.Protobuf.Login; 6 | using LoginServer.Core; 7 | using LoginServer.Net; 8 | using Serilog; 9 | 10 | namespace LoginServer.Handle 11 | { 12 | public class LoginServerHandler : Singleton 13 | { 14 | public void Init() 15 | { 16 | // 协议注册 17 | ProtoHelper.Instance.Register((int)ControlCenterProtocl.ClusterEventResp); 18 | ProtoHelper.Instance.Register((int)LoginProtocl.RegisterToLReq); 19 | ProtoHelper.Instance.Register((int)LoginProtocl.RegisterToLResp); 20 | 21 | // 消息的订阅 22 | MessageRouter.Instance.Subscribe(_HandleClusterEventResponse); 23 | MessageRouter.Instance.Subscribe(_HandleRegisterToLRequest); 24 | } 25 | 26 | public void UnInit() 27 | { 28 | 29 | } 30 | 31 | private void _HandleClusterEventResponse(Connection sender, ClusterEventResponse message) 32 | { 33 | if (message.ClusterEventNode.EventType == ClusterEventType.DbproxyEnter) 34 | { 35 | Log.Debug("A new DBProxy Server has joined the cluster."); 36 | ServersMgr.Instance.AddDBServerInfo(message.ClusterEventNode.ServerInfoNode); 37 | } 38 | else if (message.ClusterEventNode.EventType == ClusterEventType.GamegatemgrEnter) 39 | { 40 | Log.Debug("A new GGM Server has joined the cluster."); 41 | ServersMgr.Instance.AddGGMServerInfo(message.ClusterEventNode.ServerInfoNode); 42 | } 43 | } 44 | 45 | private void _HandleRegisterToLRequest(Connection conn, RegisterToLRequest message) 46 | { 47 | RegisterToLResponse resp = new(); 48 | resp.LoginToken = LoginServerMonitor.Instance.RegisterLoginGateInstance(conn, message.ServerInfoNode); 49 | resp.ResultCode = 0; 50 | conn.Send(resp); 51 | } 52 | 53 | } 54 | } -------------------------------------------------------------------------------- /MMORPG/GameServer/Hanle/GameServerHandler.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Tools; 4 | using GameServer.Core; 5 | using GameServer.Net; 6 | using HS.Protobuf.Common; 7 | using HS.Protobuf.ControlCenter; 8 | using HS.Protobuf.Game; 9 | using Serilog; 10 | using System; 11 | 12 | namespace GameServer.Handle 13 | { 14 | public class GameServerHandler : Singleton 15 | { 16 | public void Init() 17 | { 18 | // 协议注册 19 | ProtoHelper.Instance.Register((int)ControlCenterProtocl.ClusterEventResp); 20 | ProtoHelper.Instance.Register((int)GameProtocl.RegisterToGReq); 21 | ProtoHelper.Instance.Register((int)GameProtocl.RegisterToGResp); 22 | 23 | // 消息的订阅 24 | MessageRouter.Instance.Subscribe(_HandleClusterEventResponse); 25 | MessageRouter.Instance.Subscribe(_HandleRegisterToGRequest); 26 | 27 | } 28 | 29 | public void UnInit() 30 | { 31 | } 32 | 33 | private void _HandleClusterEventResponse(Connection sender, ClusterEventResponse message) 34 | { 35 | if (message.ClusterEventNode.EventType == ClusterEventType.DbproxyEnter) 36 | { 37 | Log.Debug("A new DBPorxy server has joined the cluster, {0}", message.ClusterEventNode.ServerInfoNode); 38 | ServersMgr.Instance.AddDBServerInfo(message.ClusterEventNode.ServerInfoNode); 39 | } 40 | } 41 | private void _HandleRegisterToGRequest(Connection conn, RegisterToGRequest message) 42 | { 43 | if (message.ServerInfoNode.ServerType == SERVER_TYPE.Gamegate) 44 | { 45 | Log.Information("GameGate rigister {0}", message.ServerInfoNode); 46 | } 47 | else if (message.ServerInfoNode.ServerType == SERVER_TYPE.Scene) 48 | { 49 | Log.Information("Scene rigister {0}", message.ServerInfoNode); 50 | } 51 | bool success = GameMonitor.Instance.RegisterInstance(conn, message.ServerInfoNode); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /MMORPG/GameGateServer/Handle/ChatHandler.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Tools; 4 | using GameGateServer.Net; 5 | using HS.Protobuf.Chat; 6 | using HS.Protobuf.Common; 7 | using HS.Protobuf.GameGate; 8 | 9 | namespace GameGateServer.Handle 10 | { 11 | public class ChatHandler : Singleton 12 | { 13 | public override void Init() 14 | { 15 | // 协议注册 16 | ProtoHelper.Instance.Register((int)ChatProtocl.SendChatMessageReq); 17 | ProtoHelper.Instance.Register((int)ChatProtocl.ChatMessageResp); 18 | // 消息的订阅 19 | MessageRouter.Instance.Subscribe(_HandleSendChatMessageRequest); 20 | MessageRouter.Instance.Subscribe(_HandleChatMessageResponse); 21 | } 22 | public void UnInit() 23 | { 24 | } 25 | 26 | private void _HandleSendChatMessageRequest(Connection conn, SendChatMessageRequest message) 27 | { 28 | var session = conn.Get(); 29 | if (session == null) 30 | { 31 | goto End; 32 | } 33 | 34 | // 需要将信息进行分流 35 | // 1. 附近频道的信息需要发送到scene服务器中处理 36 | // 2. 其他频道信息发送到game服务器中处理 37 | if(message.ChatMessage.Channel == ChatMessageChannel.Local) 38 | { 39 | ServersMgr.Instance.SendToSceneServer(session.curSceneId, message); 40 | } 41 | else 42 | { 43 | message.ChatMessage.FromChrId = session.m_cId; 44 | ServersMgr.Instance.SendToGameServer(message); 45 | } 46 | End: 47 | return; 48 | } 49 | private void _HandleChatMessageResponse(Connection conn, ChatMessageResponse message) 50 | { 51 | var session = SessionManager.Instance.GetSessionBySessionId(message.SessionId); 52 | if (session == null) 53 | { 54 | goto End; 55 | } 56 | message.SessionId = ""; 57 | session.Send(message); 58 | End: 59 | return; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/Boss/Impl/BossMonsterAIState_Patrol.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace SceneServer.Core.Combat.AI.MonsterAIStateImpl 9 | { 10 | public class BossMonsterAIState_Patrol : BossMonsterAIState 11 | { 12 | private Vector3 currentDestination; 13 | private float waitTimer; 14 | private bool isStartWait; 15 | 16 | public override void Enter() 17 | { 18 | GetNextDestination(); 19 | isStartWait = false; 20 | } 21 | public override void Update(float deltaTime) 22 | { 23 | monsterAI.FindNearestTarget(); 24 | 25 | // 优先级:危险 > 战斗 > 巡逻 26 | if (monsterAI.IsTargetInRange(monsterAI.maxChaseDistance)) 27 | { 28 | monsterAI.ChangeState(MonsterAIState.Chase); 29 | goto End; 30 | } 31 | 32 | // 回血回蓝 33 | monsterAI.CheckNeedRestore_HpAndMp(); 34 | 35 | // 一段巡逻结束 36 | if (!monsterAI.Monster.IsMoving && !isStartWait) 37 | { 38 | waitTimer = monsterAI.IdleWaitTime; 39 | isStartWait = true; 40 | } 41 | 42 | // 下一段巡逻 43 | if (isStartWait) 44 | { 45 | waitTimer -= deltaTime; 46 | if (waitTimer <= 0) 47 | { 48 | GetNextDestination(); 49 | isStartWait = false; 50 | } 51 | } 52 | 53 | 54 | End: 55 | return; 56 | } 57 | public override void Exit() 58 | { 59 | monsterAI.Monster.StopMove(); 60 | } 61 | private void GetNextDestination() 62 | { 63 | if (monsterAI.m_patrolPathQueue.Count > 0) 64 | { 65 | currentDestination = monsterAI.m_patrolPathQueue.Dequeue(); 66 | monsterAI.m_patrolPathQueue.Enqueue(currentDestination); 67 | monsterAI.Monster.StartMoveToPoint(currentDestination, monsterAI.patrolSpeed); 68 | waitTimer = monsterAI.random.NextInt64(3, 7); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Model/GameCharacterManager.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Tools; 2 | using HS.Protobuf.DBProxy.DBCharacter; 3 | using System.Collections.Concurrent; 4 | 5 | namespace GameServer.Core.Model 6 | { 7 | public class GameCharacterManager : Singleton 8 | { 9 | private ConcurrentDictionary characterDict = new(); 10 | private ConcurrentDictionary> sceneGrounpChr = new(); 11 | 12 | public void Init() 13 | { 14 | } 15 | public void UnInit() 16 | { 17 | characterDict.Clear(); 18 | sceneGrounpChr.Clear(); 19 | } 20 | 21 | public GameCharacter CreateGameCharacter(DBCharacterNode dbChr) 22 | { 23 | var gChr = new GameCharacter(dbChr); 24 | 25 | characterDict.TryAdd(dbChr.CId, gChr); 26 | 27 | if (!sceneGrounpChr.ContainsKey(gChr.CurSceneId)) 28 | { 29 | sceneGrounpChr.TryAdd(gChr.CurSceneId, new ConcurrentDictionary()); 30 | } 31 | sceneGrounpChr[gChr.CurSceneId].TryAdd(gChr.Cid, gChr); 32 | 33 | return gChr; 34 | } 35 | public bool RemoveGameCharacterByCid(string cId, HS.Protobuf.Scene.CharacterLeaveSceneResponse message) 36 | { 37 | bool result = false; 38 | if(!characterDict.TryRemove(cId, out var chr)) 39 | { 40 | goto End; 41 | } 42 | sceneGrounpChr[chr.CurSceneId].TryRemove(cId, out var _); 43 | chr.SaveGameCharacter(message); 44 | End: 45 | return result; 46 | } 47 | public GameCharacter GetGameCharacterByCid(string cId) 48 | { 49 | if(characterDict.TryGetValue(cId, out var gChr)) 50 | { 51 | return gChr; 52 | } 53 | return null; 54 | } 55 | 56 | public ConcurrentDictionary GetAllGameCharacter() 57 | { 58 | return characterDict; 59 | } 60 | public ConcurrentDictionary GetPartGameCharacterBySceneId(int sceneId) 61 | { 62 | sceneGrounpChr.TryGetValue(sceneId, out var chrs); 63 | return chrs; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /MMORPG/Start1.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal enabledelayedexpansion 3 | 4 | goto :main 5 | 6 | rem 函数:启动程序并记录PID 7 | :StartAndRecordPID 8 | echo Starting program in directory: %~dp0%~1 9 | cd /d "%~dp0%~1" || (echo Failed to change directory & exit /b) 10 | if not exist "%~2" ( 11 | echo File not found: %~2 12 | exit /b 13 | ) 14 | echo Current directory: %CD% 15 | start "%~3" "%~2" %~4 %~5 %~6 %~7 %~8 %~9 16 | echo Started program: %~2 with parameters: %~4 %~5 %~6 %~7 %~8 %~9 17 | rem timeout /t %DELAY% /nobreak >nul 18 | for /f "tokens=2 delims=," %%A in ('tasklist /fi "imagename eq %~2" /fo csv /nh') do ( 19 | echo %%~A >> "%~dp0pids.txt" 20 | ) 21 | exit /b 22 | 23 | :main 24 | 25 | rem 定义启动间隔(单位为s) 26 | set DELAY=0.1 27 | 28 | rem 定义所有服务器的目录路径(相对于脚本所在位置) 29 | set "CONTROL_CENTER_DIR=ControlCenter\bin\Debug\net6.0" 30 | set "DB_PROXY_SERVER_DIR=DBProxyServer\bin\Debug\net6.0" 31 | set "LOGIN_GATE_MGR_SERVER_DIR=LoginGateMgrServer\bin\Debug\net6.0" 32 | set "LOGIN_GATE_SERVER_DIR=LoginGateServer\bin\Debug\net6.0" 33 | set "LOGIN_SERVER_DIR=LoginServer\bin\Debug\net6.0" 34 | set "GAME_GATE_MGR_SERVER_DIR=GameGateMgrServer\bin\Debug\net6.0" 35 | set "GAME_GATE_SERVER_DIR=GameGateServer\bin\Debug\net6.0" 36 | set "GAME_SERVER_DIR=GameServer\bin\Debug\net6.0" 37 | set "SPACE_SERVER_DIR=SceneServer\bin\Debug\net6.0" 38 | 39 | rem 删除旧的 pids.txt 文件 40 | del "%~dp0pids.txt" >nul 2>&1 41 | 42 | rem 启动每个服务并记录其 PID 43 | echo CONTROL_CENTER_DIR=%CONTROL_CENTER_DIR% 44 | call :StartAndRecordPID "%CONTROL_CENTER_DIR%" "ControlCenter.exe" "ControlCenter" 45 | call :StartAndRecordPID "%DB_PROXY_SERVER_DIR%" "DBProxyServer.exe" "DBProxyServer" 46 | call :StartAndRecordPID "%LOGIN_GATE_MGR_SERVER_DIR%" "LoginGateMgrServer.exe" "LoginGateMgrServer" 47 | call :StartAndRecordPID "%LOGIN_GATE_SERVER_DIR%" "LoginGateServer.exe" "LoginGateServer" 48 | call :StartAndRecordPID "%LOGIN_SERVER_DIR%" "LoginServer.exe" "LoginServer" 49 | call :StartAndRecordPID "%GAME_GATE_MGR_SERVER_DIR%" "GameGateMgrServer.exe" "GameGateMgrServer" 50 | call :StartAndRecordPID "%GAME_GATE_SERVER_DIR%" "GameGateServer.exe" "GameGateServer" 51 | call :StartAndRecordPID "%GAME_SERVER_DIR%" "GameServer.exe" "GameServer" 52 | call :StartAndRecordPID "%SPACE_SERVER_DIR%" "SceneServer.exe" "SceneServer1" "-config" "config.yaml" 53 | call :StartAndRecordPID "%SPACE_SERVER_DIR%" "SceneServer.exe" "SceneServer2" "-config" "config2.yaml" 54 | 55 | endlocal 56 | 57 | pause -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/Buffs/BuffScanner.cs: -------------------------------------------------------------------------------- 1 | using SceneServer.Core.Model.Actor; 2 | using Serilog; 3 | using System; 4 | using System.Collections.Concurrent; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Reflection; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace SceneServer.Core.Combat.Buffs 12 | { 13 | 14 | // 描述了一个只能应用在类上的特性 15 | [AttributeUsage(AttributeTargets.Class)] 16 | public class BuffAttribute : Attribute 17 | { 18 | public int BuffId { get; } 19 | 20 | public BuffAttribute(int buffId) 21 | { 22 | this.BuffId = buffId; 23 | } 24 | } 25 | 26 | 27 | public class BuffScanner 28 | { 29 | public static ConcurrentDictionary BuffTypeDict = new(); 30 | 31 | // 扫描项目里带有[Skill]属性的class 32 | public static void Start() 33 | { 34 | int count = 0; 35 | Type[] types = Assembly.GetExecutingAssembly().GetTypes(); 36 | Type buffType = typeof(BuffBase); 37 | foreach (Type type in types) 38 | { 39 | // 判断这个type身上是否有BuffAttribute特性 40 | if (Attribute.IsDefined(type, typeof(BuffAttribute))) 41 | { 42 | var attribute = (BuffAttribute)Attribute.GetCustomAttribute(type, typeof(BuffAttribute)); 43 | // 拿到我们在属性中存放的技能id 44 | int buffId = attribute.BuffId; 45 | 46 | // 判断当前类型是否为buffType类或者派生类 47 | if (buffType.IsAssignableFrom(type.BaseType)) 48 | { 49 | count++; 50 | BuffTypeDict[buffId] = type; 51 | } 52 | else 53 | { 54 | Log.Error("未继承BuffBase基类:Name=[{1}]", buffId, type.Name); 55 | } 56 | 57 | } 58 | } 59 | 60 | //Log.Debug("==>共加载{0}个自定义技能", count); 61 | } 62 | 63 | // 创建Skill实例 64 | public static BuffBase CreateBuff(int buffId) 65 | { 66 | // 1.如果有注解则使用所在的类型 67 | if (BuffTypeDict.TryGetValue(buffId, out var buffType)) 68 | { 69 | object instance = Activator.CreateInstance(buffType); 70 | return (BuffBase)instance; 71 | } 72 | // 2.如果匹配不到则使用基础类型 73 | return null; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Handle/EnterGameWorldHanlder.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Tools; 4 | using Google.Protobuf; 5 | using HS.Protobuf.Scene; 6 | using SceneServer.Core.Scene; 7 | using SceneServer.Core.Scene.Component; 8 | 9 | namespace SceneServer.Handle 10 | { 11 | public class EnterGameWorldHanlder : Singleton 12 | { 13 | private int m_curWorldId; 14 | private IdGenerator m_idGenerator = new IdGenerator(); 15 | private Dictionary m_tasks = new Dictionary(); 16 | 17 | public bool Init() 18 | { 19 | // 协议注册 20 | ProtoHelper.Instance.Register((int)SceneProtocl.CharacterEnterSceneReq); 21 | ProtoHelper.Instance.Register((int)SceneProtocl.SelfCharacterEnterSceneResp); 22 | ProtoHelper.Instance.Register((int)SceneProtocl.OtherEntityEnterSceneResp); 23 | ProtoHelper.Instance.Register((int)SceneProtocl.CharacterLeaveSceneReq); 24 | ProtoHelper.Instance.Register((int)SceneProtocl.CharacterLeaveSceneResp); 25 | 26 | // 消息的订阅 27 | MessageRouter.Instance.Subscribe(_HandleCharacterEnterSceneRequest); 28 | MessageRouter.Instance.Subscribe(_HandleCharacterLeaveSceneRequest); 29 | return true; 30 | } 31 | 32 | private void _HandleCharacterEnterSceneRequest(Connection conn, CharacterEnterSceneRequest message) 33 | { 34 | SceneManager.Instance.CharacterEnterScene(conn, message); 35 | } 36 | private void _HandleCharacterLeaveSceneRequest(Connection conn, CharacterLeaveSceneRequest message) 37 | { 38 | var resp = new CharacterLeaveSceneResponse(); 39 | 40 | var chr = SceneManager.Instance.SceneCharacterManager.GetSceneCharacterByEntityId(message.EntityId); 41 | if(chr == null) { 42 | goto End; 43 | } 44 | SceneManager.Instance.CharacterExitScene(message.EntityId); 45 | resp.CId = chr.Cid; 46 | resp.SceneSaveDatea = new NeedSaveSceneData(); 47 | resp.SceneSaveDatea.Position = chr.Position; 48 | End: 49 | conn.Send(resp); 50 | return; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/AI/Boss/Impl/BossMonsterAIState_Flee.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using System; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SceneServer.Core.Combat.AI.MonsterAIStateImpl 8 | { 9 | public class BossMonsterAIState_Flee : BossMonsterAIState 10 | { 11 | private Vector3 fleeDirection; 12 | private float changeDirInterval; 13 | private float changeDirRemainTime; 14 | private float fleeDuration; 15 | 16 | public override void Enter() 17 | { 18 | fleeDuration = monsterAI.random.NextInt64(5, 8); 19 | changeDirInterval = fleeDuration * 0.2f; 20 | ChangeDir(); 21 | 22 | } 23 | public override void Update(float deltatime) 24 | { 25 | if(monsterAI.Target == null) 26 | { 27 | monsterAI.ChangeState(MonsterAIState.Patrol); 28 | goto End; 29 | } 30 | 31 | if (monsterAI.Monster.CurHP / monsterAI.Monster.MaxHP > 0.5f) 32 | { 33 | monsterAI.ChangeState(MonsterAIState.Patrol); 34 | goto End; 35 | } 36 | 37 | fleeDuration -= deltatime; 38 | if(fleeDuration <= 0) 39 | { 40 | monsterAI.ChangeState(MonsterAIState.Chase); 41 | goto End; 42 | } 43 | if (!monsterAI.IsTargetInRange(monsterAI.maxChaseDistance)) 44 | { 45 | monsterAI.ClearTarget(); 46 | monsterAI.ChangeState(MonsterAIState.Patrol); 47 | goto End; 48 | } 49 | 50 | changeDirRemainTime -= deltatime; 51 | if (changeDirRemainTime <= 0) 52 | { 53 | ChangeDir(); 54 | } 55 | 56 | End: 57 | return; 58 | } 59 | private Vector3 CalculateFleeDirection() 60 | { 61 | // 综合危险源和玩家位置计算最佳逃跑方向 62 | Vector3 tmp = (monsterAI.Monster.Position - monsterAI.Target.Position); 63 | return tmp.normalized; 64 | } 65 | private void ChangeDir() 66 | { 67 | fleeDirection = CalculateFleeDirection().normalized; 68 | var nextPos = fleeDirection * monsterAI.FleeSpeed * changeDirInterval; 69 | monsterAI.Monster.StartMoveToPoint(nextPos, monsterAI.FleeSpeed); 70 | changeDirRemainTime = changeDirInterval; 71 | } 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/Skill/SkillScanner.cs: -------------------------------------------------------------------------------- 1 | using SceneServer.Core.Model.Actor; 2 | using Serilog; 3 | using System.Collections.Concurrent; 4 | using System.Reflection; 5 | 6 | 7 | namespace SceneServer.Core.Combat.Skills 8 | { 9 | // 描述了一个只能应用在类上的特性 10 | [AttributeUsage(AttributeTargets.Class)] 11 | public class SkillAttribute : Attribute 12 | { 13 | // 技能码 其实就是skillid 14 | public int SkillId { get; } 15 | 16 | public SkillAttribute(int code) 17 | { 18 | this.SkillId = code; 19 | } 20 | } 21 | 22 | public class SkillScanner 23 | { 24 | public static ConcurrentDictionary SkillTypeDict = new(); 25 | 26 | // 扫描项目里带有[Skill]属性的class 27 | public static void Start() 28 | { 29 | int count = 0; 30 | Type[] types = Assembly.GetExecutingAssembly().GetTypes(); 31 | Type skillType = typeof(Skill); 32 | foreach (Type type in types) 33 | { 34 | //判断这个type身上是否有SkillAttribute特性 35 | if (Attribute.IsDefined(type, typeof(SkillAttribute))) 36 | { 37 | var attribute = (SkillAttribute)Attribute.GetCustomAttribute(type, typeof(SkillAttribute)); 38 | //拿到我们在属性中存放的技能id 39 | int skid = attribute.SkillId; 40 | 41 | //判断当前类型是否为skillType类或者派生类 42 | if (skillType.IsAssignableFrom(type.BaseType)) 43 | { 44 | count++; 45 | SkillTypeDict[skid] = type; 46 | //Log.Information("加载技能类型:Code=[{0}],Name=[{1}]", skid, type.Name); 47 | } 48 | else 49 | { 50 | Log.Error("未继承Skill基类:Name=[{1}]", skid, type.Name); 51 | } 52 | 53 | } 54 | } 55 | 56 | //Log.Debug("==>共加载{0}个自定义技能", count); 57 | } 58 | 59 | // 创建Skill实例 60 | public static Skill CreateSkill(SceneActor owner, int skid) 61 | { 62 | // 1.如果有注解则使用所在的类型 63 | if (SkillTypeDict.TryGetValue(skid, out var skillType)) 64 | { 65 | object instance = Activator.CreateInstance(skillType, owner, skid); 66 | return (Skill)instance; 67 | } 68 | // 2.如果匹配不到则使用基础类型 69 | return new Skill(owner, skid); 70 | } 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /MMORPG/MasterTimerServer/Net/MasterTimerServersMgr.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Server; 4 | using Common.Summer.Tools; 5 | using Google.Protobuf.Collections; 6 | using Google.Protobuf.WellKnownTypes; 7 | using HS.Protobuf.Common; 8 | using HS.Protobuf.ControlCenter; 9 | using MasterTimerServer.Utils; 10 | using Serilog; 11 | using System.Diagnostics; 12 | 13 | namespace MasterTimerServer.Net 14 | { 15 | public class MasterTimerServersMgr : BaseServersMgr 16 | { 17 | // 初始化相关 18 | protected override void InitLocalServerInfo() 19 | { 20 | // 本服务器的信息 21 | MasterTimeServerInfoNode mtNode = new(); 22 | m_localSin.ServerType = SERVER_TYPE.Mastertime; 23 | m_localSin.Ip = Config.Server.ip; 24 | m_localSin.Port = Config.Server.serverPort; 25 | m_localSin.ServerId = 0; 26 | m_localSin.MasterTimeServerInfo = mtNode; 27 | m_localSin.EventBitmap = 0; 28 | 29 | // 设置一下CC的信息 30 | m_relatedServerNode[SERVER_TYPE.Controlcenter].ServerInfoNode.Ip = Config.CCConfig.ip; 31 | m_relatedServerNode[SERVER_TYPE.Controlcenter].ServerInfoNode.Port = Config.CCConfig.port; 32 | 33 | } 34 | protected override void InitNetwork() 35 | { 36 | ConnManager.Instance.Init(Config.Server.workerCount, Config.Server.heartBeatSendInterval, Config.Server.heartBeatCheckInterval, Config.Server.heartBeatTimeOut, 37 | false, true, true, 38 | null, 0, null, null, 39 | Config.Server.ip, Config.Server.serverPort, ClusterServerConnected, ClusterServerDisconnected); 40 | } 41 | protected override void InitSpecificComponents() 42 | { 43 | } 44 | protected override void ConnectedCCAndRegisterAfter(RepeatedField clusterEventNodes) 45 | { 46 | // 开始网络监听,预示着当前服务器的正式启动 47 | ConnManager.Instance.Start(); 48 | Log.Information("\x1b[32m" + "The server is ready." + "\x1b[0m"); 49 | } 50 | 51 | // 其他服务器连接过来的服务器 的 连接事件 52 | private void ClusterServerConnected(Connection conn) 53 | { 54 | Log.Information("A slaveTimeServer connected to masterTimeServer."); 55 | } 56 | private void ClusterServerDisconnected(Connection conn) 57 | { 58 | Log.Information("A slaveTimeServer disconnected from masterTimeServer."); 59 | } 60 | } 61 | } 62 | 63 | 64 | -------------------------------------------------------------------------------- /MMORPG/DBProxyServer/Utils/Config.cs: -------------------------------------------------------------------------------- 1 | using YamlDotNet.Serialization; 2 | 3 | namespace DBProxyServer.Utils 4 | { 5 | public class ServerConfig 6 | { 7 | [YamlMember(Alias = "ip")] 8 | public string ip { get; set; } 9 | 10 | [YamlMember(Alias = "port")] 11 | public int serverPort { get; set; } 12 | 13 | [YamlMember(Alias = "workerCount")] 14 | public int workerCount { get; set; } 15 | 16 | [YamlMember(Alias = "updateHz")] 17 | public int updateHz { get; set; } 18 | 19 | [YamlMember(Alias = "heartBeatTimeOut")] 20 | public float heartBeatTimeOut { get; set; } 21 | 22 | [YamlMember(Alias = "heartBeatCheckInterval")] 23 | public float heartBeatCheckInterval { get; set; } 24 | 25 | [YamlMember(Alias = "heartBeatSendInterval")] 26 | public float heartBeatSendInterval { get; set; } 27 | } 28 | 29 | public class MongodbServerConfig 30 | { 31 | [YamlMember(Alias = "connectionString")] 32 | public string connectionString { get; set; } 33 | 34 | [YamlMember(Alias = "databaseName")] 35 | public string databaseName { get; set; } 36 | } 37 | 38 | public class CCConfig 39 | { 40 | [YamlMember(Alias = "ip")] 41 | public string ip { get; set; } 42 | 43 | [YamlMember(Alias = "port")] 44 | public int port { get; set; } 45 | } 46 | 47 | public class AppConfig 48 | { 49 | [YamlMember(Alias = "server")] 50 | public ServerConfig Server { get; set; } 51 | 52 | [YamlMember(Alias = "mongodb")] 53 | public MongodbServerConfig mongodbServer { get; set; } 54 | 55 | [YamlMember(Alias = "cc")] 56 | public CCConfig CCServer { get; set; } 57 | 58 | 59 | } 60 | 61 | public static class Config 62 | { 63 | private static AppConfig _config; 64 | 65 | public static void Init(string filePath = "config.yaml") 66 | { 67 | // 读取配置文件,当前项目根目录 68 | var yaml = File.ReadAllText(filePath); 69 | //Log.Information("LoadYamlText:\r\n {Yaml}", yaml); 70 | 71 | // 反序列化配置文件 72 | var deserializer = new DeserializerBuilder().Build(); 73 | _config = deserializer.Deserialize(yaml); 74 | } 75 | 76 | public static ServerConfig Server => _config?.Server; 77 | public static MongodbServerConfig MongodbServerConfig => _config?.mongodbServer; 78 | public static CCConfig CCConfig => _config?.CCServer; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Handle/CombatHandler.cs: -------------------------------------------------------------------------------- 1 | using Serilog; 2 | using Common.Summer.Tools; 3 | using Common.Summer.Net; 4 | using Common.Summer.Core; 5 | using HS.Protobuf.Combat.Skill; 6 | using HS.Protobuf.Scene; 7 | using SceneServer.Utils; 8 | using SceneServer.Net; 9 | using SceneServer.Core.Scene; 10 | using SceneServer.Core.Scene.Component; 11 | 12 | namespace SceneServer.Handle 13 | { 14 | public class CombatHandler : Singleton 15 | { 16 | public override void Init() 17 | { 18 | ProtoHelper.Instance.Register((int)SkillProtocol.SpellCastReq); 19 | ProtoHelper.Instance.Register((int)SkillProtocol.SpellCastResp); 20 | ProtoHelper.Instance.Register((int)SkillProtocol.SpellCastFailResp); 21 | 22 | ProtoHelper.Instance.Register((int)SceneProtocl.SceneDeliverReq); 23 | ProtoHelper.Instance.Register((int)SceneProtocl.SceneDeliverResp); 24 | ProtoHelper.Instance.Register((int)SceneProtocl.CharacterReviveReq); 25 | ProtoHelper.Instance.Register((int)SceneProtocl.CharacterReviveResp); 26 | 27 | MessageRouter.Instance.Subscribe(HandleSpellCastRequest); 28 | MessageRouter.Instance.Subscribe(HandleSpaceDeliverRequest); 29 | MessageRouter.Instance.Subscribe(HanleReviveRequest); 30 | } 31 | 32 | private void HandleSpellCastRequest(Connection conn, SpellCastRequest message) 33 | { 34 | // 将其放入当前场景的战斗管理器的缓冲队列中 35 | SceneManager.Instance.FightManager.castReqQueue.Enqueue(message.Info); 36 | } 37 | 38 | private void HanleReviveRequest(Connection conn, CharacterReviveRequest message) 39 | { 40 | // chr发的 41 | var chr = SceneManager.Instance.SceneCharacterManager.GetSceneCharacterByEntityId(message.EntityId); 42 | if (chr != null && chr.IsDeath) 43 | { 44 | chr.Revive(); 45 | } 46 | } 47 | 48 | private void HandleSpaceDeliverRequest(Connection conn, SceneDeliverRequest message) 49 | { 50 | var chr = SceneManager.Instance.SceneCharacterManager.GetSceneCharacterByEntityId(message.EntityId); 51 | if(chr != null && chr.IsDeath) 52 | { 53 | SceneManager.Instance.TransmitTo(chr, message.PointId); 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/CommonMgr.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.StaticData; 2 | using Common.Summer.Tools; 3 | using Serilog; 4 | using Serilog.Sinks.SystemConsole.Themes; 5 | using System.Collections.Generic; 6 | 7 | namespace Common.Summer 8 | { 9 | public class CommonMgr : Singleton 10 | { 11 | public override void Init() 12 | { 13 | // 这里可以初始化一些全局的东西,比如日志系统、配置加载等 14 | 15 | // 初始化日志环境 16 | var customTheme = new AnsiConsoleTheme(new Dictionary 17 | { 18 | [ConsoleThemeStyle.Text] = "\x1b[37m", // White 19 | [ConsoleThemeStyle.SecondaryText] = "\x1b[37m", // Gray 20 | [ConsoleThemeStyle.TertiaryText] = "\x1b[90m", // Dark gray 21 | [ConsoleThemeStyle.Invalid] = "\x1b[33m", // Yellow 22 | [ConsoleThemeStyle.Null] = "\x1b[34m", // Blue 23 | [ConsoleThemeStyle.Name] = "\x1b[32m", // Green 24 | [ConsoleThemeStyle.String] = "\x1b[36m", // Cyan 25 | [ConsoleThemeStyle.Number] = "\x1b[32m", // Magenta \x1b[35m 26 | [ConsoleThemeStyle.Boolean] = "\x1b[34m", // Blue 27 | [ConsoleThemeStyle.Scalar] = "\x1b[32m", // Green 28 | [ConsoleThemeStyle.LevelVerbose] = "\x1b[90m", // Dark gray 29 | [ConsoleThemeStyle.LevelDebug] = "\x1b[37m", // White 30 | [ConsoleThemeStyle.LevelInformation] = "\x1b[32m", // Green 31 | [ConsoleThemeStyle.LevelWarning] = "\x1b[33m", // Yellow 32 | [ConsoleThemeStyle.LevelError] = "\x1b[31m", // Red 33 | [ConsoleThemeStyle.LevelFatal] = "\x1b[41m\x1b[37m" // Red background, white text 34 | }); 35 | Log.Logger = new LoggerConfiguration() 36 | .MinimumLevel.Debug() 37 | .WriteTo.Console( 38 | theme: customTheme, 39 | outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] {Message:lj}{NewLine}{Exception}" 40 | ) 41 | .WriteTo.File( 42 | "logs\\server-log.txt", 43 | rollingInterval: RollingInterval.Day, 44 | outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] {Message:lj}{NewLine}{Exception}" 45 | ) 46 | .CreateLogger(); 47 | 48 | // errorcode 49 | ErrorCode.GetCode("OK"); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Tools/Varint.cs: -------------------------------------------------------------------------------- 1 | using Serilog; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Common.Summer.Tools 9 | { 10 | 11 | 12 | /// 13 | /// varints整数压缩和解码 14 | /// 15 | public class Varint 16 | { 17 | 18 | /// 19 | /// varint压缩 20 | /// 21 | /// 22 | /// 23 | public static byte[] VarintEncode(ulong value) 24 | { 25 | var list = new List(); 26 | while (value > 0) 27 | { 28 | byte b = (byte)(value & 0x7f); //获取value最低的7位 29 | value >>= 7; //value右移7位,丢弃 30 | if (value > 0) 31 | { 32 | b |= 0x80; //如果还有剩余的位需要编码,将b的最高位置为1 33 | } 34 | list.Add(b); 35 | } 36 | return list.ToArray(); 37 | } 38 | 39 | /// 40 | /// varint 解析 41 | /// 42 | /// 43 | /// 44 | public static ulong VarintDecode(byte[] buffer) 45 | { 46 | ulong value = 0; 47 | int shift = 0; 48 | int len = buffer.Length; 49 | for (int i = 0; i < len; i++) 50 | { 51 | byte b = buffer[i]; 52 | value |= (ulong)(b & 0x7F) << shift; 53 | if ((b & 0x80) == 0) 54 | { 55 | break; 56 | } 57 | shift += 7; 58 | } 59 | return value; 60 | } 61 | 62 | 63 | /// 64 | /// 判断有效字节的数量 65 | /// 66 | /// 67 | /// 68 | public static int VarintSize(ulong value) 69 | { 70 | //位置7位,如果前面都为0,说明只有一个有效字节 71 | if ((value & (0xFFFFFFFF << 7)) == 0) 72 | { 73 | return 1; 74 | } 75 | 76 | if ((value & (0xFFFFFFFF << 14)) == 0) 77 | { 78 | return 2; 79 | } 80 | 81 | if ((value & (0xFFFFFFFF << 21)) == 0) 82 | { 83 | return 3; 84 | } 85 | 86 | if ((value & (0xFFFFFFFF << 28)) == 0) 87 | { 88 | return 4; 89 | } 90 | return 5; 91 | } 92 | 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Scene/Component/SceneEntityManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using Common.Summer.Tools; 3 | using Common.Summer.Core; 4 | using SceneServer.Core.Model; 5 | using HS.Protobuf.Scene; 6 | 7 | namespace SceneServer.Core.Scene.Component 8 | { 9 | public class SceneEntityManager : Singleton 10 | { 11 | private IdGenerator _idGenerator = new IdGenerator(); 12 | private ConcurrentDictionary allEntitiesDict = new(); // 13 | 14 | public override void Init() 15 | { 16 | Scheduler.Instance.Update(Update); 17 | } 18 | 19 | public void Update() 20 | { 21 | foreach (var entity in allEntitiesDict) 22 | { 23 | entity.Value.Update(MyTime.deltaTime); 24 | } 25 | } 26 | public void AddSceneEntity(SceneEntity entity) 27 | { 28 | lock (this) 29 | { 30 | //给角色分配一个独一无二的id 31 | entity.EntityId = _idGenerator.GetId(); 32 | allEntitiesDict[entity.EntityId] = entity; 33 | } 34 | } 35 | public void RemoveSceneEntity(int entityId) 36 | { 37 | if (!allEntitiesDict.ContainsKey(entityId)) return; 38 | allEntitiesDict.TryRemove(entityId, out var entity); 39 | if (entity != null) 40 | { 41 | _idGenerator.ReturnId(entityId); 42 | } 43 | } 44 | public SceneEntity GetSceneEntityById(int entityId) 45 | { 46 | return allEntitiesDict.GetValueOrDefault(entityId); 47 | } 48 | public List GetSceneEntitiesByIds(IEnumerable ids) 49 | { 50 | List res = new(); 51 | foreach (var id in ids) 52 | { 53 | if (allEntitiesDict.TryGetValue((int)id, out var entity)) 54 | { 55 | res.Add(entity); 56 | } 57 | } 58 | return res; 59 | } 60 | public List GetSceneEntitiesByIds(List ids) 61 | { 62 | List res = new(); 63 | foreach (var id in ids) 64 | { 65 | if (allEntitiesDict.TryGetValue(id, out var entity)) 66 | { 67 | res.Add(entity); 68 | } 69 | } 70 | return res; 71 | } 72 | public bool SceneEntityIsExists(int entityId) 73 | { 74 | return allEntitiesDict.ContainsKey(entityId); 75 | } 76 | } 77 | } 78 | 79 | -------------------------------------------------------------------------------- /MMORPG/Common/Summer/Security/AesEncryption.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Security.Cryptography; 4 | using System.Text; 5 | 6 | namespace Common.Summer.Security 7 | { 8 | public class AesEncryption 9 | { 10 | private readonly byte[] key; 11 | private readonly byte[] iv; 12 | 13 | public AesEncryption(string Key,string IV) 14 | { 15 | key = Encoding.UTF8.GetBytes(Key.PadRight(32).Substring(0, 32)); 16 | iv = Encoding.UTF8.GetBytes(IV.PadRight(16).Substring(0, 16)); 17 | } 18 | 19 | public string Encrypt(string plainText) 20 | { 21 | using (Aes aesAlg = Aes.Create()) 22 | { 23 | aesAlg.Key = key; 24 | aesAlg.IV = iv; 25 | 26 | ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); 27 | 28 | using (MemoryStream msEncrypt = new MemoryStream()) 29 | { 30 | using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 31 | using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) 32 | { 33 | swEncrypt.Write(plainText); 34 | } 35 | return Convert.ToBase64String(msEncrypt.ToArray()); 36 | } 37 | } 38 | } 39 | public string Decrypt(string cipherText) 40 | { 41 | using (Aes aesAlg = Aes.Create()) 42 | { 43 | aesAlg.Key = key; 44 | aesAlg.IV = iv; 45 | ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); 46 | 47 | using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(cipherText))) 48 | using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 49 | using (StreamReader srDecrypt = new StreamReader(csDecrypt)) 50 | { 51 | return srDecrypt.ReadToEnd(); 52 | } 53 | } 54 | } 55 | 56 | public static (string Key, string IV) GenerateAesKeyAndIv() 57 | { 58 | using (Aes aes = Aes.Create()) 59 | { 60 | aes.GenerateKey(); 61 | aes.GenerateIV(); 62 | 63 | // Convert the byte arrays to Base64 strings for easy storage or transmission 64 | string key = Convert.ToBase64String(aes.Key); 65 | string iv = Convert.ToBase64String(aes.IV); 66 | 67 | return (key, iv); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Combat/Skill/SkillManager.cs: -------------------------------------------------------------------------------- 1 | using HS.Protobuf.Combat.Skill; 2 | using SceneServer.Core.Model.Actor; 3 | using SceneServer.Utils; 4 | 5 | namespace SceneServer.Core.Combat.Skills 6 | { 7 | /// 8 | /// 技能管理器,每一个Actor都有独立的技能管理器 9 | /// 10 | public class SkillManager 11 | { 12 | private SceneActor m_owner; // 管理器的归属者 13 | public List Skills = new(); // 技能队列 14 | 15 | public bool Init(SceneActor owner) 16 | { 17 | m_owner = owner; 18 | var def = StaticDataManager.Instance.weaponSkillArsenalDefineDict[m_owner.m_define.weaponSkillArsenalId]; 19 | _LoadSkillsByIds(def.SkillIds.ToList()); 20 | // 武器相关的 21 | var def2 = StaticDataManager.Instance.weaponSkillArsenalDefineDict[1]; 22 | _LoadSkillsByIds(def2.SkillIds.ToList()); 23 | 24 | return true; 25 | } 26 | 27 | public void Update(float deltaTime) 28 | { 29 | foreach (Skill skill in Skills) 30 | { 31 | skill.Update(deltaTime); 32 | } 33 | } 34 | 35 | public bool AddWeaponSkills(int skillGroundId) 36 | { 37 | var def = StaticDataManager.Instance.weaponSkillArsenalDefineDict[m_owner.m_define.weaponSkillArsenalId]; 38 | _LoadSkillsByIds(def.SkillIds.ToList()); 39 | return true; 40 | } 41 | public bool AddFixedSkills() 42 | { 43 | bool result = false; 44 | if(m_owner.NetActorNode.FixedSkillGroupInfo == null) 45 | { 46 | goto End; 47 | } 48 | 49 | foreach(var item in m_owner.NetActorNode.FixedSkillGroupInfo.Skills) 50 | { 51 | var skill = SkillScanner.CreateSkill(m_owner, item.SkillId); 52 | Skills.Add(skill); 53 | } 54 | 55 | result = true; 56 | End: 57 | return result; 58 | } 59 | private void _LoadSkillsByIds(List ids) 60 | { 61 | foreach(int skid in ids) 62 | { 63 | if (skid == 0) continue; 64 | var skill = SkillScanner.CreateSkill(m_owner, skid); 65 | Skills.Add(skill); 66 | } 67 | } 68 | public Skill GetSkillById(int skillId) 69 | { 70 | foreach (var skill in Skills) { 71 | if(skill.Define.ID == skillId) 72 | { 73 | return skill; 74 | } 75 | } 76 | return null; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /MMORPG/GameServer/core/Model/BaseItem/GameItem.cs: -------------------------------------------------------------------------------- 1 | using GameServer.Utils; 2 | using HS.Protobuf.Backpack; 3 | using HS.Protobuf.SceneEntity; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace GameServer.core.Model.BaseItem 11 | { 12 | public class GameItem 13 | { 14 | protected ItemDefine m_itemDefine; 15 | protected NetItemDataNode m_netItemDataNode; 16 | 17 | #region GetSet 18 | public int ItemId => m_itemDefine.ID; 19 | public int Count 20 | { 21 | get => m_netItemDataNode.Amount; 22 | set { m_netItemDataNode.Amount = value; } 23 | } 24 | public int GridIdx 25 | { 26 | get => m_netItemDataNode.GridIdx; 27 | set 28 | { 29 | m_netItemDataNode.GridIdx = value; 30 | } 31 | } 32 | public int StackingUpperLimit => m_itemDefine.Capicity; 33 | public NetItemDataNode NetItemDataNode => m_netItemDataNode; 34 | public ItemDefine ItemDefine => m_itemDefine; 35 | #endregion 36 | 37 | public GameItem(NetItemDataNode netItemDataNode) 38 | { 39 | this.m_itemDefine = StaticDataManager.Instance.ItemDefinedDict[netItemDataNode.ItemId]; 40 | this.m_netItemDataNode = netItemDataNode; 41 | } 42 | public GameItem(ItemDefine define, int amount = 1, int gridIdx = 0) 43 | { 44 | m_itemDefine = define; 45 | m_netItemDataNode = new NetItemDataNode() { ItemId = m_itemDefine.ID }; 46 | this.m_netItemDataNode.Amount = amount; 47 | this.m_netItemDataNode.GridIdx = gridIdx; 48 | m_netItemDataNode.ItemType = GetItemType(); 49 | } 50 | 51 | public ItemType GetItemType() 52 | { 53 | switch (m_itemDefine.ItemType) 54 | { 55 | case "消耗品": return ItemType.Consumable; 56 | case "道具": return ItemType.Material; 57 | case "装备": return ItemType.Equipment; 58 | } 59 | return ItemType.Consumable; 60 | } 61 | public ItemQuality GetItemQuality() 62 | { 63 | switch (m_itemDefine.Quality) 64 | { 65 | case "普通": return ItemQuality.Common; 66 | case "非凡": return ItemQuality.Fine; 67 | case "稀有": return ItemQuality.Rare; 68 | case "史诗": return ItemQuality.Epic; 69 | case "传说": return ItemQuality.Legendary; 70 | case "神器": return ItemQuality.Artifact; 71 | } 72 | return ItemQuality.Common; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/AOIMap/Linked/SkipList/SkipList.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace SceneServer.Core.AOI 3 | { 4 | /// 5 | /// 跳跃表 6 | /// 7 | /// 8 | public class SkipList 9 | { 10 | private int _level; 11 | private SkipListNode _header; 12 | private readonly Random _random = new Random(); 13 | 14 | public void Add(long target, T obj) 15 | { 16 | var rLevel = 1; 17 | while (rLevel <= _level && _random.Next(2) == 0) ++rLevel; 18 | 19 | if (rLevel > _level) 20 | { 21 | _level = rLevel; 22 | _header = new SkipListNode().Init(target, obj, null, _header); 23 | } 24 | 25 | SkipListNode cur = _header, last = null; 26 | 27 | for (var l = _level; l >= 1; --l) 28 | { 29 | while (cur.Right != null && cur.Right.Value < target) cur = cur.Right; 30 | 31 | if (l <= rLevel) 32 | { 33 | cur.Right = new SkipListNode().Init(target, obj, cur.Right, null); 34 | 35 | if (last != null) last.Down = cur.Right; 36 | 37 | last = cur.Right; 38 | } 39 | 40 | cur = cur.Down; 41 | } 42 | } 43 | 44 | public bool TryGetValue(long target, out SkipListNode node) 45 | { 46 | node = null; 47 | 48 | var cur = _header; 49 | 50 | while (cur != null) 51 | { 52 | while (cur.Right != null && cur.Right.Value < target) cur = cur.Right; 53 | 54 | if (cur.Right != null && cur.Right.Value == target) 55 | { 56 | node = cur.Right; 57 | while (node.Down != null) node = node.Down; 58 | return true; 59 | } 60 | 61 | cur = cur.Down; 62 | } 63 | 64 | return false; 65 | } 66 | 67 | public bool Remove(long target, out T obj) 68 | { 69 | var cur = _header; 70 | obj = default; 71 | var seen = false; 72 | 73 | for (var l = _level; l >= 1; --l) 74 | { 75 | while (cur.Right != null && cur.Right.Value < target) cur = cur.Right; 76 | 77 | if (cur.Right != null && cur.Right.Value == target) 78 | { 79 | obj = cur.Right.Obj; 80 | cur.Right = cur.Right.Right; 81 | seen = true; 82 | } 83 | 84 | cur = cur.Down; 85 | } 86 | 87 | return seen; 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /MMORPG/DBProxyServer/Handle/WorldHandler.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Tools; 4 | using DBProxyServer.Core; 5 | using HS.Protobuf.DBProxy.DBUser; 6 | using HS.Protobuf.DBProxy.DBWorld; 7 | using MongoDB.Bson; 8 | 9 | namespace DBProxyServer.Handle 10 | { 11 | public class WorldHandler : Singleton 12 | { 13 | public void Init() 14 | { 15 | // 协议注册 16 | ProtoHelper.Instance.Register((int)DBWorldProtocl.GetDbworldNodeByWorldidReq); 17 | ProtoHelper.Instance.Register((int)DBWorldProtocl.GetDbworldNodeByWorldidResp); 18 | ProtoHelper.Instance.Register((int)DBWorldProtocl.GetAllDbworldNodeReq); 19 | ProtoHelper.Instance.Register((int)DBWorldProtocl.GetAllDbworldNodeResp); 20 | // 消息的订阅 21 | MessageRouter.Instance.Subscribe(_HandleGetDBWorldNodeByWorldIdRequest); 22 | MessageRouter.Instance.Subscribe(_HandleGetAllDBWorldNodeRequest); 23 | } 24 | 25 | public async void _HandleGetDBWorldNodeByWorldIdRequest(Connection sender, GetDBWorldNodeByWorldIdRequest message) 26 | { 27 | GetDBWorldNodeByWorldIdResponse resp = new(); 28 | resp.TaskId = message.TaskId; 29 | 30 | DBWorldNode dBWorldNode = await WorldOperations.Instance.GetDBWorldNodeByWorldIdAsync(message.WorldId); 31 | if (dBWorldNode == null) 32 | { 33 | resp.ResultCode = 1; 34 | resp.ResultMsg = $"No information found for the worldId: {message.WorldId}."; 35 | goto End; 36 | } 37 | else 38 | { 39 | resp.DbWorldNode = dBWorldNode; 40 | resp.ResultCode = 0; 41 | } 42 | 43 | End: 44 | sender.Send(resp); 45 | } 46 | 47 | private async void _HandleGetAllDBWorldNodeRequest(Connection sender, GetAllDBWorldNodeRequest message) 48 | { 49 | GetAllDBWorldNodeResponse resp = new(); 50 | resp.TaskId = message.TaskId; 51 | 52 | var worlds = await WorldOperations.Instance.GetAllWorldNodeAsync(); 53 | if (worlds == null) 54 | { 55 | resp.ResultCode = 1; 56 | resp.ResultMsg = "Unopened World"; 57 | goto End; 58 | } 59 | else 60 | { 61 | resp.ResultCode = 0; 62 | resp.Nodes.AddRange(worlds); 63 | } 64 | End: 65 | sender.Send(resp); 66 | } 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /MMORPG/LoginGateServer/Handle/EnterGameWorldHanlder.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Security; 4 | using Common.Summer.Tools; 5 | using Google.Protobuf; 6 | using HS.Protobuf.DBProxy.DBWorld; 7 | using HS.Protobuf.Login; 8 | using LoginGateServer.Net; 9 | 10 | namespace LoginGateServer.Handle 11 | { 12 | public class EnterGameWorldHanlder : Singleton 13 | { 14 | public bool Init() 15 | { 16 | // 协议注册 17 | ProtoHelper.Instance.Register((int)LoginProtocl.GetAllWorldInfoNodeReq); 18 | ProtoHelper.Instance.Register((int)LoginProtocl.GetAllWorldInfoNodeResp); 19 | ProtoHelper.Instance.Register((int)LoginProtocl.GetGameGateByWorldidReq); 20 | ProtoHelper.Instance.Register((int)LoginProtocl.GetGameGateByWorldidResp); 21 | // 消息的订阅 22 | MessageRouter.Instance.Subscribe(_HandleGetAllWorldInfosRequest); 23 | MessageRouter.Instance.Subscribe(_HandleGetAllWorldInfosResponse); 24 | MessageRouter.Instance.Subscribe(_HandleGetGameGateByWorldIdRequest); 25 | MessageRouter.Instance.Subscribe(_HandleGetGameGateByWorldIdResponse); 26 | return true; 27 | } 28 | 29 | public bool UnInit() 30 | { 31 | return true; 32 | } 33 | 34 | private void _HandleGetAllWorldInfosRequest(Connection conn, GetAllWorldInfosRequest message) 35 | { 36 | // 转发到loginServer 37 | message.LoginToken = ServersMgr.Instance.LoginToken; 38 | ServersMgr.Instance.SendToLoginServer(message); 39 | } 40 | private void _HandleGetAllWorldInfosResponse(Connection conn, GetAllWorldInfosResponse message) 41 | { 42 | LoginGateToken token = LoginGateTokenManager.Instance.GetToken(message.LoginGateToken); 43 | message.LoginGateToken = ""; 44 | token.Send(message); 45 | } 46 | 47 | private void _HandleGetGameGateByWorldIdRequest(Connection conn, GetGameGateByWorldIdRequest message) 48 | { 49 | // 转发到loginServer 50 | message.LoginToken = ServersMgr.Instance.LoginToken; 51 | ServersMgr.Instance.SendToLoginServer(message); 52 | } 53 | private void _HandleGetGameGateByWorldIdResponse(Connection conn, GetGameGateByWorldIdResponse message) 54 | { 55 | LoginGateToken token = LoginGateTokenManager.Instance.GetToken(message.LoginGateToken); 56 | message.LoginGateToken = ""; 57 | token.Send(message); 58 | } 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /MMORPG/LoginGateServer/Handle/UserHandler.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using Common.Summer.Net; 3 | using Common.Summer.Tools; 4 | using HS.Protobuf.Login; 5 | using LoginGateServer.Net; 6 | 7 | namespace LoginGateServer.Handle 8 | { 9 | public class UserHandler : Singleton 10 | { 11 | public bool Init() 12 | { 13 | // 协议注册 14 | ProtoHelper.Instance.Register((int)LoginProtocl.UserLoginReq); 15 | ProtoHelper.Instance.Register((int)LoginProtocl.UserLoginResp); 16 | ProtoHelper.Instance.Register((int)LoginProtocl.UserRegisterReq); 17 | ProtoHelper.Instance.Register((int)LoginProtocl.UserRegisterResp); 18 | // 消息的订阅 19 | MessageRouter.Instance.Subscribe(_HandleUserLoginRequest); 20 | MessageRouter.Instance.Subscribe(_HandleUserLoginResponse); 21 | MessageRouter.Instance.Subscribe(_HandleUserRegisterRequest); 22 | MessageRouter.Instance.Subscribe(_HandleUserRegisterResponse); 23 | return true; 24 | } 25 | public bool UnInit() 26 | { 27 | return true; 28 | } 29 | 30 | private void _HandleUserLoginRequest(Connection conn, UserLoginRequest message) 31 | { 32 | // 解密 33 | message.Username = conn.m_encryptionManager.AesDecrypt(message.Username); 34 | message.Password = conn.m_encryptionManager.AesDecrypt(message.Password); 35 | // 转发到loginServer 36 | message.LoginToken = ServersMgr.Instance.LoginToken; 37 | ServersMgr.Instance.SendToLoginServer(message); 38 | } 39 | private void _HandleUserLoginResponse(Connection conn, UserLoginResponse message) 40 | { 41 | LoginGateToken token = LoginGateTokenManager.Instance.GetToken(message.LoginGateToken); 42 | message.LoginGateToken = ""; 43 | token.Send(message); 44 | } 45 | private void _HandleUserRegisterRequest(Connection conn, UserRegisterRequest message) 46 | { 47 | // 解密 48 | message.Username = conn.m_encryptionManager.AesDecrypt(message.Username); 49 | message.Password = conn.m_encryptionManager.AesDecrypt(message.Password); 50 | message.LoginToken = ServersMgr.Instance.LoginToken; 51 | 52 | // 转发到loginServer 53 | ServersMgr.Instance.SendToLoginServer(message); 54 | } 55 | private void _HandleUserRegisterResponse(Connection conn, UserRegisterResponse message) 56 | { 57 | LoginGateToken token = LoginGateTokenManager.Instance.GetToken(message.LoginGateToken); 58 | message.LoginGateToken = ""; 59 | token.Send(message); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /MMORPG/SceneServer/Core/Model/SceneEntity.cs: -------------------------------------------------------------------------------- 1 | using Common.Summer.Core; 2 | using HS.Protobuf.Common; 3 | using HS.Protobuf.SceneEntity; 4 | using SceneServer.AOIMap.NineSquareGrid; 5 | 6 | namespace SceneServer.Core.Model 7 | { 8 | public class SceneEntity : IAOIUnit 9 | { 10 | protected int m_entityId; 11 | private Vector3Int m_position; // 这里的vector3都是*1000倍的 12 | private Vector3Int m_rotation; 13 | private Vector3Int m_scale; 14 | private Vector2 m_aoiPos; 15 | 16 | #region GetSet 17 | public int EntityId 18 | { 19 | get { return m_entityId; } 20 | set 21 | { 22 | m_entityId = value; 23 | } 24 | } 25 | public Vector3Int Position 26 | { 27 | get { return m_position; } 28 | set 29 | { 30 | m_position = value; 31 | } 32 | } 33 | public Vector3Int Rotation 34 | { 35 | get { return m_rotation; } 36 | set 37 | { 38 | m_rotation = value; 39 | } 40 | } 41 | public Vector3Int Scale 42 | { 43 | get { return m_scale; } 44 | set 45 | { 46 | m_scale = value; 47 | } 48 | } 49 | public Vector2 AoiPos => m_aoiPos; 50 | #endregion 51 | 52 | #region 生命周期 53 | protected void Init(NetVector3 pos, Vector3Int rotation ,Vector3 scale) 54 | { 55 | m_position = pos; 56 | m_rotation = rotation; 57 | m_scale = scale; 58 | m_aoiPos = new Vector2(m_position.x, m_position.z) / 1000; 59 | } 60 | public virtual void Update(float deltaTime) 61 | { 62 | 63 | } 64 | #endregion 65 | 66 | #region Tools 67 | public virtual void SetTransform(NetTransform transform) 68 | { 69 | m_position = transform.Position; 70 | m_rotation = transform.Rotation; 71 | m_scale = transform.Scale; 72 | 73 | m_aoiPos.x = m_position.x / 1000.0f; 74 | m_aoiPos.y = m_position.z / 1000.0f; 75 | } 76 | public virtual NetTransform GetTransform() 77 | { 78 | return new NetTransform 79 | { 80 | Position = m_position, 81 | Rotation = m_rotation, 82 | Scale = m_scale, 83 | }; 84 | } 85 | #endregion 86 | 87 | #region AOI 88 | public virtual void OnUnitEnter(IAOIUnit unit) 89 | { 90 | } 91 | public virtual void OnUnitLeave(IAOIUnit unit) 92 | { 93 | } 94 | public virtual void OnPosError() 95 | { 96 | } 97 | #endregion 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /MMORPG/GameServer/Utils/Config.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using YamlDotNet.Serialization; 3 | 4 | namespace GameServer.Utils 5 | { 6 | public class DatabaseConfig 7 | { 8 | [YamlMember(Alias = "host")] 9 | public string Host { get; set; } 10 | 11 | [YamlMember(Alias = "port")] 12 | public int Port { get; set; } 13 | 14 | [YamlMember(Alias = "username")] 15 | public string Username { get; set; } 16 | 17 | [YamlMember(Alias = "password")] 18 | public string Password { get; set; } 19 | 20 | [YamlMember(Alias = "dbName")] 21 | public string DbName { get; set; } 22 | } 23 | 24 | public class ServerConfig 25 | { 26 | [YamlMember(Alias = "gameWorldId")] 27 | public int gameWorldId; 28 | 29 | [YamlMember(Alias = "ip")] 30 | public string ip { get; set; } 31 | 32 | [YamlMember(Alias = "serverPort")] 33 | public int serverPort { get; set; } 34 | 35 | [YamlMember(Alias = "workerCount")] 36 | public int workerCount { get; set; } 37 | 38 | [YamlMember(Alias = "aoiViewArea")] 39 | public float aoiViewArea { get; set; } 40 | 41 | [YamlMember(Alias = "updateHz")] 42 | public int updateHz { get; set; } 43 | 44 | [YamlMember(Alias = "heartBeatTimeOut")] 45 | public float heartBeatTimeOut { get; set; } 46 | 47 | [YamlMember(Alias = "heartBeatCheckInterval")] 48 | public float heartBeatCheckInterval { get; set; } 49 | 50 | [YamlMember(Alias = "heartBeatSendInterval")] 51 | public float heartBeatSendInterval { get; set; } 52 | } 53 | 54 | public class CCConfig 55 | { 56 | [YamlMember(Alias = "ip")] 57 | public string ip { get; set; } 58 | 59 | [YamlMember(Alias = "port")] 60 | public int port { get; set; } 61 | } 62 | 63 | public class AppConfig 64 | { 65 | [YamlMember(Alias = "database")] 66 | public DatabaseConfig Database { get; set; } 67 | 68 | [YamlMember(Alias = "server")] 69 | public ServerConfig Server { get; set; } 70 | 71 | [YamlMember(Alias = "cc")] 72 | public CCConfig CCServer { get; set; } 73 | } 74 | 75 | public static class Config 76 | { 77 | private static AppConfig _config; 78 | 79 | public static void Init(string filePath = "config.yaml") 80 | { 81 | // 读取配置文件,当前项目根目录 82 | var yaml = File.ReadAllText(filePath); 83 | //Log.Information("LoadYamlText:\r\n {Yaml}", yaml); 84 | 85 | // 反序列化配置文件 86 | var deserializer = new DeserializerBuilder().Build(); 87 | _config = deserializer.Deserialize(yaml); 88 | } 89 | 90 | public static DatabaseConfig Database => _config?.Database; 91 | public static ServerConfig Server => _config?.Server; 92 | public static CCConfig CCConfig => _config?.CCServer; 93 | } 94 | } 95 | --------------------------------------------------------------------------------