Changes

Jump to navigation Jump to search
+ new APIs in SMAPI 2.8
Line 5: Line 5:  
__TOC__
 
__TOC__
 
==Methods==
 
==Methods==
===GetNewID===
+
===Get new ID===
 
In some cases the game expects a 'multiplayer ID' value, which is a unique 64-bit number. This is mainly intended for cases where the game expects a multiplayer ID for data sync, such as when creating farm animals:
 
In some cases the game expects a 'multiplayer ID' value, which is a unique 64-bit number. This is mainly intended for cases where the game expects a multiplayer ID for data sync, such as when creating farm animals:
 
<source lang="c#">
 
<source lang="c#">
Line 12: Line 12:  
</source>
 
</source>
   −
===GetActiveLocations===
+
===Get active locations===
 
In multiplayer mode, the game doesn't sync all locations to other players. Each farmhand will receive data for their current location, the farm, farmhouse, and farm buildings. You can get a list of the locations being sync'd:
 
In multiplayer mode, the game doesn't sync all locations to other players. Each farmhand will receive data for their current location, the farm, farmhouse, and farm buildings. You can get a list of the locations being sync'd:
 
<source lang="C#">
 
<source lang="C#">
Line 18: Line 18:  
{
 
{
 
   // do stuff
 
   // do stuff
 +
}
 +
</source>
 +
 +
===Get connected player info===
 +
{{SMAPI upcoming|2.8}}
 +
 +
You can see basic info about other players connected to the same server using the <tt>GetConnectedPlayer(playerID)</tt> and <tt>GetConnectedPlayers()</tt> methods. Most of the information is only available for players who are running SMAPI too. You can access these fields for each player:
 +
{| class="wikitable"
 +
|-
 +
! field
 +
! type
 +
! description
 +
|-
 +
| <tt>PlayerID</tt>
 +
| <tt>long</tt>
 +
| The player's unique multiplayer ID, which you can pass to game methods and fields that expect a unique player ID.
 +
|-
 +
| <tt>IsHost</tt>
 +
| <tt>bool</tt>
 +
| True if this player is hosting the server; false if they're a farmhand.
 +
|-
 +
| <tt>HasSmapi</tt>
 +
| <tt>bool</tt>
 +
| Whether this player has SMAPI installed.
 +
|-
 +
| <tt>Platform</tt>
 +
| <tt>GamePlatform</tt>
 +
| (Requires SMAPI.) The player's operating system as a <tt>GamePlatform</tt> enum (one of <tt>Linux</tt>, <tt>Mac</tt>, or <tt>Windows</tt>).
 +
|-
 +
| <tt>GameVersion</tt>
 +
| <tt>ISemanticVersion</tt>
 +
| (Requires SMAPI.) The version of the game they have installed (like <tt>1.3.31</tt>).
 +
|-
 +
| <tt>ApiVersion</tt>
 +
| <tt>ISemanticVersion</tt>
 +
| (Requires SMAPI.) The version of SMAPI they have installed (like <tt>2.8</tt>).
 +
|-
 +
| <tt>Mods</tt>
 +
| <tt>IEnumerable&lt;IMultiplayerPeerMod&gt;</tt>
 +
| The mods they have installed. Each mod includes the name, unique ID, and version.
 +
|-
 +
| <tt>GetMod(id)</tt>
 +
| ''method'' returns <tt>IMultiplayerPeerMod</tt>
 +
| A method which returns the mod with the given mod ID using the same case-insensitivity rules as SMAPI, if available. For example, this can be used to check if a mod is installed: <code>if (peer.GetMod("Pathoschild.ContentPatcher") != null)</code>.
 +
|}
 +
 +
For example, this will log information about the currently connected players:
 +
<source lang="C#">
 +
foreach (IMultiplayerPeer peer in this.Helper.Multiplayer.GetConnectedPlayers())
 +
{
 +
    if (peer.HasSmapi)
 +
    {
 +
        // prints something like: "Found player -1634555469947451666 running Stardew Valley 1.3.31 and SMAPI 2.8-beta.5 on Windows with 41 mods."
 +
        this.Monitor.Log($"Found player {peer.PlayerID} running Stardew Valley {peer.GameVersion} and SMAPI {peer.ApiVersion} on {peer.Platform} with {peer.Mods.Count()} mods.");
 +
    }
 +
    else
 +
    {
 +
        // most info not available if they don't have SMAPI
 +
        this.Monitor.Log($"Found player {peer.PlayerID} running Stardew Valley without SMAPI.");
 +
    }
 +
}
 +
</source>
 +
 +
'''Note:''' players whose connections haven't been approved by the game yet are returned too. Although you can send/receive messages through SMAPI's APIs, the game itself may not know about them yet. If you only want players who are fully connected, you can do something like this instead:
 +
<source lang="C#">
 +
foreach (Farmer farmer in Game1.getOnlineFarmers())
 +
{
 +
  IMultiplayerPeer peer = this.Helper.Multiplayer.GetConnectedPlayer(farmer.UniqueMultiplayerID);
 +
}
 +
</source>
 +
 +
===Send messages===
 +
{{SMAPI upcoming|2.8}}
 +
 +
You can send a message to mods on other players' computers using the <tt>SendMessage</tt> method. The destination can range from very narrow (e.g. one mod on one connected computer) to very broad (all mods on all computers).
 +
 +
When sending a message, you must specify three things:
 +
* A data model, which contains the data you want to send. This can be a simple value (like a number or string), or a class instance. When using a class instance with custom constructors, make sure it has a default constructor too.
 +
* A message type, so the destination mods can know which message it is. This doesn't need to be globally unique, since mods should check the originating mod ID.
 +
* Who should receive the message. You can specify any combination of player IDs and/or mod IDs. By default, the message is sent to all mods and players.
 +
 +
For example:
 +
<source lang="C#">
 +
// broadcast a message to all mods on all computers
 +
MyMessage message = new MyMessage(...); // create your own class with the data to send
 +
this.Helper.Multiplayer.SendMessage(message, "MyMessageType");
 +
</source>
 +
<source lang="C#">
 +
// send a message to a specific mod on all computers
 +
MyMessage message = new MyMessage(...);
 +
this.Helper.Multiplayer.SendMessage(message, "MyMessageType", toModIDs: new[] { this.ModManifest.UniqueID });
 +
</source>
 +
 +
===Receive messages===
 +
{{SMAPI upcoming|2.8}}
 +
 +
You can receive messages by listening to the <tt>helper.Multiplayer.ModMessageReceived</tt> [[Modding:Modder Guide/APIs/Events|event]]. Within your event handler, the event arguments specify who sent the message and let you read the message into a matching data model:
 +
<source lang="C#">
 +
public void OnModMessageReceived(object sender, ModMessageReceivedEventArgs e)
 +
{
 +
  if (e.FromModID == "ExpectedModID" && e.Type == "ExampleMessageType")
 +
  {
 +
      MyMessageClass message = e.ReadAs<MyMessageClass>();
 +
      // handle message fields here
 +
  }
 
}
 
}
 
</source>
 
</source>
translators
8,403

edits

Navigation menu