### Initialize Location Server in C# Source: https://context7.com/et-packages/cn.etetet.actorlocation/llms.txt Illustrates the process of initializing a Location scene server. This involves adding necessary components like MailBoxComponent, TimerComponent, CoroutineLockComponent, and crucially, the LocationManagerComoponent, which is responsible for storing and managing actor locations. This setup is typically handled by a FiberInit_Location class invoked at scene startup. ```csharp // Location server initialization (handled by FiberInit_Location) [Invoke(SceneType.Location)] public class FiberInit_Location : AInvokeHandler { public override async ETTask Handle(FiberInit fiberInit) { Scene root = fiberInit.Fiber.Root; // Add required components root.AddComponent(MailBoxType.UnOrderedMessage); root.AddComponent(); root.AddComponent(); root.AddComponent(); root.AddComponent(); root.AddComponent(); // Core location storage await ETTask.CompletedTask; } } // The location server automatically handles: // - ObjectAddRequest: Register actor locations // - ObjectGetRequest: Query actor locations // - ObjectLockRequest: Lock locations for migration // - ObjectUnLockRequest: Unlock and update locations // - ObjectRemoveRequest: Unregister actor locations ``` -------------------------------- ### Handle Location Messages in C# Source: https://context7.com/et-packages/cn.etetet.actorlocation/llms.txt Provides examples of implementing message handlers for ET's location service. It shows how to create handlers for one-way messages (like chat) and for request-response RPC calls. These handlers are crucial for entities to receive and process messages sent through the location infrastructure. ```csharp // Handler for one-way location messages [MessageLocationHandler] public class ChatMessageHandler : MessageLocationHandler { protected override async ETTask Run(Player player, ChatMessage message) { Log.Info($"Player {player.Id} received chat: {message.Content}"); // Process the message player.GetComponent().AddMessage(message.Content); await ETTask.CompletedTask; } } // Handler for location RPC (request/response) [MessageLocationHandler] public class GetPlayerDataHandler : MessageLocationHandler { protected override async ETTask Run(Player player, GetPlayerDataRequest request, GetPlayerDataResponse response) { // Populate response response.Level = player.Level; response.Gold = player.GetComponent().Gold; response.Error = ErrorCode.ERR_Success; await ETTask.CompletedTask; } } ``` -------------------------------- ### Configure Location Types and Servers in C# Source: https://context7.com/et-packages/cn.etetet.actorlocation/llms.txt Shows how to define custom location types as constants for categorizing actors and how to configure multiple Location servers for scalability. The `StartSceneConfigHelper` class demonstrates adding multiple Location scenes, distributing actors across them based on keys, and hints at the automatic handling of location-related requests by the server. ```csharp // Define location types in your project public static class PlayerLocationType { public const int Player = 1; public const int Pet = 2; public const int Guild = 3; } // Usage in startup configuration public static class StartSceneConfigHelper { public static void AddLocationServers(this StartSceneConfig config) { // Add multiple location servers for horizontal scaling // ActorIds are distributed via key % locationCount config.AddScene(SceneType.Location, "Location1"); config.AddScene(SceneType.Location, "Location2"); config.AddScene(SceneType.Location, "Location3"); } } ``` -------------------------------- ### Handle Location Service Errors with Retries (C#) Source: https://context7.com/et-packages/cn.etetet.actorlocation/llms.txt Provides a safe method to retrieve player location, implementing retry logic for common errors like timeouts and 'not found' scenarios. It leverages `LocationProxyComponent` and `TimerComponent` for asynchronous operations and delays, returning the `ActorId` or default on failure. ```csharp // Robust error handling for location operations public async ETTask GetPlayerLocationSafe(long playerId, int maxRetries = 3) { Scene root = GetScene(); LocationProxyComponent locationProxy = root.GetComponent(); for (int retry = 0; retry < maxRetries; retry++) { try { ActorId actorId = await locationProxy.Get(PlayerLocationType.Player, playerId); if (actorId == default) { await TimerComponent.Instance.WaitAsync(500); continue; } return actorId; } catch (RpcException e) when (e.Error == ErrorCode.ERR_MessageTimeout) { Log.Warning($"Location query timeout (attempt {retry + 1}/{maxRetries})"); if (retry < maxRetries - 1) await TimerComponent.Instance.WaitAsync(1000); } catch (RpcException e) when (e.Error == ErrorCode.ERR_NotFoundActor) { Log.Warning($"Player {playerId} not registered in location service"); return default; } } throw new Exception($"Failed to get location for player {playerId} after {maxRetries} retries"); } ``` -------------------------------- ### Call RPC via Location Service in C# Source: https://context7.com/et-packages/cn.etetet.actorlocation/llms.txt Demonstrates how to make an RPC call to a remote entity by its ID using the MessageLocationSenderComponent. It includes request creation, sending the call with automatic retries, and handling success or error responses. This method relies on the entity's location being resolvable by the location service. ```csharp // Call RPC on remote player entity Scene root = GetScene(); MessageLocationSenderComponent senderComponent = root.GetComponent(); MessageLocationSenderOneType sender = senderComponent.Get(PlayerLocationType.Player); long targetPlayerId = 987654321; // Create request GetPlayerDataRequest request = GetPlayerDataRequest.Create(); request.PlayerId = targetPlayerId; try { // Automatic retry up to 20 times with 500ms delays IResponse response = await sender.Call(targetPlayerId, request); if (response.Error != ErrorCode.ERR_Success) { Log.Error($"RPC failed: {response.Error} {response.Message}"); return; } GetPlayerDataResponse dataResponse = (GetPlayerDataResponse)response; Log.Info($"Player data: Level={dataResponse.Level}, Gold={dataResponse.Gold}"); } catch (RpcException e) when (e.Error == ErrorCode.ERR_NotFoundActor) { Log.Warning($"Player {targetPlayerId} not found after retries") } catch (Exception e) { Log.Error($"RPC error: {e}"); } ``` -------------------------------- ### Query Actor Location in C# Source: https://context7.com/et-packages/cn.etetet.actorlocation/llms.txt Retrieves the ActorId for a given entity ID from the location service. This allows services to find the current network address or process where an entity resides. It includes error handling for cases where the entity is not found or a communication error occurs. Requires Scene and LocationProxyComponent. ```csharp // Query where a player entity is located Scene root = GetScene(); LocationProxyComponent locationProxy = root.GetComponent(); long playerId = 123456789; int locationType = PlayerLocationType.Player; try { ActorId actorId = await locationProxy.Get(locationType, playerId); if (actorId == default) { Log.Warning($"Player {playerId} not found in location service"); } else { Log.Info($"Player {playerId} located at {actorId}"); } } catch (Exception e) { Log.Error($"Failed to query location: {e}"); } ``` -------------------------------- ### Register Actor Location in C# Source: https://context7.com/et-packages/cn.etetet.actorlocation/llms.txt Registers an entity's location with the distributed location service. It maps a location type and entity ID to an ActorId, enabling other services to find the entity. This function is crucial for making entities discoverable in a distributed environment. Dependencies include the ET framework's Scene and LocationProxyComponent. ```csharp // Register a player entity with the location service // locationType defines the category (e.g., PlayerLocationType) Scene root = entity.Root(); LocationProxyComponent locationProxy = root.GetComponent(); // Method 1: Direct registration int locationType = 1; // Define your location type constant long entityId = player.Id; ActorId actorId = player.GetActorId(); await locationProxy.Add(locationType, entityId, actorId); // Method 2: Extension method on entity await player.AddLocation(PlayerLocationType.Player); ``` -------------------------------- ### Lock Actor Location in C# Source: https://context7.com/et-packages/cn.etetet.actorlocation/llms.txt Acquires a lock on an actor's location, typically before migrating it to a new server or performing critical updates. This prevents concurrent operations that could lead to data inconsistency. The lock has a specified timeout and must be explicitly unlocked. Dependencies include Scene, LocationProxyComponent, and migration logic. ```csharp // Lock a player's location before transferring between servers Scene root = GetScene(); LocationProxyComponent locationProxy = root.GetComponent(); long playerId = 123456789; int locationType = PlayerLocationType.Player; ActorId currentActorId = player.GetActorId(); int lockTimeMs = 60000; // 60 second timeout try { // Acquire lock for migration await locationProxy.Lock(locationType, playerId, currentActorId, lockTimeMs); // Perform migration operations... ActorId newActorId = await MigratePlayerToNewServer(player); // Unlock and update to new location await locationProxy.UnLock(locationType, playerId, currentActorId, newActorId); } catch (Exception e) { Log.Error($"Migration failed: {e}"); } ``` -------------------------------- ### Send Message via Location in C# Source: https://context7.com/et-packages/cn.etetet.actorlocation/llms.txt Sends a message to an entity using its location information without needing to know its direct network endpoint. This is facilitated by the MessageLocationSenderComponent, which resolves the ActorId based on the entity's location type and ID. Supports both fire-and-forget and auto-retry messaging patterns. Dependencies include Scene and MessageLocationSenderComponent. ```csharp // Send a message to a player by ID Scene root = GetScene(); MessageLocationSenderComponent senderComponent = root.GetComponent(); MessageLocationSenderOneType sender = senderComponent.Get(PlayerLocationType.Player); long targetPlayerId = 987654321; // Fire-and-forget message PlayerInfoMessage message = PlayerInfoMessage.Create(); message.Level = 50; message.Name = "Hero"; sender.Send(targetPlayerId, message); // Or for ILocationMessage with auto-retry ChatMessage chatMsg = ChatMessage.Create(); chatMsg.Content = "Hello!"; sender.Send(targetPlayerId, chatMsg); ``` -------------------------------- ### Remove Actor Location in C# Source: https://context7.com/et-packages/cn.etetet.actorlocation/llms.txt Removes an entity's location registration from the distributed service, typically when the entity is destroyed or no longer needs to be discoverable. This ensures the location service is kept up-to-date and frees up resources. It can be done directly or via an extension method. Requires Scene and LocationProxyComponent. ```csharp // Unregister player when they disconnect Scene root = player.Root(); LocationProxyComponent locationProxy = root.GetComponent(); int locationType = PlayerLocationType.Player; long playerId = player.Id; await locationProxy.Remove(locationType, playerId); // Or use extension method await player.RemoveLocation(PlayerLocationType.Player); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.