| @@ -36,7 +36,7 @@ namespace Client | |||||
| public string PlaybackFile { get; set; } = DefaultArgumentOptions.FileName; | public string PlaybackFile { get; set; } = DefaultArgumentOptions.FileName; | ||||
| [Option("playbackSpeed", Required = false, HelpText = "The speed of the playback, between 0.25 and 4.0")] | [Option("playbackSpeed", Required = false, HelpText = "The speed of the playback, between 0.25 and 4.0")] | ||||
| public double PlaybackSpeed { get; set; } = 1.0; | |||||
| public double PlaybackSpeed { get; set; } = 2.0; | |||||
| } | } | ||||
| } | } | ||||
| @@ -413,19 +413,6 @@ namespace Client | |||||
| { | { | ||||
| human = obj.StudentMessage; | human = obj.StudentMessage; | ||||
| } | } | ||||
| if (obj.StudentMessage.PlayerId < GameData.numOfStudent) | |||||
| { | |||||
| IStudentType occupation = (IStudentType)OccupationFactory.FindIOccupation(Transformation.ToStudentType(obj.StudentMessage.StudentType)); | |||||
| totalLife[obj.StudentMessage.PlayerId] = occupation.MaxHp; | |||||
| totalDeath[obj.StudentMessage.PlayerId] = occupation.MaxGamingAddiction; | |||||
| int i = 0; | |||||
| foreach (var skill in occupation.ListOfIActiveSkill) | |||||
| { | |||||
| var iActiveSkill = SkillFactory.FindIActiveSkill(skill); | |||||
| coolTime[i, obj.StudentMessage.PlayerId] = iActiveSkill.SkillCD; | |||||
| ++i; | |||||
| } | |||||
| } | |||||
| listOfHuman.Add(obj.StudentMessage); | listOfHuman.Add(obj.StudentMessage); | ||||
| break; | break; | ||||
| case MessageOfObj.MessageOfObjOneofCase.TrickerMessage: | case MessageOfObj.MessageOfObjOneofCase.TrickerMessage: | ||||
| @@ -433,14 +420,6 @@ namespace Client | |||||
| { | { | ||||
| butcher = obj.TrickerMessage; | butcher = obj.TrickerMessage; | ||||
| } | } | ||||
| IGhostType occupation1 = (IGhostType)OccupationFactory.FindIOccupation(Transformation.ToTrickerType(obj.TrickerMessage.TrickerType)); | |||||
| int j = 0; | |||||
| foreach (var skill in occupation1.ListOfIActiveSkill) | |||||
| { | |||||
| var iActiveSkill = SkillFactory.FindIActiveSkill(skill); | |||||
| coolTime[j, GameData.numOfStudent] = iActiveSkill.SkillCD; | |||||
| ++j; | |||||
| } | |||||
| listOfButcher.Add(obj.TrickerMessage); | listOfButcher.Add(obj.TrickerMessage); | ||||
| break; | break; | ||||
| case MessageOfObj.MessageOfObjOneofCase.PropMessage: | case MessageOfObj.MessageOfObjOneofCase.PropMessage: | ||||
| @@ -519,6 +498,7 @@ namespace Client | |||||
| listOfAll.Add(content.AllMessage); | listOfAll.Add(content.AllMessage); | ||||
| break; | break; | ||||
| case GameState.GameEnd: | case GameState.GameEnd: | ||||
| MessageBox.Show("Game Over!"); | |||||
| foreach (var obj in content.ObjMessage) | foreach (var obj in content.ObjMessage) | ||||
| { | { | ||||
| switch (obj.MessageOfObjCase) | switch (obj.MessageOfObjCase) | ||||
| @@ -667,53 +647,81 @@ namespace Client | |||||
| private void Refresh(object? sender, EventArgs e) //log未更新 | private void Refresh(object? sender, EventArgs e) //log未更新 | ||||
| { | { | ||||
| // Bonus(); | |||||
| if (WindowState == WindowState.Maximized) | |||||
| MaxButton.Content = "❐"; | |||||
| else | |||||
| MaxButton.Content = "🗖"; | |||||
| if (StatusBarsOfSurvivor != null) | |||||
| lock (drawPicLock) // 加锁是必要的,画图操作和接收信息操作不能同时进行 | |||||
| { | { | ||||
| for (int i = 0; i < GameData.numOfStudent; i++) | |||||
| // Bonus(); | |||||
| if (WindowState == WindowState.Maximized) | |||||
| MaxButton.Content = "❐"; | |||||
| else | |||||
| MaxButton.Content = "🗖"; | |||||
| foreach (var obj in listOfHuman) | |||||
| { | { | ||||
| StatusBarsOfSurvivor[i].SetFontSize(12 * UpperLayerOfMap.ActualHeight / 650); | |||||
| StatusBarsOfSurvivor[i].NewData(totalLife, totalDeath, coolTime); | |||||
| if (obj.PlayerId < GameData.numOfStudent) | |||||
| { | |||||
| IStudentType occupation = (IStudentType)OccupationFactory.FindIOccupation(Transformation.ToStudentType(obj.StudentType)); | |||||
| totalLife[obj.PlayerId] = occupation.MaxHp; | |||||
| totalDeath[obj.PlayerId] = occupation.MaxGamingAddiction; | |||||
| int i = 0; | |||||
| foreach (var skill in occupation.ListOfIActiveSkill) | |||||
| { | |||||
| var iActiveSkill = SkillFactory.FindIActiveSkill(skill); | |||||
| coolTime[i, obj.PlayerId] = iActiveSkill.SkillCD; | |||||
| ++i; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | |||||
| if (StatusBarsOfHunter != null) | |||||
| { | |||||
| StatusBarsOfHunter.SetFontSize(12 * UpperLayerOfMap.ActualHeight / 650); | |||||
| StatusBarsOfHunter.NewData(totalLife, totalDeath, coolTime); | |||||
| } | |||||
| if (StatusBarsOfCircumstance != null) | |||||
| StatusBarsOfCircumstance.SetFontSize(12 * UpperLayerOfMap.ActualHeight / 650); | |||||
| // 完成窗口信息更新 | |||||
| if (!isClientStocked) | |||||
| { | |||||
| unit = Math.Sqrt(UpperLayerOfMap.ActualHeight * UpperLayerOfMap.ActualWidth) / 50; | |||||
| unitHeight = UpperLayerOfMap.ActualHeight / 50; | |||||
| unitWidth = UpperLayerOfMap.ActualWidth / 50; | |||||
| try | |||||
| foreach (var obj in listOfButcher) | |||||
| { | { | ||||
| // if (log != null) | |||||
| //{ | |||||
| // string temp = ""; | |||||
| // for (int i = 0; i < dataDict[GameObjType.Character].Count; i++) | |||||
| // { | |||||
| // temp += Convert.ToString(dataDict[GameObjType.Character][i].MessageOfCharacter.TeamID) + "\n"; | |||||
| // } | |||||
| // log.Content = temp; | |||||
| // } | |||||
| UpperLayerOfMap.Children.Clear(); | |||||
| // if ((communicator == null || !communicator.Client.IsConnected) && !isPlaybackMode) | |||||
| //{ | |||||
| // UnderLayerOfMap.Children.Clear(); | |||||
| // throw new Exception("Client is unconnected."); | |||||
| // } | |||||
| // else | |||||
| //{ | |||||
| lock (drawPicLock) // 加锁是必要的,画图操作和接收信息操作不能同时进行 | |||||
| IGhostType occupation1 = (IGhostType)OccupationFactory.FindIOccupation(Transformation.ToTrickerType(obj.TrickerType)); | |||||
| int j = 0; | |||||
| foreach (var skill in occupation1.ListOfIActiveSkill) | |||||
| { | { | ||||
| var iActiveSkill = SkillFactory.FindIActiveSkill(skill); | |||||
| coolTime[j, GameData.numOfStudent] = iActiveSkill.SkillCD; | |||||
| ++j; | |||||
| } | |||||
| } | |||||
| if (StatusBarsOfSurvivor != null) | |||||
| { | |||||
| for (int i = 0; i < GameData.numOfStudent; i++) | |||||
| { | |||||
| StatusBarsOfSurvivor[i].SetFontSize(12 * UpperLayerOfMap.ActualHeight / 650); | |||||
| StatusBarsOfSurvivor[i].NewData(totalLife, totalDeath, coolTime); | |||||
| } | |||||
| } | |||||
| if (StatusBarsOfHunter != null) | |||||
| { | |||||
| StatusBarsOfHunter.SetFontSize(12 * UpperLayerOfMap.ActualHeight / 650); | |||||
| StatusBarsOfHunter.NewData(totalLife, totalDeath, coolTime); | |||||
| } | |||||
| if (StatusBarsOfCircumstance != null) | |||||
| StatusBarsOfCircumstance.SetFontSize(12 * UpperLayerOfMap.ActualHeight / 650); | |||||
| // 完成窗口信息更新 | |||||
| if (!isClientStocked) | |||||
| { | |||||
| unit = Math.Sqrt(UpperLayerOfMap.ActualHeight * UpperLayerOfMap.ActualWidth) / 50; | |||||
| unitHeight = UpperLayerOfMap.ActualHeight / 50; | |||||
| unitWidth = UpperLayerOfMap.ActualWidth / 50; | |||||
| try | |||||
| { | |||||
| // if (log != null) | |||||
| //{ | |||||
| // string temp = ""; | |||||
| // for (int i = 0; i < dataDict[GameObjType.Character].Count; i++) | |||||
| // { | |||||
| // temp += Convert.ToString(dataDict[GameObjType.Character][i].MessageOfCharacter.TeamID) + "\n"; | |||||
| // } | |||||
| // log.Content = temp; | |||||
| // } | |||||
| UpperLayerOfMap.Children.Clear(); | |||||
| // if ((communicator == null || !communicator.Client.IsConnected) && !isPlaybackMode) | |||||
| //{ | |||||
| // UnderLayerOfMap.Children.Clear(); | |||||
| // throw new Exception("Client is unconnected."); | |||||
| // } | |||||
| // else | |||||
| //{ | |||||
| foreach (var data in listOfAll) | foreach (var data in listOfAll) | ||||
| { | { | ||||
| StatusBarsOfCircumstance.SetValue(data, gateOpened, isEmergencyDrawed, isEmergencyOpened, playerID); | StatusBarsOfCircumstance.SetValue(data, gateOpened, isEmergencyDrawed, isEmergencyOpened, playerID); | ||||
| @@ -978,17 +986,18 @@ namespace Client | |||||
| } | } | ||||
| //} | //} | ||||
| ZoomMap(); | ZoomMap(); | ||||
| } | |||||
| catch (Exception exc) | |||||
| { | |||||
| ErrorDisplayer error = new("Error: " + exc.ToString()); | |||||
| error.Show(); | |||||
| isClientStocked = true; | |||||
| PorC.Content = "▶"; | |||||
| } | } | ||||
| } | } | ||||
| catch (Exception exc) | |||||
| { | |||||
| ErrorDisplayer error = new("Error: " + exc.ToString()); | |||||
| error.Show(); | |||||
| isClientStocked = true; | |||||
| PorC.Content = "▶"; | |||||
| } | |||||
| counter++; | |||||
| } | } | ||||
| counter++; | |||||
| } | } | ||||
| // 键盘控制,未完善 | // 键盘控制,未完善 | ||||
| @@ -1210,10 +1219,18 @@ namespace Client | |||||
| isClientStocked = true; | isClientStocked = true; | ||||
| PorC.Content = "▶"; | PorC.Content = "▶"; | ||||
| } | } | ||||
| else | |||||
| else if (!isPlaybackMode) | |||||
| { | { | ||||
| isClientStocked = false; | |||||
| PorC.Content = "⏸"; | |||||
| try | |||||
| { | |||||
| isClientStocked = false; | |||||
| PorC.Content = "⏸"; | |||||
| } | |||||
| catch (Exception ex) | |||||
| { | |||||
| ErrorDisplayer error = new("发生错误。以下是系统报告:\n" + ex.ToString()); | |||||
| error.Show(); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| // 未复现 | // 未复现 | ||||
| @@ -1341,6 +1358,7 @@ namespace Client | |||||
| private List<MessageOfGate> listOfGate; | private List<MessageOfGate> listOfGate; | ||||
| private List<MessageOfHiddenGate> listOfHiddenGate; | private List<MessageOfHiddenGate> listOfHiddenGate; | ||||
| private object drawPicLock = new object(); | private object drawPicLock = new object(); | ||||
| private object recvLock = new object(); | |||||
| private MessageOfStudent? human = null; | private MessageOfStudent? human = null; | ||||
| private MessageOfTricker? butcher = null; | private MessageOfTricker? butcher = null; | ||||
| private bool humanOrButcher;//true for human | private bool humanOrButcher;//true for human | ||||
| @@ -1407,6 +1425,7 @@ namespace Client | |||||
| bool isSpectatorMode = false; | bool isSpectatorMode = false; | ||||
| bool isEmergencyOpened = false; | bool isEmergencyOpened = false; | ||||
| bool isEmergencyDrawed = false; | bool isEmergencyDrawed = false; | ||||
| bool isDataFixed = false; | |||||
| const double radiusTimes = 1.0 * Preparation.Utility.GameData.characterRadius / Preparation.Utility.GameData.numOfPosGridPerCell; | const double radiusTimes = 1.0 * Preparation.Utility.GameData.characterRadius / Preparation.Utility.GameData.numOfPosGridPerCell; | ||||
| private int[] totalLife = new int[4] { 100, 100, 100, 100 }, totalDeath = new int[4] { 100, 100, 100, 100 }; | private int[] totalLife = new int[4] { 100, 100, 100, 100 }, totalDeath = new int[4] { 100, 100, 100, 100 }; | ||||
| private int[,] coolTime = new int[3, 5] { { 100, 100, 100, 100, 100 }, { 100, 100, 100, 100, 100 }, { 100, 100, 100, 100, 100 } }; | private int[,] coolTime = new int[3, 5] { { 100, 100, 100, 100, 100 }, { 100, 100, 100, 100, 100 }, { 100, 100, 100, 100, 100 } }; | ||||
| @@ -7,6 +7,7 @@ using Protobuf; | |||||
| using Playback; | using Playback; | ||||
| using System.Threading; | using System.Threading; | ||||
| using Timothy.FrameRateTask; | using Timothy.FrameRateTask; | ||||
| using System.Windows; | |||||
| namespace Client | namespace Client | ||||
| { | { | ||||
| @@ -79,183 +80,194 @@ namespace Client | |||||
| } | } | ||||
| } | } | ||||
| }; | }; | ||||
| new Thread(() => | new Thread(() => | ||||
| { | { | ||||
| new FrameRateTaskExecutor<int> | |||||
| ( | |||||
| () => !endFile, | |||||
| () => | |||||
| { | |||||
| var content = Reader.ReadOne(); | |||||
| if (content == null) | |||||
| endFile = true; | |||||
| else | |||||
| int i = 0; | |||||
| try | |||||
| { | |||||
| new FrameRateTaskExecutor<int> | |||||
| ( | |||||
| () => !endFile, | |||||
| () => | |||||
| { | { | ||||
| lock (dataLock) | |||||
| var content = Reader.ReadOne(); | |||||
| i++; | |||||
| if (content == null) | |||||
| { | |||||
| MessageBox.Show($"End! {i}"); | |||||
| endFile = true; | |||||
| } | |||||
| else | |||||
| { | { | ||||
| listOfHuman.Clear(); | |||||
| listOfButcher.Clear(); | |||||
| listOfProp.Clear(); | |||||
| listOfBombedBullet.Clear(); | |||||
| listOfBullet.Clear(); | |||||
| listOfAll.Clear(); | |||||
| listOfChest.Clear(); | |||||
| listOfClassroom.Clear(); | |||||
| listOfDoor.Clear(); | |||||
| listOfHiddenGate.Clear(); | |||||
| listOfGate.Clear(); | |||||
| switch (content.GameState) | |||||
| lock (dataLock) | |||||
| { | { | ||||
| case GameState.GameStart: | |||||
| foreach (var obj in content.ObjMessage) | |||||
| { | |||||
| switch (obj.MessageOfObjCase) | |||||
| listOfHuman.Clear(); | |||||
| listOfButcher.Clear(); | |||||
| listOfProp.Clear(); | |||||
| listOfBombedBullet.Clear(); | |||||
| listOfBullet.Clear(); | |||||
| listOfAll.Clear(); | |||||
| listOfChest.Clear(); | |||||
| listOfClassroom.Clear(); | |||||
| listOfDoor.Clear(); | |||||
| listOfHiddenGate.Clear(); | |||||
| listOfGate.Clear(); | |||||
| switch (content.GameState) | |||||
| { | |||||
| case GameState.GameStart: | |||||
| foreach (var obj in content.ObjMessage) | |||||
| { | { | ||||
| case MessageOfObj.MessageOfObjOneofCase.StudentMessage: | |||||
| //if (humanOrButcher && obj.StudentMessage.PlayerId == playerID) | |||||
| //{ | |||||
| // human = obj.StudentMessage; | |||||
| //} | |||||
| listOfHuman.Add(obj.StudentMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.TrickerMessage: | |||||
| //if (!humanOrButcher && obj.TrickerMessage.PlayerId == playerID) | |||||
| //{ | |||||
| // butcher = obj.TrickerMessage; | |||||
| //} | |||||
| listOfButcher.Add(obj.TrickerMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.PropMessage: | |||||
| listOfProp.Add(obj.PropMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.BombedBulletMessage: | |||||
| listOfBombedBullet.Add(obj.BombedBulletMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.BulletMessage: | |||||
| listOfBullet.Add(obj.BulletMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.ChestMessage: | |||||
| listOfChest.Add(obj.ChestMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.ClassroomMessage: | |||||
| listOfClassroom.Add(obj.ClassroomMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.DoorMessage: | |||||
| listOfDoor.Add(obj.DoorMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.GateMessage: | |||||
| listOfGate.Add(obj.GateMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.HiddenGateMessage: | |||||
| listOfHiddenGate.Add(obj.HiddenGateMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.MapMessage: | |||||
| break; | |||||
| switch (obj.MessageOfObjCase) | |||||
| { | |||||
| case MessageOfObj.MessageOfObjOneofCase.StudentMessage: | |||||
| //if (humanOrButcher && obj.StudentMessage.PlayerId == playerID) | |||||
| //{ | |||||
| // human = obj.StudentMessage; | |||||
| //} | |||||
| listOfHuman.Add(obj.StudentMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.TrickerMessage: | |||||
| //if (!humanOrButcher && obj.TrickerMessage.PlayerId == playerID) | |||||
| //{ | |||||
| // butcher = obj.TrickerMessage; | |||||
| //} | |||||
| listOfButcher.Add(obj.TrickerMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.PropMessage: | |||||
| listOfProp.Add(obj.PropMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.BombedBulletMessage: | |||||
| listOfBombedBullet.Add(obj.BombedBulletMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.BulletMessage: | |||||
| listOfBullet.Add(obj.BulletMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.ChestMessage: | |||||
| listOfChest.Add(obj.ChestMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.ClassroomMessage: | |||||
| listOfClassroom.Add(obj.ClassroomMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.DoorMessage: | |||||
| listOfDoor.Add(obj.DoorMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.GateMessage: | |||||
| listOfGate.Add(obj.GateMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.HiddenGateMessage: | |||||
| listOfHiddenGate.Add(obj.HiddenGateMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.MapMessage: | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | |||||
| listOfAll.Add(content.AllMessage); | |||||
| break; | |||||
| case GameState.GameRunning: | |||||
| foreach (var obj in content.ObjMessage) | |||||
| { | |||||
| switch (obj.MessageOfObjCase) | |||||
| listOfAll.Add(content.AllMessage); | |||||
| break; | |||||
| case GameState.GameRunning: | |||||
| foreach (var obj in content.ObjMessage) | |||||
| { | { | ||||
| case MessageOfObj.MessageOfObjOneofCase.StudentMessage: | |||||
| //if (humanOrButcher && obj.StudentMessage.PlayerId == playerID) | |||||
| //{ | |||||
| // human = obj.StudentMessage; | |||||
| //} | |||||
| listOfHuman.Add(obj.StudentMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.TrickerMessage: | |||||
| //if (!humanOrButcher && obj.TrickerMessage.PlayerId == playerID) | |||||
| //{ | |||||
| // butcher = obj.TrickerMessage; | |||||
| //} | |||||
| listOfButcher.Add(obj.TrickerMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.PropMessage: | |||||
| listOfProp.Add(obj.PropMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.BombedBulletMessage: | |||||
| listOfBombedBullet.Add(obj.BombedBulletMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.BulletMessage: | |||||
| listOfBullet.Add(obj.BulletMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.ChestMessage: | |||||
| listOfChest.Add(obj.ChestMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.ClassroomMessage: | |||||
| listOfClassroom.Add(obj.ClassroomMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.DoorMessage: | |||||
| listOfDoor.Add(obj.DoorMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.HiddenGateMessage: | |||||
| listOfHiddenGate.Add(obj.HiddenGateMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.GateMessage: | |||||
| listOfGate.Add(obj.GateMessage); | |||||
| break; | |||||
| switch (obj.MessageOfObjCase) | |||||
| { | |||||
| case MessageOfObj.MessageOfObjOneofCase.StudentMessage: | |||||
| //if (humanOrButcher && obj.StudentMessage.PlayerId == playerID) | |||||
| //{ | |||||
| // human = obj.StudentMessage; | |||||
| //} | |||||
| listOfHuman.Add(obj.StudentMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.TrickerMessage: | |||||
| //if (!humanOrButcher && obj.TrickerMessage.PlayerId == playerID) | |||||
| //{ | |||||
| // butcher = obj.TrickerMessage; | |||||
| //} | |||||
| listOfButcher.Add(obj.TrickerMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.PropMessage: | |||||
| listOfProp.Add(obj.PropMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.BombedBulletMessage: | |||||
| listOfBombedBullet.Add(obj.BombedBulletMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.BulletMessage: | |||||
| listOfBullet.Add(obj.BulletMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.ChestMessage: | |||||
| listOfChest.Add(obj.ChestMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.ClassroomMessage: | |||||
| listOfClassroom.Add(obj.ClassroomMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.DoorMessage: | |||||
| listOfDoor.Add(obj.DoorMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.HiddenGateMessage: | |||||
| listOfHiddenGate.Add(obj.HiddenGateMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.GateMessage: | |||||
| listOfGate.Add(obj.GateMessage); | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | |||||
| listOfAll.Add(content.AllMessage); | |||||
| break; | |||||
| listOfAll.Add(content.AllMessage); | |||||
| break; | |||||
| case GameState.GameEnd: | |||||
| foreach (var obj in content.ObjMessage) | |||||
| { | |||||
| switch (obj.MessageOfObjCase) | |||||
| case GameState.GameEnd: | |||||
| MessageBox.Show("Game Over!"); | |||||
| foreach (var obj in content.ObjMessage) | |||||
| { | { | ||||
| case MessageOfObj.MessageOfObjOneofCase.StudentMessage: | |||||
| listOfHuman.Add(obj.StudentMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.TrickerMessage: | |||||
| listOfButcher.Add(obj.TrickerMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.PropMessage: | |||||
| listOfProp.Add(obj.PropMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.BombedBulletMessage: | |||||
| listOfBombedBullet.Add(obj.BombedBulletMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.BulletMessage: | |||||
| listOfBullet.Add(obj.BulletMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.ChestMessage: | |||||
| listOfChest.Add(obj.ChestMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.ClassroomMessage: | |||||
| listOfClassroom.Add(obj.ClassroomMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.DoorMessage: | |||||
| listOfDoor.Add(obj.DoorMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.HiddenGateMessage: | |||||
| listOfHiddenGate.Add(obj.HiddenGateMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.GateMessage: | |||||
| listOfGate.Add(obj.GateMessage); | |||||
| break; | |||||
| switch (obj.MessageOfObjCase) | |||||
| { | |||||
| case MessageOfObj.MessageOfObjOneofCase.StudentMessage: | |||||
| listOfHuman.Add(obj.StudentMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.TrickerMessage: | |||||
| listOfButcher.Add(obj.TrickerMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.PropMessage: | |||||
| listOfProp.Add(obj.PropMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.BombedBulletMessage: | |||||
| listOfBombedBullet.Add(obj.BombedBulletMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.BulletMessage: | |||||
| listOfBullet.Add(obj.BulletMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.ChestMessage: | |||||
| listOfChest.Add(obj.ChestMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.ClassroomMessage: | |||||
| listOfClassroom.Add(obj.ClassroomMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.DoorMessage: | |||||
| listOfDoor.Add(obj.DoorMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.HiddenGateMessage: | |||||
| listOfHiddenGate.Add(obj.HiddenGateMessage); | |||||
| break; | |||||
| case MessageOfObj.MessageOfObjOneofCase.GateMessage: | |||||
| listOfGate.Add(obj.GateMessage); | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | |||||
| listOfAll.Add(content.AllMessage); | |||||
| break; | |||||
| listOfAll.Add(content.AllMessage); | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | |||||
| }, | |||||
| frame, | |||||
| () => | |||||
| }, | |||||
| frame, | |||||
| () => | |||||
| { | |||||
| Sema.Release(); | |||||
| return 1; | |||||
| } | |||||
| ) | |||||
| { AllowTimeExceed = true }.Start(); | |||||
| } | |||||
| catch (Exception ex) | |||||
| { | { | ||||
| Sema.Release(); | |||||
| //MessageBox.Show("Game Over!"); | |||||
| return 1; | |||||
| MessageBox.Show(ex.Message); | |||||
| } | } | ||||
| ) | |||||
| { AllowTimeExceed = true }.Start(); | |||||
| }) | }) | ||||
| { IsBackground = true }.Start(); | { IsBackground = true }.Start(); | ||||
| return map; | return map; | ||||
| @@ -2,7 +2,7 @@ | |||||
| "profiles": { | "profiles": { | ||||
| "Client": { | "Client": { | ||||
| "commandName": "Project", | "commandName": "Project", | ||||
| "commandLineArgs": "--ip 127.0.0.1 --cl --port 8888 --characterID 4 --type 2 --occupation 2" | |||||
| "commandLineArgs": "--cl --playbackFile D:\\2_autumn\\thuai6\\THUAI6\\logic\\cmd\\test.thuaipb --playbackSpeed 2 " | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -31,10 +31,13 @@ namespace Client | |||||
| } | } | ||||
| public void SetFontSize(double fontsize) | public void SetFontSize(double fontsize) | ||||
| { | { | ||||
| status.FontSize = 13 * fontsize / 12; | |||||
| time.FontSize = 14 * fontsize / 12; | |||||
| name.FontSize = 14 * fontsize / 12; | |||||
| scoresOfStudents.FontSize = scoresOfTrickers.FontSize = fontsize; | |||||
| if (fontsize != 0) | |||||
| { | |||||
| status.FontSize = 13 * fontsize / 12; | |||||
| time.FontSize = 14 * fontsize / 12; | |||||
| name.FontSize = 14 * fontsize / 12; | |||||
| scoresOfStudents.FontSize = scoresOfTrickers.FontSize = fontsize; | |||||
| } | |||||
| } | } | ||||
| public void SetValue(MessageOfAll obj, bool gateOpened, bool hiddenGateRefreshed, bool hiddenGateOpened, long playerId) | public void SetValue(MessageOfAll obj, bool gateOpened, bool hiddenGateRefreshed, bool hiddenGateOpened, long playerId) | ||||
| @@ -32,7 +32,8 @@ namespace Client | |||||
| } | } | ||||
| public void SetFontSize(double fontsize) | public void SetFontSize(double fontsize) | ||||
| { | { | ||||
| serial.FontSize = scores.FontSize = state.FontSize = status.FontSize = activeSkill0.FontSize = activeSkill1.FontSize = activeSkill2.FontSize = prop0.FontSize = prop1.FontSize = prop2.FontSize = fontsize; | |||||
| if (fontsize != 0) | |||||
| serial.FontSize = scores.FontSize = state.FontSize = status.FontSize = activeSkill0.FontSize = activeSkill1.FontSize = activeSkill2.FontSize = prop0.FontSize = prop1.FontSize = prop2.FontSize = fontsize; | |||||
| } | } | ||||
| private void SetStaticValue(MessageOfTricker obj) | private void SetStaticValue(MessageOfTricker obj) | ||||
| @@ -31,7 +31,8 @@ namespace Client | |||||
| } | } | ||||
| public void SetFontSize(double fontsize) | public void SetFontSize(double fontsize) | ||||
| { | { | ||||
| serial.FontSize = scores.FontSize = status.FontSize = activeSkill0.FontSize = activeSkill1.FontSize = activeSkill2.FontSize = prop0.FontSize = prop1.FontSize = prop2.FontSize = fontsize; | |||||
| if (fontsize != 0) | |||||
| serial.FontSize = scores.FontSize = status.FontSize = activeSkill0.FontSize = activeSkill1.FontSize = activeSkill2.FontSize = prop0.FontSize = prop1.FontSize = prop2.FontSize = fontsize; | |||||
| } | } | ||||
| private void SetStaticValue(MessageOfStudent obj) | private void SetStaticValue(MessageOfStudent obj) | ||||
| { | { | ||||
| @@ -130,7 +130,7 @@ namespace Server | |||||
| case GameState.GameRunning: | case GameState.GameRunning: | ||||
| case GameState.GameEnd: | case GameState.GameEnd: | ||||
| case GameState.GameStart: | case GameState.GameStart: | ||||
| currentGameInfo.ObjMessage.Add(currentMapMsg); | |||||
| if (gameState == GameState.GameStart) currentGameInfo.ObjMessage.Add(currentMapMsg); | |||||
| foreach (GameObj gameObj in gameObjList) | foreach (GameObj gameObj in gameObjList) | ||||
| { | { | ||||
| MessageOfObj? msg = CopyInfo.Auto(gameObj); | MessageOfObj? msg = CopyInfo.Auto(gameObj); | ||||
| @@ -153,7 +153,6 @@ namespace Server | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| foreach (var kvp in semaDict) | foreach (var kvp in semaDict) | ||||
| { | { | ||||
| kvp.Value.Item1.Release(); | kvp.Value.Item1.Release(); | ||||
| @@ -1,6 +1,6 @@ | |||||
| @echo off | @echo off | ||||
| start cmd /k ..\Server\bin\Debug\net6.0\Server.exe --ip 0.0.0.0 --port 8888 --studentCount 4 --trickerCount 1 --gameTimeInSecond 600 --fileName test | |||||
| start cmd /k ..\Server\bin\Debug\net6.0\Server.exe --ip 0.0.0.0 --port 8888 --studentCount 4 --trickerCount 1 --gameTimeInSecond 60 --fileName test | |||||
| ping -n 2 127.0.0.1 > NUL | ping -n 2 127.0.0.1 > NUL | ||||
| @@ -12,4 +12,6 @@ start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --cl --port 8888 --ch | |||||
| start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --cl --port 8888 --characterID 2 --type 1 --occupation 3 | start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --cl --port 8888 --characterID 2 --type 1 --occupation 3 | ||||
| start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --cl --port 8888 --characterID 3 --type 1 --occupation 3 | |||||
| start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --cl --port 8888 --characterID 3 --type 1 --occupation 3 | |||||
| ::start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --ip 0.0.0.0 --port 8888 --characterID 2030 | |||||
| @@ -1,5 +1,5 @@ | |||||
| @echo off | @echo off | ||||
| start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --cl --playbackFile .\test.thuaipb --playbackSpeed 3 | |||||
| start cmd /k ..\Client\bin\Debug\net6.0-windows\Client.exe --cl --playbackFile .\test.thuaipb --playbackSpeed 1 | |||||
| ping -n 2 127.0.0.1 > NUL | ping -n 2 127.0.0.1 > NUL | ||||
| @@ -27,7 +27,7 @@ namespace Playback | |||||
| public readonly uint teamCount; | public readonly uint teamCount; | ||||
| public readonly uint playerCount; | public readonly uint playerCount; | ||||
| const int bufferMaxSize = 1024 * 1024; // 1M | |||||
| const int bufferMaxSize = 10 * 1024 * 1024; // 10M | |||||
| public MessageReader(string fileName) | public MessageReader(string fileName) | ||||
| { | { | ||||
| @@ -83,7 +83,8 @@ namespace Playback | |||||
| public MessageToClient? ReadOne() | public MessageToClient? ReadOne() | ||||
| { | { | ||||
| beginRead: | beginRead: | ||||
| if (Finished) return null; | |||||
| if (Finished) | |||||
| return null; | |||||
| var pos = cos.Position; | var pos = cos.Position; | ||||
| try | try | ||||
| { | { | ||||
| @@ -94,9 +95,21 @@ namespace Playback | |||||
| catch (InvalidProtocolBufferException) | catch (InvalidProtocolBufferException) | ||||
| { | { | ||||
| var leftByte = buffer.Length - pos; // 上次读取剩余的字节 | var leftByte = buffer.Length - pos; // 上次读取剩余的字节 | ||||
| for (int i = 0; i < leftByte; ++i) | |||||
| if (buffer.Length < bufferMaxSize / 2) | |||||
| { | { | ||||
| buffer[i] = buffer[pos + i]; | |||||
| var newBuffer = new byte[bufferMaxSize]; | |||||
| for (int i = 0; i < leftByte; i++) | |||||
| { | |||||
| newBuffer[i] = buffer[pos + i]; | |||||
| } | |||||
| buffer = newBuffer; | |||||
| } | |||||
| else | |||||
| { | |||||
| for (int i = 0; i < leftByte; ++i) | |||||
| { | |||||
| buffer[i] = buffer[pos + i]; | |||||
| } | |||||
| } | } | ||||
| var bufferSize = gzs.Read(buffer, (int)leftByte, (int)(buffer.Length - leftByte)) + leftByte; | var bufferSize = gzs.Read(buffer, (int)leftByte, (int)(buffer.Length - leftByte)) + leftByte; | ||||
| if (bufferSize == leftByte) | if (bufferSize == leftByte) | ||||
| @@ -12,7 +12,7 @@ namespace Playback | |||||
| private CodedOutputStream cos; | private CodedOutputStream cos; | ||||
| private MemoryStream ms; | private MemoryStream ms; | ||||
| private GZipStream gzs; | private GZipStream gzs; | ||||
| private const int memoryCapacity = 1024 * 1024; // 1M | |||||
| private const int memoryCapacity = 10 * 1024 * 1024; // 10M | |||||
| private static void ClearMemoryStream(MemoryStream msToClear) | private static void ClearMemoryStream(MemoryStream msToClear) | ||||
| { | { | ||||