Browse Source

Merge github.com:eesast/THUAI6 into dev

tags/0.1.0
Shawqeem 2 years ago
parent
commit
29acbecc5d
40 changed files with 1793 additions and 1007 deletions
  1. +3
    -0
      .github/FUNDING.yaml
  2. +0
    -13
      .github/workflows/clang-format.yml
  3. +34
    -0
      .github/workflows/format.yml
  4. +65
    -170
      CAPI/API/include/API.h
  5. +12
    -12
      CAPI/API/include/Communication.h
  6. +14
    -21
      CAPI/API/include/logic.h
  7. +1
    -2
      CAPI/API/include/structures.h
  8. +10
    -2
      CAPI/API/include/utils.hpp
  9. +4
    -0
      CAPI/API/src/AI.cpp
  10. +16
    -22
      CAPI/API/src/API.cpp
  11. +67
    -79
      CAPI/API/src/Communication.cpp
  12. +249
    -0
      CAPI/API/src/DebugAPI.cpp
  13. +94
    -53
      CAPI/API/src/logic.cpp
  14. +4
    -2
      CAPI/API/src/main.cpp
  15. +45
    -105
      CAPI/proto/Services.grpc.pb.cc
  16. +210
    -417
      CAPI/proto/Services.grpc.pb.h
  17. +16
    -17
      CAPI/proto/Services.pb.cc
  18. +34
    -0
      dependency/proto/Protos.csproj
  19. +2
    -3
      dependency/proto/Services.proto
  20. +13
    -3
      dependency/shell/format.sh
  21. +1
    -1
      installer/Installer/AssemblyInfo.cs
  22. +2
    -1
      installer/Installer/Installer.csproj
  23. +24
    -6
      installer/Installer/MainWindow.xaml
  24. +240
    -16
      installer/Installer/Model.cs
  25. +97
    -31
      installer/Installer/ViewModel.cs
  26. +1
    -1
      launcher/Launcher/AssemblyInfo.cs
  27. +20
    -0
      logic/ClientTest/ClientTest.csproj
  28. +36
    -0
      logic/ClientTest/Program.cs
  29. +68
    -0
      logic/GameClass/GameObj/Team.cs
  30. +4
    -4
      logic/GameEngine/CollisionChecker.cs
  31. +18
    -18
      logic/GameEngine/MoveEngine.cs
  32. +66
    -0
      logic/Gaming/MoveManager.cs
  33. +4
    -6
      logic/Preparation/Utility/EnumType.cs
  34. +13
    -0
      logic/Preparation/Utility/XY.cs
  35. +110
    -0
      logic/Server/Game.cs
  36. +121
    -0
      logic/Server/GameServer.cs
  37. +35
    -2
      logic/Server/Program.cs
  38. +15
    -0
      logic/Server/Server.csproj
  39. +7
    -0
      logic/cmd/test.cmd
  40. +18
    -0
      logic/logic.sln

+ 3
- 0
.github/FUNDING.yaml View File

@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: [TCL606]

+ 0
- 13
.github/workflows/clang-format.yml View File

@@ -1,13 +0,0 @@
name: clang-format
on: [push, pull_request]
jobs:
clang-format-checking:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: DoozyX/clang-format-lint-action@v0.14
with:
source: '.'
extensions: 'cs,c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx,i,ixx,ipp,i++'
clangFormatVersion: 14
inplace: False

+ 34
- 0
.github/workflows/format.yml View File

@@ -0,0 +1,34 @@
name: format
on: [push, pull_request]
jobs:
clang-format-checking:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: DoozyX/clang-format-lint-action@v0.14
with:
source: '.'
extensions: 'c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx,i,ixx,ipp,i++'
clangFormatVersion: 14
inplace: False
dotnet-format-checking:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.x
- name: Check Logic
run: dotnet format "./logic/logic.sln" --severity error --no-restore
- name: Check Installer
run: dotnet format "./installer/installer.sln" --severity error --no-restore
- name: Check Launcher
run: dotnet format "./launcher/launcher.sln" --severity error --no-restore
- name: Check Playback
run: dotnet format "./playback/playback.sln" --severity error --no-restore

+ 65
- 170
CAPI/API/include/API.h View File

@@ -45,25 +45,24 @@ public:
virtual bool HaveMessage() = 0;
virtual std::pair<int64_t, std::string> GetMessage() = 0;

virtual bool WaitThread() = 0;

virtual int GetCounter() const = 0;

// IHumanAPI使用的部分
virtual bool Escape() = 0;

// 说明:双向stream由三个函数共同实现,两个记录开始和结束,结果由Logic里的私有的成员变量记录,获得返回值则另调函数
virtual void StartFixMachine() = 0;
virtual void EndFixMachine() = 0;
virtual bool GetFixStatus() = 0;
virtual bool StartFixMachine() = 0;
virtual bool EndFixMachine() = 0;

virtual void StartSaveHuman() = 0;
virtual void EndSaveHuman() = 0;
virtual bool GetSaveStatus() = 0;
virtual bool StartSaveHuman() = 0;
virtual bool EndSaveHuman() = 0;

// IButcherAPI使用的部分
virtual bool Attack(double angle) = 0;
virtual bool CarryHuman() = 0;
virtual bool ReleaseHuman() = 0;
virtual bool HangHuman() = 0;

virtual bool WaitThread() = 0;

virtual int GetCounter() = 0;
};

class IAPI
@@ -129,12 +128,10 @@ class IHumanAPI : public IAPI
public:
/*****人类阵营的特定函数*****/

virtual void StartFixMachine() = 0;
virtual void EndFixMachine() = 0;
virtual std::future<bool> GetFixStatus() = 0;
virtual void StartSaveHuman() = 0;
virtual void EndSaveHuman() = 0;
virtual std::future<bool> GetSaveStatus() = 0;
virtual std::future<bool> StartFixMachine() = 0;
virtual std::future<bool> EndFixMachine() = 0;
virtual std::future<bool> StartSaveHuman() = 0;
virtual std::future<bool> EndSaveHuman() = 0;
virtual std::future<bool> Escape() = 0;
[[nodiscard]] virtual std::shared_ptr<const THUAI6::Human> GetSelfInfo() const = 0;
};
@@ -205,16 +202,12 @@ public:
[[nodiscard]] std::vector<std::vector<THUAI6::PlaceType>> GetFullMap() const override;
[[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const override;

[[nodiscard]] const std::vector<int64_t> GetPlayerGUIDs() const override
{
}
[[nodiscard]] const std::vector<int64_t> GetPlayerGUIDs() const override;

void StartFixMachine() override;
void EndFixMachine() override;
std::future<bool> GetFixStatus() override;
void StartSaveHuman() override;
void EndSaveHuman() override;
std::future<bool> GetSaveStatus() override;
std::future<bool> StartFixMachine() override;
std::future<bool> EndFixMachine() override;
std::future<bool> StartSaveHuman() override;
std::future<bool> EndSaveHuman() override;
std::future<bool> Escape() override;
[[nodiscard]] std::shared_ptr<const THUAI6::Human> GetSelfInfo() const override;

@@ -268,9 +261,7 @@ public:
[[nodiscard]] std::vector<std::vector<THUAI6::PlaceType>> GetFullMap() const override;
[[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const override;

[[nodiscard]] const std::vector<int64_t> GetPlayerGUIDs() const override
{
}
[[nodiscard]] const std::vector<int64_t> GetPlayerGUIDs() const override;

std::future<bool> Attack(double angleInRadian) override;
std::future<bool> CarryHuman() override;
@@ -297,97 +288,45 @@ public:
}
void Play(IAI& ai) override;

std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override
{
}
std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override;

[[nodiscard]] int GetFrameCount() const override
{
}

std::future<bool> MoveRight(int64_t timeInMilliseconds) override
{
}
std::future<bool> MoveUp(int64_t timeInMilliseconds) override
{
}
std::future<bool> MoveLeft(int64_t timeInMilliseconds) override
{
}
std::future<bool> MoveDown(int64_t timeInMilliseconds) override
{
}
std::future<bool> MoveRight(int64_t timeInMilliseconds) override;
std::future<bool> MoveUp(int64_t timeInMilliseconds) override;
std::future<bool> MoveLeft(int64_t timeInMilliseconds) override;
std::future<bool> MoveDown(int64_t timeInMilliseconds) override;

std::future<bool> PickProp(THUAI6::PropType prop) override
{
}
std::future<bool> UseProp() override
{
}
std::future<bool> UseSkill() override
{
}
std::future<bool> PickProp(THUAI6::PropType prop) override;
std::future<bool> UseProp() override;
std::future<bool> UseSkill() override;

std::future<bool> SendMessage(int64_t, std::string) override
{
}
[[nodiscard]] std::future<bool> HaveMessage() override
{
}
[[nodiscard]] std::future<std::pair<int64_t, std::string>> GetMessage() override
{
}
std::future<bool> SendMessage(int64_t, std::string) override;
[[nodiscard]] std::future<bool> HaveMessage() override;
[[nodiscard]] std::future<std::pair<int64_t, std::string>> GetMessage() override;

std::future<bool> Wait() override
{
}

[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Human>> GetHuman() const override
{
}
[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButcher() const override
{
}
[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Human>> GetHuman() const override;
[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButcher() const override;

[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const override
{
}
[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const override;

[[nodiscard]] std::vector<std::vector<THUAI6::PlaceType>> GetFullMap() const override
{
}
[[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const override
{
}
[[nodiscard]] std::vector<std::vector<THUAI6::PlaceType>> GetFullMap() const override;
[[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const override;

[[nodiscard]] const std::vector<int64_t> GetPlayerGUIDs() const override
{
}
[[nodiscard]] const std::vector<int64_t> GetPlayerGUIDs() const override;

void StartFixMachine() override
{
}
void EndFixMachine() override
{
}
std::future<bool> GetFixStatus() override
{
}
void StartSaveHuman() override
{
}
void EndSaveHuman() override
{
}
std::future<bool> GetSaveStatus() override
{
}
std::future<bool> Escape() override
{
}
[[nodiscard]] virtual std::shared_ptr<const THUAI6::Human> GetSelfInfo() const override
{
}
std::future<bool> StartFixMachine() override;
std::future<bool> EndFixMachine() override;
std::future<bool> StartSaveHuman() override;
std::future<bool> EndSaveHuman() override;
std::future<bool> Escape() override;
[[nodiscard]] virtual std::shared_ptr<const THUAI6::Human> GetSelfInfo() const override;

private:
ILogic& logic;
@@ -408,88 +347,44 @@ public:
}
void Play(IAI& ai) override;

std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override
{
}
std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian) override;

[[nodiscard]] int GetFrameCount() const override
{
}

std::future<bool> MoveRight(int64_t timeInMilliseconds) override
{
}
std::future<bool> MoveUp(int64_t timeInMilliseconds) override
{
}
std::future<bool> MoveLeft(int64_t timeInMilliseconds) override
{
}
std::future<bool> MoveDown(int64_t timeInMilliseconds) override
{
}
std::future<bool> MoveRight(int64_t timeInMilliseconds) override;
std::future<bool> MoveUp(int64_t timeInMilliseconds) override;
std::future<bool> MoveLeft(int64_t timeInMilliseconds) override;
std::future<bool> MoveDown(int64_t timeInMilliseconds) override;

std::future<bool> PickProp(THUAI6::PropType prop) override
{
}
std::future<bool> UseProp() override
{
}
std::future<bool> UseSkill() override
{
}
std::future<bool> PickProp(THUAI6::PropType prop) override;
std::future<bool> UseProp() override;
std::future<bool> UseSkill() override;

std::future<bool> SendMessage(int64_t, std::string) override
{
}
[[nodiscard]] std::future<bool> HaveMessage() override
{
}
[[nodiscard]] std::future<std::pair<int64_t, std::string>> GetMessage() override
{
}
std::future<bool> SendMessage(int64_t, std::string) override;
[[nodiscard]] std::future<bool> HaveMessage() override;
[[nodiscard]] std::future<std::pair<int64_t, std::string>> GetMessage() override;

std::future<bool> Wait() override
{
}

[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Human>> GetHuman() const override
{
}
[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButcher() const override
{
}
[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Human>> GetHuman() const override;
[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Butcher>> GetButcher() const override;

[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const override
{
}
[[nodiscard]] std::vector<std::shared_ptr<const THUAI6::Prop>> GetProps() const override;

[[nodiscard]] std::vector<std::vector<THUAI6::PlaceType>> GetFullMap() const override
{
}
[[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const override
{
}
[[nodiscard]] std::vector<std::vector<THUAI6::PlaceType>> GetFullMap() const override;
[[nodiscard]] THUAI6::PlaceType GetPlaceType(int32_t CellX, int32_t CellY) const override;

[[nodiscard]] const std::vector<int64_t> GetPlayerGUIDs() const override
{
}
[[nodiscard]] const std::vector<int64_t> GetPlayerGUIDs() const override;

std::future<bool> Attack(double angleInRadian) override
{
}
std::future<bool> CarryHuman() override
{
}
std::future<bool> ReleaseHuman() override
{
}
std::future<bool> HangHuman() override
{
}
[[nodiscard]] std::shared_ptr<const THUAI6::Butcher> GetSelfInfo() const override
{
}
std::future<bool> Attack(double angleInRadian) override;
std::future<bool> CarryHuman() override;
std::future<bool> ReleaseHuman() override;
std::future<bool> HangHuman() override;
[[nodiscard]] std::shared_ptr<const THUAI6::Butcher> GetSelfInfo() const override;

private:
ILogic& logic;


+ 12
- 12
CAPI/API/include/Communication.h View File

@@ -9,6 +9,8 @@
#include <grpcpp/grpcpp.h>
#include "structures.h"
#include <thread>
#include <mutex>
#include <queue>

class Logic;

@@ -23,17 +25,15 @@ public:
bool PickProp(THUAI6::PropType prop, int64_t playerID);
bool UseProp(int64_t playerID);
bool UseSkill(int64_t playerID);
std::pair<int64_t, std::string> GetMessage();
bool HaveMessage();
bool SendMessage(int64_t toID, std::string message, int64_t playerID);
bool HaveMessage(int64_t playerID);
std::pair<int64_t, std::string> GetMessage(int64_t playerID);
bool Escape(int64_t playerID);

void StartFixMachine(int64_t playerID);
void EndFixMachine();
bool GetFixStatus();
void StartSaveHuman(int64_t playerID);
void EndSaveHuman();
bool GetSaveStatus();
bool StartFixMachine(int64_t playerID);
bool EndFixMachine(int64_t playerID);
bool StartSaveHuman(int64_t playerID);
bool EndSaveHuman(int64_t playerID);

bool Attack(double angle, int64_t playerID);

@@ -46,14 +46,14 @@ public:
bool HaveMessage2Client();
void AddPlayer(int64_t playerID, THUAI6::PlayerType playerType, THUAI6::HumanType humanType, THUAI6::ButcherType butcherType);

void ReadMessage(int64_t playerID);

private:
void FixMachine(int64_t playerID);
void SaveHuman(int64_t playerID);
std::unique_ptr<protobuf::AvailableService::Stub> THUAI6Stub;
bool haveNewMessage = false;
protobuf::MessageToClient message2Client;
bool isFixing = false;
bool isSaving = false;
std::queue<std::pair<int64_t, std::string>> messageQueue;
std::mutex messageMutex;
};

#endif

+ 14
- 21
CAPI/API/include/logic.h View File

@@ -13,6 +13,7 @@
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <queue>

#include "Message2Server.pb.h"
#include "Message2Clients.pb.h"
@@ -57,26 +58,28 @@ private:
std::condition_variable cvBuffer;
std::condition_variable cvAI;

// 信息队列目前可能会不用?具体待定
// 信息队列
std::queue<std::pair<int64_t, std::string>> messageQueue;

// 存储状态,分别是现在的状态和缓冲区的状态。
State state[2];
State* currentState;
State* bufferState;

// 保存缓冲区数
int counterState = 0;
int counterBuffer = 0;

// 是否应该执行player()
std::atomic_bool AILoop = true;

// buffer是否更新完毕
bool bufferUpdated = true;

// 是否可以启用当前状态
bool currentStateAccessed = false;

// 是否应当启动AI
bool AIStart = false;

// 控制内容更新的变量
// asynchronous = true 时控制内容更新的变量
std::atomic_bool freshed = false;

// 提供给API使用的函数
@@ -103,33 +106,23 @@ private:

bool Escape() override;

// 说明:双向stream由三个函数共同实现,两个记录开始和结束,结果由Logic里的私有的成员变量记录,获得返回值则另调函数
void StartFixMachine() override;
void EndFixMachine() override;
bool GetFixStatus() override;
bool StartFixMachine() override;
bool EndFixMachine() override;

void StartSaveHuman() override;
void EndSaveHuman() override;
bool GetSaveStatus() override;
bool StartSaveHuman() override;
bool EndSaveHuman() override;

bool Attack(double angle) override;
bool CarryHuman() override;
bool ReleaseHuman() override;
bool HangHuman() override;

bool WaitThread() override
{
}
bool WaitThread() override;

int GetCounter() override
{
}
int GetCounter() const override;

bool TryConnection();

// 执行AI线程
void PlayerWrapper(std::function<void()> player);

// THUAI5中的一系列用于处理信息的函数可能也不会再用

void ProcessMessage();


+ 1
- 2
CAPI/API/include/structures.h View File

@@ -118,8 +118,7 @@ namespace THUAI6

struct Human : public Player
{
bool onChair; // 是否被挂
bool onGround; // 是否倒地
HumanState state; // 人类状态
int32_t life; // 剩余生命(本次倒地之前还能承受的伤害)
int32_t hangedTime; // 被挂的次数



+ 10
- 2
CAPI/API/include/utils.hpp View File

@@ -76,6 +76,15 @@ namespace Proto2THUAI6
{protobuf::ButcherBuffType::BBUFFTYPE4, THUAI6::ButcherBuffType::ButcherBuffType4},
};

inline std::map<protobuf::HumanState, THUAI6::HumanState> humanStateDict{
{protobuf::HumanState::NULL_STATUS, THUAI6::HumanState::NullHumanState},
{protobuf::HumanState::IDLE, THUAI6::HumanState::Idle},
{protobuf::HumanState::FIXING, THUAI6::HumanState::Fixing},
{protobuf::HumanState::DYING, THUAI6::HumanState::Dying},
{protobuf::HumanState::ON_CHAIR, THUAI6::HumanState::OnChair},
{protobuf::HumanState::DEAD, THUAI6::HumanState::Dead},
};

// 用于将Protobuf中的类转换为THUAI6的类
inline std::shared_ptr<THUAI6::Butcher> Protobuf2THUAI6Butcher(const protobuf::MessageOfButcher& butcherMsg)
{
@@ -115,8 +124,7 @@ namespace Proto2THUAI6
human->playerType = THUAI6::PlayerType::HumanPlayer;
human->prop = propTypeDict[humanMsg.prop()];
human->place = placeTypeDict[humanMsg.place()];
human->onChair = humanMsg.on_chair();
human->onGround = humanMsg.on_ground();
human->state = humanStateDict[humanMsg.state()];
human->life = humanMsg.life();
human->hangedTime = humanMsg.hanged_time();
human->humanType = humanTypeDict[humanMsg.human_type()];


+ 4
- 0
CAPI/API/src/AI.cpp View File

@@ -2,6 +2,9 @@
#include <thread>
#include "AI.h"

// 为假则play()期间确保游戏状态不更新,为真则只保证游戏状态在调用相关方法时不更新
extern const bool asynchronous = false;

// 选手必须定义该变量来选择自己的阵营
extern const THUAI6::PlayerType playerType = THUAI6::PlayerType::HumanPlayer;

@@ -14,6 +17,7 @@ extern const THUAI6::HumanType humanType = THUAI6::HumanType::HumanType1;

void AI::play(IHumanAPI& api)
{
// api.Move(1, 1);
}

void AI::play(IButcherAPI& api)


+ 16
- 22
CAPI/API/src/API.cpp View File

@@ -176,44 +176,38 @@ std::vector<std::vector<THUAI6::PlaceType>> ButcherAPI::GetFullMap() const
return logic.GetFullMap();
}

void HumanAPI::StartFixMachine()
const std::vector<int64_t> HumanAPI::GetPlayerGUIDs() const
{
std::thread([&]()
{ logic.StartFixMachine(); })
.detach();
// todo
}

void HumanAPI::EndFixMachine()
const std::vector<int64_t> ButcherAPI::GetPlayerGUIDs() const
{
std::thread([&]()
{ logic.EndFixMachine(); })
.detach();
// todo
}

std::future<bool> HumanAPI::GetFixStatus()
std::future<bool> HumanAPI::StartFixMachine()
{
return std::async(std::launch::async, [&]()
{ return logic.GetFixStatus(); });
std::async(std::launch::async, [&]()
{ return logic.StartFixMachine(); });
}

void HumanAPI::StartSaveHuman()
std::future<bool> HumanAPI::EndFixMachine()
{
std::thread([&]()
{ logic.StartSaveHuman(); })
.detach();
std::async(std::launch::async, [&]()
{ return logic.EndFixMachine(); });
}

void HumanAPI::EndSaveHuman()
std::future<bool> HumanAPI::StartSaveHuman()
{
std::thread([&]()
{ logic.EndSaveHuman(); })
.detach();
std::async(std::launch::async, [&]()
{ return logic.StartSaveHuman(); });
}

std::future<bool> HumanAPI::GetSaveStatus()
std::future<bool> HumanAPI::EndSaveHuman()
{
return std::async(std::launch::async, [&]()
{ return logic.GetSaveStatus(); });
std::async(std::launch::async, [&]()
{ return logic.EndSaveHuman(); });
}

std::future<bool> HumanAPI::Escape()


+ 67
- 79
CAPI/API/src/Communication.cpp View File

@@ -73,115 +73,64 @@ bool Communication::SendMessage(int64_t toID, std::string message, int64_t playe
return false;
}

bool Communication::HaveMessage(int64_t playerID)
bool Communication::Escape(int64_t playerID)
{
protobuf::BoolRes haveMessageResult;
protobuf::BoolRes escapeResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->HaveMessage(&context, request, &haveMessageResult);
auto status = THUAI6Stub->Escape(&context, request, &escapeResult);
if (status.ok())
return haveMessageResult.act_success();
return escapeResult.act_success();
else
return false;
}

std::pair<int64_t, std::string> Communication::GetMessage(int64_t playerID)
bool Communication::StartFixMachine(int64_t playerID)
{
protobuf::MsgRes getMessageResult;
protobuf::BoolRes startFixMachineResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->GetMessage(&context, request, &getMessageResult);
auto status = THUAI6Stub->StartFixMachine(&context, request, &startFixMachineResult);
if (status.ok())
{
if (getMessageResult.have_message())
return std::make_pair(getMessageResult.from_player_id(), getMessageResult.message_received());
else
return std::make_pair(-1, "");
}
return startFixMachineResult.act_success();
else
return std::make_pair(-1, "");
return false;
}

bool Communication::Escape(int64_t playerID)
bool Communication::EndFixMachine(int64_t playerID)
{
protobuf::BoolRes escapeResult;
protobuf::BoolRes endFixMachineResult;
ClientContext context;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->Escape(&context, request, &escapeResult);
auto status = THUAI6Stub->EndFixMachine(&context, request, &endFixMachineResult);
if (status.ok())
return escapeResult.act_success();
return endFixMachineResult.act_success();
else
return false;
}

void Communication::FixMachine(int64_t playerID)
bool Communication::StartSaveHuman(int64_t playerID)
{
protobuf::BoolRes fixMachineResult;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
protobuf::BoolRes saveHumanResult;
ClientContext context;
while (isFixing)
{
auto fixStream = THUAI6Stub->FixMachine(&context);
fixStream->Write(request);
fixStream->Read(&fixMachineResult);
if (!fixMachineResult.act_success())
{
isFixing = false;
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10)); // 防止巨量发信
}
}

void Communication::StartFixMachine(int64_t playerID)
{
isFixing = true;
FixMachine(playerID);
}

void Communication::EndFixMachine()
{
isFixing = false;
}

bool Communication::GetFixStatus()
{
return isFixing;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->StartSaveHuman(&context, request, &saveHumanResult);
if (status.ok())
return saveHumanResult.act_success();
else
return false;
}

void Communication::SaveHuman(int64_t playerID)
bool Communication::EndSaveHuman(int64_t playerID)
{
protobuf::BoolRes saveHumanResult;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
ClientContext context;
while (isSaving)
{
auto saveStream = THUAI6Stub->SaveHuman(&context);
saveStream->Write(request);
saveStream->Read(&saveHumanResult);
if (!saveHumanResult.act_success())
{
isSaving = false;
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10)); // 防止巨量发信
}
}

void Communication::StartSaveHuman(int64_t playerID)
{
isSaving = true;
SaveHuman(playerID);
}

void Communication::EndSaveHuman()
{
isSaving = false;
}

bool Communication::GetSaveStatus()
{
return isSaving;
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->EndSaveHuman(&context, request, &saveHumanResult);
if (status.ok())
return saveHumanResult.act_success();
else
return false;
}

bool Communication::Attack(double angle, int64_t playerID)
@@ -239,7 +188,10 @@ bool Communication::TryConnection(int64_t playerID)
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
auto status = THUAI6Stub->TryConnection(&context, request, &reply);
if (status.ok())
{
std::cout << "Connection success!" << std::endl;
return true;
}
else
return false;
}
@@ -255,6 +207,42 @@ bool Communication::HaveMessage2Client()
return haveNewMessage;
}

std::pair<int64_t, std::string> Communication::GetMessage()
{
std::lock_guard<std::mutex> lock(messageMutex);
if (messageQueue.empty())
return std::make_pair(-1, "");
else
{
auto message = messageQueue.front();
messageQueue.pop();
return message;
}
}

bool Communication::HaveMessage()
{
std::lock_guard<std::mutex> lock(messageMutex);
return !messageQueue.empty();
}

void Communication::ReadMessage(int64_t playerID)
{
auto tRead = [&]()
{
auto request = THUAI62Proto::THUAI62ProtobufID(playerID);
ClientContext context;
protobuf::MsgRes messageReceived;
auto reader = THUAI6Stub->GetMessage(&context, request);
while (reader->Read(&messageReceived))
{
std::lock_guard<std::mutex> lock(messageMutex);
messageQueue.push(std::make_pair(messageReceived.from_player_id(), messageReceived.message_received()));
}
};
std::thread(tRead).detach();
}

void Communication::AddPlayer(int64_t playerID, THUAI6::PlayerType playerType, THUAI6::HumanType humanType, THUAI6::ButcherType butcherType)
{
auto msgThread = [&]()


+ 249
- 0
CAPI/API/src/DebugAPI.cpp View File

@@ -1,5 +1,254 @@
#include "AI.h"
#include "API.h"
#define PI 3.14159265358979323846

std::future<bool> HumanDebugAPI::Move(int64_t timeInMilliseconds, double angleInRadian)
{
return std::async(std::launch::async, [&]()
{ return logic.Move(timeInMilliseconds, angleInRadian); });
}

std::future<bool> HumanDebugAPI::MoveDown(int64_t timeInMilliseconds)
{
return Move(timeInMilliseconds, 0);
}

std::future<bool> HumanDebugAPI::MoveRight(int64_t timeInMilliseconds)
{
return Move(timeInMilliseconds, PI * 0.5);
}

std::future<bool> HumanDebugAPI::MoveUp(int64_t timeInMilliseconds)
{
return Move(timeInMilliseconds, PI);
}

std::future<bool> HumanDebugAPI::MoveLeft(int64_t timeInMilliseconds)
{
return Move(timeInMilliseconds, PI * 1.5);
}

std::future<bool> ButcherDebugAPI::Move(int64_t timeInMilliseconds, double angleInRadian)
{
return std::async(std::launch::async, [&]()
{ return logic.Move(timeInMilliseconds, angleInRadian); });
}

std::future<bool> ButcherDebugAPI::MoveDown(int64_t timeInMilliseconds)
{
return Move(timeInMilliseconds, 0);
}

std::future<bool> ButcherDebugAPI::MoveRight(int64_t timeInMilliseconds)
{
return Move(timeInMilliseconds, PI * 0.5);
}

std::future<bool> ButcherDebugAPI::MoveUp(int64_t timeInMilliseconds)
{
return Move(timeInMilliseconds, PI);
}

std::future<bool> ButcherDebugAPI::MoveLeft(int64_t timeInMilliseconds)
{
return Move(timeInMilliseconds, PI * 1.5);
}

std::future<bool> HumanDebugAPI::PickProp(THUAI6::PropType prop)
{
return std::async(std::launch::async, [&]()
{ return logic.PickProp(prop); });
}

std::future<bool> HumanDebugAPI::UseProp()
{
return std::async(std::launch::async, [&]()
{ return logic.UseProp(); });
}

std::future<bool> ButcherDebugAPI::PickProp(THUAI6::PropType prop)
{
return std::async(std::launch::async, [&]()
{ return logic.PickProp(prop); });
}

std::future<bool> ButcherDebugAPI::UseProp()
{
return std::async(std::launch::async, [&]()
{ return logic.UseProp(); });
}

std::future<bool> HumanDebugAPI::UseSkill()
{
return std::async(std::launch::async, [&]()
{ return logic.UseSkill(); });
}

std::future<bool> ButcherDebugAPI::UseSkill()
{
return std::async(std::launch::async, [&]()
{ return logic.UseSkill(); });
}

std::future<bool> HumanDebugAPI::SendMessage(int64_t toID, std::string message)
{
return std::async(std::launch::async, [&]()
{ return logic.SendMessage(toID, message); });
}

std::future<bool> ButcherDebugAPI::SendMessage(int64_t toID, std::string message)
{
return std::async(std::launch::async, [&]()
{ return logic.SendMessage(toID, message); });
}

std::future<bool> HumanDebugAPI::HaveMessage()
{
return std::async(std::launch::async, [&]()
{ return logic.HaveMessage(); });
}

std::future<bool> ButcherDebugAPI::HaveMessage()
{
return std::async(std::launch::async, [&]()
{ return logic.HaveMessage(); });
}

std::future<std::pair<int64_t, std::string>> HumanDebugAPI::GetMessage()
{
return std::async(std::launch::async, [&]()
{ return logic.GetMessage(); });
}

std::future<std::pair<int64_t, std::string>> ButcherDebugAPI::GetMessage()
{
return std::async(std::launch::async, [&]()
{ return logic.GetMessage(); });
}

std::vector<std::shared_ptr<const THUAI6::Butcher>> HumanDebugAPI::GetButcher() const
{
return logic.GetButchers();
}

std::vector<std::shared_ptr<const THUAI6::Human>> HumanDebugAPI::GetHuman() const
{
return logic.GetHumans();
}

std::vector<std::shared_ptr<const THUAI6::Butcher>> ButcherDebugAPI::GetButcher() const
{
return logic.GetButchers();
}

std::vector<std::shared_ptr<const THUAI6::Human>> ButcherDebugAPI::GetHuman() const
{
return logic.GetHumans();
}

std::vector<std::shared_ptr<const THUAI6::Prop>> HumanDebugAPI::GetProps() const
{
return logic.GetProps();
}

std::vector<std::shared_ptr<const THUAI6::Prop>> ButcherDebugAPI::GetProps() const
{
return logic.GetProps();
}

std::vector<std::vector<THUAI6::PlaceType>> HumanDebugAPI::GetFullMap() const
{
return logic.GetFullMap();
}

THUAI6::PlaceType HumanDebugAPI::GetPlaceType(int32_t CellX, int32_t CellY) const
{
return logic.GetPlaceType(CellX, CellY);
}

THUAI6::PlaceType ButcherDebugAPI::GetPlaceType(int32_t CellX, int32_t CellY) const
{
return logic.GetPlaceType(CellX, CellY);
}

std::vector<std::vector<THUAI6::PlaceType>> ButcherDebugAPI::GetFullMap() const
{
return logic.GetFullMap();
}

const std::vector<int64_t> HumanDebugAPI::GetPlayerGUIDs() const
{
// todo
}

const std::vector<int64_t> ButcherDebugAPI::GetPlayerGUIDs() const
{
// todo
}

std::future<bool> HumanDebugAPI::StartFixMachine()
{
std::async(std::launch::async, [&]()
{ return logic.StartFixMachine(); });
}

std::future<bool> HumanDebugAPI::EndFixMachine()
{
std::async(std::launch::async, [&]()
{ return logic.EndFixMachine(); });
}

std::future<bool> HumanDebugAPI::StartSaveHuman()
{
std::async(std::launch::async, [&]()
{ return logic.StartSaveHuman(); });
}

std::future<bool> HumanDebugAPI::EndSaveHuman()
{
std::async(std::launch::async, [&]()
{ return logic.EndSaveHuman(); });
}

std::future<bool> HumanDebugAPI::Escape()
{
return std::async(std::launch::async, [&]()
{ return logic.Escape(); });
}

std::shared_ptr<const THUAI6::Human> HumanDebugAPI::GetSelfInfo() const
{
return logic.HumanGetSelfInfo();
}

std::future<bool> ButcherDebugAPI::Attack(double angleInRadian)
{
return std::async(std::launch::async, [&]()
{ return logic.Attack(angleInRadian); });
}

std::future<bool> ButcherDebugAPI::CarryHuman()
{
return std::async(std::launch::async, [&]()
{ return logic.CarryHuman(); });
}

std::future<bool> ButcherDebugAPI::ReleaseHuman()
{
return std::async(std::launch::async, [&]()
{ return logic.ReleaseHuman(); });
}

std::future<bool> ButcherDebugAPI::HangHuman()
{
return std::async(std::launch::async, [&]()
{ return logic.HangHuman(); });
}

std::shared_ptr<const THUAI6::Butcher> ButcherDebugAPI::GetSelfInfo() const
{
return logic.ButcherGetSelfInfo();
}

void HumanDebugAPI::Play(IAI& ai)
{


+ 94
- 53
CAPI/API/src/logic.cpp View File

@@ -5,9 +5,7 @@
#include "utils.hpp"
#include "Communication.h"

// using grpc::ClientContext;
// using grpc::Status;

extern const bool asynchronous;
extern const THUAI6::PlayerType playerType;

Logic::Logic(THUAI6::PlayerType type, int64_t ID, THUAI6::ButcherType butcher, THUAI6::HumanType human) :
@@ -22,7 +20,7 @@ Logic::Logic(THUAI6::PlayerType type, int64_t ID, THUAI6::ButcherType butcher, T

std::vector<std::shared_ptr<const THUAI6::Butcher>> Logic::GetButchers() const
{
std::lock_guard<std::mutex> lock(mtxState);
std::lock_guard<std::mutex> lock(mtxBuffer);
std::vector<std::shared_ptr<const THUAI6::Butcher>> temp;
temp.assign(currentState->butchers.begin(), currentState->butchers.end());
return temp;
@@ -30,7 +28,7 @@ std::vector<std::shared_ptr<const THUAI6::Butcher>> Logic::GetButchers() const

std::vector<std::shared_ptr<const THUAI6::Human>> Logic::GetHumans() const
{
std::lock_guard<std::mutex> lock(mtxState);
std::unique_lock<std::mutex> lock(mtxBuffer);
std::vector<std::shared_ptr<const THUAI6::Human>> temp;
temp.assign(currentState->humans.begin(), currentState->humans.end());
return temp;
@@ -38,7 +36,7 @@ std::vector<std::shared_ptr<const THUAI6::Human>> Logic::GetHumans() const

std::vector<std::shared_ptr<const THUAI6::Prop>> Logic::GetProps() const
{
std::lock_guard<std::mutex> lock(mtxState);
std::unique_lock<std::mutex> lock(mtxBuffer);
std::vector<std::shared_ptr<const THUAI6::Prop>> temp;
temp.assign(currentState->props.begin(), currentState->props.end());
return temp;
@@ -46,25 +44,25 @@ std::vector<std::shared_ptr<const THUAI6::Prop>> Logic::GetProps() const

std::shared_ptr<const THUAI6::Human> Logic::HumanGetSelfInfo() const
{
std::lock_guard<std::mutex> lock(mtxState);
std::unique_lock<std::mutex> lock(mtxBuffer);
return currentState->humanSelf;
}

std::shared_ptr<const THUAI6::Butcher> Logic::ButcherGetSelfInfo() const
{
std::lock_guard<std::mutex> lock(mtxState);
std::unique_lock<std::mutex> lock(mtxBuffer);
return currentState->butcherSelf;
}

std::vector<std::vector<THUAI6::PlaceType>> Logic::GetFullMap() const
{
std::lock_guard<std::mutex> lock(mtxState);
std::unique_lock<std::mutex> lock(mtxBuffer);
return currentState->gamemap;
}

THUAI6::PlaceType Logic::GetPlaceType(int32_t CellX, int32_t CellY) const
{
std::lock_guard<std::mutex> lock(mtxState);
std::unique_lock<std::mutex> lock(mtxBuffer);
return currentState->gamemap[CellX][CellY];
}

@@ -95,12 +93,12 @@ bool Logic::SendMessage(int64_t toID, std::string message)

bool Logic::HaveMessage()
{
return pComm->HaveMessage(playerID);
return pComm->HaveMessage();
}

std::pair<int64_t, std::string> Logic::GetMessage()
{
return pComm->GetMessage(playerID);
return pComm->GetMessage();
}

bool Logic::Escape()
@@ -108,34 +106,24 @@ bool Logic::Escape()
return pComm->Escape(playerID);
}

void Logic::StartFixMachine()
{
pComm->StartFixMachine(playerID);
}

void Logic::EndFixMachine()
{
pComm->EndFixMachine();
}

bool Logic::GetFixStatus()
bool Logic::StartFixMachine()
{
return pComm->GetFixStatus();
return pComm->StartFixMachine(playerID);
}

void Logic::StartSaveHuman()
bool Logic::EndFixMachine()
{
pComm->StartSaveHuman(playerID);
return pComm->EndFixMachine(playerID);
}

void Logic::EndSaveHuman()
bool Logic::StartSaveHuman()
{
pComm->EndSaveHuman();
return pComm->StartSaveHuman(playerID);
}

bool Logic::GetSaveStatus()
bool Logic::EndSaveHuman()
{
return pComm->GetSaveStatus();
return pComm->EndSaveHuman(playerID);
}

bool Logic::Attack(double angle)
@@ -158,22 +146,16 @@ bool Logic::HangHuman()
return pComm->HangHuman(playerID);
}

bool Logic::WaitThread()
{
Update();
return true;
}

void Logic::ProcessMessage()
{
auto messageThread = [&]()
{
// // 首先设置消息、通过加入游戏,开始与服务端建立联系
// protobuf::MessageToClient clientMsg;
// protobuf::PlayerMsg playerMsg = THUAI62Proto::THUAI62ProtobufPlayer(playerID, playerType, humanType, butcherType);
// grpc::ClientContext context;
// auto MessageReader = THUAI6Stub->AddPlayer(&context, playerMsg);

// // 持续读取服务端的消息
// while (MessageReader->Read(&clientMsg))
// {
// LoadBuffer(clientMsg);
// }

std::cout << "Join Player!" << std::endl;
pComm->AddPlayer(playerID, playerType, humanType, butcherType);
while (true)
@@ -229,27 +211,77 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message)
}

bufferState->gamemap = Proto2THUAI6::Protobuf2THUAI6Map(message.map_message());
cvBuffer.notify_one();
if (asynchronous)
{
{
std::lock_guard<std::mutex> lock(mtxState);
std::swap(currentState, bufferState);
}
freshed = true;
}
else
bufferUpdated = true;
counterBuffer++;
}
// 唤醒其他线程
cvBuffer.notify_one();
}

void Logic::Update() noexcept
{
if (!asynchronous)
{
std::unique_lock<std::mutex> lock(mtxBuffer);

// 缓冲区被更新之后才可以使用
cvBuffer.wait(lock, [&]()
{ return bufferUpdated; });

std::swap(currentState, bufferState);
bufferUpdated = false;
counterState = counterBuffer;
}
}

void Logic::PlayerWrapper(std::function<void()> player)
void Logic::Wait() noexcept
{
// {
// std::unique_lock<std::mutex> lock(mtxAI);
// cvAI.wait(lock, [this]()
// { return AIStart; });
// }
player();
freshed = false;
{
std::unique_lock<std::mutex> lock(mtxBuffer);
cvBuffer.wait(lock, [&]()
{ return freshed.load(); });
}
}

void Logic::UnBlockAI()
{
{
std::lock_guard<std::mutex> lock(mtxAI);
AIStart = true;
}
cvAI.notify_one();
}

void Logic::UnBlockBuffer()
{
{
std::lock_guard<std::mutex> lock(mtxBuffer);
bufferUpdated = true;
}
cvBuffer.notify_one();
}

int Logic::GetCounter() const
{
std::unique_lock<std::mutex> lock(mtxState);
return counterState;
}

bool Logic::TryConnection()
{
return pComm->TryConnection(playerID);
std::cout << "Trying to connect to server..." << std::endl;
bool result = pComm->TryConnection(playerID);
return result;
}

void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port)
@@ -267,8 +299,14 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port)
timer = std::make_unique<ButcherAPI>(*this);

// 构造AI线程
auto AIThread = [&, this]()
auto AIThread = [&]()
{
{
std::unique_lock<std::mutex> lock(mtxAI);
cvAI.wait(lock, [this]()
{ return AIStart; });
}
std::cout << "AI Start!" << std::endl;
auto ai = createAI();
ProcessMessage();
while (AILoop)
@@ -280,7 +318,7 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port)
}
};

tAI = std::thread(&Logic::PlayerWrapper, this, AIThread);
tAI = std::thread(AIThread);

// 连接服务器
if (TryConnection())
@@ -289,11 +327,14 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port)
if (tAI.joinable())
{
std::cout << "Join the AI thread." << std::endl;
AIStart = true;
cvAI.notify_one();
tAI.join();
}
}
else
{
std::cout << "Connection error!" << std::endl;
return;
}
}

+ 4
- 2
CAPI/API/src/main.cpp View File

@@ -6,12 +6,14 @@
#pragma warning(disable : 4996)
#endif

extern const bool asynchronous;

int THUAI6Main(CreateAIFunc AIBuilder)
{
// 仅供调试使用
int playerID = 123;
std::string sIP = "localhost";
std::string sPort = "12345";
std::string sIP = "183.172.208.84";
std::string sPort = "8888";
extern const THUAI6::PlayerType playerType;
extern const THUAI6::ButcherType butcherType;
extern const THUAI6::HumanType humanType;


+ 45
- 105
CAPI/proto/Services.grpc.pb.cc View File

@@ -30,11 +30,10 @@ namespace protobuf
"/protobuf.AvailableService/UseProp",
"/protobuf.AvailableService/UseSkill",
"/protobuf.AvailableService/SendMessage",
"/protobuf.AvailableService/HaveMessage",
"/protobuf.AvailableService/GetMessage",
"/protobuf.AvailableService/StartFixMachine",
"/protobuf.AvailableService/EndFixMachine",
"/protobuf.AvailableService/SaveHuman",
"/protobuf.AvailableService/StartSaveHuman",
"/protobuf.AvailableService/EndSaveHuman",
"/protobuf.AvailableService/Attack",
"/protobuf.AvailableService/CarryHuman",
@@ -59,17 +58,16 @@ namespace protobuf
rpcmethod_UseProp_(AvailableService_method_names[4], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_UseSkill_(AvailableService_method_names[5], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_SendMessage_(AvailableService_method_names[6], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_HaveMessage_(AvailableService_method_names[7], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_GetMessage_(AvailableService_method_names[8], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_StartFixMachine_(AvailableService_method_names[9], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_EndFixMachine_(AvailableService_method_names[10], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_SaveHuman_(AvailableService_method_names[11], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_EndSaveHuman_(AvailableService_method_names[12], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_Attack_(AvailableService_method_names[13], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_CarryHuman_(AvailableService_method_names[14], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_ReleaseHuman_(AvailableService_method_names[15], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_HangHuman_(AvailableService_method_names[16], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_Escape_(AvailableService_method_names[17], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
rpcmethod_GetMessage_(AvailableService_method_names[7], options.suffix_for_stats(), ::grpc::internal::RpcMethod::SERVER_STREAMING, channel),
rpcmethod_StartFixMachine_(AvailableService_method_names[8], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_EndFixMachine_(AvailableService_method_names[9], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_StartSaveHuman_(AvailableService_method_names[10], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_EndSaveHuman_(AvailableService_method_names[11], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_Attack_(AvailableService_method_names[12], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_CarryHuman_(AvailableService_method_names[13], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_ReleaseHuman_(AvailableService_method_names[14], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_HangHuman_(AvailableService_method_names[15], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel),
rpcmethod_Escape_(AvailableService_method_names[16], options.suffix_for_stats(), ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
{
}

@@ -261,60 +259,24 @@ namespace protobuf
return result;
}

::grpc::Status AvailableService::Stub::HaveMessage(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::protobuf::BoolRes* response)
::grpc::ClientReader<::protobuf::MsgRes>* AvailableService::Stub::GetMessageRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request)
{
return ::grpc::internal::BlockingUnaryCall<::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_HaveMessage_, context, request, response);
return ::grpc::internal::ClientReaderFactory<::protobuf::MsgRes>::Create(channel_.get(), rpcmethod_GetMessage_, context, request);
}

void AvailableService::Stub::async::HaveMessage(::grpc::ClientContext* context, const ::protobuf::IDMsg* request, ::protobuf::BoolRes* response, std::function<void(::grpc::Status)> f)
void AvailableService::Stub::async::GetMessage(::grpc::ClientContext* context, const ::protobuf::IDMsg* request, ::grpc::ClientReadReactor<::protobuf::MsgRes>* reactor)
{
::grpc::internal::CallbackUnaryCall<::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_HaveMessage_, context, request, response, std::move(f));
::grpc::internal::ClientCallbackReaderFactory<::protobuf::MsgRes>::Create(stub_->channel_.get(), stub_->rpcmethod_GetMessage_, context, request, reactor);
}

void AvailableService::Stub::async::HaveMessage(::grpc::ClientContext* context, const ::protobuf::IDMsg* request, ::protobuf::BoolRes* response, ::grpc::ClientUnaryReactor* reactor)
::grpc::ClientAsyncReader<::protobuf::MsgRes>* AvailableService::Stub::AsyncGetMessageRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq, void* tag)
{
::grpc::internal::ClientCallbackUnaryFactory::Create<::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_HaveMessage_, context, request, response, reactor);
return ::grpc::internal::ClientAsyncReaderFactory<::protobuf::MsgRes>::Create(channel_.get(), cq, rpcmethod_GetMessage_, context, request, true, tag);
}

::grpc::ClientAsyncResponseReader<::protobuf::BoolRes>* AvailableService::Stub::PrepareAsyncHaveMessageRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq)
::grpc::ClientAsyncReader<::protobuf::MsgRes>* AvailableService::Stub::PrepareAsyncGetMessageRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq)
{
return ::grpc::internal::ClientAsyncResponseReaderHelper::Create<::protobuf::BoolRes, ::protobuf::IDMsg, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_HaveMessage_, context, request);
}

::grpc::ClientAsyncResponseReader<::protobuf::BoolRes>* AvailableService::Stub::AsyncHaveMessageRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq)
{
auto* result =
this->PrepareAsyncHaveMessageRaw(context, request, cq);
result->StartCall();
return result;
}

::grpc::Status AvailableService::Stub::GetMessage(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::protobuf::MsgRes* response)
{
return ::grpc::internal::BlockingUnaryCall<::protobuf::IDMsg, ::protobuf::MsgRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_GetMessage_, context, request, response);
}

void AvailableService::Stub::async::GetMessage(::grpc::ClientContext* context, const ::protobuf::IDMsg* request, ::protobuf::MsgRes* response, std::function<void(::grpc::Status)> f)
{
::grpc::internal::CallbackUnaryCall<::protobuf::IDMsg, ::protobuf::MsgRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_GetMessage_, context, request, response, std::move(f));
}

void AvailableService::Stub::async::GetMessage(::grpc::ClientContext* context, const ::protobuf::IDMsg* request, ::protobuf::MsgRes* response, ::grpc::ClientUnaryReactor* reactor)
{
::grpc::internal::ClientCallbackUnaryFactory::Create<::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_GetMessage_, context, request, response, reactor);
}

::grpc::ClientAsyncResponseReader<::protobuf::MsgRes>* AvailableService::Stub::PrepareAsyncGetMessageRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq)
{
return ::grpc::internal::ClientAsyncResponseReaderHelper::Create<::protobuf::MsgRes, ::protobuf::IDMsg, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_GetMessage_, context, request);
}

::grpc::ClientAsyncResponseReader<::protobuf::MsgRes>* AvailableService::Stub::AsyncGetMessageRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq)
{
auto* result =
this->PrepareAsyncGetMessageRaw(context, request, cq);
result->StartCall();
return result;
return ::grpc::internal::ClientAsyncReaderFactory<::protobuf::MsgRes>::Create(channel_.get(), cq, rpcmethod_GetMessage_, context, request, false, nullptr);
}

::grpc::Status AvailableService::Stub::StartFixMachine(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::protobuf::BoolRes* response)
@@ -373,30 +335,30 @@ namespace protobuf
return result;
}

::grpc::Status AvailableService::Stub::SaveHuman(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::protobuf::BoolRes* response)
::grpc::Status AvailableService::Stub::StartSaveHuman(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::protobuf::BoolRes* response)
{
return ::grpc::internal::BlockingUnaryCall<::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_SaveHuman_, context, request, response);
return ::grpc::internal::BlockingUnaryCall<::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_StartSaveHuman_, context, request, response);
}

void AvailableService::Stub::async::SaveHuman(::grpc::ClientContext* context, const ::protobuf::IDMsg* request, ::protobuf::BoolRes* response, std::function<void(::grpc::Status)> f)
void AvailableService::Stub::async::StartSaveHuman(::grpc::ClientContext* context, const ::protobuf::IDMsg* request, ::protobuf::BoolRes* response, std::function<void(::grpc::Status)> f)
{
::grpc::internal::CallbackUnaryCall<::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_SaveHuman_, context, request, response, std::move(f));
::grpc::internal::CallbackUnaryCall<::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_StartSaveHuman_, context, request, response, std::move(f));
}

void AvailableService::Stub::async::SaveHuman(::grpc::ClientContext* context, const ::protobuf::IDMsg* request, ::protobuf::BoolRes* response, ::grpc::ClientUnaryReactor* reactor)
void AvailableService::Stub::async::StartSaveHuman(::grpc::ClientContext* context, const ::protobuf::IDMsg* request, ::protobuf::BoolRes* response, ::grpc::ClientUnaryReactor* reactor)
{
::grpc::internal::ClientCallbackUnaryFactory::Create<::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_SaveHuman_, context, request, response, reactor);
::grpc::internal::ClientCallbackUnaryFactory::Create<::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_StartSaveHuman_, context, request, response, reactor);
}

::grpc::ClientAsyncResponseReader<::protobuf::BoolRes>* AvailableService::Stub::PrepareAsyncSaveHumanRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq)
::grpc::ClientAsyncResponseReader<::protobuf::BoolRes>* AvailableService::Stub::PrepareAsyncStartSaveHumanRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq)
{
return ::grpc::internal::ClientAsyncResponseReaderHelper::Create<::protobuf::BoolRes, ::protobuf::IDMsg, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_SaveHuman_, context, request);
return ::grpc::internal::ClientAsyncResponseReaderHelper::Create<::protobuf::BoolRes, ::protobuf::IDMsg, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_StartSaveHuman_, context, request);
}

::grpc::ClientAsyncResponseReader<::protobuf::BoolRes>* AvailableService::Stub::AsyncSaveHumanRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq)
::grpc::ClientAsyncResponseReader<::protobuf::BoolRes>* AvailableService::Stub::AsyncStartSaveHumanRaw(::grpc::ClientContext* context, const ::protobuf::IDMsg& request, ::grpc::CompletionQueue* cq)
{
auto* result =
this->PrepareAsyncSaveHumanRaw(context, request, cq);
this->PrepareAsyncStartSaveHumanRaw(context, request, cq);
result->StartCall();
return result;
}
@@ -671,14 +633,14 @@ namespace protobuf
));
AddMethod(new ::grpc::internal::RpcServiceMethod(
AvailableService_method_names[7],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
::grpc::internal::RpcMethod::SERVER_STREAMING,
new ::grpc::internal::ServerStreamingHandler<AvailableService::Service, ::protobuf::IDMsg, ::protobuf::MsgRes>(
[](AvailableService::Service* service,
::grpc::ServerContext* ctx,
const ::protobuf::IDMsg* req,
::protobuf::BoolRes* resp)
::grpc::ServerWriter<::protobuf::MsgRes>* writer)
{
return service->HaveMessage(ctx, req, resp);
return service->GetMessage(ctx, req, writer);
},
this
)
@@ -686,20 +648,6 @@ namespace protobuf
AddMethod(new ::grpc::internal::RpcServiceMethod(
AvailableService_method_names[8],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::IDMsg, ::protobuf::MsgRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
[](AvailableService::Service* service,
::grpc::ServerContext* ctx,
const ::protobuf::IDMsg* req,
::protobuf::MsgRes* resp)
{
return service->GetMessage(ctx, req, resp);
},
this
)
));
AddMethod(new ::grpc::internal::RpcServiceMethod(
AvailableService_method_names[9],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
[](AvailableService::Service* service,
::grpc::ServerContext* ctx,
@@ -712,7 +660,7 @@ namespace protobuf
)
));
AddMethod(new ::grpc::internal::RpcServiceMethod(
AvailableService_method_names[10],
AvailableService_method_names[9],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
[](AvailableService::Service* service,
@@ -726,7 +674,7 @@ namespace protobuf
)
));
AddMethod(new ::grpc::internal::RpcServiceMethod(
AvailableService_method_names[11],
AvailableService_method_names[10],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
[](AvailableService::Service* service,
@@ -734,13 +682,13 @@ namespace protobuf
const ::protobuf::IDMsg* req,
::protobuf::BoolRes* resp)
{
return service->SaveHuman(ctx, req, resp);
return service->StartSaveHuman(ctx, req, resp);
},
this
)
));
AddMethod(new ::grpc::internal::RpcServiceMethod(
AvailableService_method_names[12],
AvailableService_method_names[11],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
[](AvailableService::Service* service,
@@ -754,7 +702,7 @@ namespace protobuf
)
));
AddMethod(new ::grpc::internal::RpcServiceMethod(
AvailableService_method_names[13],
AvailableService_method_names[12],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::AttackMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
[](AvailableService::Service* service,
@@ -768,7 +716,7 @@ namespace protobuf
)
));
AddMethod(new ::grpc::internal::RpcServiceMethod(
AvailableService_method_names[14],
AvailableService_method_names[13],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
[](AvailableService::Service* service,
@@ -782,7 +730,7 @@ namespace protobuf
)
));
AddMethod(new ::grpc::internal::RpcServiceMethod(
AvailableService_method_names[15],
AvailableService_method_names[14],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
[](AvailableService::Service* service,
@@ -796,7 +744,7 @@ namespace protobuf
)
));
AddMethod(new ::grpc::internal::RpcServiceMethod(
AvailableService_method_names[16],
AvailableService_method_names[15],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
[](AvailableService::Service* service,
@@ -810,7 +758,7 @@ namespace protobuf
)
));
AddMethod(new ::grpc::internal::RpcServiceMethod(
AvailableService_method_names[17],
AvailableService_method_names[16],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler<AvailableService::Service, ::protobuf::IDMsg, ::protobuf::BoolRes, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
[](AvailableService::Service* service,
@@ -885,19 +833,11 @@ namespace protobuf
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}

::grpc::Status AvailableService::Service::HaveMessage(::grpc::ServerContext* context, const ::protobuf::IDMsg* request, ::protobuf::BoolRes* response)
::grpc::Status AvailableService::Service::GetMessage(::grpc::ServerContext* context, const ::protobuf::IDMsg* request, ::grpc::ServerWriter<::protobuf::MsgRes>* writer)
{
(void)context;
(void)request;
(void)response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}

::grpc::Status AvailableService::Service::GetMessage(::grpc::ServerContext* context, const ::protobuf::IDMsg* request, ::protobuf::MsgRes* response)
{
(void)context;
(void)request;
(void)response;
(void)writer;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}

@@ -917,7 +857,7 @@ namespace protobuf
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}

::grpc::Status AvailableService::Service::SaveHuman(::grpc::ServerContext* context, const ::protobuf::IDMsg* request, ::protobuf::BoolRes* response)
::grpc::Status AvailableService::Service::StartSaveHuman(::grpc::ServerContext* context, const ::protobuf::IDMsg* request, ::protobuf::BoolRes* response)
{
(void)context;
(void)request;


+ 210
- 417
CAPI/proto/Services.grpc.pb.h
File diff suppressed because it is too large
View File


+ 16
- 17
CAPI/proto/Services.pb.cc View File

@@ -31,7 +31,7 @@ static constexpr ::_pb::Message* const* file_default_instances = nullptr;

const char descriptor_table_protodef_Services_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
"\n\016Services.proto\022\010protobuf\032\025Message2Clie"
"nts.proto\032\024Message2Server.proto2\246\007\n\020Avai"
"nts.proto\032\024Message2Server.proto2\372\006\n\020Avai"
"lableService\0223\n\rTryConnection\022\017.protobuf"
".IDMsg\032\021.protobuf.BoolRes\022=\n\tAddPlayer\022\023"
".protobuf.PlayerMsg\032\031.protobuf.MessageTo"
@@ -41,21 +41,20 @@ const char descriptor_table_protodef_Services_2eproto[] PROTOBUF_SECTION_VARIABL
"otobuf.IDMsg\032\021.protobuf.BoolRes\022.\n\010UseSk"
"ill\022\017.protobuf.IDMsg\032\021.protobuf.BoolRes\022"
"3\n\013SendMessage\022\021.protobuf.SendMsg\032\021.prot"
"obuf.BoolRes\0221\n\013HaveMessage\022\017.protobuf.I"
"DMsg\032\021.protobuf.BoolRes\022/\n\nGetMessage\022\017."
"protobuf.IDMsg\032\020.protobuf.MsgRes\0225\n\017Star"
"tFixMachine\022\017.protobuf.IDMsg\032\021.protobuf."
"BoolRes\0223\n\rEndFixMachine\022\017.protobuf.IDMs"
"g\032\021.protobuf.BoolRes\022/\n\tSaveHuman\022\017.prot"
"obuf.IDMsg\032\021.protobuf.BoolRes\0222\n\014EndSave"
"Human\022\017.protobuf.IDMsg\032\021.protobuf.BoolRe"
"s\0220\n\006Attack\022\023.protobuf.AttackMsg\032\021.proto"
"buf.BoolRes\0220\n\nCarryHuman\022\017.protobuf.IDM"
"sg\032\021.protobuf.BoolRes\0222\n\014ReleaseHuman\022\017."
"protobuf.IDMsg\032\021.protobuf.BoolRes\022/\n\tHan"
"gHuman\022\017.protobuf.IDMsg\032\021.protobuf.BoolR"
"es\022,\n\006Escape\022\017.protobuf.IDMsg\032\021.protobuf"
".BoolResb\006proto3";
"obuf.BoolRes\0221\n\nGetMessage\022\017.protobuf.ID"
"Msg\032\020.protobuf.MsgRes0\001\0225\n\017StartFixMachi"
"ne\022\017.protobuf.IDMsg\032\021.protobuf.BoolRes\0223"
"\n\rEndFixMachine\022\017.protobuf.IDMsg\032\021.proto"
"buf.BoolRes\0224\n\016StartSaveHuman\022\017.protobuf"
".IDMsg\032\021.protobuf.BoolRes\0222\n\014EndSaveHuma"
"n\022\017.protobuf.IDMsg\032\021.protobuf.BoolRes\0220\n"
"\006Attack\022\023.protobuf.AttackMsg\032\021.protobuf."
"BoolRes\0220\n\nCarryHuman\022\017.protobuf.IDMsg\032\021"
".protobuf.BoolRes\0222\n\014ReleaseHuman\022\017.prot"
"obuf.IDMsg\032\021.protobuf.BoolRes\022/\n\tHangHum"
"an\022\017.protobuf.IDMsg\032\021.protobuf.BoolRes\022,"
"\n\006Escape\022\017.protobuf.IDMsg\032\021.protobuf.Boo"
"lResb\006proto3";
static const ::_pbi::DescriptorTable* const descriptor_table_Services_2eproto_deps[2] = {
&::descriptor_table_Message2Clients_2eproto,
&::descriptor_table_Message2Server_2eproto,
@@ -64,7 +63,7 @@ static ::_pbi::once_flag descriptor_table_Services_2eproto_once;
const ::_pbi::DescriptorTable descriptor_table_Services_2eproto = {
false,
false,
1016,
972,
descriptor_table_protodef_Services_2eproto,
"Services.proto",
&descriptor_table_Services_2eproto_once,


+ 34
- 0
dependency/proto/Protos.csproj View File

@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<!--<ItemGroup>
<None Remove="Message2Clients.proto" />
<None Remove="Message2Server.proto" />
<None Remove="MessageType.proto" />
<None Remove="Services.proto" />
</ItemGroup>-->

<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.21.9" />
<PackageReference Include="Google.Protobuf.Tools" Version="3.21.9" />
<PackageReference Include="Grpc" Version="2.46.5" />
<PackageReference Include="Grpc.Core" Version="2.46.5" />
<PackageReference Include="Grpc.Tools" Version="2.50.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<Protobuf Include="Message2Clients.proto" />
<Protobuf Include="Message2Server.proto" />
<Protobuf Include="MessageType.proto" />
<Protobuf Include="Services.proto" />
</ItemGroup>

</Project>

+ 2
- 3
dependency/proto/Services.proto View File

@@ -17,11 +17,10 @@ service AvailableService
rpc UseProp(IDMsg) returns (BoolRes);
rpc UseSkill(IDMsg) returns (BoolRes);
rpc SendMessage(SendMsg) returns (BoolRes);
rpc HaveMessage(IDMsg) returns (BoolRes);
rpc GetMessage(IDMsg) returns (MsgRes);
rpc GetMessage(IDMsg) returns (stream MsgRes);
rpc StartFixMachine(IDMsg) returns (BoolRes); // 开始修理机器
rpc EndFixMachine(IDMsg) returns (BoolRes); // 主动停止修复
rpc SaveHuman(IDMsg) returns (BoolRes); // 开始救人
rpc StartSaveHuman(IDMsg) returns (BoolRes); // 开始救人
rpc EndSaveHuman(IDMsg) returns (BoolRes); // 主动停止救人
rpc Attack (AttackMsg) returns (BoolRes);
rpc CarryHuman (IDMsg) returns (BoolRes);


+ 13
- 3
dependency/shell/format.sh View File

@@ -1,7 +1,10 @@
for i in {1..10}
SHELL_FOLDER=$(dirname $(readlink -f "$0"))
cd $SHELL_FOLDER
cd ../..

for i in {1..3}
do
find . -iname "*.cs" \
-or -iname "*.c" \
find . -iname "*.c" \
-or -iname "*.h" \
-or -iname "*.C" \
-or -iname "*.H" \
@@ -19,3 +22,10 @@ find . -iname "*.cs" \
-or -iname "*.i++" \
| xargs clang-format -i
done

cd logic && dotnet format && cd ..
cd installer && dotnet format && cd ..
cd launcher && dotnet format && cd ..
cd playback && dotnet format && cd ..

echo "Done!"

+ 1
- 1
installer/Installer/AssemblyInfo.cs View File

@@ -1,6 +1,6 @@
using System.Windows;

[assembly:ThemeInfo(
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, // where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)


+ 2
- 1
installer/Installer/Installer.csproj View File

@@ -9,7 +9,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Tencent.QCloud.Cos.Sdk" Version="5.4.32" />
</ItemGroup>



+ 24
- 6
installer/Installer/MainWindow.xaml View File

@@ -9,21 +9,39 @@
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="400" />
<ColumnDefinition Width="75" />
<ColumnDefinition Width="75" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="250" />
<ColumnDefinition Width="75" />
<ColumnDefinition Width="75" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="20" />
<RowDefinition Height="20" />
<RowDefinition Height="20" />
<RowDefinition Height="20" />
<RowDefinition Height="20" />
<RowDefinition Height="20" />
<RowDefinition Height="20" />
<RowDefinition Height="*" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="1" Grid.Column="1" Text="将主体程序安装在:" />
<TextBox Grid.Row="2" Grid.Column="1" Name="RouteTxtBox" Text="{Binding Route}" IsEnabled="{Binding CanEditRoute}" />
<Button Grid.Row="2" Grid.Column="2" Name="GetRouteBtn" Content="Browse..." Command="{Binding ClickBrowseCommand}" IsEnabled="{Binding CanEditRoute}" />
<Button Grid.Row="2" Grid.Column="3" Name="SetBtm" Content="Confirm" Command="{Binding ClickConfirmCommand}" />
<TextBlock Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" Text="欢迎使用选手包" Visibility="{Binding InstIntroVis}"/>
<TextBlock Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" Text="你已经安装了选手包,请选择你要进行的操作" Visibility="{Binding EditIntroVis}"/>

<TextBlock Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" Text="将主体程序安装在:" Visibility="{Binding InstIntroVis}"/>
<TextBlock Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" Text="将主体程序移动到:" Visibility="{Binding MoveIntroVis}"/>

<TextBox Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="3" Name="RouteTxtBox" Text="{Binding Route}" Visibility="{Binding RouteBoxVis}"/>
<Button Grid.Row="3" Grid.Column="4" Name="GetRouteBtn" Content="Browse..." Command="{Binding ClickBrowseCommand}" Visibility="{Binding RouteBoxVis}" />
<Button Grid.Row="3" Grid.Column="5" Name="SetBtm" Content="Confirm" Command="{Binding ClickConfirmCommand}" Visibility="{Binding RouteBoxVis}"/>
<Button Grid.Row="3" Grid.Column="2" Name="UpdateBtn" Content="Update" Command="{Binding ClickUpdateCommand}" Visibility="{Binding EditIntroVis}" />

<Button Grid.Row="5" Grid.Column="2" Name="MoveBtn" Content="Move" Command="{Binding ClickMoveCommand}" Visibility="{Binding EditIntroVis}" />

<Button Grid.Row="7" Grid.Column="2" Name="UninstBtn" Content="UnInst" Command="{Binding ClickUninstCommand}" Visibility="{Binding EditIntroVis}" />
</Grid>
</Window>

+ 240
- 16
installer/Installer/Model.cs View File

@@ -9,6 +9,16 @@ using System.IO;
using System.Security.Cryptography;
using System.Text;
using System;
using COSXML.Model.Bucket;
using System.Runtime.InteropServices;
using System.Text.Json.Nodes;
using System.Net.Http.Json;
using System.Text.Json;
using System.Xml.Schema;
using static Downloader.Program;
using System.Threading.Tasks;
using System.Net.Http;
using System.Windows;

namespace starter.viewmodel.settings
{
@@ -17,28 +27,71 @@ namespace starter.viewmodel.settings
/// </summary>
public class SettingsModel
{
/// <summary>
/// downloader function
/// </summary>
private Downloader.Program.Data configData = new Downloader.Program.Data("");
private Downloader.Program.Tencent_cos_download cloud = new Downloader.Program.Tencent_cos_download();

/// <summary>
/// save settings
/// </summary>
public void install()
public bool install()
{
if (Downloader.Program.Tencent_cos_download.CheckAlreadyDownload())
{
MessageBoxResult repeatOption = MessageBox.Show($"文件已存在于{Downloader.Program.Data.FilePath},是否移动到新位置?", "重复安装", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
//ask if abort install, with warning sign, defalut no;
if (repeatOption == MessageBoxResult.Cancel)
{
return false; //回到选择地址界面
}
else if (repeatOption == MessageBoxResult.No)
{
System.Environment.Exit(0);
return false;
}
else
{
Downloader.Program.Tencent_cos_download.MoveProgram(Route);
return true;
}
}
else
{
Downloader.Program.Data.ResetFilepath(Route);
Downloader.Program.Tencent_cos_download.DownloadAll();
return true;
}
}
/// <summary>
/// Route of files
/// </summary>
public string Route {
get; set; }
public string Route
{
get
{
return Downloader.Program.Data.FilePath;
}
set
{
Downloader.Program.Data.FilePath = value;
}
}
/// <summary>
/// if the route was set or is under editing
/// </summary>
public bool HaveRoute {
get; set; }
public bool EditingRoute {
get; set; }
/// <summary>
/// downloader function
public bool EditingRoute
{
get; set;
}
///<summary>
///if already installed
/// </summary>
private Downloader.Program downloader = new Downloader.Program();
public bool installed
{
get; set;
}
}
}
namespace Downloader
@@ -144,7 +197,8 @@ namespace Downloader
GetObjectRequest request = new GetObjectRequest(bucket, key, localDir, localFileName);

Dictionary<string, string> test = request.GetRequestHeaders();
request.SetCosProgressCallback(delegate(long completed, long total) {
request.SetCosProgressCallback(delegate (long completed, long total)
{
Console.WriteLine(String.Format("progress = {0:##.##}%", completed * 100.0 / total));
});
// 执行请求
@@ -556,9 +610,8 @@ namespace Downloader
File.WriteAllText(@System.IO.Path.Combine(Data.FilePath, "hash.json"), Contentjson);
}

public static void MoveProgram()
public static void MoveProgram(string newPath)
{
string newPath = Console.ReadLine();
DirectoryInfo newdi = new DirectoryInfo(newPath);
DirectoryInfo olddi = new DirectoryInfo(Data.FilePath);
try
@@ -601,8 +654,10 @@ namespace Downloader
Data.ResetFilepath(newPath);
Console.WriteLine("更改路径成功!");
}
public static void main(string[] args)
public static async Task main(string[] args)
{
var client = new HttpClient();
var web = new WebConnect.Web();
Data date = new Data("");
while (true)
{
@@ -670,7 +725,22 @@ namespace Downloader
}
else if (choose == "6")
{
MoveProgram();
string newPath;
newPath = Console.ReadLine();
MoveProgram(newPath);
}
else if (choose == "7")
{
Console.WriteLine("请输入email:");
string username = Console.ReadLine();
Console.WriteLine("请输入密码:");
string password = Console.ReadLine();

await web.LoginToEEsast(client, username, password);
}
else if (choose == "8")
{
await web.UserDetails(client);
}
else if (choose == "exit")
{
@@ -680,4 +750,158 @@ namespace Downloader
}
}
}
}
}

namespace WebConnect
{
class Web
{
public static string logintoken = "";
async public Task LoginToEEsast(HttpClient client, string useremail, string password)
{
string token = "";
using (var response = await client.PostAsync("https://api.eesast.com/users/login", JsonContent.Create(new
{
email = useremail,
password = password,
})))
{
switch (response.StatusCode)
{
case System.Net.HttpStatusCode.OK:
Console.WriteLine("Success login");
token = (System.Text.Json.JsonSerializer.Deserialize(await response.Content.ReadAsStreamAsync(), typeof(LoginResponse), new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
}) as LoginResponse)?.Token ?? throw new Exception("no token!");
logintoken = token;
SaveToken();
break;

default:
int code = ((int)response.StatusCode);
Console.WriteLine(code);
if (code == 401)
{
Console.WriteLine("邮箱或密码错误!");
}
return;
}
}
}

async public Task UserDetails(HttpClient client) //用来测试访问网站
{
if (!ReadToken()) //读取token失败
{
return;
}
try
{
client.DefaultRequestHeaders.Authorization = new("Bearer", logintoken);
Console.WriteLine(logintoken);
using (var response = await client.GetAsync("https://api.eesast.com/application/info")) //JsonContent.Create(new
//{

//})))
{
switch (response.StatusCode)
{
case System.Net.HttpStatusCode.OK:
Console.WriteLine("Require OK");
Console.WriteLine(await response.Content.ReadAsStringAsync());
break;
default:
int code = ((int)response.StatusCode);
if (code == 401)
{
Console.WriteLine("您未登录或登录过期,请先登录");
}
return;
}
}
}
catch
{
Console.WriteLine("请求错误!请检查网络连接!");
}
}

public void SaveToken()//保存token
{
string savepath = Path.Combine(Data.dataPath, "Token.dat");
try
{
FileStream fs = new FileStream(savepath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
fs.SetLength(0);
sw.Write(logintoken); //将token写入文件
sw.Close();
fs.Close();
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("保存token时未找到下载器地址!请检查下载器是否被移动!");
}
catch (PathTooLongException)
{
Console.WriteLine("下载器的路径名太长!请尝试移动下载器!");
}
catch (ArgumentNullException)
{
Console.WriteLine("下载器路径初始化失败!");
}
catch (IOException)
{
Console.WriteLine("写入token.dat发生冲突!请检查token.dat是否被其它程序占用!");
}
}
public bool ReadToken()//读取token
{
try
{
string savepath = Path.Combine(Data.dataPath, "Token.dat");
FileStream fs = new FileStream(savepath, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs);
logintoken = sr.ReadLine();
sr.Close();
fs.Close();
return true;
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("读取token时未找到下载器地址!请检查下载器是否被移动!");
return false;
}
catch (FileNotFoundException)
{
//没有登陆
Console.WriteLine("请先登陆!");
return false;
}
catch (PathTooLongException)
{
Console.WriteLine("下载器的路径名太长!请尝试移动下载器!");
return false;
}
catch (ArgumentNullException)
{
Console.WriteLine("下载器路径初始化失败!");
return false;
}
catch (IOException)
{
Console.WriteLine("写入token.dat发生冲突!请检查token.dat是否被其它程序占用!");
return false;
}
}
}
[Serializable]
record LoginResponse
{
// Map `Token` to `token` when serializing

public string Token { get; set; } = "";
}

}

+ 97
- 31
installer/Installer/ViewModel.cs View File

@@ -1,6 +1,7 @@

using starter.viewmodel.common;
using System;
using System.Windows;
using System.Windows.Forms;

namespace starter.viewmodel.settings
@@ -16,37 +17,98 @@ namespace starter.viewmodel.settings
/// </summary>
public SettingsViewModel()
{
Route = Environment.GetEnvironmentVariable("USERPROFILE") + "\\THUAI6";
CanEditRoute = true;
if (Downloader.Program.Tencent_cos_download.CheckAlreadyDownload())
{
Installed = true;
}
else
{
Route = Environment.GetEnvironmentVariable("USERPROFILE") + "\\THUAI6";
EditingRoute = true;
}
}

public string Route
{
get {
get
{
return obj.Route;
}
set {
set
{
obj.Route = value;
this.RaisePropertyChanged("Route");
}
}

public bool CanEditRoute // if the user can still edit install route
public bool Installed
{
get {
return !obj.HaveRoute;
get
{
return obj.installed;
}
set {
obj.HaveRoute = !value;
set
{
obj.installed = value;
this.RaisePropertyChanged("Installed");
this.RaisePropertyChanged("InstIntroVis");
this.RaisePropertyChanged("EditIntroVis");
this.RaisePropertyChanged("MoveIntroVis");
}
}
public bool EditingRoute
{
get
{
return obj.EditingRoute;
}
set
{
obj.EditingRoute = value;
this.RaisePropertyChanged("CanEditRoute");
this.RaisePropertyChanged("EditingRoute");
this.RaisePropertyChanged("MoveIntroVis");
this.RaisePropertyChanged("RouteBoxVis");
}
}
public Visibility RouteBoxVis //if the route editing textbox is visible
{
get
{
return obj.EditingRoute ? Visibility.Visible : Visibility.Collapsed;
}
}
/// <summary>
/// if the install/edit instruction can be seen
/// </summary>
public Visibility InstIntroVis
{
get
{
return obj.installed ? Visibility.Collapsed : Visibility.Visible;
}
}
public Visibility EditIntroVis
{
get
{
return obj.installed ? Visibility.Visible : Visibility.Collapsed;
}
}
public Visibility MoveIntroVis
{
get
{
if (obj.installed == true && obj.EditingRoute == true)
return Visibility.Visible;
else
return Visibility.Collapsed;
}
}

private BaseCommand clickBrowseCommand;
public BaseCommand ClickBrowseCommand
{
get {
get
{
if (clickBrowseCommand == null)
{
clickBrowseCommand = new BaseCommand(new Action<object>(o =>
@@ -54,28 +116,32 @@ namespace starter.viewmodel.settings
using (FolderBrowserDialog dialog = new FolderBrowserDialog())
{
_ = dialog.ShowDialog();
if (dialog.SelectedPath != String.Empty)
Route = dialog.SelectedPath;
}
}));
if (dialog.SelectedPath != String.Empty)
Route = dialog.SelectedPath;
}
}));
}
return clickBrowseCommand;
}
}
private BaseCommand clickConfirmCommand;
public BaseCommand ClickConfirmCommand
{
get {
if (clickConfirmCommand == null)
return clickBrowseCommand;
}
}
private BaseCommand clickConfirmCommand;
public BaseCommand ClickConfirmCommand
{
get
{
if (clickConfirmCommand == null)
{
clickConfirmCommand = new BaseCommand(new Action<object>(o =>
{
CanEditRoute = false;
obj.install();
}));
}
if (obj.install())
{
EditingRoute = false;
Installed = true;
}
}));
}
return clickConfirmCommand;
}
}
}
}
}
}
}

+ 1
- 1
launcher/Launcher/AssemblyInfo.cs View File

@@ -1,6 +1,6 @@
using System.Windows;

[assembly:ThemeInfo(
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, // where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)


+ 20
- 0
logic/ClientTest/ClientTest.csproj View File

@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.21.9" />
<PackageReference Include="Grpc" Version="2.46.5" />
<PackageReference Include="Grpc.Core" Version="2.46.5" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\dependency\proto\Protos.csproj" />
</ItemGroup>

</Project>

+ 36
- 0
logic/ClientTest/Program.cs View File

@@ -0,0 +1,36 @@
using Grpc.Core;
using Protobuf;

namespace ClientTest
{
public class Program
{
public static async Task Main(string[] args)
{
Channel channel = new Channel("0.0.0.0:8888", ChannelCredentials.Insecure);
var client = new AvailableService.AvailableServiceClient(channel);
PlayerMsg playerInfo = new();
playerInfo.PlayerId = Convert.ToInt32(args[0]);
playerInfo.PlayerType = (PlayerType)Convert.ToInt32(args[1]);
var call = client.AddPlayer(playerInfo);
while (await call.ResponseStream.MoveNext())
{
var currentGameInfo = call.ResponseStream.Current;
if (playerInfo.PlayerType == PlayerType.HumanPlayer)
{
for (int i = 0; i < currentGameInfo.HumanMessage.Count; i++)
{
Console.WriteLine($"Human is at ({currentGameInfo.HumanMessage[i].X}, {currentGameInfo.HumanMessage[i].Y})");
}
}
if (playerInfo.PlayerType == PlayerType.ButcherPlayer)
{
for (int i = 0; i < currentGameInfo.ButcherMessage.Count; i++)
{
Console.WriteLine($"Butcher is at ({currentGameInfo.ButcherMessage[i].X}, {currentGameInfo.ButcherMessage[i].Y})");
}
}
}
}
}
}

+ 68
- 0
logic/GameClass/GameObj/Team.cs View File

@@ -0,0 +1,68 @@
using System.Collections.Generic;

namespace GameClass.GameObj
{
public class Team
{
private static long currentMaxTeamID = 0;
public static long CurrentMaxTeamID => currentMaxTeamID;
private readonly long teamID;
public long TeamID => teamID;
public const long invalidTeamID = long.MaxValue;
public const long noneTeamID = long.MinValue;
private readonly List<Character> playerList;
public int Score
{
get {
int score = 0;
foreach (var player in playerList)
score += player.Score;
return score;
}
}
public Character? GetPlayer(long ID)
{
foreach (Character player in playerList)
{
if (player.ID == ID)
{
return player;
}
}
return null;
}
public void AddPlayer(Character player)
{
playerList.Add(player);
}
public void OutPlayer(long ID)
{
int i;
for (i = 0; i < playerList.Count; ++i)
{
if (playerList[i].ID == ID)
break;
}
playerList.RemoveAt(i);
}
public long[] GetPlayerIDs()
{
long[] playerIDs = new long[playerList.Count];
int num = 0;
foreach (Character player in playerList)
{
playerIDs[num++] = player.ID;
}
return playerIDs;
}
public static bool teamExists(long findTeamID)
{
return findTeamID < currentMaxTeamID;
}
public Team()
{
teamID = currentMaxTeamID++;
playerList = new List<Character>();
}
}
}

+ 4
- 4
logic/GameEngine/CollisionChecker.cs View File

@@ -17,7 +17,7 @@ namespace GameEngine
/// <returns>和它碰撞的物体</returns>
public IGameObj? CheckCollision(IMoveable obj, XY moveVec)
{
XY nextPos = obj.Position + XY.VectorToXY(moveVec);
XY nextPos = obj.Position + moveVec;
if (!obj.IsRigid)
{
if (gameMap.IsOutOfBound(obj))
@@ -156,7 +156,7 @@ namespace GameEngine
{
double tmp = mod - obj.Radius - listObj.Radius;
// 计算能走的最长距离,好像这么算有一点误差?
tmp = tmp / Math.Cos(Math.Atan2(orgDeltaY, orgDeltaX) - moveVec.angle);
tmp = tmp / Math.Cos(Math.Atan2(orgDeltaY, orgDeltaX) - moveVec.Angle());
if (tmp < 0 || tmp > uint.MaxValue || tmp == double.NaN)
{
tmpMax = uint.MaxValue;
@@ -177,11 +177,11 @@ namespace GameEngine
else
{
// 二分查找最大可能移动距离
int left = 0, right = (int)moveVec.length;
int left = 0, right = (int)moveVec.Length();
while (left < right - 1)
{
int mid = (right - left) / 2 + left;
if (obj.WillCollideWith(listObj, obj.Position + new XY((int)(mid * Math.Cos(moveVec.angle)), (int)(mid * Math.Sin(moveVec.angle)))))
if (obj.WillCollideWith(listObj, obj.Position + new XY((int)(mid * Math.Cos(moveVec.Angle())), (int)(mid * Math.Sin(moveVec.Angle())))))
{
right = mid;
}


+ 18
- 18
logic/GameEngine/MoveEngine.cs View File

@@ -50,10 +50,10 @@ namespace GameEngine
{

/*由于四周是墙,所以人物永远不可能与越界方块碰撞*/
XY nextPos = obj.Position + XY.VectorToXY(moveVec);
XY nextPos = obj.Position + moveVec;
double maxLen = collisionChecker.FindMax(obj, nextPos, moveVec);
maxLen = Math.Min(maxLen, obj.MoveSpeed / GameData.numOfStepPerSecond);
_ = obj.Move(new Vector(moveVec.angle, maxLen));
_ = obj.Move(new XY(moveVec.Angle(), maxLen));
}

public void MoveObj(IMoveable obj, int moveTime, double direction)
@@ -62,33 +62,33 @@ namespace GameEngine
return;
new Thread
(
()=>
() =>
{
if (!obj.IsAvailable&&gameTimer.IsGaming) //不能动就直接return,后面都是能动的情况
return;
return;
lock (obj.MoveLock)
obj.IsMoving = true;

XY moveVec = new(direction, 0.0);
double deltaLen = moveVec.length - Math.Sqrt(obj.Move(moveVec)); // 转向,并用deltaLen存储行走的误差
double moveVecLength = 0.0;
double deltaLen = moveVecLength - Math.Sqrt(obj.Move(new XY(direction, moveVecLength))); // 转向,并用deltaLen存储行走的误差
IGameObj? collisionObj = null;
bool isDestroyed = false;
new FrameRateTaskExecutor<int>(
() => gameTimer.IsGaming && obj.CanMove && !obj.IsResetting,
() =>
{
moveVec.length = obj.MoveSpeed / GameData.numOfStepPerSecond;
moveVecLength = obj.MoveSpeed / GameData.numOfStepPerSecond;

// 越界情况处理:如果越界,则与越界方块碰撞
bool flag; // 循环标志
do
{
flag = false;
collisionObj = collisionChecker.CheckCollision(obj, moveVec);
collisionObj = collisionChecker.CheckCollision(obj, new XY(direction, moveVecLength));
if (collisionObj == null)
break;

switch (OnCollision(obj, collisionObj, moveVec))
switch (OnCollision(obj, collisionObj, new XY(direction, moveVecLength)))
{
case AfterCollision.ContinueCheck:
flag = true;
@@ -98,13 +98,13 @@ namespace GameEngine
isDestroyed = true;
return false;
case AfterCollision.MoveMax:
MoveMax(obj, moveVec);
moveVec.length = 0;
MoveMax(obj, new XY(direction, moveVecLength));
moveVecLength = 0;
break;
}
} while (flag);

deltaLen += moveVec.length - Math.Sqrt(obj.Move(moveVec));
deltaLen += moveVecLength - Math.Sqrt(obj.Move(new XY(direction, moveVecLength)));

return true;
},
@@ -118,14 +118,14 @@ namespace GameEngine
flag = false;
if (!isDestroyed)
{
moveVec.length = deltaLen + leftTime * obj.MoveSpeed / GameData.numOfPosGridPerCell;
if ((collisionObj = collisionChecker.CheckCollision(obj, moveVec)) == null)
moveVecLength = deltaLen + leftTime * obj.MoveSpeed / GameData.numOfPosGridPerCell;
if ((collisionObj = collisionChecker.CheckCollision(obj, new XY(direction, moveVecLength))) == null)
{
obj.Move(moveVec);
obj.Move(new XY(direction, moveVecLength));
}
else
{
switch (OnCollision(obj, collisionObj, moveVec))
switch (OnCollision(obj, collisionObj, new XY(direction, moveVecLength)))
{
case AfterCollision.ContinueCheck:
flag = true;
@@ -135,8 +135,8 @@ namespace GameEngine
isDestroyed = true;
break;
case AfterCollision.MoveMax:
MoveMax(obj, moveVec);
moveVec.length = 0;
MoveMax(obj, new XY(direction, moveVecLength));
moveVecLength = 0;
break;
}
}


+ 66
- 0
logic/Gaming/MoveManager.cs View File

@@ -0,0 +1,66 @@
using System;
using GameClass.GameObj;
using GameEngine;
using Preparation.Utility;

namespace Gaming
{
public partial class Game
{
private readonly MoveManager moveManager;
private class MoveManager
{

// 人物移动
public void MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection)
{
moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection);
}

/*
private void ActivateMine(Character player, Mine mine)
{
gameMap.ObjListLock.EnterWriteLock();
try { gameMap.ObjList.Remove(mine); }
catch { }
finally { gameMap.ObjListLock.ExitWriteLock(); }

switch (mine.GetPropType())
{
case PropType.Dirt:
player.AddMoveSpeed(Constant.dirtMoveSpeedDebuff, Constant.buffPropTime);
break;
case PropType.Attenuator:
player.AddAP(Constant.attenuatorAtkDebuff, Constant.buffPropTime);
break;
case PropType.Divider:
player.ChangeCD(Constant.dividerCdDiscount, Constant.buffPropTime);
break;
}
}
*/

// private readonly Map gameMap;
private readonly MoveEngine moveEngine;
public MoveManager(Map gameMap)
{
// this.gameMap = gameMap;
this.moveEngine = new MoveEngine(
gameMap: gameMap,
OnCollision: (obj, collisionObj, moveVec) =>
{
//if (collisionObj is Mine)
//{
// ActivateMine((Character)obj, (Mine)collisionObj);
// return MoveEngine.AfterCollision.ContinueCheck;
//}
return MoveEngine.AfterCollision.MoveMax; },
EndMove: obj =>
{
// Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64);
}
);
}
}
}
}

+ 4
- 6
logic/Preparation/Utility/EnumType.cs View File

@@ -87,11 +87,9 @@ namespace Preparation.Utility
{
None = 0,
Player = 1,
Bullet = 2,
Prop = 3,
Gem = 4,
Map = 5,
BombedBullet = 6,
PickedProp = 7
Prop = 2,
Map = 3,
BombedBullet = 4,
PickedProp = 5
}
}

+ 13
- 0
logic/Preparation/Utility/XY.cs View File

@@ -12,6 +12,11 @@ namespace Preparation.Utility
this.x = x;
this.y = y;
}
public XY(double angle, double length)
{
this.x = (int)(length * Math.Cos(angle));
this.y = (int)(length * Math.Sin(angle));
}
public override string ToString()
{
return "(" + x.ToString() + "," + y.ToString() + ")";
@@ -32,5 +37,13 @@ namespace Preparation.Utility
{
return Math.Sqrt(((long)(p1.x - p2.x) * (p1.x - p2.x)) + ((long)(p1.y - p2.y) * (p1.y - p2.y)));
}
public double Length()
{
return Math.Sqrt(((long)x * x) + ((long)y * y));
}
public double Angle()
{
return Math.Atan2(y, x);
}
}
}

+ 110
- 0
logic/Server/Game.cs View File

@@ -0,0 +1,110 @@
using Grpc.Core;
using Protobuf;
using System.Threading;
using Timothy.FrameRateTask;
using System;
using System.Net.Http.Headers;

namespace Server
{
public class Game
{
private const int gameTime = 3000;
public int GameTime => gameTime;

private MessageToClient gameInfo = new();
private object gameInfoLock = new();
private int isGaming = 0;
public bool IsGaming
{
get => Interlocked.CompareExchange(ref isGaming, 0, 0) != 0;
set => Interlocked.Exchange(ref isGaming, value ? 1 : 0);
}

public MessageToClient GetCopiedGameInfo()
{
lock (gameInfoLock)
{
return gameInfo.Clone();
}
}
public void AddPlayer(PlayerMsg player)
{
lock (gameInfoLock)
{
if (player.PlayerType == PlayerType.NullPlayerType)
return;
if (player.PlayerType == PlayerType.HumanPlayer)
{
gameInfo.HumanMessage.Add(new MessageOfHuman()
{
PlayerId = player.PlayerId
});
return;
}
if (player.PlayerType == PlayerType.ButcherPlayer)
{
gameInfo.ButcherMessage.Add(new MessageOfButcher()
{
PlayerId = player.PlayerId
});
return;
}
}
}

public void Move()
{

}

public SemaphoreSlim StartGame()
{
IsGaming = true;
var waitHandle = new SemaphoreSlim(0);

new Thread
(
() =>
{
new FrameRateTaskExecutor<int>
(
() => IsGaming,
() =>
{
lock (gameInfo)
{
for (int i = 0; i < gameInfo.HumanMessage.Count; i++)
{
if (gameInfo.HumanMessage[i] != null)
{
gameInfo.HumanMessage[i].X++;
gameInfo.HumanMessage[i].Y--;
}
}
for (int i = 0; i < gameInfo.ButcherMessage.Count; i++)
{
if (gameInfo.ButcherMessage[i] != null)
{
gameInfo.ButcherMessage[i].X--;
gameInfo.ButcherMessage[i].Y++;
}
}
}
},
100,
() =>
{
IsGaming = false;
waitHandle.Release();
return 0;
},
gameTime
).Start();
}
)
{ IsBackground = true }.Start();
return waitHandle;
}
}
}

+ 121
- 0
logic/Server/GameServer.cs View File

@@ -0,0 +1,121 @@
using Grpc.Core;
using Protobuf;
using System.Threading;
using Timothy.FrameRateTask;
using System;
using System.Net.Http.Headers;

namespace Server
{
public class GameServer : AvailableService.AvailableServiceBase
{
private Dictionary<long, (SemaphoreSlim, SemaphoreSlim)> semaDict = new();
private object gameLock = new();
private const int playerNum = 1;
private MessageToClient currentGameInfo = new();
private Game game = new();
public int GameTime => game.GameTime;
private SemaphoreSlim endGameSem = new(0);

public override Task<BoolRes> TryConnection(IDMsg request, ServerCallContext context)
{
var onConnection = new BoolRes();
lock (gameLock)
{
// if (0 <= request.PlayerId && request.PlayerId < playerNum)
{
onConnection.ActSuccess = true;
Console.WriteLine(onConnection.ActSuccess);
return Task.FromResult(onConnection);
}
}
onConnection.ActSuccess = false;
return Task.FromResult(onConnection);
}

public override async Task AddPlayer(PlayerMsg request, IServerStreamWriter<MessageToClient> responseStream, ServerCallContext context)
{
lock (gameLock)
{
if (game.IsGaming)
return;
game.AddPlayer(request);
var temp = (new SemaphoreSlim(0, 1), new SemaphoreSlim(0, 1));

bool start = false;
Console.WriteLine($"Id: {request.PlayerId} joins.");
lock (semaDict)
{
semaDict.Add(request.PlayerId, temp);
start = semaDict.Count == playerNum;
}

if (start)
{
Console.WriteLine("Game starts!");
StartGame();
}
}

do
{
semaDict[request.PlayerId].Item1.Wait();
if (currentGameInfo != null)
{
await responseStream.WriteAsync(currentGameInfo);
Console.WriteLine("Send!");
}
semaDict[request.PlayerId].Item2.Release();
} while (game.IsGaming);
}
public void StartGame()
{
var waitHandle = game.StartGame();
new Thread(() =>
{
new FrameRateTaskExecutor<int>
(
() => game.IsGaming,
ReportGame,
1000,
() =>
{
ReportGame(); // 最后发一次消息,唤醒发消息的线程,防止发消息的线程由于有概率处在 Wait 状态而卡住
return 0;
}
).Start();
})
{ IsBackground = true }.Start();
new Thread(() =>
{
waitHandle.Wait();
this.endGameSem.Release();
})
{ IsBackground = true }.Start();

}
public void WaitForEnd()
{
this.endGameSem.Wait();
}

public void ReportGame()
{
currentGameInfo = game.GetCopiedGameInfo();

foreach (var kvp in semaDict)
{
kvp.Value.Item1.Release();
}

foreach (var kvp in semaDict)
{
kvp.Value.Item2.Wait();
}
}

public GameServer()
{
}
}
}

+ 35
- 2
logic/Server/Program.cs View File

@@ -1,2 +1,35 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
using Grpc.Core;
using Protobuf;
using System.Threading;
using Timothy.FrameRateTask;
using System;
using System.Net.Http.Headers;

namespace Server
{
public class Program
{
public static void Main()
{
try
{
GameServer gameServer = new();
Grpc.Core.Server server = new Grpc.Core.Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
{
Services = { AvailableService.BindService(gameServer) },
Ports = { new ServerPort("0.0.0.0", 8888, ServerCredentials.Insecure) }
};
server.Start();

Console.WriteLine("Server begins to listen!");
gameServer.WaitForEnd();
Console.WriteLine("Server end!");
server.ShutdownAsync().Wait();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}

+ 15
- 0
logic/Server/Server.csproj View File

@@ -7,4 +7,19 @@
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FrameRateTask" Version="1.1.2" />
<PackageReference Include="Google.Protobuf" Version="3.21.9" />
<PackageReference Include="Grpc" Version="2.46.5" />
<PackageReference Include="Grpc.Core" Version="2.46.5" />
<PackageReference Include="Grpc.Tools" Version="2.50.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\dependency\proto\Protos.csproj" />
</ItemGroup>

</Project>

+ 7
- 0
logic/cmd/test.cmd View File

@@ -0,0 +1,7 @@
@echo off

start cmd /k .\Server\bin\Debug\net6.0\Server.exe

start cmd /k .\ClientTest\bin\Debug\net6.0\ClientTest.exe 0 1

start cmd /k .\ClientTest\bin\Debug\net6.0\ClientTest.exe 1 2

+ 18
- 0
logic/logic.sln View File

@@ -5,6 +5,12 @@ VisualStudioVersion = 17.0.32014.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientTest", "ClientTest\ClientTest.csproj", "{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Protos", "..\dependency\proto\Protos.csproj", "{9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GameEngine", "GameEngine\GameEngine.csproj", "{C7A82045-5EE5-46E8-AD0C-04103EFEAF7E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +21,18 @@ Global
{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}.Release|Any CPU.Build.0 = Release|Any CPU
{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}.Release|Any CPU.Build.0 = Release|Any CPU
{9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}.Release|Any CPU.Build.0 = Release|Any CPU
{C7A82045-5EE5-46E8-AD0C-04103EFEAF7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C7A82045-5EE5-46E8-AD0C-04103EFEAF7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C7A82045-5EE5-46E8-AD0C-04103EFEAF7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C7A82045-5EE5-46E8-AD0C-04103EFEAF7E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE


Loading…
Cancel
Save