-
-
Notifications
You must be signed in to change notification settings - Fork 3
API Integration
MixScrims provides a comprehensive API for other Swiftly plugins to integrate with and control match functionality. The API allows external plugins to monitor match states, manage teams, control match flow, and interact with the player system.
Key Capabilities:
- Monitor and control match states and flow
- Manage team composition and captains
- Control timeouts and surrenders
- Handle player assignments and punishment queues
- Integrate custom matchmaking or tournament systems
1. Reference the contract DLL in your plugin:
csgo/addons/swiftlys2/plugins/MixScrims/resources/exports/MixScrims.Contract.dll
2. Get the API instance:
using MixScrims.Contract;
public class MyPlugin : BasePlugin
{
private IMixScrims? _mixScrims;
public MyPlugin(ISwiftlyCore core) : base(core)
{
}
public override void UseSharedInterface(IInterfaceManager interfaceManager)
{
if (interfaceManager.HasSharedInterface("MixScrims.API"))
{
try
{
_mixScrims = interfaceManager.GetSharedInterface<IMixScrims>("MixScrims.API");
}
catch (Exception ex)
{
Logger.LogError($"Failed to get MixScrims API: {ex.Message}");
}
}
}
public override void Unload()
{
// API implements IDisposable - managed by Swiftly
_mixScrims = null;
}
}Note: The API interface implements IDisposable, but disposal is automatically managed by the Swiftly framework. You only need to set your reference to null when your plugin unloads.
MatchState currentState = _mixScrims.GetCurrentMatchState();Returns the current match phase:
| State | Description |
|---|---|
Warmup |
Players readying up |
MapVoting |
Voting for map |
MapLoading |
Map is loading |
MapChosen |
Map loaded, players readying |
PickingTeam |
Captains picking teams |
KnifeRound |
Knife round active |
PickingStartingSide |
Choosing sides after knife |
Match |
Competitive match in progress |
Timeout |
Team timeout active |
Ended |
Match finished |
Reset |
Match resetting |
_mixScrims.SetMatchState(MatchState.Warmup);Manually sets the match to a specific state. Use with caution as this bypasses normal state transition logic.
PluginState pluginState = _mixScrims.GetCurrentPluginState();Returns the plugin mode:
| State | Description | Config |
|---|---|---|
Production |
Normal mode | TestMode: false |
Staging |
Test mode with bots | TestMode: true |
_mixScrims.SetPluginState(PluginState.Production);Changes the plugin operational mode between Production and Staging.
_mixScrims.SetCounterTerroristsTeamName("Team Alpha");
_mixScrims.SetTerroristsTeamName("Team Bravo");Sets custom display names for CT and T teams. Useful for tournaments or custom team identifiers.
_mixScrims.SetCtCaptain(76561198012345678);
_mixScrims.SetTCaptain(76561198087654321);Assigns specific players as team captains using their Steam ID64.
_mixScrims.StartWarmup();Initiates the warmup phase where players ready up before match start.
_mixScrims.StartMapVoting();Begins the map voting process, presenting the configured map pool to players.
_mixScrims.StartTeamPicking();Initiates the team selection phase where captains pick players for their teams.
_mixScrims.StartKnifeRound();Begins the knife round to determine which team chooses starting sides.
_mixScrims.StartMatch();Starts the competitive match with live rounds and scoring enabled.
_mixScrims.CancelMatch();Immediately cancels the current match and resets all match state.
// Official map
_mixScrims.ChangeMap("de_mirage");
// Workshop map
_mixScrims.ChangeMap(workshopId: "123456789");Changes to a specified map. Provide workshop ID for workshop maps, leave empty for official maps.
_mixScrims.StartTimeoutCt(); // Start CT timeout
_mixScrims.StartTimeoutT(); // Start T timeout
_mixScrims.StopTimeout(); // Stop active timeoutControls team tactical timeouts during matches.
_mixScrims.SurrenderCt(); // CT team surrenders
_mixScrims.SurrenderT(); // T team surrendersForces immediate surrender for the specified team, ending the match.
_mixScrims.ForceAllPlayersToReady();
_mixScrims.ForceAllPlayersToUnready();Overrides all player ready states. Useful for admin control or testing.
// Kick players not in the active match
_mixScrims.KickNotPlayingPlayers("Not in active match");
// Kick players not picked during team selection
_mixScrims.KickNotPickedPlayers("Not selected for teams");Removes players based on their match participation status. Optional reason parameter included in kick message.
_mixScrims.PreventNewPlayersJoining(true); // Block new joins
_mixScrims.PreventNewPlayersJoining(false); // Allow new joinsControls whether new players can join during an active match. Automatically disabled when match ends.
// Get list of picked CT players
List<ulong> ctPicked = _mixScrims.GetPickedCtPlayers();
// Add player to CT picked list
_mixScrims.AddPlayerToPickedCtPlayers(76561198012345678);
// Remove player from CT picked list
_mixScrims.RemovePlayerFromPickedCtPlayers(76561198012345678);Manages the list of players selected for CT team during the picking phase.
// Get list of picked T players
List<ulong> tPicked = _mixScrims.GetPickedTPlayers();
// Add player to T picked list
_mixScrims.AddPlayerToPickedTPlayers(76561198087654321);
// Remove player from T picked list
_mixScrims.RemovePlayerFromPickedTPlayers(76561198087654321);Manages the list of players selected for T team during the picking phase.
// Get list of active CT players in match
List<ulong> ctPlaying = _mixScrims.GetPlayingCtPlayers();
// Add player to active CT roster
_mixScrims.AddPlayerToPlayingCtPlayers(76561198012345678);
// Remove player from active CT roster
_mixScrims.RemovePlayerFromPlayingCtPlayers(76561198012345678);Manages the roster of players actively participating for CT team during the match.
// Get list of active T players in match
List<ulong> tPlaying = _mixScrims.GetPlayingTPlayers();
// Add player to active T roster
_mixScrims.AddPlayerToPlayingTPlayers(76561198087654321);
// Remove player from active T roster
_mixScrims.RemovePlayerFromPlayingTPlayers(76561198087654321);Manages the roster of players actively participating for T team during the match.
// Get players awaiting punishment
List<ulong> awaitingPunishment = _mixScrims.GetPlayersWaitingForPunishment(76561198012345678);
// Add player to punishment queue
_mixScrims.AddPlayerToWaitingForPunishmentList(76561198012345678);
// Remove player from punishment queue
_mixScrims.RemovePlayerFromWaitingForPunishmentList(76561198012345678);Manages the queue of players who disconnected during a match and are awaiting punishment based on configured leave punishment settings.
public class MyPlugin : BasePlugin
{
private IMixScrims? _mixScrims;
public MyPlugin(ISwiftlyCore core) : base(core)
{
}
public override void UseSharedInterface(IInterfaceManager interfaceManager)
{
if (interfaceManager.HasSharedInterface("MixScrims.API"))
{
try
{
_mixScrims = interfaceManager.GetSharedInterface<IMixScrims>("MixScrims.API");
}
catch (Exception ex)
{
Logger.LogError($"Failed to get MixScrims API: {ex.Message}");
}
}
}
public void OnPlayerCommand(CCSPlayerController player, string command)
{
if (_mixScrims == null) return;
var matchState = _mixScrims.GetCurrentMatchState();
// Block certain commands during active match
if (matchState == MatchState.Match)
{
player.PrintToChat("This command is disabled during matches");
return;
}
// Your command logic here
}
}public class CustomTeamPlugin : BasePlugin
{
private IMixScrims? _mixScrims;
// Custom logic to assign teams based on rank/skill
public void AssignBalancedTeams(List<ulong> players)
{
if (_mixScrims == null) return;
// Sort players by skill (your custom logic)
var sortedPlayers = SortPlayersBySkill(players);
// Assign teams in alternating fashion
for (int i = 0; i < sortedPlayers.Count; i++)
{
if (i % 2 == 0)
_mixScrims.AddPlayerToPickedCtPlayers(sortedPlayers[i]);
else
_mixScrims.AddPlayerToPickedTPlayers(sortedPlayers[i]);
}
// Set custom team names
_mixScrims.SetCounterTerroristsTeamName("High Skill");
_mixScrims.SetTerroristsTeamName("Medium Skill");
// Skip picking phase and start match
_mixScrims.StartKnifeRound();
}
}public class MatchAutomationPlugin : BasePlugin
{
private IMixScrims? _mixScrims;
private Timer? _autoStartTimer;
// Automatically start match when 10 players ready
public void CheckAutoStart()
{
if (_mixScrims == null) return;
var state = _mixScrims.GetCurrentMatchState();
if (state == MatchState.Warmup)
{
// Get all connected players
var players = Utilities.GetPlayers();
if (players.Count >= 10)
{
// Force everyone ready and start voting
_mixScrims.ForceAllPlayersToReady();
_mixScrims.StartMapVoting();
}
}
}
// Handle player disconnections during match
public void OnPlayerDisconnect(CCSPlayerController player)
{
if (_mixScrims == null) return;
var state = _mixScrims.GetCurrentMatchState();
var steamId = player.SteamID;
// If player was in active match, add to punishment queue
if (state == MatchState.Match)
{
var ctPlayers = _mixScrims.GetPlayingCtPlayers();
var tPlayers = _mixScrims.GetPlayingTPlayers();
if (ctPlayers.Contains(steamId) || tPlayers.Contains(steamId))
{
_mixScrims.AddPlayerToWaitingForPunishmentList(steamId);
Logger.LogInfo($"Player {steamId} added to punishment queue");
}
}
}
}public class TournamentPlugin : BasePlugin
{
private IMixScrims? _mixScrims;
// Setup tournament match with predefined teams
public void SetupTournamentMatch(string ctTeamName, List<ulong> ctPlayers,
string tTeamName, List<ulong> tPlayers,
string mapName)
{
if (_mixScrims == null) return;
// Set team names
_mixScrims.SetCounterTerroristsTeamName(ctTeamName);
_mixScrims.SetTerroristsTeamName(tTeamName);
// Assign players to teams
foreach (var player in ctPlayers)
_mixScrims.AddPlayerToPickedCtPlayers(player);
foreach (var player in tPlayers)
_mixScrims.AddPlayerToPickedTPlayers(player);
// Set captains (first player in each team)
if (ctPlayers.Count > 0)
_mixScrims.SetCtCaptain(ctPlayers[0]);
if (tPlayers.Count > 0)
_mixScrims.SetTCaptain(tPlayers[0]);
// Prevent random joins during tournament
_mixScrims.PreventNewPlayersJoining(true);
// Change to tournament map
_mixScrims.ChangeMap(mapName);
// Start knife round
_mixScrims.StartKnifeRound();
}
// Admin force end match
public void EndTournamentMatch(string reason)
{
if (_mixScrims == null) return;
Server.PrintToChatAll($"[Tournament] Match ended: {reason}");
_mixScrims.CancelMatch();
_mixScrims.PreventNewPlayersJoining(false);
}
}Always verify the API instance is available before using it:
if (_mixScrims == null)
{
Logger.LogWarning("MixScrims API not available");
return;
}Check the current match state before performing operations:
var state = _mixScrims.GetCurrentMatchState();
if (state != MatchState.Match)
{
// Operation only valid during active match
return;
}All player-related methods use Steam ID64 (ulong):
ulong steamId = player.SteamID; // Correct format
_mixScrims.AddPlayerToPickedCtPlayers(steamId);- Avoid state changes during critical phases (knife round, active rounds)
- Use
SetMatchState()sparingly - prefer built-in flow methods - Don't interrupt timeouts or surrender votes
- Validate player counts before team operations
- Hook into MixScrims state transitions, don't force them
- Disable conflicting plugin features during matches
- Log all API interactions for debugging
- Handle exceptions gracefully to prevent plugin crashes
Check if match is in progress:
bool isMatchActive = matchState == MatchState.Match
|| matchState == MatchState.Timeout;Check if teams are being formed:
bool isTeamFormation = matchState == MatchState.PickingTeam
|| matchState == MatchState.MapChosen;Check if match is competitive state:
bool isCompetitive = matchState == MatchState.KnifeRound
|| matchState == MatchState.Match
|| matchState == MatchState.Timeout
|| matchState == MatchState.PickingStartingSide;-
Cache match state if checking frequently:
private MatchState _cachedState; private DateTime _lastStateCheck; public MatchState GetCachedState() { if ((DateTime.Now - _lastStateCheck).TotalSeconds > 5) { _cachedState = _mixScrims.GetCurrentMatchState(); _lastStateCheck = DateTime.Now; } return _cachedState; }
-
Batch player operations when possible:
// Add multiple players at once foreach (var steamId in playerList) _mixScrims.AddPlayerToPickedCtPlayers(steamId);
Enable detailed logging to monitor API interactions:
Logger.LogInfo($"Current match state: {_mixScrims.GetCurrentMatchState()}");
Logger.LogInfo($"CT Players: {string.Join(", ", _mixScrims.GetPlayingCtPlayers())}");
Logger.LogInfo($"T Players: {string.Join(", ", _mixScrims.GetPlayingTPlayers())}");- API is stable across minor MixScrims updates
- Test with your target MixScrims version
- Check for API interface existence before use
- Handle API not available gracefully in your plugin
| Category | Methods |
|---|---|
| State Management |
GetCurrentMatchState(), SetMatchState(), GetCurrentPluginState(), SetPluginState()
|
| Team Configuration |
SetCounterTerroristsTeamName(), SetTerroristsTeamName(), SetCtCaptain(), SetTCaptain()
|
| Match Flow |
StartWarmup(), StartMapVoting(), StartTeamPicking(), StartKnifeRound(), StartMatch(), CancelMatch(), ChangeMap()
|
| Timeout & Surrender |
StartTimeoutCt(), StartTimeoutT(), StopTimeout(), SurrenderCt(), SurrenderT()
|
| Player Management |
ForceAllPlayersToReady(), ForceAllPlayersToUnready(), KickNotPlayingPlayers(), KickNotPickedPlayers(), PreventNewPlayersJoining()
|
| CT Picked Players |
GetPickedCtPlayers(), AddPlayerToPickedCtPlayers(), RemovePlayerFromPickedCtPlayers()
|
| T Picked Players |
GetPickedTPlayers(), AddPlayerToPickedTPlayers(), RemovePlayerFromPickedTPlayers()
|
| CT Playing Players |
GetPlayingCtPlayers(), AddPlayerToPlayingCtPlayers(), RemovePlayerFromPlayingCtPlayers()
|
| T Playing Players |
GetPlayingTPlayers(), AddPlayerToPlayingTPlayers(), RemovePlayerFromPlayingTPlayers()
|
| Punishment System |
GetPlayersWaitingForPunishment(), AddPlayerToWaitingForPunishmentList(), RemovePlayerFromWaitingForPunishmentList()
|
- Source Code: GitHub Repository
- Issue Tracker: Report bugs or request features on GitHub Issues
- Documentation: Full wiki available in repository
For plugin development questions, refer to the Swiftly Plugin Development Guide.