diff --git a/dependency/shell/run.sh b/dependency/shell/run.sh index 71ae4abf..d92f7663 100644 --- a/dependency/shell/run.sh +++ b/dependency/shell/run.sh @@ -5,10 +5,10 @@ python_main_dir=/usr/local/PlayerCode/CAPI/python playback_dir=/usr/local/playback if [ $EXPOSED -eq 1 ]; then - nice -10 ./Server --port 8888 --studentCount 4 --trickerCount 1 --resultFileName $playback_dir/result --gameTimeInSecond $TIME --mapResource $MAP --url $URL --token $TOKEN --fileName $playback_dir/video --startLockFile $playback_dir/start.lock > $playback_dir/server.log 2>&1 & + nice -10 ./Server --port 8888 --studentCount 4 --trickerCount 1 --resultFileName $playback_dir/result --gameTimeInSecond $TIME --mode $MODE --mapResource $MAP --url $URL --token $TOKEN --fileName $playback_dir/video --startLockFile $playback_dir/start.lock > $playback_dir/server.log 2>&1 & server_pid=$! else - nice -10 ./Server --port 8888 --studentCount 4 --trickerCount 1 --resultFileName $playback_dir/result --gameTimeInSecond $TIME --mapResource $MAP --notAllowSpectator --url $URL --token $TOKEN --fileName $playback_dir/video --startLockFile $playback_dir/start.lock > $playback_dir/server.log 2>&1 & + nice -10 ./Server --port 8888 --studentCount 4 --trickerCount 1 --resultFileName $playback_dir/result --gameTimeInSecond $TIME --mode $MODE --mapResource $MAP --notAllowSpectator --url $URL --token $TOKEN --fileName $playback_dir/video --startLockFile $playback_dir/start.lock > $playback_dir/server.log 2>&1 & server_pid=$! fi sleep 5 diff --git a/logic/GameClass/GameObj/Character/Character.Skill.cs b/logic/GameClass/GameObj/Character/Character.Skill.cs index cc8e98cd..f2d887ec 100644 --- a/logic/GameClass/GameObj/Character/Character.Skill.cs +++ b/logic/GameClass/GameObj/Character/Character.Skill.cs @@ -11,7 +11,7 @@ public partial class Character private readonly IOccupation occupation; public IOccupation Occupation => occupation; - private Dictionary activeSkillDictionary = new(); + private readonly Dictionary activeSkillDictionary = new(); public Dictionary ActiveSkillDictionary => activeSkillDictionary; public ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType) @@ -42,9 +42,9 @@ protected Character(XY initPos, int initRadius, CharacterType characterType) : this.alertnessRadius = Occupation.AlertnessRadius; this.viewRange = Occupation.ViewRange; this.characterType = characterType; - this.SpeedOfOpeningOrLocking = Occupation.SpeedOfOpeningOrLocking; - this.SpeedOfClimbingThroughWindows = Occupation.SpeedOfClimbingThroughWindows; - this.SpeedOfOpenChest = Occupation.SpeedOfOpenChest; + this.speedOfOpeningOrLocking = Occupation.SpeedOfOpeningOrLocking; + this.speedOfClimbingThroughWindows = Occupation.SpeedOfClimbingThroughWindows; + this.speedOfOpenChest = Occupation.SpeedOfOpenChest; foreach (var activeSkill in this.Occupation.ListOfIActiveSkill) { diff --git a/logic/GameClass/GameObj/Character/Character.Student.cs b/logic/GameClass/GameObj/Character/Character.Student.cs index 88e101b7..d0a4902c 100644 --- a/logic/GameClass/GameObj/Character/Character.Student.cs +++ b/logic/GameClass/GameObj/Character/Character.Student.cs @@ -7,16 +7,21 @@ namespace GameClass.GameObj { public class Student : Character { + private readonly object fixLock = new(); protected int fixSpeed; /// /// 修理电机速度 /// public int FixSpeed { - get => fixSpeed; + get + { + lock (fixLock) + return fixSpeed; + } set { - lock (gameObjLock) + lock (fixLock) { fixSpeed = value; } @@ -25,7 +30,7 @@ public int FixSpeed /// /// 原初修理电机速度 /// - public int OrgFixSpeed { get; protected set; } + protected readonly int orgFixSpeed; protected int treatSpeed = GameData.basicTreatSpeed; public int TreatSpeed @@ -122,7 +127,7 @@ public void SetTimeOfRescue(int value) public Student(XY initPos, int initRadius, CharacterType characterType) : base(initPos, initRadius, characterType) { - this.OrgFixSpeed = this.fixSpeed = ((IStudentType)Occupation).FixSpeed; + this.orgFixSpeed = this.fixSpeed = ((IStudentType)Occupation).FixSpeed; this.TreatSpeed = this.OrgTreatSpeed = ((IStudentType)Occupation).TreatSpeed; this.MaxGamingAddiction = ((IStudentType)Occupation).MaxGamingAddiction; } diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index 95df5c5c..3e6b9374 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -31,7 +31,15 @@ public int CD } } } - public int OrgCD { get; protected set; } + private int orgCD; + public int OrgCD + { + get + { + lock (actionLock) + return orgCD; + } + } public readonly BulletType OriBulletOfPlayer; private BulletType bulletOfPlayer; @@ -49,7 +57,7 @@ public BulletType BulletOfPlayer lock (actionLock) { bulletOfPlayer = value; - cd = OrgCD = (BulletFactory.BulletCD(value)); + cd = orgCD = (BulletFactory.BulletCD(value)); Debugger.Output(this, string.Format("'s CD has been set to: {0}.", cd)); maxBulletNum = bulletNum = (BulletFactory.BulletNum(value)); } @@ -167,43 +175,22 @@ public void AddBgm(BgmType bgm, double value) public int ViewRange => viewRange; #endregion #region 交互相关的基本属性及方法 - private int speedOfOpeningOrLocking; + private readonly int speedOfOpeningOrLocking; public int SpeedOfOpeningOrLocking { get => speedOfOpeningOrLocking; - set - { - lock (gameObjLock) - { - speedOfOpeningOrLocking = value; - } - } } - private int speedOfClimbingThroughWindows; + private readonly int speedOfClimbingThroughWindows; public int SpeedOfClimbingThroughWindows { get => speedOfClimbingThroughWindows; - set - { - lock (gameObjLock) - { - speedOfClimbingThroughWindows = value; - } - } } - private int speedOfOpenChest; + private readonly int speedOfOpenChest; public int SpeedOfOpenChest { get => speedOfOpenChest; - set - { - lock (gameObjLock) - { - speedOfOpenChest = value; - } - } } #endregion #region 血量相关的基本属性及方法 diff --git a/logic/GameClass/GameObj/Map/Chest.cs b/logic/GameClass/GameObj/Map/Chest.cs index 1d86d3d2..ddacde21 100644 --- a/logic/GameClass/GameObj/Map/Chest.cs +++ b/logic/GameClass/GameObj/Map/Chest.cs @@ -25,7 +25,7 @@ public Chest(XY initPos) : public Character? WhoOpen => whoOpen; public bool Open(Character character) { - lock (GameObjReaderWriterLock) + lock (gameObjLock) { if (whoOpen != null) return false; openStartTime = Environment.TickCount64; @@ -35,7 +35,7 @@ public bool Open(Character character) } public void StopOpen() { - lock (GameObjReaderWriterLock) + lock (gameObjLock) { whoOpen = null; } diff --git a/logic/GameClass/GameObj/Map/Door.cs b/logic/GameClass/GameObj/Map/Door.cs index c4c6527a..ab459b5b 100644 --- a/logic/GameClass/GameObj/Map/Door.cs +++ b/logic/GameClass/GameObj/Map/Door.cs @@ -98,6 +98,7 @@ public void StopOpen() if (whoLockOrOpen != null) { if ((Environment.TickCount64 - openStartTime) >= GameData.degreeOfLockingOrOpeningTheDoor / whoLockOrOpen.SpeedOfOpeningOrLocking) + //现在框架没有问题,但是调用可变的SpeedOfOpeningOrLocking可能死锁 isOpen = true; whoLockOrOpen = null; } diff --git a/logic/GameClass/GameObj/Map/Map.cs b/logic/GameClass/GameObj/Map/Map.cs index 93f39da4..775681a6 100644 --- a/logic/GameClass/GameObj/Map/Map.cs +++ b/logic/GameClass/GameObj/Map/Map.cs @@ -21,7 +21,7 @@ public void AddNumOfRepairedGenerators() uint value = Interlocked.Increment(ref numOfRepairedGenerators); if (value == GameData.numOfGeneratorRequiredForEmergencyExit) { - GameObjLockDict[GameObjType.EmergencyExit].EnterWriteLock(); + GameObjLockDict[GameObjType.EmergencyExit].EnterReadLock(); try { Random r = new Random(Environment.TickCount); @@ -31,13 +31,13 @@ public void AddNumOfRepairedGenerators() } finally { - GameObjLockDict[GameObjType.EmergencyExit].ExitWriteLock(); + GameObjLockDict[GameObjType.EmergencyExit].ExitReadLock(); } } else if (value == GameData.numOfGeneratorRequiredForRepair) { - GameObjLockDict[GameObjType.Doorway].EnterWriteLock(); + GameObjLockDict[GameObjType.Doorway].EnterReadLock(); try { foreach (Doorway doorway in GameObjDict[GameObjType.Doorway]) @@ -45,7 +45,7 @@ public void AddNumOfRepairedGenerators() } finally { - GameObjLockDict[GameObjType.Doorway].ExitWriteLock(); + GameObjLockDict[GameObjType.Doorway].ExitReadLock(); } } } diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 7c43541c..522ac2f4 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -52,14 +52,7 @@ public bool MovePlayerWhenStunned(Character playerToMove, int moveTimeInMillisec { moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection, playerToMove.StateNum); Thread.Sleep(moveTimeInMilliseconds); - lock (playerToMove.ActionLock) - { - lock (playerToMove.ActionLock) - { - if (stateNum == playerToMove.StateNum) - playerToMove.SetPlayerStateNaturally(); - } - } + playerToMove.ResetPlayerState(stateNum); } } ) @@ -664,7 +657,7 @@ public ActionManager(Map gameMap, CharacterManager characterManager) } break; case GameObjType.Character: - if (player.FindActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed == 1 && ((Character)collisionObj).IsGhost()) + if (player.FindActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed && ((Character)collisionObj).IsGhost()) { if (CharacterManager.BeStunned((Character)collisionObj, GameData.timeOfGhostStunnedWhenCharge) > 0) player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenCharge)); diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs index 0fe1706e..04af9bdc 100644 --- a/logic/Gaming/Game.cs +++ b/logic/Gaming/Game.cs @@ -281,7 +281,7 @@ public void AllPlayerUsePassiveSkill() { if (!gameMap.Timer.IsGaming) return; - gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock(); + gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); try { foreach (Character player in gameMap.GameObjDict[GameObjType.Character]) @@ -291,7 +291,7 @@ public void AllPlayerUsePassiveSkill() } finally { - gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); + gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock(); } } diff --git a/logic/Gaming/PropManager.cs b/logic/Gaming/PropManager.cs index 67e29f2c..5127f641 100644 --- a/logic/Gaming/PropManager.cs +++ b/logic/Gaming/PropManager.cs @@ -142,7 +142,7 @@ public void StartProducing() int len = availableCellForGenerateProp.Count; Random r = new Random(Environment.TickCount); - gameMap.GameObjLockDict[GameObjType.Chest].EnterWriteLock(); + gameMap.GameObjLockDict[GameObjType.Chest].EnterReadLock(); try { int cou = 0; @@ -181,7 +181,7 @@ public void StartProducing() } finally { - gameMap.GameObjLockDict[GameObjType.Chest].ExitWriteLock(); + gameMap.GameObjLockDict[GameObjType.Chest].ExitReadLock(); } /* new Thread diff --git a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs index dde4cae2..8f6d003a 100644 --- a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs +++ b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs @@ -505,11 +505,11 @@ public static bool ActiveSkillEffect(ActiveSkill activeSkill, Character player, (() => { startSkill(); - activeSkill.IsBeingUsed = 1; + activeSkill.IsBeingUsed = true; Thread.Sleep(activeSkill.DurationTime); endSkill(); - activeSkill.IsBeingUsed = 0; + activeSkill.IsBeingUsed = false; Debugger.Output(player, "return to normal."); } ) diff --git a/logic/Preparation/Interface/ISkill.cs b/logic/Preparation/Interface/ISkill.cs index fbf6170a..36c50a36 100644 --- a/logic/Preparation/Interface/ISkill.cs +++ b/logic/Preparation/Interface/ISkill.cs @@ -16,7 +16,7 @@ public interface IActiveSkill : ISkill public int SkillCD { get; } public int DurationTime { get; } //技能持续时间 public object ActiveSkillUseLock { get; } - public int IsBeingUsed { get; set; } + public bool IsBeingUsed { get; set; } } public abstract class ActiveSkill : IActiveSkill @@ -53,10 +53,10 @@ public bool StartSkill() } public int isBeingUsed = 0;//实为bool - public int IsBeingUsed + public bool IsBeingUsed { - get => Interlocked.CompareExchange(ref isBeingUsed, 0, 0); - set => Interlocked.Exchange(ref isBeingUsed, value); + get => (Interlocked.CompareExchange(ref isBeingUsed, -1, -1) == 1); + set => Interlocked.Exchange(ref isBeingUsed, value ? 1 : 0); } } diff --git a/logic/Server/ArgumentOption.cs b/logic/Server/ArgumentOption.cs index 641e7d34..dbd6efd7 100644 --- a/logic/Server/ArgumentOption.cs +++ b/logic/Server/ArgumentOption.cs @@ -74,5 +74,8 @@ public class ArgumentOptions [Option("startLockFile", Required = false, HelpText = "Whether to create a file that identifies whether the game has started")] public string StartLockFile { get; set; } = DefaultArgumentOptions.FileName; + + [Option("mode", Required = false, HelpText = "Whether to run final competition")] + public int Mode { get; set; } = 0; } -} \ No newline at end of file +} diff --git a/logic/Server/GameServer.cs b/logic/Server/GameServer.cs index 68e65c67..afebe2f7 100644 --- a/logic/Server/GameServer.cs +++ b/logic/Server/GameServer.cs @@ -102,10 +102,9 @@ private void SaveGameResult(string path) } } } - protected void SendGameResult() // 天梯的 Server 给网站发消息记录比赛结果 + protected void SendGameResult(int[] scores, int mode) // 天梯的 Server 给网站发消息记录比赛结果 { - int[] scores = GetScore(); - httpSender?.SendHttpRequest(scores).Wait(); + httpSender?.SendHttpRequest(scores, mode).Wait(); } private void OnGameEnd() @@ -114,7 +113,8 @@ private void OnGameEnd() mwr?.Flush(); if (options.ResultFileName != DefaultArgumentOptions.FileName) SaveGameResult(options.ResultFileName.EndsWith(".json") ? options.ResultFileName : options.ResultFileName + ".json"); - SendGameResult(); + int[] scores = GetScore(); + SendGameResult(scores, options.Mode); this.endGameSem.Release(); } public void ReportGame(GameState gameState, bool requiredGaming = true) diff --git a/logic/Server/HttpSender.cs b/logic/Server/HttpSender.cs index 59442ae4..b9bfb2dd 100644 --- a/logic/Server/HttpSender.cs +++ b/logic/Server/HttpSender.cs @@ -20,7 +20,7 @@ public HttpSender(string url, string token) // { // this.SendHttpRequest(new()).Wait(); // } - public async Task SendHttpRequest(int[] scores) + public async Task SendHttpRequest(int[] scores, int mode) { try { @@ -33,7 +33,7 @@ public async Task SendHttpRequest(int[] scores) new TeamScore() { team_id = 0, score = scores[0], }, new TeamScore() { team_id = 1, score = scores[1], }, }, - mode = 0 + mode = mode }))) { Console.WriteLine("Send to web successfully!"); diff --git a/logic/cmd/spectatorForLadder.cmd b/logic/cmd/spectatorForLadder.cmd index d6cc7ae3..d2dd4ac4 100644 --- a/logic/cmd/spectatorForLadder.cmd +++ b/logic/cmd/spectatorForLadder.cmd @@ -1,3 +1,2 @@ @echo off - -start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --port 8891 --characterId 2087 --ip thuai6.eesast.com \ No newline at end of file +start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --port 8894 --characterID 123321123 --type 1 --occupation 1 --ip thuai6.eesast.com --cl \ No newline at end of file