Table of Contents

Class GuildRules

Namespace
FishMMO.Server.Implementation.World.SceneServer
Assembly
FishMMO.Server.dll

The guild permission rules, as pure functions of a resolved standing.

public static class GuildRules
Inheritance
GuildRules
Inherited Members

Remarks

Every server-side guild permission decision is one of these. They were originally inline in the async handlers, which meant the only way to exercise them was to stand up a database, a network connection and a scene server — so in practice they were not exercised at all, and a permission model nobody can test is a permission model nobody can trust.

Pulled out here they take a GuildAuthority and some plain values, touch nothing else, and are called by exactly one place each. The handler keeps the IO; this keeps the policy.

Methods

CanChangeMemberRank(GuildAuthority, byte, byte)

May the actor move a member from one rank to another?

public static GuildActionResult CanChangeMemberRank(GuildAuthority actor, byte currentRankOrder, byte newRankOrder)

Parameters

actor GuildAuthority

The actor's standing.

currentRankOrder byte

The member's present ladder position.

newRankOrder byte

The requested ladder position.

Returns

GuildActionResult

The decision.

Remarks

Four rules. The destination must exist; neither the top seat may be entered nor left through this path (that is a leadership transfer, which demotes the outgoing holder in the same breath); the actor must outrank the member's CURRENT rank; and the actor must outrank the DESTINATION.

The last is the one that is easy to omit and is a direct escalation: without it an officer able to promote could move somebody — or a second character of their own — into a rank above their own, and be outranked by a seat they created.

CanCreateRank(GuildAuthority, byte, GuildPermissions)

May the actor add a rank at the given position with the given permissions?

public static GuildActionResult CanCreateRank(GuildAuthority actor, byte rankOrder, GuildPermissions proposed)

Parameters

actor GuildAuthority

The actor's standing.

rankOrder byte

The requested position.

proposed GuildPermissions

The requested mask.

Returns

GuildActionResult

The decision.

CanDeleteRank(GuildAuthority, byte)

May the actor remove a rank?

public static GuildActionResult CanDeleteRank(GuildAuthority actor, byte rankOrder)

Parameters

actor GuildAuthority

The actor's standing.

rankOrder byte

The rank to remove.

Returns

GuildActionResult

The decision.

Remarks

Whether the rank still has MEMBERS is not decided here — that is a race the database settles in the same statement as the delete. What is decided here is whether the guild would still work afterwards.

CanEditRank(GuildAuthority, byte, GuildPermissions)

May the actor change a rank's name and permissions?

public static GuildActionResult CanEditRank(GuildAuthority actor, byte rankOrder, GuildPermissions proposed)

Parameters

actor GuildAuthority

The actor's standing.

rankOrder byte

The rank being edited.

proposed GuildPermissions

The mask the rank would end up with.

Returns

GuildActionResult

The decision.

Remarks

The grant check compares only the bits being ADDED against the actor's own mask. A rank that already holds a permission the actor lacks keeps it: removing it is not an escalation, and refusing the whole edit over it would make such a rank uneditable forever by anyone below the person who granted it.

CanKick(GuildAuthority, byte)

May the actor remove the member holding the given rank?

public static GuildActionResult CanKick(GuildAuthority actor, byte targetRankOrder)

Parameters

actor GuildAuthority

The actor's standing.

targetRankOrder byte

The target's ladder position.

Returns

GuildActionResult

The decision.

CanTransferLeadership(GuildAuthority)

May the actor hand the guild's top seat to somebody else?

public static GuildActionResult CanTransferLeadership(GuildAuthority actor)

Parameters

actor GuildAuthority

The actor's standing.

Returns

GuildActionResult

The decision.

Remarks

Stricter than the permission alone: the actor must also currently OCCUPY the top seat. A rank editor could grant TransferLeadership to a subordinate rank, and giving away the leader's own seat is not something a subordinate should be able to do.

CanUse(GuildAuthority, GuildPermissions)

May the actor perform an action gated by a single permission and nothing else?

public static GuildActionResult CanUse(GuildAuthority actor, GuildPermissions permission)

Parameters

actor GuildAuthority

The actor's standing.

permission GuildPermissions

The permission required.

Returns

GuildActionResult

The decision.

Remarks

Covers invite, disband, the two text edits, the two note edits, recruitment editing and the application queue — every action whose only question is "do you hold the bit".

WouldOrphanRankAdministration(IReadOnlyList<GuildRankData>, byte, GuildPermissions)

Would this change leave no rank able to administer ranks?

public static bool WouldOrphanRankAdministration(IReadOnlyList<GuildRankData> ladder, byte rankOrder, GuildPermissions newPermissions)

Parameters

ladder IReadOnlyList<GuildRankData>

The guild's rank rows.

rankOrder byte

The rank being changed or removed.

newPermissions GuildPermissions

The mask that rank would end up with.

Returns

bool

True when the change must be refused.

Remarks

The soft-lock guard. A guild whose only rank holding EditRanks gives it up can never get it back — editing ranks is the permission that would be needed — and cannot promote anybody into a rank that has it, because there is no such rank. The guild is then frozen in whatever shape it was in, permanently, with no in-game recovery.

Only EditRanks is protected this way. It is the one permission whose absence prevents its own restoration; a guild that loses every Invite can still edit a rank to grant it back.