├── .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