Mod Examples
From fCraft Wiki
This page demonstrates examples of modifying and extending fCraft.
Contents |
[edit] Hooking up custom code
| | This method of modding fCraft's code directly will be obsoleted when the plugin system is done |
Until the proper Plugin API is finished, I recommend minimizing edits to fCraft's existing files, and trying to contain all custom code in your own namespace/files. You will need to make at least one change to Server.cs though, to add your code to run on startup. Use that very first call to subscribe to various events. For detailed information about the startup procedure, see API: Startup.
// Add this to beginning of Server.InitServer ClassWithMyMods.Init(); // Meanwhile, in ClassWithMyMods: // Use this to hook up events. Dont do anything else quite yet. public static void Init(){ Server.Initialized += MyServerInitializedHandler; Server.Started += MyServerStartedHandler; // etc events } // This is where you can go ahead and register custom commands, brushes, etc // Server.Initialized is invoked after everything else in Server.InitServer() is done static void MyServerInitializedHandler( object sender, EventArgs e ){ CommandManager.RegisterCustomCommand( CdMyCommandStuff ); } // This is where you can start timers, open up ports, manipulate world list, etc // Server.Started is invoked just after server fully finished its startup routine static void MyServerStartedHandler( object sender, EventArgs e ){ Scheduler.NewTask( MyTask ).RunForever( myTaskInterval ); }
[edit] Calling custom code at regular intervals
The following example will call BleepTask method every 10 seconds.
// Interval at which your callback is called TimeSpan bleepInterval = TimeSpan.FromSeconds( 10 ); // Adding your callback Scheduler.NewTask( BleepTask ).RunForever( bleepInterval ); // Your callback. Implements SchedulerCallback delegate. void BleepTask( SchedulerTask task ){ Chat.Say( Player.Console, "bleep" ); }
Besides RunForever(TimeSpan), SchedulerTask has many Run* methods for running a task once, several times, or forever - with different delays and at different intervals.
[edit] Checking incoming players
There are many events fired while the player is connecting. For a full explanation, see API: Login. For example Player.Connected event is fired after fCraft looks player up in the database/verifies name/checks bans, but just before a handshake reply is sent to the player. This event allows addition more checks before player is allowed into the server. Here we're using Player.Ready event, which is fired when a player is fully connected, and just after they join the main map. This is where all announcement code should go.
// Subscribing to the event Player.Ready += OnPlayerReady; // Event handler void OnPlayerReady( object sender, PlayerEventArgs e ) { // if connecting player is of highest rank (presumably owner) if( e.Player.Info.Rank == RankManager.HighestRank ) { // Get a list of players who can see them join // (to avoid accidentally revealing hidden owners) var playersToMsg = Server.Players.CanSee( e.Player ); // Spam them (use &Y colorcode, which maps to SayColor) playersToMsg.Message( "&YOMG THE OWNER IS HERE! EVERYONE SAY \"HEY {0}\"", e.Player.Name ); // or, if player's name contains the word "grief" } else if( e.Player.Name.Contains( "grief", StringComparison.OrdinalIgnoreCase ) ) { // Spam everyone some more! Server.Message( "&YLOOK OUT! GRIEFERS ARE COMING!" ); } }
[edit] Adding a new command
New commands can be added by calling CommandManager.RegisterCustomCommand. You need to provide a CommandDescriptor object. If there is any conflict between your command and existing ones, or if some aspect of your command's descriptor is unacceptible, a CommandRegistrationException will be thrown.
// Command descriptor CommandDescriptor CdBleep = new CommandDescriptor { Name = "bleep", Aliases = new[] { "bloop" }, Category = CommandCategory.Chat, Permissions = new[] { Permission.Chat }, Help = "Prints a number of bleeps in chat.", Usage = "/bleep [Times]", Handler = BleepHandler }; // Command handler - must implement CommandHandler delegate void BleepHandler( Player player, Command cmd ) { int numberOfBleeps = 10; // if a param is given if( cmd.HasNext ) { // try to parse it as a number, and save to numberOfBleeps if( !cmd.NextInt( out numberOfBleeps ) ) { // if that fails (not a number), print usage CdBleep.PrintUsage( player ); return; } } // check the range if( numberOfBleeps < 1 || numberOfBleeps > 32 ) { player.Message( "Specify between 1 and 32 bleeps." ); return; } for( int i = 0; i < numberOfBleeps; i++ ) { Chat.SendGlobal( player, "bleep" ); } } // Registering your command with the server CommandManager.RegisterCustomCommand( CdBleep );
[edit] Reacting to server shutdown
There are two events associated with shutdown: Server.ShutdownBegan and Server.ShutdownEnded. Both supply a ShutdownEventArgs object that provides information about the shutdown parameters. For more information about how server shutdown works, see API: Shutdown.
// Subscribing to the event Server.ShutdownBegan += OnShutdownBegan; // Event handler void OnShutdownBegan( object sender, ShutdownEventArgs e ){ Console.Write( "The end is near!" ); if( e.Restart ){ Console.Write( "But we will be back shortly." ); } }