Merge branch 'develop' into feature/elseplayer

# Conflicts:
#	Assets/NetworkLib/Debug/netstandard2.1/CSNetwork.dll
#	Assets/Scripts/CECHostPlayer.cs
#	Assets/Scripts/GameController.cs
This commit is contained in:
tung.do@monkey.edu.vn
2025-09-14 01:15:24 +07:00
22 changed files with 766 additions and 107 deletions
+1
View File
@@ -97,3 +97,4 @@ InitTestScene*.unity*
# Auto-generated scenes by play mode tests
/[Aa]ssets/[Ii]nit[Tt]est[Ss]cene*.unity*
ProjectSettings/EditorBuildSettings.asset
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RiderProjectSettingsUpdater">
<option name="singleClickDiffPreview" value="1" />
<option name="unhandledExceptionsIgnoreList" value="1" />
<option name="vcsConfiguration" value="3" />
</component>
</project>
+142
View File
@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="49831fc9-7cbb-46fb-90e9-7754de73bafb" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/ProjectSettings/EditorBuildSettings.asset" beforeDir="false" afterPath="$PROJECT_DIR$/ProjectSettings/EditorBuildSettings.asset" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ProjectSettings/ShaderGraphSettings.asset" beforeDir="false" afterPath="$PROJECT_DIR$/ProjectSettings/ShaderGraphSettings.asset" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="HighlightingSettingsPerFile">
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/47e9cf78f2614f72ae7df046d55ebcf24a400/d6/1d32d257/RoleInfo.cs" root0="FORCE_HIGHLIGHTING" />
</component>
<component name="ProjectColorInfo"><![CDATA[{
"associatedIndex": 4
}]]></component>
<component name="ProjectId" id="32GqMZwPghqrbXiQw3BfBEQJAAE" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ModuleVcsDetector.initialDetectionPerformed": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.git.unshallow": "true",
"git-widget-placeholder": "main",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="RunManager" selected="Attach to Unity Editor.Attach to Unity Editor">
<configuration name="Start Unity" type="RunUnityExe" factoryName="Unity Executable">
<option name="EXE_PATH" value="C:\Program Files\Unity\Hub\Editor\6000.0.56f1\Editor\Unity.exe" />
<option name="PROGRAM_PARAMETERS" value="-projectPath E:\PerfectWorld\perfect-world-unity -debugCodeOptimization" />
<option name="WORKING_DIRECTORY" value="E:\PerfectWorld\perfect-world-unity" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="ENV_FILE_PATHS" value="" />
<option name="REDIRECT_INPUT_PATH" value="" />
<option name="PTY_MODE" value="Auto" />
<option name="MIXED_MODE_DEBUG" value="0" />
<method v="2" />
</configuration>
<configuration name="Unit Tests (batch mode)" type="RunUnityExe" factoryName="Unity Executable">
<option name="EXE_PATH" value="C:\Program Files\Unity\Hub\Editor\6000.0.56f1\Editor\Unity.exe" />
<option name="PROGRAM_PARAMETERS" value="-runTests -batchmode -projectPath E:\PerfectWorld\perfect-world-unity -testResults Logs/results.xml -logFile Logs/Editor.log -testPlatform EditMode -debugCodeOptimization" />
<option name="WORKING_DIRECTORY" value="E:\PerfectWorld\perfect-world-unity" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="ENV_FILE_PATHS" value="" />
<option name="REDIRECT_INPUT_PATH" value="" />
<option name="PTY_MODE" value="Auto" />
<option name="MIXED_MODE_DEBUG" value="0" />
<method v="2" />
</configuration>
<configuration name="Attach to Unity Editor &amp; Play" type="UNITY_DEBUG_RUN_CONFIGURATION" factoryName="UNITY_ATTACH_AND_PLAY" show_console_on_std_err="false" show_console_on_std_out="false" port="50000" address="localhost">
<option name="allowRunningInParallel" value="false" />
<option name="listenPortForConnections" value="false" />
<option name="pid" />
<option name="projectPathOnTarget" />
<option name="runtimes">
<list />
</option>
<option name="selectedOptions">
<list />
</option>
<option name="useMixedMode" value="false" />
<method v="2" />
</configuration>
<configuration name="Attach to Unity Editor" type="UNITY_DEBUG_RUN_CONFIGURATION" factoryName="Unity Debug" show_console_on_std_err="false" show_console_on_std_out="false" port="50000" address="localhost">
<option name="allowRunningInParallel" value="false" />
<option name="listenPortForConnections" value="false" />
<option name="pid" />
<option name="projectPathOnTarget" />
<option name="runtimes">
<list />
</option>
<option name="selectedOptions">
<list />
</option>
<option name="useMixedMode" value="false" />
<method v="2" />
</configuration>
<configuration name="Attach to Device" type="UnityDevicePlayer" factoryName="UnityAttachToDevicePlayer">
<method v="2" />
</configuration>
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="49831fc9-7cbb-46fb-90e9-7754de73bafb" name="Changes" comment="" />
<created>1757057210233</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1757057210233</updated>
<workItem from="1757057212282" duration="5649000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="UnityProjectConfiguration" hasMinimizedUI="true" />
<component name="UnityProjectDiscoverer">
<option name="hasUnityReference" value="true" />
<option name="unityProject" value="true" />
<option name="unityProjectFolder" value="true" />
</component>
<component name="VcsManagerConfiguration">
<option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<breakpoint enabled="true" type="DotNet_Exception_Breakpoints">
<properties exception="System.OperationCanceledException" breakIfHandledByOtherCode="false" displayValue="System.OperationCanceledException" />
<option name="timeStamp" value="1" />
</breakpoint>
<breakpoint enabled="true" type="DotNet_Exception_Breakpoints">
<properties exception="System.Threading.Tasks.TaskCanceledException" breakIfHandledByOtherCode="false" displayValue="System.Threading.Tasks.TaskCanceledException" />
<option name="timeStamp" value="2" />
</breakpoint>
<breakpoint enabled="true" type="DotNet_Exception_Breakpoints">
<properties exception="System.Threading.ThreadAbortException" breakIfHandledByOtherCode="false" displayValue="System.Threading.ThreadAbortException" />
<option name="timeStamp" value="3" />
</breakpoint>
</breakpoints>
</breakpoint-manager>
</component>
</project>
+160
View File
@@ -0,0 +1,160 @@
// Assets/Editor/EditorLogTools.cs
#if UNITY_EDITOR
using System;
using System.IO;
using UnityEditor;
using UnityEngine;
public static class EditorLogTools
{
// ===== Public Menu =====
[MenuItem("Tools/Logs/Clear Editor.log")]
public static void ClearEditorLogMenu()
{
string path = GetEditorLogPath();
if (string.IsNullOrEmpty(path))
{
EditorUtility.DisplayDialog("Editor.log", "Không xác định được đường dẫn Editor.log trên hệ điều hành này.", "OK");
return;
}
if (!File.Exists(path))
{
EditorUtility.DisplayDialog("Editor.log", $"Không tìm thấy file:\n{path}", "OK");
return;
}
try
{
TruncateFile(path);
EditorUtility.DisplayDialog("Editor.log", "Đã xoá sạch nội dung Editor.log ✅", "OK");
}
catch (Exception e)
{
Debug.LogError($"[EditorLogTools] Clear failed: {e}");
EditorUtility.DisplayDialog("Editor.log", "Xoá thất bại. Xem Console để biết chi tiết.", "OK");
}
}
[MenuItem("Tools/Logs/Trim Editor.log…")]
public static void TrimEditorLogMenu()
{
string input = EditorUtility.DisplayDialogComplex("Trim Editor.log",
"Chọn kích thước còn lại của Editor.log sau khi cắt:",
"Giữ 256 KB", "Giữ 1 MB", "Tự nhập (KB)") switch
{
0 => "256",
1 => "1024",
_ => EditorUtility.DisplayDialog("Nhập dung lượng", "Nhập số KB muốn giữ lại (ví dụ 512):", "OK")
? "512" // fallback, Unity không có input prompt chuẩn; giữ default
: null
};
if (string.IsNullOrEmpty(input)) return;
if (!int.TryParse(input, out int keepKb) || keepKb < 1) keepKb = 512;
string path = GetEditorLogPath();
if (!File.Exists(path))
{
EditorUtility.DisplayDialog("Editor.log", $"Không tìm thấy file:\n{path}", "OK");
return;
}
try
{
TrimTail(path, keepKb * 1024);
EditorUtility.DisplayDialog("Editor.log", $"Đã cắt Editor.log, giữ lại ~{keepKb} KB cuối cùng ✅", "OK");
}
catch (Exception e)
{
Debug.LogError($"[EditorLogTools] Trim failed: {e}");
EditorUtility.DisplayDialog("Editor.log", "Trim thất bại. Xem Console để biết chi tiết.", "OK");
}
}
[MenuItem("Tools/Logs/Open Editor.log")]
public static void OpenEditorLogMenu()
{
string path = GetEditorLogPath();
if (File.Exists(path))
EditorUtility.OpenWithDefaultApp(path);
else
EditorUtility.DisplayDialog("Editor.log", $"Không tìm thấy file:\n{path}", "OK");
}
[MenuItem("Tools/Logs/Reveal log folder")]
public static void RevealLogFolder()
{
string path = GetEditorLogPath();
string dir = string.IsNullOrEmpty(path) ? null : Path.GetDirectoryName(path);
if (!string.IsNullOrEmpty(dir) && Directory.Exists(dir))
EditorUtility.RevealInFinder(dir);
else
EditorUtility.DisplayDialog("Editor.log", "Không mở được thư mục log.", "OK");
}
// ===== Core =====
private static void TruncateFile(string path)
{
// Cho phép Editor tiếp tục ghi khi ta truncate (FileShare.ReadWrite)
using var fs = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite);
fs.SetLength(0);
fs.Flush(true);
}
private static void TrimTail(string path, int keepBytes)
{
var fi = new FileInfo(path);
long size = fi.Length;
if (size <= keepBytes)
return; // không cần cắt
// đọc phần đuôi rồi ghi đè lại
byte[] buffer;
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
fs.Seek(size - keepBytes, SeekOrigin.Begin);
buffer = new byte[keepBytes];
int read = fs.Read(buffer, 0, keepBytes);
if (read < keepBytes)
{
Array.Resize(ref buffer, read);
}
}
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite))
{
fs.SetLength(0);
fs.Write(buffer, 0, buffer.Length);
fs.Flush(true);
}
}
// ===== OS Paths =====
private static string GetEditorLogPath()
{
// Tham chiếu đường dẫn theo Unity docs
switch (Application.platform)
{
case RuntimePlatform.WindowsEditor:
// C:\Users\<user>\AppData\Local\Unity\Editor\Editor.log
string localApp = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
return Path.Combine(localApp, "Unity", "Editor", "Editor.log");
case RuntimePlatform.OSXEditor:
// ~/Library/Logs/Unity/Editor.log
string home = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
return Path.Combine(home, "Library", "Logs", "Unity", "Editor.log");
case RuntimePlatform.LinuxEditor:
// ~/.config/unity3d/Editor.log (đường dẫn phổ biến cho Editor)
string homeLinux = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
return Path.Combine(homeLinux, ".config", "unity3d", "Editor.log");
default:
return null;
}
}
}
#endif
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b640a9ed9ecce724cb2cd5891d01b4ff
@@ -1,10 +1,13 @@
using System.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class Joystick : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
public event Action OnPointUp;
public float Horizontal { get { return (snapX) ? SnapFloat(input.x, AxisOptions.Horizontal) : input.x; } }
public float Vertical { get { return (snapY) ? SnapFloat(input.y, AxisOptions.Vertical) : input.y; } }
public Vector2 Direction { get { return new Vector2(Horizontal, Vertical); } }
@@ -133,6 +136,8 @@ public class Joystick : MonoBehaviour, IPointerDownHandler, IDragHandler, IPoint
{
input = Vector2.zero;
handle.anchoredPosition = Vector2.zero;
OnPointUp?.Invoke();
}
protected Vector2 ScreenPointToAnchoredPosition(Vector2 screenPosition)
Binary file not shown.
@@ -0,0 +1,40 @@
using BrewMonster;
using CSNetwork;
using CSNetwork.GPDataType;
using System;
using System.Runtime.InteropServices;
using UnityEngine;
namespace PerfectWorld.Scripts.Managers
{
namespace BrewMonster.Managers
{
public class EC_HostPlayer : IMsgHandler
{
public int HandlerId => (int)MANAGER_INDEX.MAN_PLAYER;
public bool ProcessMessage(ECMSG Msg)
{
switch ((int)Msg.dwMsg)
{
case int value when value == EC_MsgDef.MSG_HST_IVTRINFO:
{
OnMsgHstIvtrInfo(Msg);
break;
}
}
return true;
}
public void OnMsgHstIvtrInfo(ECMSG Msg)
{
switch (Convert.ToInt32(Msg.dwParam2))
{
case CommandID.OWN_IVTR_DATA:
{
Debug.Log("Chay OWN_IVTR_DATA");
break;
}
}
}
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: eece34ce0cfd6bc409982ce9b90b263b
@@ -29,6 +29,7 @@ namespace PerfectWorld.Scripts.Managers
if (Msg.iSubID == 0)
{
Debug.LogWarning("HoangDev : EC_ManPlayerEC_ManPlayerEC_ManPlayer");
if (GameController.Instance == null) return true;
GameController.Instance.GetHostPlayer().ProcessMessage(Msg);
}
else if (Msg.iSubID < 0)
@@ -37,6 +38,7 @@ namespace PerfectWorld.Scripts.Managers
{
case int value when value == EC_MsgDef.MSG_PM_PLAYERINFO:
{
Debug.Log(" EC_MsgDef.MSG_PM_PLAYERINFO");
OnMsgPlayerInfo(Msg);
break;
}
@@ -88,6 +90,7 @@ namespace PerfectWorld.Scripts.Managers
break;
}
case CommandID.SELF_INFO_1:
Debug.Log("SELF_INFO_1");
cmd_self_info_1 info = GPDataTypeHelper.FromBytes<cmd_self_info_1>((byte[])Msg.dwParam1);
HostPlayerInfo1(info);
break;
@@ -223,9 +226,9 @@ namespace PerfectWorld.Scripts.Managers
public bool HostPlayerInfo1(cmd_self_info_1 info)
{
Debug.Log("HostPlayerInfo1");
bool isDoneWorldRender = false;
bool isDoneNPCRender = false;
Debug.Log("HostPlayerInfo1HostPlayerInfo1");
Action actLoadChar = () =>
{
if (!isDoneNPCRender || !isDoneWorldRender)
@@ -70,7 +70,17 @@ namespace BrewMonster.Network
Instance._gameSession.LoginAsync(username, password, onLoginComplete);
}
public void c2s_SendCmdStopMove(in Vector3 vDest, float fSpeed, int iMoveMode,
byte byDir, ushort wStamp, int iTime)
{
Debug.LogWarning("HoangDev : c2s_SendCmdStopMove");
Instance._gameSession.c2s_SendCmdStopMove(EC_Utility.ToNumerics( vDest),fSpeed,iMoveMode,byDir,wStamp,iTime);
}
public void c2s_CmdPlayerMove(in Vector3 vCurPos, in Vector3 vDest,
int iTime, float fSpeed, int iMoveMode, ushort wStamp)
{
Instance._gameSession.c2s_CmdPlayerMove(EC_Utility.ToNumerics(vCurPos),EC_Utility.ToNumerics( vDest),iTime,fSpeed,iMoveMode,wStamp);
}
protected override void Initialize()
{
BaseSecurity.Initizalize();
@@ -102,6 +112,16 @@ namespace BrewMonster.Network
{
Instance._gameSession.SelectRoleAsync(roleInfo, callback);
}
public static void EnterWorldAsync(RoleInfo roleInfo, Action callback = null)
{
Debug.Log("EnterWorldAsync !!!!! nay ");
Instance._gameSession.EnterWorldAsync(roleInfo, callback);
}
public static void RequestInventoryAsync(Action callback = null)
{
Instance._gameSession.RequestInventoryAsync(callback);
}
public void LoadScene(string sceneName, LoadSceneMode mode, Action<bool> actDone)
{
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using BrewMonster.Network;
using CSNetwork.Protocols;
using CSNetwork.Protocols.RPCData;
@@ -82,8 +83,6 @@ namespace BrewMonster.UI
private void OnSelectRoleComplete(RoleInfo roleInfo)
{
Logger.Log($"OnSelectRoleComplete {roleInfo.name} - {roleInfo.roleid}");
// now we have to enter the world
UnityGameSession.SendProtocol(
new enterworld()
@@ -97,8 +96,24 @@ namespace BrewMonster.UI
Timeout = 0
}
);
/* Debug.Log("OnSelectRoleComplete");
UnityGameSession.EnterWorldAsync(roleInfo, OnEnterWorldComplete);*/
}
private async void OnEnterWorldComplete()
{
Debug.Log("OnEnterWorldDelay");
await Task.Delay(2000);
Logger.Log("Entered world successfully.");
UnityGameSession.RequestInventoryAsync(() => { Logger.Log("Sent Inventory Detail Request"); });
}
//private void OnInventoryReceived(List<InventoryItem> inventoryData)
//{
// _inventoryUI.DisplayInventory(inventoryData);
//}
#if UNITY_EDITOR
private void OnValidate()
{
+143 -22
View File
@@ -1,7 +1,6 @@
using BrewMonster.Network;
using CSNetwork;
using CSNetwork.GPDataType;
using CSNetwork.C2SCommand;
using CSNetwork.Protocols;
using CSNetwork.Protocols.RPCData;
using System;
@@ -13,8 +12,10 @@ using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Scene = UnityEngine.SceneManagement.Scene;
using System.Runtime.InteropServices;
using static UnityEngine.InputManagerEntry;
using Unity.VisualScripting;
using PerfectWorld.Scripts.Managers;
using System.Collections;
public class CECHostPlayer : MonoBehaviour
{
@@ -26,8 +27,9 @@ public class CECHostPlayer : MonoBehaviour
[SerializeField] private Button btnRun;
[SerializeField] private Transform parentModel;
PlayerStateMachine playerStateMachine;
PlayerMoveState moveState;
PlayerStateMachine _playerStateMachine;
PlayerMoveState _moveState;
PlayerIdleState _idleState;
CECHostMove m_MoveCtrl;
float playerSpeed = 5.0f;
@@ -57,8 +59,9 @@ public class CECHostPlayer : MonoBehaviour
private void Awake()
{
moveState = new PlayerMoveState(this);
playerStateMachine = new PlayerStateMachine();
_moveState = new PlayerMoveState(this);
_idleState = new PlayerIdleState(this);
_playerStateMachine = new PlayerStateMachine();
m_MoveCtrl = new CECHostMove(this);
// Cache: không bắt buộc, nhưng gọn tay và ít gọi property lặp.
@@ -69,12 +72,11 @@ public class CECHostPlayer : MonoBehaviour
}
}
public IEnumerator SetModelHostPlayer()
public void SetModelHostPlayer()
{
Scene scene = SceneManager.GetSceneByName("WorldRender");
//SceneManager.MoveGameObjectToScene(gameObject, scene);
yield return new WaitUntil(()=> NPCManager.Instance != null);
modle = NPCManager.Instance.GetModelPlayer();
Scene scene = SceneManager.GetSceneByName("WorldRender");
SceneManager.MoveGameObjectToScene(modle, scene);
modle.transform.SetParent(parentModel);
modle.transform.localPosition = Vector3.zero;
@@ -82,19 +84,23 @@ public class CECHostPlayer : MonoBehaviour
}
private void Start()
{
playerStateMachine.InitState(moveState);
_playerStateMachine.InitState(_moveState);
// btnJump.onClick.AddListener(HandleJump);
}
private void Update()
{
m_MoveCtrl.Tick(Time.deltaTime);
Debug.Log($"(ulong)Time.deltaTime * 1000 {(ulong)(Time.deltaTime * 1000)}");
m_MoveCtrl.Tick((ulong)(Time.deltaTime * 1000));
// Nếu có thay đổi runtime, có thể lấy lại mỗi vài giây/Start nếu bạn thích:
// ccRadius = controller.radius; ccSkin = controller.skinWidth;
playerStateMachine.UpdateState();
_playerStateMachine.UpdateState();
}
public void StopMovement()
{
m_MoveCtrl.SendStopMoveCmd(transform.position, 5f, (int)MoveMode.GP_MOVE_WALK);
}
public void HandleMovement()
{
// 1) Kiểm tra grounded bằng SphereCast ngắn dựa trên radius + skinWidth
@@ -128,9 +134,14 @@ public class CECHostPlayer : MonoBehaviour
transform.forward = move;
Debug.LogWarning("HoangDev :HandleMovement");
m_MoveCtrl.GroundMove(Time.deltaTime);
m_MoveCtrl.SendMoveCmd(transform.position, controller.velocity, (int)MoveMode.GP_MOVE_WALK);
m_MoveCtrl.SendMoveCmd(transform.position, controller.velocity, (int)MoveMode.GP_MOVE_RUN);
}
else
{
//_playerStateMachine.ChangeState(_idleState);
}
if (joystick)
{
}
@@ -138,6 +149,10 @@ public class CECHostPlayer : MonoBehaviour
Vector3 finalMove = (move * playerSpeed) + (playerVelocity.y * Vector3.up);
controller.Move(finalMove * Time.deltaTime);
}
private void JoystickRelease()
{
StopMovement();
}
private bool GroundCheck(out RaycastHit hit)
{
@@ -186,20 +201,125 @@ public class CECHostPlayer : MonoBehaviour
}
public void ProcessMessage(in ECMSG Msg)
{
Debug.LogWarning("HoangDev : ProcessMessageProcessMessageProcessMessage");
switch ((int)Msg.dwMsg)
{
case int value when value == EC_MsgDef.MSG_HST_CORRECTPOS: OnMsgHstCorrectPos(Msg); break;
case int value when value == EC_MsgDef.MSG_HST_GOTO: OnMsgHstGoto(Msg); break;
case int value when value == EC_MsgDef.MSG_HST_IVTRINFO:
{
OnMsgHstIvtrInfo(Msg);
break;
}
}
}
public void OnMsgHstIvtrInfo(ECMSG Msg)
{
var data = Msg.dwParam1 as byte[];
int cmd = Convert.ToInt32(Msg.dwParam2);
int hostId = Convert.ToInt32(Msg.dwParam3);
switch (cmd)
{
case CommandID.OWN_IVTR_DATA:
{
Debug.Log("[Inventory] OWN_IVTR_DATA received");
LogInventoryPacket("OWN_IVTR_DATA", data, hostId);
break;
}
case CommandID.OWN_IVTR_DETAIL_DATA:
{
Debug.Log("[Inventory] OWN_IVTR_DETAIL_DATA received");
LogInventoryPacket("OWN_IVTR_DETAIL_DATA", data, hostId);
break;
}
case CommandID.GET_OWN_MONEY:
{
Debug.Log("[Inventory] GET_OWN_MONEY received");
LogInventoryRaw("GET_OWN_MONEY", data);
break;
}
case CommandID.CHANGE_IVTR_SIZE:
{
Debug.Log("[Inventory] CHANGE_IVTR_SIZE received");
LogInventoryRaw("CHANGE_IVTR_SIZE", data);
break;
}
default:
{
Debug.Log($"[Inventory] Unhandled inventory cmd={cmd}");
LogInventoryRaw($"CMD_{cmd}", data);
break;
}
}
}
public void OnMsgHstCorrectPos(in ECMSG Msg)
{
Debug.Log("OnMsgHstCorrectPos");
cmd_host_correct_pos pCmd = (cmd_host_correct_pos)Msg.dwParam1;
Debug.LogWarning("pCmd.pos " + pCmd.pos);
Debug.LogWarning("HoangDev : OnMsgHstCorrectPos");
byte[] buf = (byte[])Msg.dwParam1; // chỗ bạn lưu pDataBuf
GCHandle handle = GCHandle.Alloc(buf, GCHandleType.Pinned);
cmd_host_correct_pos pCmd = (cmd_host_correct_pos)Marshal.PtrToStructure(
handle.AddrOfPinnedObject(), typeof(cmd_host_correct_pos));
handle.Free();
Debug.LogWarning("HoangDev :pCmd.pos " + pCmd.pos);
SetPos(pCmd.pos);
}
public void OnMsgHstGoto(in ECMSG Msg)
{
Debug.Log("HoangDev :OnMsgHstGoto");
cmd_notify_hostpos pCmd = (cmd_notify_hostpos)Msg.dwParam1;
}
private void LogInventoryPacket(string tag, byte[] buffer, int hostId)
{
if (buffer == null)
{
Debug.LogWarning($"[Inventory] {tag}: buffer is null (hostId={hostId})");
return;
}
int index = 0;
if (buffer.Length < 6)
{
Debug.LogWarning($"[Inventory] {tag}: buffer too small: {buffer.Length} bytes (hostId={hostId})");
LogInventoryRaw(tag, buffer);
return;
}
byte byPackage = buffer[index++];
byte ivtrSize = buffer[index++];
uint contentLength = BitConverter.ToUInt32(buffer, index); index += 4;
int remaining = buffer.Length - index;
int contentBytes = remaining;
if (contentLength < (uint)remaining)
{
contentBytes = (int)contentLength;
}
Debug.Log($"[Inventory] {tag}: hostId={hostId}, totalBytes={buffer.Length}, byPackage={byPackage}, ivtrSize={ivtrSize}, contentLength={contentLength}, actualContentBytes={contentBytes}");
if (contentBytes > 0)
{
byte[] content = new byte[contentBytes];
Buffer.BlockCopy(buffer, index, content, 0, contentBytes);
Debug.Log($"[Inventory] {tag}: content HEX=\n{BitConverter.ToString(content)}");
}
int trailing = buffer.Length - (index + contentBytes);
if (trailing > 0)
{
byte[] tail = new byte[trailing];
Buffer.BlockCopy(buffer, index + contentBytes, tail, 0, trailing);
Debug.Log($"[Inventory] {tag}: trailing {trailing} byte(s) HEX=\n{BitConverter.ToString(tail)}");
}
}
private void LogInventoryRaw(string tag, byte[] buffer)
{
Debug.Log($"[Inventory] {tag}: RAW HEX (len={buffer?.Length ?? 0})=\n{(buffer == null ? "<null>" : BitConverter.ToString(buffer))}");
}
private void SetPos(Vector3 pos)
{
transform.position = pos;
@@ -223,9 +343,10 @@ public class CECHostPlayer : MonoBehaviour
Vector3 pos = new Vector3(role.pos.x, role.pos.y, role.pos.z);
if (txtName != null) txtName.text = roleName;
transform.position = pos;
StartCoroutine(SetModelHostPlayer());
SetModelHostPlayer();
Debug.LogError("Pos Character = " + pos);
joystick = FindAnyObjectByType<Joystick>();
joystick.OnPointUp += JoystickRelease;
}
public void InitCharacter(info_player_1 role)
@@ -238,7 +359,7 @@ public class CECHostPlayer : MonoBehaviour
Vector3 pos = new Vector3(role.pos.x, role.pos.y, role.pos.z);
if (txtName != null) txtName.text = roleName;
transform.position = pos;
StartCoroutine(SetModelHostPlayer());
SetModelHostPlayer();
Debug.LogError("Pos Character = " + pos);
}
}
+4 -20
View File
@@ -15,25 +15,9 @@ struct cmd_host_correct_pos
public Vector3 pos;
public ushort stamp;
};
enum MoveMode
struct cmd_notify_hostpos
{
GP_MOVE_WALK = 0,
GP_MOVE_RUN = 1,
GP_MOVE_STAND = 2,
GP_MOVE_FALL = 3,
GP_MOVE_SLIDE = 4,
GP_MOVE_PUSH = 5, // only sent to NPC
GP_MOVE_FLYFALL = 6,
GP_MOVE_RETURN = 7,
GP_MOVE_JUMP = 8,
GP_MOVE_PULL = 9, // only sent to NPC
GP_MOVE_BLINK = 10, // only sent to NPC£¨Ë²ÒÆ£©
GP_MOVE_MASK = 0x0f,
GP_MOVE_TURN = 0x10, // Turnaround
GP_MOVE_DEAD = 0x20,
GP_MOVE_AIR = 0x40,
GP_MOVE_WATER = 0x80,
GP_MOVE_ENVMASK = 0xc0,
public Vector3 vPos;
public int tag;
public int line;
};
+37
View File
@@ -0,0 +1,37 @@
using System;
using UnityEngine;
public static class EC_Utility
{
public static byte glb_CompressDirH(float x, float z)
{
const float fInvInter = 256.0f / 360.0f;
if (Math.Abs(x) < 0.00001f)
{
if (z > 0.0f)
return 64;
else
return 192;
}
else
{
// atan2 trong C# trả về radian, cần đổi sang độ
float fDeg = (float)(Math.Atan2(z, x) * (180.0 / Math.PI));
// đảm bảo góc nằm trong [0, 360)
if (fDeg < 0)
fDeg += 360.0f;
return (byte)(fDeg * fInvInter);
}
}
public static System.Numerics.Vector3 ToNumerics(this UnityEngine.Vector3 v)
{
return new System.Numerics.Vector3(v.x, v.y, v.z);
}
public static float MagnitudeH(this Vector3 v)
{
return Mathf.Sqrt(v.x * v.x + v.z * v.z);
}
}
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 927789371b017f345a12f6d7adbc87ff
+18 -7
View File
@@ -1,4 +1,3 @@
using CSNetwork;
using CSNetwork.GPDataType;
using CSNetwork.Protocols.RPCData;
using System.Data;
@@ -21,18 +20,26 @@ public class GameController : MonoBehaviour
if (instance == null)
{
instance = FindAnyObjectByType<GameController>();
if (instance == null)
{
var go = new GameObject("GameController");
instance = go.AddComponent<GameController>();
DontDestroyOnLoad(go);
}
}
return instance;
}
}
public int HandlerId => 99;
private void Awake()
{
if(instance == null)
{
instance = this;
DontDestroyOnLoad(gameObject);
}
else if(instance != this)
{
Destroy(gameObject);
}
}
@@ -47,6 +54,11 @@ public class GameController : MonoBehaviour
}
public CECHostPlayer GetHostPlayer()
{
if(hostPlayer == null)
{
hostPlayer = FindAnyObjectByType<CECHostPlayer>();
}
Debug.Log("hostPlayer " + hostPlayer);
return hostPlayer;
}
public void InitCharacter(cmd_self_info_1 info)
@@ -78,9 +90,8 @@ public class GameController : MonoBehaviour
character.InitCharacter(info);
return character.gameObject;
}
public bool ProcessMessage(ECMSG Msg)
private void OnDestroy()
{
throw new System.NotImplementedException();
instance = null;
}
}
+132 -27
View File
@@ -8,47 +8,127 @@ using System.Text;
using UnityEngine;
using CSNetwork.Protocols;
using UnityEngine.LightTransport;
using CSNetwork;
public class CECHostMove
{
ushort m_wMoveStamp;
ushort m_wMoveStamp;
float m_fMoveTime;
CECHostPlayer m_pHost;
CECCounter m_CmdTimeCnt;
bool m_bStop;
const float MOVECMD_INTERVAL = .5f;
Vector3 m_vLastSevPos;
STOPMOVE m_DelayedStop;
ulong cmdstopdelayCounter = 500;
ulong cmdmovedelayCounter = 500;
ulong m_dwLastTime;
Vector3 m_vLastPos;
float m_fAverSpeedH;
public CECHostMove(CECHostPlayer pHost)
{
m_wMoveStamp = 0;
m_fMoveTime = 0.0f;
m_pHost = pHost;
m_bStop = true;
m_CmdTimeCnt = new CECCounter();
m_CmdTimeCnt.SetPeriod(MOVECMD_INTERVAL);
m_bStop = false;
}
public void Tick(float dwDeltaTime)
public void Tick(ulong dwDeltaTime)
{
m_CmdTimeCnt.IncCounter(dwDeltaTime);
cmdstopdelayCounter += dwDeltaTime;
cmdmovedelayCounter += dwDeltaTime;
if (cmdstopdelayCounter >= 500 && m_DelayedStop.bValid)
{
var m = m_DelayedStop;
// a_GetTime() -> Environment.TickCount (ms)
ulong dwCurrent = (ulong)Mathf.RoundToInt( Time.time * 1000);
// iTime: thời gian tích lũy (ms) + delta từ timestamp đến hiện tại
int iTime = (int)((m.fTime * 1000f)
+ ((dwCurrent > m.dwTimeStamp) ? (dwCurrent - m.dwTimeStamp) : 0));
// tính tốc độ trung bình (giây = iTime * 0.001f)
float fSpeed = l_CalcAverageSpeed(m_vLastSevPos, m.vPos, iTime * 0.001f, m.fSpeed);
int iMoveMode = m.iMoveMode;
// make a potential check with tuojigua
iMoveMode |= (int)MoveMode.GP_MOVE_DEAD;
UnityGameSession.Instance.c2s_SendCmdStopMove(
m.vPos, fSpeed, iMoveMode, m.byDir, m_wMoveStamp++, iTime
);
// Record this position
m_vLastSevPos = m.vPos;
Reset();
}
m_dwLastTime = Math.Max(m_dwLastTime, 1);
Vector3 vOffset = m_pHost.transform.position - m_vLastPos;
m_fAverSpeedH = EC_Utility.MagnitudeH(vOffset) * 1000.0f / m_dwLastTime;
m_vLastPos = m_pHost.transform.position;
m_dwLastTime = dwDeltaTime;
}
public void SendStopMoveCmd(in Vector3 vPos, float fSpeed, int iMoveMode)
{
Debug.LogWarning("HoangDev : SendStopMoveCmd");
iMoveMode |= (int)MoveMode.GP_MOVE_DEAD;
if (cmdstopdelayCounter == 500)
{
Vector3 vDir = m_pHost.transform.forward;
byte byDir = EC_Utility.glb_CompressDirH(vDir.x, vDir.z);
fSpeed = l_CalcAverageSpeed(m_vLastSevPos, vPos, m_fMoveTime, fSpeed);
int iTime = (int)(m_fMoveTime * 1000);
UnityGameSession.Instance.c2s_SendCmdStopMove(vPos, fSpeed, iMoveMode, byDir, m_wMoveStamp++, iTime);
m_vLastSevPos = vPos;
Reset();
}
else
{
Vector3 vDir = m_pHost.transform.forward;
byte byDir = EC_Utility.glb_CompressDirH(vDir.x, vDir.z);
if (!m_DelayedStop.bValid)
{
m_DelayedStop.dwTimeStamp = (ulong)Mathf.RoundToInt(Time.time * 1000);
m_DelayedStop.fTime = m_fMoveTime;
}
m_DelayedStop.bValid = true;
m_DelayedStop.byDir = byDir;
m_DelayedStop.vPos = vPos;
m_DelayedStop.iMoveMode = iMoveMode;
m_DelayedStop.fSpeed = fSpeed;
}
m_fMoveTime = 0.0f;
}
public void SendMoveCmd(in Vector3 vCurPos, in Vector3 vVel, int iMoveMode, bool bForceSend = false)
{
Vector3 vMoveDir = vVel;
float fSpeed = vMoveDir.magnitude;
SendMoveCmd(vCurPos, fSpeed, iMoveMode, bForceSend);
SendMoveCmd(vCurPos, fSpeed, iMoveMode, bForceSend);
}
void SendMoveCmd(in Vector3 vCurPos,
float fSpeed, int iMoveMode, bool bForceSend)
{
Debug.LogWarning($"cmdmovedelayCounter 1 = {cmdmovedelayCounter}");
if (m_bStop)
{
Debug.LogWarning($"cmdmovedelayCounter 2 = {(ulong)m_fMoveTime * 1000}");
// m_CmdTimeCnt.Reset();
m_CmdTimeCnt.SetCounter((m_fMoveTime * 1000));
cmdmovedelayCounter = (ulong)( m_fMoveTime * 1000);
m_bStop = false;
}
if (!bForceSend && !m_CmdTimeCnt.IsFull())
Debug.LogWarning($"cmdmovedelayCounter = {cmdmovedelayCounter}");
if (!bForceSend && cmdmovedelayCounter < 500)
return;
int iTime = (int)(m_fMoveTime * 1000);
@@ -58,38 +138,63 @@ public class CECHostMove
if (iTime == 0 || !bForceSend)
{
// if time is too little, wait again
m_CmdTimeCnt.SetCounter(iTime);
cmdmovedelayCounter = (ulong)(iTime);
return;
}
}
m_CmdTimeCnt.Reset();
cmdmovedelayCounter = 0;
m_DelayedStop.bValid = false;
c2s_CmdPlayerMove(vCurPos, vCurPos, iTime/* MOVECMD_INTERVAL */, fSpeed, iMoveMode, m_wMoveStamp++);
fSpeed = l_CalcAverageSpeed(m_vLastSevPos, vCurPos, m_fMoveTime, fSpeed);
m_fMoveTime = 0.0f;
iMoveMode |= (int)MoveMode.GP_MOVE_DEAD;
Debug.LogWarning("nityGameSession.Instance.c2s_CmdPlayerMove");
UnityGameSession.Instance.c2s_CmdPlayerMove(vCurPos, vCurPos, iTime/* MOVECMD_INTERVAL */, fSpeed, iMoveMode, m_wMoveStamp++);
m_vLastSevPos = vCurPos;
}
float l_CalcAverageSpeed(in Vector3 p1, in Vector3 p2, float fTime, float fDefSpeed)
{
if (Mathf.Approximately(fTime, 0f))
return fDefSpeed;
Vector3 d = p2 - p1;
float fSpeed = d.magnitude / fTime;
if (fTime < 0.05f || fSpeed > 50.0f)
{
// tương đương ASSERT(0) trong C++, ở đây có thể Debug.LogWarning
Debug.LogWarning("CalcAverageSpeed: invalid input, fallback to default speed.");
return fDefSpeed;
}
return fSpeed;
}
private void Reset()
{
cmdstopdelayCounter = 0;
m_bStop = true;
m_DelayedStop.bValid = false;
}
private void c2s_CmdPlayerMove(in Vector3 vCurPos, in Vector3 vDest,
int iTime, float fSpeed, int iMoveMode, ushort wStamp)
{
gamedatasend gamedatasend = new gamedatasend();
//TODO: tim cach convert vector 3 unity sang System.Numerics.Vector3
Debug.LogWarning("vCurPos " + vCurPos);
gamedatasend.Data = C2SCommandFactory.CreatePlayerMove(ToSysVec3(vCurPos), ToSysVec3(vDest), (ushort)iTime, (short)fSpeed, (byte)iMoveMode, wStamp);
UnityGameSession.SendProtocol(gamedatasend);
Debug.LogWarning("HoangDev : SendProtocolSendProtocolSendProtocol");
}
public void GroundMove(float ftime)
{
m_fMoveTime += ftime;
}
public System.Numerics.Vector3 ToSysVec3(UnityEngine.Vector3 v)
=> new System.Numerics.Vector3(v.x, v.y, v.z);
struct STOPMOVE
{
public bool bValid; // Valid flag
public Vector3 vPos;
public float fSpeed;
public int iMoveMode;
public byte byDir;
public ulong dwTimeStamp;
public float fTime;
};
}
public struct CDR_INFO
{
@@ -123,4 +228,4 @@ public struct CDR_INFO
//the moving dist
public float fMoveDist;
};
};
@@ -0,0 +1,23 @@
using UnityEngine;
public class PlayerIdleState : PlayerState
{
public PlayerIdleState(CECHostPlayer characterCtrl) : base(characterCtrl)
{
}
public override void Enter()
{
}
public override void Exit()
{
}
public override void Update()
{
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 89482cfe1c5315b4d833133e919eac40
@@ -13,11 +13,12 @@ public class PlayerMoveState : PlayerState
public override void Exit()
{
_characterCtrl.StopMovement();
}
public override void Update()
{
_characterCtrl.HandleMovement();
}
}
-25
View File
@@ -1,25 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1045 &1
EditorBuildSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Scenes:
- enabled: 1
path: Assets/PerfectWorld/Scene/Boostrap.unity
guid: 40f9b53766c74f541b85df4d35cfc767
- enabled: 1
path: Assets/PerfectWorld/Scene/LoginScene.unity
guid: 48fc9d6a0ce7ade4ba2075f927f8e305
- enabled: 1
path: Assets/Scenes/NPCRender.unity
guid: a104c7e42c2924c12843255c6bab3a8b
- enabled: 1
path: Assets/Scenes/WorldRender.unity
guid: 6d5fa77a0ed1542c8a76520fd198c7f1
- enabled: 1
path: Assets/Scenes/HoangTest.unity
guid: 9172bad49fed35e46819504e93c44a84
m_configObjects:
com.unity.input.settings.actions: {fileID: -944628639613478452, guid: 052faaac586de48259a63d0c4782560b, type: 3}
m_UseUCBPForAssetBundles: 0