OnWireConnect
OnWireConnect is called when a player uses the wire tool to make a wire connection between an output socket and an input socket, before the connection is stored. Returning a non-null value cancels the connection.
object OnWireConnect(BasePlayer player, IOEntity inputEntity, int inputIndex, IOEntity outputEntity, int outputIndex, List<UnityEngine.Vector3> linePoints, List<float> slackLevels)Parameters
| Parameter | Type | Description |
|---|---|---|
player | BasePlayer | The BasePlayer who is drawing the wire with the wire tool. Can be null-checked and used for permission tests or personal limits. |
inputEntity | IOEntity | The IOEntity that owns the input socket the wire is being plugged into, for example an electrical switch or a door controller. |
inputIndex | int | The index of the input socket on inputEntity that the connection targets. |
outputEntity | IOEntity | The IOEntity that owns the output socket the wire is coming from, for example a generator or battery. |
outputIndex | int | The index of the output socket on outputEntity the wire starts at. |
linePoints | List<UnityEngine.Vector3> | The list of world-space points describing the wire's path that the client sent with the connection request. Modifying it before the wire is created changes the stored line shape. |
slackLevels | List<float> | Per-segment slack values for the wire path. They feed into how the wire sags and are passed alongside linePoints. |
Return value
Returning null lets the connection proceed exactly as normal. Returning any non-null value stops the original method before the wire is created, so the connection is rejected and no change is written to either entity.
How it works
The hook fires inside WireTool.RPC_MakeConnection, after the server has validated the player-side line anchors and before it applies the wire colour and writes the connection onto both IOEntity objects. That means it fires for every successful wire-tool connection attempt a player submits: generators to switches, switches to lights, outputs to inputs across the electrical and industrial systems.
player is the connecting player, useful for permission checks, per-player wire caps or ownership rules. inputEntity and inputIndex describe the receiving socket; outputEntity and outputIndex describe the source socket. linePoints and slackLevels are the client-supplied geometry for the wire - you can read them to measure length or rewrite them to reshape the wire that gets saved.
Because both socket entities are passed as IOEntity, you can narrow the parameters to a more specific type such as IOEntity subclasses only if you are certain every connection you care about involves that type; Oxide skips your method when the argument is not an instance of the declared type. Most plugins should keep IOEntity and inspect ShortPrefabName instead.
Example plugin: Restrict wire connections to a permitted tier of builders
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Wire Connect Guard", "RustPluginGenerator", "1.0.0")]
[Description("Gates wire tool connections behind a permission and enforces a maximum wire length")]
public class WireConnectGuard : RustPlugin
{
private const string PermUse = "wireconnectguard.use";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Require permission to connect wires")]
public bool RequirePermission { get; set; } = true;
[JsonProperty("Maximum wire length (metres, 0 = unlimited)")]
public float MaxWireLength { get; set; } = 30f;
}
protected override void LoadDefaultConfig() => config = new PluginConfig();
protected override void LoadConfig()
{
base.LoadConfig();
try
{
config = Config.ReadObject<PluginConfig>();
if (config == null) throw new Exception();
}
catch
{
PrintWarning("Configuration file is invalid, using defaults");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void SaveConfig() => Config.WriteObject(config);
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["NoPermission"] = "You do not have permission to connect wires.",
["TooLong"] = "That wire is too long ({0} m, maximum {1} m)."
}, this);
}
private string Msg(string key, string userId = null, params object[] args) => string.Format(lang.GetMessage(key, this, userId), args);
private void Init()
{
permission.RegisterPermission(PermUse, this);
}
private object OnWireConnect(BasePlayer player, IOEntity inputEntity, int inputIndex, IOEntity outputEntity, int outputIndex, List<Vector3> linePoints, List<float> slackLevels)
{
if (player == null || inputEntity == null || outputEntity == null)
return null;
if (config.RequirePermission && !permission.UserHasPermission(player.UserIDString, PermUse))
{
player.ChatMessage(Msg("NoPermission", player.UserIDString));
return false;
}
if (config.MaxWireLength <= 0f || linePoints == null || linePoints.Count < 2)
return null;
float length = 0f;
for (int i = 1; i < linePoints.Count; i++)
length += Vector3.Distance(linePoints[i - 1], linePoints[i]);
if (length > config.MaxWireLength)
{
player.ChatMessage(Msg("TooLong", player.UserIDString, Mathf.RoundToInt(length), Mathf.RoundToInt(config.MaxWireLength)));
return false;
}
return null;
}
}
}The plugin gives players with wireconnectguard.use the ability to make wire connections freely, and blocks everyone else. On a blocked attempt it sends a language message and returns false, which is non-null and therefore cancels the connection inside WireTool.RPC_MakeConnection. It also keeps a configurable per-player wire length budget: linePoints is walked to sum segment distances, and connections longer than the configured maximum are refused so players cannot stretch wires across whole bases. Everything is driven by LoadDefaultConfig/LoadDefaultMessages, so limits and text are editable without recompiling.
Common use cases
Permission-gated wiring
Only let players with a specific permission draw wires, so default players must use deployables you place for them. Return a value to reject the attempt.
Maximum wire length
Sum distances between
linePointsand reject connections that exceed a server-wide limit, preventing long runs across large bases or between compounds.Socket-specific rules
Inspect
inputEntity.ShortPrefabNameoroutputEntity.OwnerIDto block connections into entities a player does not own, or to forbid hooking generators into turret controls directly.
Pitfalls
Fires after anchor validation
The hook only runs when
ValidateLineAnchorsalready passed, so it never sees malformed or out-of-range attempts. Do not rely on it for anti-cheat on line geometry alone.Returning any object cancels
The injection checks for null only. Returning
false,0or any other value blocks the wire - usenullwhen you want to allow it.Editing linePoints persists
The lists you receive are what the server stores for the wire. Mutating them changes the saved wire shape, so only alter them when you actually intend to reshape the connection.
Build a plugin with OnWireConnect
Describe what should happen and get a compiled plugin that uses this hook.
Edit the prompt on the next screen. 2 free plugins a month, no card.
Last updated Oct 26, 2026. Found a mistake? Email support@rustplugingenerator.com.
Build a plugin with OnWireConnect
Generate