From 1e947a38b002500037b84fc5e2a663bceaa6586b Mon Sep 17 00:00:00 2001 From: Jonty800 Date: Tue, 6 Aug 2013 20:57:40 +0100 Subject: [PATCH] Code cleanup on all 245 files --- ConfigGUI/AddWorldPopup.cs | 451 ++++--- ConfigGUI/ChatPreview.cs | 48 +- ConfigGUI/ColorPicker.cs | 6 +- ConfigGUI/CustomPictureBox.cs | 8 +- ConfigGUI/DeleteRankPopup.cs | 17 +- ConfigGUI/KeywordPicker.cs | 18 +- ConfigGUI/MainForm.Adapter.cs | 338 ++--- ConfigGUI/MainForm.ToolTips.cs | 277 ++-- ConfigGUI/MainForm.cs | 781 ++++++----- ConfigGUI/PermissionLimitBox.cs | 19 +- ConfigGUI/Program.cs | 11 +- ConfigGUI/Properties/AssemblyInfo.cs | 21 +- ConfigGUI/SortableBindingList.cs | 65 +- ConfigGUI/TextEditorPopup.cs | 29 +- ConfigGUI/UpdaterSettingsPopup.cs | 52 +- ConfigGUI/WorldListEntry.cs | 485 +++---- ConfigGUI/app.config | 2 +- ServerCLI/Program.cs | 122 +- ServerCLI/Properties/AssemblyInfo.cs | 21 +- ServerCLI/app.config | 2 +- ServerGUI/ConsoleBox.cs | 51 +- ServerGUI/MainForm.cs | 146 ++- ServerGUI/Program.cs | 10 +- ServerGUI/Properties/AssemblyInfo.cs | 21 +- ServerGUI/SkinViewer.cs | 69 +- ServerGUI/UpdateWindow.cs | 39 +- ServerGUI/app.config | 2 +- UpdateInstaller/Program.cs | 293 ++--- UpdateInstaller/Properties/AssemblyInfo.cs | 20 +- UpdateInstaller/ZipStorer.cs | 261 ++-- UpdateInstaller/app.config | 2 +- UpdaterBuilder/Program.cs | 33 +- UpdaterBuilder/Properties/AssemblyInfo.cs | 22 +- UpdaterBuilder/ZipStorer.cs | 261 ++-- UpdaterBuilder/app.config | 2 +- fCraft/AutoRank/AutoRankManager.cs | 41 +- fCraft/AutoRank/Conditions.cs | 199 +-- fCraft/AutoRank/Criterion.cs | 36 +- fCraft/Commands/BuildingCommands.cs | 611 +++++---- fCraft/Commands/ChatCommands.cs | 141 +- .../Command Handlers/BroModeHandler.cs | 131 +- fCraft/Commands/Command Handlers/FeedData.cs | 73 +- .../Commands/Command Handlers/FlyHandler.cs | 21 +- .../Commands/Command Handlers/GunHandler.cs | 511 +++----- .../Commands/Command Handlers/LifeHandler.cs | 1015 +++++++-------- .../Math Handlers/EqualityDrawOperation.cs | 247 ++-- .../Math Handlers/Expression.cs | 597 +++++---- .../Math Handlers/FuncDrawOperation.cs | 278 ++-- .../Math Handlers/FuncDrawOperationPSF.cs | 272 ++-- .../Math Handlers/InequalityDrawOperation.cs | 157 +-- .../Math Handlers/ManifoldDrawOperation.cs | 193 ++- .../PrepareParametrizedManifold.cs | 274 ++-- .../Command Handlers/Math Handlers/Scaler.cs | 114 +- .../Math Handlers/SimpleParser.cs | 433 +++---- .../Commands/Command Handlers/RealmHandler.cs | 63 +- .../Commands/Command Handlers/VoteHandler.cs | 62 +- fCraft/Commands/Command.cs | 59 +- fCraft/Commands/CommandCategory.cs | 4 +- fCraft/Commands/CommandDescriptor.cs | 44 +- fCraft/Commands/CommandManager.cs | 115 +- fCraft/Commands/DevCommands.cs | 30 +- fCraft/Commands/FunCommands.cs | 49 +- fCraft/Commands/InfoCommands.cs | 236 ++-- fCraft/Commands/MaintenanceCommands.cs | 187 ++- fCraft/Commands/MathCommands.cs | 62 +- fCraft/Commands/ModerationCommands.cs | 352 +++-- fCraft/Commands/System.Drawing/FontHandler.cs | 76 +- fCraft/Commands/System.Drawing/ShapesLib.cs | 118 +- fCraft/Commands/WorldCommands.cs | 504 ++++---- fCraft/Commands/ZoneCommands.cs | 106 +- fCraft/Doors/Door.cs | 53 +- fCraft/Doors/DoorException.cs | 19 +- fCraft/Doors/DoorHandler.cs | 58 +- fCraft/Doors/DoorRange.cs | 22 +- fCraft/Doors/DoorSerialization.cs | 46 +- fCraft/Drawing/Axis.cs | 5 +- fCraft/Drawing/BrushManager.cs | 33 +- .../Brushes/AbstractPerlinNoiseBrush.cs | 61 +- fCraft/Drawing/Brushes/CheckeredBrush.cs | 71 +- fCraft/Drawing/Brushes/CloudyBrush.cs | 68 +- fCraft/Drawing/Brushes/DiagonalBrush.cs | 167 ++- fCraft/Drawing/Brushes/MarbledBrush.cs | 73 +- fCraft/Drawing/Brushes/NormalBrush.cs | 65 +- fCraft/Drawing/Brushes/RainbowBrush.cs | 28 +- fCraft/Drawing/Brushes/RandomBrush.cs | 111 +- fCraft/Drawing/Brushes/ReplaceBrush.cs | 91 +- fCraft/Drawing/Brushes/ReplaceBrushBrush.cs | 85 +- fCraft/Drawing/Brushes/ReplaceNotBrush.cs | 92 +- fCraft/Drawing/CopyState.cs | 15 +- fCraft/Drawing/DrawOpWithBrush.cs | 16 +- fCraft/Drawing/DrawOperation.cs | 131 +- .../Drawing/DrawOps/BlockDBDrawOperation.cs | 65 +- fCraft/Drawing/DrawOps/CuboidDrawOperation.cs | 20 +- .../DrawOps/CuboidHollowDrawOperation.cs | 52 +- .../DrawOps/CuboidWireframeDrawOperation.cs | 80 +- fCraft/Drawing/DrawOps/CutDrawOperation.cs | 36 +- .../Drawing/DrawOps/CylinderDrawOperation.cs | 34 +- fCraft/Drawing/DrawOps/DrawImageOperation.cs | 72 +- .../Drawing/DrawOps/EllipsoidDrawOperation.cs | 50 +- .../DrawOps/EllipsoidHollowDrawOperation.cs | 92 +- fCraft/Drawing/DrawOps/Fill2DDrawOperation.cs | 126 +- fCraft/Drawing/DrawOps/LineDrawOperation.cs | 43 +- fCraft/Drawing/DrawOps/Maze.cs | 304 ++--- .../DrawOps/MazeCuboidDrawOperation.cs | 113 +- fCraft/Drawing/DrawOps/PasteDrawOperation.cs | 76 +- .../DrawOps/QuickPasteDrawOperation.cs | 6 +- .../DrawOps/RandomMazeDrawOperation.cs | 367 +++--- fCraft/Drawing/DrawOps/SphereDrawOperation.cs | 20 +- .../DrawOps/SphereHollowDrawOperation.cs | 20 +- fCraft/Drawing/DrawOps/TorusDrawOperation.cs | 49 +- .../Drawing/DrawOps/TriangleDrawOperation.cs | 84 +- .../DrawOps/TriangleWireframeDrawOperation.cs | 45 +- fCraft/Drawing/DrawOps/UndoDrawOperation.cs | 26 +- fCraft/Drawing/DrawOps/WallsOp.cs | 23 +- fCraft/Drawing/IBrush.cs | 5 +- fCraft/Drawing/UndoState.cs | 83 +- fCraft/Games/Football.cs | 17 +- fCraft/Games/GameMode.cs | 8 +- fCraft/Games/MineChallenge.cs | 94 +- fCraft/Games/MineField.cs | 33 +- fCraft/Games/PlayerProximityTracker.cs | 417 +++--- fCraft/Games/Spell.cs | 7 +- fCraft/Games/ZombieGame.cs | 45 +- fCraft/MapConversion/IMapConverter.cs | 66 +- fCraft/MapConversion/INIFile.cs | 55 +- fCraft/MapConversion/MapD3.cs | 162 ++- fCraft/MapConversion/MapDAT.cs | 191 +-- fCraft/MapConversion/MapFCMv2.cs | 62 +- fCraft/MapConversion/MapFCMv3.cs | 228 ++-- fCraft/MapConversion/MapFCMv4.cs | 119 +- fCraft/MapConversion/MapFormat.cs | 5 +- fCraft/MapConversion/MapFormatException.cs | 12 +- fCraft/MapConversion/MapJTE.cs | 115 +- fCraft/MapConversion/MapMCSharp.cs | 279 ++-- fCraft/MapConversion/MapMinerCPP.cs | 63 +- fCraft/MapConversion/MapMyne.cs | 65 +- fCraft/MapConversion/MapNBT.cs | 37 +- fCraft/MapConversion/MapOpticraft.cs | 124 +- fCraft/MapConversion/MapUtility.cs | 62 +- fCraft/MapConversion/NBTag.cs | 319 +++-- fCraft/MessageBlocks/MessageBlock.cs | 65 +- fCraft/MessageBlocks/MessageBlockHandler.cs | 34 +- fCraft/MessageBlocks/MessageBlockRange.cs | 15 +- .../MessageBlockSerialization.cs | 17 +- fCraft/Network/Heartbeat.cs | 291 ++--- fCraft/Network/IPBanInfo.cs | 77 +- fCraft/Network/IPBanList.cs | 317 ++--- fCraft/Network/IRC.cs | 296 +++-- fCraft/Network/IRCCommands.cs | 10 +- fCraft/Network/IRCMessage.cs | 20 +- fCraft/Network/LineWrapper.cs | 332 +++-- fCraft/Network/OpCode.cs | 1 + fCraft/Network/Packet.cs | 16 +- fCraft/Network/PacketWriter.cs | 109 +- fCraft/Network/Player.Networking.cs | 328 +++-- fCraft/Physics/ExplodingPhysics.cs | 260 ++-- fCraft/Physics/Life/Life2DZone.cs | 995 +++++++------- fCraft/Physics/Life/Life2d.cs | 291 ++--- fCraft/Physics/Life/LifeSerialization.cs | 81 +- fCraft/Physics/ParticleSystem.cs | 494 +++---- fCraft/Physics/Physics.cs | 224 ++-- fCraft/Physics/PhysicsHeap.cs | 148 +-- fCraft/Physics/PhysicsScheduler.cs | 208 ++- fCraft/Physics/PlantPhysics.cs | 202 ++- fCraft/Physics/SandPhysics.cs | 54 +- fCraft/Physics/TreeGeneration.cs | 71 +- fCraft/Physics/WaterPhysics.cs | 138 +- fCraft/Player/Chat.cs | 570 ++++---- fCraft/Player/ChatTimer.cs | 86 +- fCraft/Player/Permission.cs | 7 +- fCraft/Player/Player.Events.cs | 234 ++-- fCraft/Player/Player.cs | 634 ++++----- fCraft/Player/PlayerConstants.cs | 21 +- fCraft/Player/PlayerDB.cs | 401 +++--- fCraft/Player/PlayerEnumerable.cs | 412 +++--- fCraft/Player/PlayerInfo.Actions.cs | 433 ++++--- fCraft/Player/PlayerInfo.Events.cs | 124 +- fCraft/Player/PlayerInfo.cs | 724 ++++++----- fCraft/Player/PlayerOpException.cs | 153 ++- fCraft/Player/Position.cs | 29 +- fCraft/Player/Rank.cs | 256 ++-- fCraft/Player/RankManager.cs | 116 +- fCraft/Plugins/Plugin.cs | 17 +- fCraft/Plugins/PluginConfig.cs | 33 +- fCraft/Plugins/PluginConfigSerializer.cs | 33 +- fCraft/Plugins/PluginManager.cs | 16 +- fCraft/Plugins/Plugins/TrollPlugin.cs | 100 +- fCraft/Plugins/SecurityController.cs | 176 +-- fCraft/Portals/Portal.cs | 65 +- fCraft/Portals/PortalException.cs | 19 +- fCraft/Portals/PortalHandler.cs | 38 +- fCraft/Portals/PortalRange.cs | 22 +- fCraft/Portals/PortalSerialization.cs | 45 +- fCraft/Properties/AssemblyInfo.cs | 21 +- fCraft/System/ArgKey.cs | 4 +- fCraft/System/Config.cs | 524 ++++---- fCraft/System/ConfigKey.Metadata.cs | 159 +-- fCraft/System/ConfigKey.cs | 69 +- fCraft/System/ConfigSection.cs | 1 + fCraft/System/Logger.cs | 439 +++---- fCraft/System/Scheduler.cs | 120 +- fCraft/System/SchedulerTask.cs | 63 +- fCraft/System/Server.Events.cs | 60 +- fCraft/System/Server.cs | 618 ++++----- fCraft/Utils/BoundingBox.cs | 54 +- fCraft/Utils/Color.cs | 453 +++---- fCraft/Utils/Direction.cs | 45 +- fCraft/Utils/EventInterfaces.cs | 10 +- fCraft/Utils/ExtensionMethods.cs | 687 ++++------ fCraft/Utils/HeartbeatSaverUtil.cs | 38 +- fCraft/Utils/IClassy.cs | 4 +- fCraft/Utils/JetBrains.Annotations.cs | 149 +-- fCraft/Utils/LogRecorder.cs | 50 +- fCraft/Utils/MetadataCollection.cs | 244 ++-- fCraft/Utils/MonoCompat.cs | 122 +- fCraft/Utils/Noise.cs | 354 +++-- fCraft/Utils/PathFinding.cs | 147 +-- fCraft/Utils/Paths.cs | 168 ++- fCraft/Utils/PerlinNoise3D.cs | 55 +- fCraft/Utils/RWLSExtension.cs | 22 +- fCraft/Utils/Trie.cs | 521 ++++---- fCraft/Utils/Updater.cs | 142 +- fCraft/Utils/Vector3F.cs | 118 +- fCraft/Utils/Vector3I.cs | 127 +- fCraft/Utils/YesNoAuto.cs | 1 + fCraft/Utils/ZipStorer.cs | 298 +++-- fCraft/World/Block.cs | 1 + fCraft/World/BlockChangeContext.cs | 3 +- fCraft/World/BlockDB.cs | 420 +++--- fCraft/World/BlockDBEntry.cs | 9 +- fCraft/World/BlockDBSearchType.cs | 2 + fCraft/World/BlockUpdate.cs | 7 +- fCraft/World/Forester.cs | 547 ++++---- fCraft/World/Map.cs | 252 ++-- fCraft/World/MapGenerator.cs | 912 ++++++------- fCraft/World/MapGeneratorArgs.cs | 335 ++--- fCraft/World/World.Events.cs | 26 +- fCraft/World/World.cs | 1141 ++++++++--------- fCraft/World/WorldManager.cs | 433 ++++--- fCraft/World/WorldOpException.cs | 8 +- fCraft/World/Zone.cs | 213 ++- fCraft/World/ZoneCollection.cs | 154 +-- fCraftGUI/AboutWindow.cs | 14 +- fCraftGUI/IsoCat.cs | 227 ++-- fCraftGUI/Properties/AssemblyInfo.cs | 22 +- 245 files changed, 18397 insertions(+), 19276 deletions(-) diff --git a/ConfigGUI/AddWorldPopup.cs b/ConfigGUI/AddWorldPopup.cs index 0b4d821..e2cb806 100644 --- a/ConfigGUI/AddWorldPopup.cs +++ b/ConfigGUI/AddWorldPopup.cs @@ -12,49 +12,49 @@ using fCraft.GUI; using fCraft.MapConversion; - namespace fCraft.ConfigGUI { + sealed partial class AddWorldPopup : Form { - readonly BackgroundWorker bwLoader = new BackgroundWorker(), + + private readonly BackgroundWorker bwLoader = new BackgroundWorker(), bwGenerator = new BackgroundWorker(), bwRenderer = new BackgroundWorker(); - const string MapLoadFilter = "Minecraft Maps|*.fcm;*.lvl;*.dat;*.mclevel;*.gz;*.map;*.meta;*.mine;*.save"; + private const string MapLoadFilter = "Minecraft Maps|*.fcm;*.lvl;*.dat;*.mclevel;*.gz;*.map;*.meta;*.mine;*.save"; + + private readonly object redrawLock = new object(); - readonly object redrawLock = new object(); + private Map map; - Map map; - Map Map { + private Map Map { get { return map; } set { try { - bOK.Invoke( (MethodInvoker)delegate { + bOK.Invoke( ( MethodInvoker )delegate { try { - bOK.Enabled = (value != null); + bOK.Enabled = ( value != null ); lCreateMap.Visible = !bOK.Enabled; - } catch( ObjectDisposedException ) { - } catch( InvalidOperationException ) { } + } catch ( ObjectDisposedException ) { + } catch ( InvalidOperationException ) { } } ); - } catch( ObjectDisposedException ) { - } catch( InvalidOperationException ) { } + } catch ( ObjectDisposedException ) { + } catch ( InvalidOperationException ) { } map = value; } } - Stopwatch stopwatch; - int previewRotation; - Bitmap previewImage; - bool floodBarrier; - string originalWorldName; - readonly List copyOptionsList = new List(); - Tabs tab; - + private Stopwatch stopwatch; + private int previewRotation; + private Bitmap previewImage; + private bool floodBarrier; + private string originalWorldName; + private readonly List copyOptionsList = new List(); + private Tabs tab; internal WorldListEntry World { get; private set; } - public AddWorldPopup( WorldListEntry world ) { InitializeComponent(); fileBrowser.Filter = MapLoadFilter; @@ -83,7 +83,7 @@ public AddWorldPopup( WorldListEntry world ) { cAccess.Items.Add( "(everyone)" ); cBuild.Items.Add( "(everyone)" ); - foreach( Rank rank in RankManager.Ranks ) { + foreach ( Rank rank in RankManager.Ranks ) { cAccess.Items.Add( MainForm.ToComboBoxOption( rank ) ); cBuild.Items.Add( MainForm.ToComboBoxOption( rank ) ); } @@ -105,22 +105,21 @@ public AddWorldPopup( WorldListEntry world ) { Shown += LoadMap; } - - void LoadMap( object sender, EventArgs args ) { + private void LoadMap( object sender, EventArgs args ) { // Fill in the "Copy existing world" combobox - foreach( WorldListEntry otherWorld in MainForm.Worlds ) { - if( otherWorld != World ) { + foreach ( WorldListEntry otherWorld in MainForm.Worlds ) { + if ( otherWorld != World ) { cWorld.Items.Add( otherWorld.Name + " (" + otherWorld.Description + ")" ); copyOptionsList.Add( otherWorld ); } } - if( World == null ) { + if ( World == null ) { Text = "Adding a New World"; // keep trying "NewWorld#" until we find an unused number int worldNameCounter = 1; - while( MainForm.IsWorldNameTaken( "NewWorld" + worldNameCounter ) ) { + while ( MainForm.IsWorldNameTaken( "NewWorld" + worldNameCounter ) ) { worldNameCounter++; } @@ -132,7 +131,6 @@ void LoadMap( object sender, EventArgs args ) { cBackup.SelectedIndex = 5; xBlockDB.CheckState = CheckState.Indeterminate; Map = null; - } else { // Editing a world World = new WorldListEntry( World ); @@ -144,13 +142,15 @@ void LoadMap( object sender, EventArgs args ) { cBackup.SelectedItem = World.Backup; xHidden.Checked = World.Hidden; - switch( World.BlockDBEnabled ) { + switch ( World.BlockDBEnabled ) { case YesNoAuto.Auto: xBlockDB.CheckState = CheckState.Indeterminate; break; + case YesNoAuto.Yes: xBlockDB.CheckState = CheckState.Checked; break; + case YesNoAuto.No: xBlockDB.CheckState = CheckState.Unchecked; break; @@ -158,7 +158,7 @@ void LoadMap( object sender, EventArgs args ) { } // Disable "copy" tab if there are no other worlds - if( cWorld.Items.Count > 0 ) { + if ( cWorld.Items.Count > 0 ) { cWorld.SelectedIndex = 0; } else { tabs.TabPages.Remove( tabCopy ); @@ -166,7 +166,7 @@ void LoadMap( object sender, EventArgs args ) { // Disable "existing map" tab if mapfile does not exist fileToLoad = World.FullFileName; - if( File.Exists( fileToLoad ) ) { + if ( File.Exists( fileToLoad ) ) { ShowMapDetails( tExistingMapInfo, fileToLoad ); StartLoadingMap(); } else { @@ -175,15 +175,14 @@ void LoadMap( object sender, EventArgs args ) { } // Set Generator comboboxes to defaults - cTemplates.SelectedIndex = (int)MapGenTemplate.River; + cTemplates.SelectedIndex = ( int )MapGenTemplate.River; savePreviewDialog.FileName = World.Name; } - #region Loading/Saving Map - void StartLoadingMap() { + private void StartLoadingMap() { Map = null; tStatus1.Text = "Loading " + new FileInfo( fileToLoad ).Name; tStatus2.Text = ""; @@ -194,7 +193,7 @@ void StartLoadingMap() { private void bBrowseFile_Click( object sender, EventArgs e ) { fileBrowser.FileName = tFile.Text; - if( fileBrowser.ShowDialog() == DialogResult.OK && !String.IsNullOrEmpty( fileBrowser.FileName ) ) { + if ( fileBrowser.ShowDialog() == DialogResult.OK && !String.IsNullOrEmpty( fileBrowser.FileName ) ) { tFolder.Text = ""; tFile.Text = fileBrowser.FileName; tFile.SelectAll(); @@ -208,7 +207,7 @@ private void bBrowseFile_Click( object sender, EventArgs e ) { } private void bBrowseFolder_Click( object sender, EventArgs e ) { - if( folderBrowser.ShowDialog() == DialogResult.OK && !String.IsNullOrEmpty( folderBrowser.SelectedPath ) ) { + if ( folderBrowser.ShowDialog() == DialogResult.OK && !String.IsNullOrEmpty( folderBrowser.SelectedPath ) ) { tFile.Text = ""; tFolder.Text = folderBrowser.SelectedPath; tFolder.SelectAll(); @@ -221,78 +220,82 @@ private void bBrowseFolder_Click( object sender, EventArgs e ) { } } - string fileToLoad; - void AsyncLoad( object sender, DoWorkEventArgs e ) { + private string fileToLoad; + + private void AsyncLoad( object sender, DoWorkEventArgs e ) { stopwatch = Stopwatch.StartNew(); try { Map = MapUtility.Load( fileToLoad ); Map.CalculateShadows(); - } catch( Exception ex ) { + } catch ( Exception ex ) { MessageBox.Show( String.Format( "Could not load specified map: {0}: {1}", ex.GetType().Name, ex.Message ) ); } } - void AsyncLoadCompleted( object sender, RunWorkerCompletedEventArgs e ) { + private void AsyncLoadCompleted( object sender, RunWorkerCompletedEventArgs e ) { stopwatch.Stop(); - if( Map == null ) { + if ( Map == null ) { tStatus1.Text = "Load failed!"; } else { tStatus1.Text = "Load successful (" + stopwatch.Elapsed.TotalSeconds.ToString( "0.000" ) + "s)"; tStatus2.Text = ", drawing..."; Redraw( true ); } - if( tab == Tabs.CopyWorld ) { + if ( tab == Tabs.CopyWorld ) { bShow.Enabled = true; } } - #endregion Loading - + #endregion Loading/Saving Map #region Map Preview - IsoCat renderer; + private IsoCat renderer; - void Redraw( bool drawAgain ) { - lock( redrawLock ) { + private void Redraw( bool drawAgain ) { + lock ( redrawLock ) { progressBar.Visible = true; progressBar.Style = ProgressBarStyle.Continuous; - if( bwRenderer.IsBusy ) { + if ( bwRenderer.IsBusy ) { bwRenderer.CancelAsync(); - while( bwRenderer.IsBusy ) { + while ( bwRenderer.IsBusy ) { Thread.Sleep( 1 ); Application.DoEvents(); } } - if( drawAgain ) bwRenderer.RunWorkerAsync(); + if ( drawAgain ) + bwRenderer.RunWorkerAsync(); } } - void AsyncDraw( object sender, DoWorkEventArgs e ) { + private void AsyncDraw( object sender, DoWorkEventArgs e ) { stopwatch = Stopwatch.StartNew(); renderer = new IsoCat( Map, IsoCatMode.Normal, previewRotation ); Rectangle cropRectangle; - if( bwRenderer.CancellationPending ) return; + if ( bwRenderer.CancellationPending ) + return; Bitmap rawImage = renderer.Draw( out cropRectangle, bwRenderer ); - if( bwRenderer.CancellationPending ) return; - if( rawImage != null ) { + if ( bwRenderer.CancellationPending ) + return; + if ( rawImage != null ) { previewImage = rawImage.Clone( cropRectangle, rawImage.PixelFormat ); } renderer = null; GC.Collect( GC.MaxGeneration, GCCollectionMode.Optimized ); } - void AsyncDrawProgress( object sender, ProgressChangedEventArgs e ) { + private void AsyncDrawProgress( object sender, ProgressChangedEventArgs e ) { progressBar.Value = e.ProgressPercentage; } - void AsyncDrawCompleted( object sender, RunWorkerCompletedEventArgs e ) { + private void AsyncDrawCompleted( object sender, RunWorkerCompletedEventArgs e ) { stopwatch.Stop(); tStatus2.Text = String.Format( "drawn ({0:0.000}s)", stopwatch.Elapsed.TotalSeconds ); - if( previewImage != null && previewImage != preview.Image ) { + if ( previewImage != null && previewImage != preview.Image ) { Image oldImage = preview.Image; - if( oldImage != null ) oldImage.Dispose(); + if ( oldImage != null ) + oldImage.Dispose(); preview.Image = previewImage; bSavePreview.Enabled = true; } @@ -300,35 +303,40 @@ void AsyncDrawCompleted( object sender, RunWorkerCompletedEventArgs e ) { } private void bPreviewPrev_Click( object sender, EventArgs e ) { - if( Map == null ) return; - if( previewRotation == 0 ) previewRotation = 3; - else previewRotation--; + if ( Map == null ) + return; + if ( previewRotation == 0 ) + previewRotation = 3; + else + previewRotation--; tStatus2.Text = ", redrawing..."; Redraw( true ); } private void bPreviewNext_Click( object sender, EventArgs e ) { - if( Map == null ) return; - if( previewRotation == 3 ) previewRotation = 0; - else previewRotation++; + if ( Map == null ) + return; + if ( previewRotation == 3 ) + previewRotation = 0; + else + previewRotation++; tStatus2.Text = ", redrawing..."; Redraw( true ); } - #endregion - + #endregion Map Preview #region Map Generation - MapGeneratorArgs generatorArgs = new MapGeneratorArgs(); + private MapGeneratorArgs generatorArgs = new MapGeneratorArgs(); private void bGenerate_Click( object sender, EventArgs e ) { Map = null; bGenerate.Enabled = false; bFlatgrassGenerate.Enabled = false; - if( tab == Tabs.Generator ) { - if( !xSeed.Checked ) { + if ( tab == Tabs.Generator ) { + if ( !xSeed.Checked ) { nSeed.Value = GetRandomSeed(); } @@ -347,11 +355,11 @@ private void bGenerate_Click( object sender, EventArgs e ) { World.MapChangedOn = DateTime.UtcNow; } - void AsyncGen( object sender, DoWorkEventArgs e ) { + private void AsyncGen( object sender, DoWorkEventArgs e ) { stopwatch = Stopwatch.StartNew(); GC.Collect( GC.MaxGeneration, GCCollectionMode.Forced ); Map generatedMap; - if( tab == Tabs.Generator ) { + if ( tab == Tabs.Generator ) { MapGenerator gen = new MapGenerator( generatorArgs ); gen.ProgressChanged += ( progressSender, progressArgs ) => @@ -363,20 +371,21 @@ void AsyncGen( object sender, DoWorkEventArgs e ) { Convert.ToInt32( nFlatgrassDimZ.Value ) ); } - if( floodBarrier ) generatedMap.MakeFloodBarrier(); + if ( floodBarrier ) + generatedMap.MakeFloodBarrier(); generatedMap.CalculateShadows(); Map = generatedMap; GC.Collect( GC.MaxGeneration, GCCollectionMode.Forced ); } - void AsyncGenProgress( object sender, ProgressChangedEventArgs e ) { + private void AsyncGenProgress( object sender, ProgressChangedEventArgs e ) { progressBar.Value = e.ProgressPercentage; - tStatus1.Text = (string)e.UserState; + tStatus1.Text = ( string )e.UserState; } - void AsyncGenCompleted( object sender, RunWorkerCompletedEventArgs e ) { + private void AsyncGenCompleted( object sender, RunWorkerCompletedEventArgs e ) { stopwatch.Stop(); - if( Map == null ) { + if ( Map == null ) { tStatus1.Text = "Generation failed!"; } else { tStatus1.Text = "Generation successful (" + stopwatch.Elapsed.TotalSeconds.ToString( "0.000" ) + "s)"; @@ -387,31 +396,28 @@ void AsyncGenCompleted( object sender, RunWorkerCompletedEventArgs e ) { bFlatgrassGenerate.Enabled = true; } + private readonly Random rand = new Random(); - readonly Random rand = new Random(); - int GetRandomSeed() { + private int GetRandomSeed() { return rand.Next() - rand.Next(); } - #endregion - + #endregion Map Generation #region Input Handlers - void xFloodBarrier_CheckedChanged( object sender, EventArgs e ) { + private void xFloodBarrier_CheckedChanged( object sender, EventArgs e ) { floodBarrier = xFloodBarrier.Checked; } - - static void MapDimensionValidating( object sender, CancelEventArgs e ) { - ((NumericUpDown)sender).Value = Convert.ToInt32( ((NumericUpDown)sender).Value / 16 ) * 16; + private static void MapDimensionValidating( object sender, CancelEventArgs e ) { + ( ( NumericUpDown )sender ).Value = Convert.ToInt32( ( ( NumericUpDown )sender ).Value / 16 ) * 16; } - - void tName_Validating( object sender, CancelEventArgs e ) { - if( fCraft.World.IsValidName( tName.Text ) && - (!MainForm.IsWorldNameTaken( tName.Text ) || - (originalWorldName != null && tName.Text.Equals(originalWorldName, StringComparison.OrdinalIgnoreCase))) ) { + private void tName_Validating( object sender, CancelEventArgs e ) { + if ( fCraft.World.IsValidName( tName.Text ) && + ( !MainForm.IsWorldNameTaken( tName.Text ) || + ( originalWorldName != null && tName.Text.Equals( originalWorldName, StringComparison.OrdinalIgnoreCase ) ) ) ) { tName.ForeColor = SystemColors.ControlText; } else { tName.ForeColor = System.Drawing.Color.Red; @@ -419,34 +425,28 @@ void tName_Validating( object sender, CancelEventArgs e ) { } } - - void tName_Validated( object sender, EventArgs e ) { + private void tName_Validated( object sender, EventArgs e ) { World.Name = tName.Text; } - - void cAccess_SelectedIndexChanged( object sender, EventArgs e ) { + private void cAccess_SelectedIndexChanged( object sender, EventArgs e ) { World.AccessPermission = cAccess.SelectedItem.ToString(); } - - void cBuild_SelectedIndexChanged( object sender, EventArgs e ) { + private void cBuild_SelectedIndexChanged( object sender, EventArgs e ) { World.BuildPermission = cBuild.SelectedItem.ToString(); } - - void cBackup_SelectedIndexChanged( object sender, EventArgs e ) { + private void cBackup_SelectedIndexChanged( object sender, EventArgs e ) { World.Backup = cBackup.SelectedItem.ToString(); } - - void xHidden_CheckedChanged( object sender, EventArgs e ) { + private void xHidden_CheckedChanged( object sender, EventArgs e ) { World.Hidden = xHidden.Checked; } - - void bShow_Click( object sender, EventArgs e ) { - if( cWorld.SelectedIndex != -1 && File.Exists( copyOptionsList[cWorld.SelectedIndex].FullFileName ) ) { + private void bShow_Click( object sender, EventArgs e ) { + if ( cWorld.SelectedIndex != -1 && File.Exists( copyOptionsList[cWorld.SelectedIndex].FullFileName ) ) { bShow.Enabled = false; fileToLoad = copyOptionsList[cWorld.SelectedIndex].FullFileName; ShowMapDetails( tCopyInfo, fileToLoad ); @@ -454,17 +454,15 @@ void bShow_Click( object sender, EventArgs e ) { } } - - void cWorld_SelectedIndexChanged( object sender, EventArgs e ) { - if( cWorld.SelectedIndex != -1 ) { + private void cWorld_SelectedIndexChanged( object sender, EventArgs e ) { + if ( cWorld.SelectedIndex != -1 ) { string fileName = copyOptionsList[cWorld.SelectedIndex].FullFileName; bShow.Enabled = File.Exists( fileName ); ShowMapDetails( tCopyInfo, fileName ); } } - - void xAdvanced_CheckedChanged( object sender, EventArgs e ) { + private void xAdvanced_CheckedChanged( object sender, EventArgs e ) { gTerrainFeatures.Visible = xAdvanced.Checked; gHeightmapCreation.Visible = xAdvanced.Checked; gTrees.Visible = xAdvanced.Checked && xAddTrees.Checked; @@ -474,51 +472,45 @@ void xAdvanced_CheckedChanged( object sender, EventArgs e ) { gBeaches.Visible = xAdvanced.Checked && xAddBeaches.Checked; } - - void MapDimensionChanged( object sender, EventArgs e ) { - sFeatureScale.Maximum = (int)Math.Log( (double)Math.Max( nMapWidth.Value, nMapLength.Value ), 2 ); + private void MapDimensionChanged( object sender, EventArgs e ) { + sFeatureScale.Maximum = ( int )Math.Log( ( double )Math.Max( nMapWidth.Value, nMapLength.Value ), 2 ); int value = sDetailScale.Maximum - sDetailScale.Value; sDetailScale.Maximum = sFeatureScale.Maximum; sDetailScale.Value = sDetailScale.Maximum - value; - int resolution = 1 << (sDetailScale.Maximum - sDetailScale.Value); + int resolution = 1 << ( sDetailScale.Maximum - sDetailScale.Value ); lDetailSizeDisplay.Text = resolution + "×" + resolution; - resolution = 1 << (sFeatureScale.Maximum - sFeatureScale.Value); + resolution = 1 << ( sFeatureScale.Maximum - sFeatureScale.Value ); lFeatureSizeDisplay.Text = resolution + "×" + resolution; } - - void sFeatureSize_ValueChanged( object sender, EventArgs e ) { - int resolution = 1 << (sFeatureScale.Maximum - sFeatureScale.Value); + private void sFeatureSize_ValueChanged( object sender, EventArgs e ) { + int resolution = 1 << ( sFeatureScale.Maximum - sFeatureScale.Value ); lFeatureSizeDisplay.Text = resolution + "×" + resolution; - if( sDetailScale.Value < sFeatureScale.Value ) { + if ( sDetailScale.Value < sFeatureScale.Value ) { sDetailScale.Value = sFeatureScale.Value; } } - - void sDetailSize_ValueChanged( object sender, EventArgs e ) { - int resolution = 1 << (sDetailScale.Maximum - sDetailScale.Value); + private void sDetailSize_ValueChanged( object sender, EventArgs e ) { + int resolution = 1 << ( sDetailScale.Maximum - sDetailScale.Value ); lDetailSizeDisplay.Text = resolution + "×" + resolution; - if( sFeatureScale.Value > sDetailScale.Value ) { + if ( sFeatureScale.Value > sDetailScale.Value ) { sFeatureScale.Value = sDetailScale.Value; } } - - void xMatchWaterCoverage_CheckedChanged( object sender, EventArgs e ) { + private void xMatchWaterCoverage_CheckedChanged( object sender, EventArgs e ) { sWaterCoverage.Enabled = xMatchWaterCoverage.Checked; } - - void sWaterCoverage_ValueChanged( object sender, EventArgs e ) { + private void sWaterCoverage_ValueChanged( object sender, EventArgs e ) { lMatchWaterCoverageDisplay.Text = sWaterCoverage.Value + "%"; } - - void sBias_ValueChanged( object sender, EventArgs e ) { + private void sBias_ValueChanged( object sender, EventArgs e ) { lBiasDisplay.Text = sBias.Value + "%"; - bool useBias = (sBias.Value != 0); + bool useBias = ( sBias.Value != 0 ); nRaisedCorners.Enabled = useBias; nLoweredCorners.Enabled = useBias; @@ -526,71 +518,70 @@ void sBias_ValueChanged( object sender, EventArgs e ) { xDelayBias.Enabled = useBias; } - - void sRoughness_ValueChanged( object sender, EventArgs e ) { + private void sRoughness_ValueChanged( object sender, EventArgs e ) { lRoughnessDisplay.Text = sRoughness.Value + "%"; } - - void xSeed_CheckedChanged( object sender, EventArgs e ) { + private void xSeed_CheckedChanged( object sender, EventArgs e ) { nSeed.Enabled = xSeed.Checked; } - - void nRaisedCorners_ValueChanged( object sender, EventArgs e ) { + private void nRaisedCorners_ValueChanged( object sender, EventArgs e ) { nLoweredCorners.Value = Math.Min( 4 - nRaisedCorners.Value, nLoweredCorners.Value ); } - - void nLoweredCorners_ValueChanged( object sender, EventArgs e ) { + private void nLoweredCorners_ValueChanged( object sender, EventArgs e ) { nRaisedCorners.Value = Math.Min( 4 - nLoweredCorners.Value, nRaisedCorners.Value ); } - #endregion - + #endregion Input Handlers #region Tabs private void tabs_SelectedIndexChanged( object sender, EventArgs e ) { - if( tabs.SelectedTab == tabExisting ) { + if ( tabs.SelectedTab == tabExisting ) { tab = Tabs.ExistingMap; - } else if( tabs.SelectedTab == tabLoad ) { + } else if ( tabs.SelectedTab == tabLoad ) { tab = Tabs.LoadFile; - } else if( tabs.SelectedTab == tabCopy ) { + } else if ( tabs.SelectedTab == tabCopy ) { tab = Tabs.CopyWorld; - } else if( tabs.SelectedTab == tabFlatgrass ) { + } else if ( tabs.SelectedTab == tabFlatgrass ) { tab = Tabs.Flatgrass; } else { tab = Tabs.Generator; } - switch( tab ) { + switch ( tab ) { case Tabs.ExistingMap: fileToLoad = World.FullFileName; ShowMapDetails( tExistingMapInfo, fileToLoad ); StartLoadingMap(); return; + case Tabs.LoadFile: - if( !String.IsNullOrEmpty( tFile.Text ) ) { + if ( !String.IsNullOrEmpty( tFile.Text ) ) { tFile.SelectAll(); fileToLoad = tFile.Text; ShowMapDetails( tLoadFileInfo, fileToLoad ); StartLoadingMap(); } return; + case Tabs.CopyWorld: - if( cWorld.SelectedIndex != -1 ) { + if ( cWorld.SelectedIndex != -1 ) { bShow.Enabled = File.Exists( copyOptionsList[cWorld.SelectedIndex].FullFileName ); } return; + case Tabs.Flatgrass: return; + case Tabs.Generator: return; } } - enum Tabs { + private enum Tabs { ExistingMap, LoadFile, CopyWorld, @@ -598,25 +589,22 @@ enum Tabs { Generator } - #endregion - + #endregion Tabs - static void ShowMapDetails( TextBox textBox, string fileName ) { + private static void ShowMapDetails( TextBox textBox, string fileName ) { DateTime creationTime, modificationTime; long fileSize; - if( File.Exists( fileName ) ) { + if ( File.Exists( fileName ) ) { FileInfo existingMapFileInfo = new FileInfo( fileName ); creationTime = existingMapFileInfo.CreationTime; modificationTime = existingMapFileInfo.LastWriteTime; fileSize = existingMapFileInfo.Length; - - } else if( Directory.Exists( fileName ) ) { + } else if ( Directory.Exists( fileName ) ) { DirectoryInfo dirInfo = new DirectoryInfo( fileName ); creationTime = dirInfo.CreationTime; modificationTime = dirInfo.LastWriteTime; fileSize = dirInfo.GetFiles().Sum( finfo => finfo.Length ); - } else { textBox.Text = "File or directory \"" + fileName + "\" does not exist."; return; @@ -636,15 +624,14 @@ static void ShowMapDetails( TextBox textBox, string fileName ) { textBox.Text = String.Format( msgFormat, fileName, format, - (fileSize / 1024), + ( fileSize / 1024 ), creationTime.ToLongDateString(), modificationTime.ToLongDateString(), loadedMap.Width, loadedMap.Length, loadedMap.Height, loadedMap.Volume ); - - } catch( Exception ex ) { + } catch ( Exception ex ) { const string msgFormat = @" Location: {0} Format: {1} @@ -657,7 +644,7 @@ static void ShowMapDetails( TextBox textBox, string fileName ) { textBox.Text = String.Format( msgFormat, fileName, format, - (fileSize / 1024), + ( fileSize / 1024 ), creationTime.ToLongDateString(), modificationTime.ToLongDateString(), ex.GetType().Name, @@ -665,11 +652,10 @@ static void ShowMapDetails( TextBox textBox, string fileName ) { } } - private void AddWorldPopup_FormClosing( object sender, FormClosingEventArgs e ) { Redraw( false ); - if( DialogResult == DialogResult.OK ) { - if( Map == null ) { + if ( DialogResult == DialogResult.OK ) { + if ( Map == null ) { e.Cancel = true; } else { bwRenderer.CancelAsync(); @@ -684,10 +670,10 @@ private void AddWorldPopup_FormClosing( object sender, FormClosingEventArgs e ) Map.Save( newFileName ); string oldFileName = Path.Combine( Paths.MapPath, originalWorldName + ".fcm" ); - if( originalWorldName != null && originalWorldName != World.Name && File.Exists( oldFileName ) ) { + if ( originalWorldName != null && originalWorldName != World.Name && File.Exists( oldFileName ) ) { try { File.Delete( oldFileName ); - } catch( Exception ex ) { + } catch ( Exception ex ) { string errorMessage = String.Format( "Renaming the map file failed. Please delete the old file ({0}.fcm) manually.{1}{2}", originalWorldName, Environment.NewLine, ex ); MessageBox.Show( errorMessage, "Error renaming the map file" ); @@ -697,49 +683,56 @@ private void AddWorldPopup_FormClosing( object sender, FormClosingEventArgs e ) } } + private readonly SaveFileDialog savePreviewDialog = new SaveFileDialog(); - readonly SaveFileDialog savePreviewDialog = new SaveFileDialog(); private void bSavePreview_Click( object sender, EventArgs e ) { try { - using( Image img = (Image)preview.Image.Clone() ) { - if( savePreviewDialog.ShowDialog() == DialogResult.OK && !String.IsNullOrEmpty( savePreviewDialog.FileName ) ) { - switch( savePreviewDialog.FilterIndex ) { + using ( Image img = ( Image )preview.Image.Clone() ) { + if ( savePreviewDialog.ShowDialog() == DialogResult.OK && !String.IsNullOrEmpty( savePreviewDialog.FileName ) ) { + switch ( savePreviewDialog.FilterIndex ) { case 1: - img.Save( savePreviewDialog.FileName, ImageFormat.Png ); break; + img.Save( savePreviewDialog.FileName, ImageFormat.Png ); + break; + case 2: - img.Save( savePreviewDialog.FileName, ImageFormat.Tiff ); break; + img.Save( savePreviewDialog.FileName, ImageFormat.Tiff ); + break; + case 3: - img.Save( savePreviewDialog.FileName, ImageFormat.Bmp ); break; + img.Save( savePreviewDialog.FileName, ImageFormat.Bmp ); + break; + case 4: - img.Save( savePreviewDialog.FileName, ImageFormat.Jpeg ); break; + img.Save( savePreviewDialog.FileName, ImageFormat.Jpeg ); + break; } } } - } catch( Exception ex ) { + } catch ( Exception ex ) { MessageBox.Show( "Could not prepare image for saving: " + ex ); } } + private readonly OpenFileDialog browseTemplateDialog = new OpenFileDialog(); - readonly OpenFileDialog browseTemplateDialog = new OpenFileDialog(); private void bBrowseTemplate_Click( object sender, EventArgs e ) { - if( browseTemplateDialog.ShowDialog() == DialogResult.OK && !String.IsNullOrEmpty( browseTemplateDialog.FileName ) ) { + if ( browseTemplateDialog.ShowDialog() == DialogResult.OK && !String.IsNullOrEmpty( browseTemplateDialog.FileName ) ) { try { generatorArgs = new MapGeneratorArgs( browseTemplateDialog.FileName ); LoadGeneratorArgs(); bGenerate.PerformClick(); - } catch( Exception ex ) { + } catch ( Exception ex ) { MessageBox.Show( "Could not open template file: " + ex ); } } } - void LoadGeneratorArgs() { + private void LoadGeneratorArgs() { nMapHeight.Value = generatorArgs.MapHeight; nMapWidth.Value = generatorArgs.MapWidth; nMapLength.Value = generatorArgs.MapLength; - cTheme.SelectedIndex = (int)generatorArgs.Theme; + cTheme.SelectedIndex = ( int )generatorArgs.Theme; sDetailScale.Value = generatorArgs.DetailScale; sFeatureScale.Value = generatorArgs.FeatureScale; @@ -751,32 +744,34 @@ void LoadGeneratorArgs() { nMaxDepth.Value = generatorArgs.MaxDepth; nMaxHeight.Value = generatorArgs.MaxHeight; - sRoughness.Value = (int)(generatorArgs.Roughness * 100); + sRoughness.Value = ( int )( generatorArgs.Roughness * 100 ); nSeed.Value = generatorArgs.Seed; xWater.Checked = generatorArgs.AddWater; - if( generatorArgs.UseBias ) sBias.Value = (int)(generatorArgs.Bias * 100); - else sBias.Value = 0; + if ( generatorArgs.UseBias ) + sBias.Value = ( int )( generatorArgs.Bias * 100 ); + else + sBias.Value = 0; xDelayBias.Checked = generatorArgs.DelayBias; - sWaterCoverage.Value = (int)(100 * generatorArgs.WaterCoverage); + sWaterCoverage.Value = ( int )( 100 * generatorArgs.WaterCoverage ); cMidpoint.SelectedIndex = generatorArgs.MidPoint + 1; nRaisedCorners.Value = generatorArgs.RaisedCorners; nLoweredCorners.Value = generatorArgs.LoweredCorners; xAddTrees.Checked = generatorArgs.AddTrees; xGiantTrees.Checked = generatorArgs.AddGiantTrees; - nTreeHeight.Value = (generatorArgs.TreeHeightMax + generatorArgs.TreeHeightMin) / 2m; - nTreeHeightVariation.Value = (generatorArgs.TreeHeightMax - generatorArgs.TreeHeightMin) / 2m; - nTreeSpacing.Value = (generatorArgs.TreeSpacingMax + generatorArgs.TreeSpacingMin) / 2m; - nTreeSpacingVariation.Value = (generatorArgs.TreeSpacingMax - generatorArgs.TreeSpacingMin) / 2m; + nTreeHeight.Value = ( generatorArgs.TreeHeightMax + generatorArgs.TreeHeightMin ) / 2m; + nTreeHeightVariation.Value = ( generatorArgs.TreeHeightMax - generatorArgs.TreeHeightMin ) / 2m; + nTreeSpacing.Value = ( generatorArgs.TreeSpacingMax + generatorArgs.TreeSpacingMin ) / 2m; + nTreeSpacingVariation.Value = ( generatorArgs.TreeSpacingMax - generatorArgs.TreeSpacingMin ) / 2m; xCaves.Checked = generatorArgs.AddCaves; xCaveLava.Checked = generatorArgs.AddCaveLava; xCaveWater.Checked = generatorArgs.AddCaveWater; xOre.Checked = generatorArgs.AddOre; - sCaveDensity.Value = (int)(generatorArgs.CaveDensity * 100); - sCaveSize.Value = (int)(generatorArgs.CaveSize * 100); + sCaveDensity.Value = ( int )( generatorArgs.CaveDensity * 100 ); + sCaveSize.Value = ( int )( generatorArgs.CaveSize * 100 ); xWaterLevel.Checked = generatorArgs.CustomWaterLevel; nWaterLevel.Maximum = generatorArgs.MapHeight; @@ -784,11 +779,11 @@ void LoadGeneratorArgs() { xAddSnow.Checked = generatorArgs.AddSnow; - nSnowAltitude.Value = generatorArgs.SnowAltitude - (generatorArgs.CustomWaterLevel ? generatorArgs.WaterLevel : generatorArgs.MapHeight / 2); + nSnowAltitude.Value = generatorArgs.SnowAltitude - ( generatorArgs.CustomWaterLevel ? generatorArgs.WaterLevel : generatorArgs.MapHeight / 2 ); nSnowTransition.Value = generatorArgs.SnowTransition; xAddCliffs.Checked = generatorArgs.AddCliffs; - sCliffThreshold.Value = (int)(generatorArgs.CliffThreshold * 100); + sCliffThreshold.Value = ( int )( generatorArgs.CliffThreshold * 100 ); xCliffSmoothing.Checked = generatorArgs.CliffSmoothing; xAddBeaches.Checked = generatorArgs.AddBeaches; @@ -802,34 +797,34 @@ void LoadGeneratorArgs() { nMaxDepthVariation.Value = generatorArgs.MaxDepthVariation; } - void SaveGeneratorArgs() { + private void SaveGeneratorArgs() { generatorArgs = new MapGeneratorArgs { DetailScale = sDetailScale.Value, FeatureScale = sFeatureScale.Value, - MapHeight = (int)nMapHeight.Value, - MapWidth = (int)nMapWidth.Value, - MapLength = (int)nMapLength.Value, + MapHeight = ( int )nMapHeight.Value, + MapWidth = ( int )nMapWidth.Value, + MapLength = ( int )nMapLength.Value, LayeredHeightmap = xLayeredHeightmap.Checked, MarbledHeightmap = xMarbledMode.Checked, MatchWaterCoverage = xMatchWaterCoverage.Checked, - MaxDepth = (int)nMaxDepth.Value, - MaxHeight = (int)nMaxHeight.Value, + MaxDepth = ( int )nMaxDepth.Value, + MaxHeight = ( int )nMaxHeight.Value, AddTrees = xAddTrees.Checked, AddGiantTrees = xGiantTrees.Checked, Roughness = sRoughness.Value / 100f, - Seed = (int)nSeed.Value, - Theme = (MapGenTheme)cTheme.SelectedIndex, - TreeHeightMax = (int)(nTreeHeight.Value + nTreeHeightVariation.Value), - TreeHeightMin = (int)(nTreeHeight.Value - nTreeHeightVariation.Value), - TreeSpacingMax = (int)(nTreeSpacing.Value + nTreeSpacingVariation.Value), - TreeSpacingMin = (int)(nTreeSpacing.Value - nTreeSpacingVariation.Value), - UseBias = (sBias.Value != 0), + Seed = ( int )nSeed.Value, + Theme = ( MapGenTheme )cTheme.SelectedIndex, + TreeHeightMax = ( int )( nTreeHeight.Value + nTreeHeightVariation.Value ), + TreeHeightMin = ( int )( nTreeHeight.Value - nTreeHeightVariation.Value ), + TreeSpacingMax = ( int )( nTreeSpacing.Value + nTreeSpacingVariation.Value ), + TreeSpacingMin = ( int )( nTreeSpacing.Value - nTreeSpacingVariation.Value ), + UseBias = ( sBias.Value != 0 ), DelayBias = xDelayBias.Checked, WaterCoverage = sWaterCoverage.Value / 100f, Bias = sBias.Value / 100f, MidPoint = cMidpoint.SelectedIndex - 1, - RaisedCorners = (int)nRaisedCorners.Value, - LoweredCorners = (int)nLoweredCorners.Value, + RaisedCorners = ( int )nRaisedCorners.Value, + LoweredCorners = ( int )nLoweredCorners.Value, InvertHeightmap = xInvert.Checked, AddWater = xWater.Checked, AddCaves = xCaves.Checked, @@ -839,38 +834,38 @@ void SaveGeneratorArgs() { CaveDensity = sCaveDensity.Value / 100f, CaveSize = sCaveSize.Value / 100f, CustomWaterLevel = xWaterLevel.Checked, - WaterLevel = (int)(xWaterLevel.Checked ? nWaterLevel.Value : nMapHeight.Value / 2), + WaterLevel = ( int )( xWaterLevel.Checked ? nWaterLevel.Value : nMapHeight.Value / 2 ), AddSnow = xAddSnow.Checked, - SnowTransition = (int)nSnowTransition.Value, - SnowAltitude = (int)(nSnowAltitude.Value + (xWaterLevel.Checked ? nWaterLevel.Value : nMapHeight.Value / 2)), + SnowTransition = ( int )nSnowTransition.Value, + SnowAltitude = ( int )( nSnowAltitude.Value + ( xWaterLevel.Checked ? nWaterLevel.Value : nMapHeight.Value / 2 ) ), AddCliffs = xAddCliffs.Checked, CliffThreshold = sCliffThreshold.Value / 100f, CliffSmoothing = xCliffSmoothing.Checked, AddBeaches = xAddBeaches.Checked, - BeachExtent = (int)nBeachExtent.Value, - BeachHeight = (int)nBeachHeight.Value, + BeachExtent = ( int )nBeachExtent.Value, + BeachHeight = ( int )nBeachHeight.Value, AboveFuncExponent = TrackBarToExponent( sAboveFunc ), BelowFuncExponent = TrackBarToExponent( sBelowFunc ), - MaxHeightVariation = (int)nMaxHeightVariation.Value, - MaxDepthVariation = (int)nMaxDepthVariation.Value + MaxHeightVariation = ( int )nMaxHeightVariation.Value, + MaxDepthVariation = ( int )nMaxDepthVariation.Value }; } + private readonly SaveFileDialog saveTemplateDialog = new SaveFileDialog(); - readonly SaveFileDialog saveTemplateDialog = new SaveFileDialog(); private void bSaveTemplate_Click( object sender, EventArgs e ) { - if( saveTemplateDialog.ShowDialog() == DialogResult.OK && !String.IsNullOrEmpty( saveTemplateDialog.FileName ) ) { + if ( saveTemplateDialog.ShowDialog() == DialogResult.OK && !String.IsNullOrEmpty( saveTemplateDialog.FileName ) ) { try { SaveGeneratorArgs(); generatorArgs.Save( saveTemplateDialog.FileName ); - } catch( Exception ex ) { + } catch ( Exception ex ) { MessageBox.Show( "Could not open template file: " + ex ); } } } private void cTemplates_SelectedIndexChanged( object sender, EventArgs e ) { - generatorArgs = MapGenerator.MakeTemplate( (MapGenTemplate)cTemplates.SelectedIndex ); + generatorArgs = MapGenerator.MakeTemplate( ( MapGenTemplate )cTemplates.SelectedIndex ); LoadGeneratorArgs(); bGenerate.PerformClick(); } @@ -905,30 +900,30 @@ private void xWater_CheckedChanged( object sender, EventArgs e ) { } private void sAboveFunc_ValueChanged( object sender, EventArgs e ) { - lAboveFuncUnits.Text = (1 / TrackBarToExponent( sAboveFunc )).ToString( "0.0%" ); + lAboveFuncUnits.Text = ( 1 / TrackBarToExponent( sAboveFunc ) ).ToString( "0.0%" ); } private void sBelowFunc_ValueChanged( object sender, EventArgs e ) { - lBelowFuncUnits.Text = (1 / TrackBarToExponent( sBelowFunc )).ToString( "0.0%" ); + lBelowFuncUnits.Text = ( 1 / TrackBarToExponent( sBelowFunc ) ).ToString( "0.0%" ); } - static float TrackBarToExponent( TrackBar bar ) { - if( bar.Value >= bar.Maximum / 2 ) { - float normalized = (bar.Value - bar.Maximum / 2f) / (bar.Maximum / 2f); + private static float TrackBarToExponent( TrackBar bar ) { + if ( bar.Value >= bar.Maximum / 2 ) { + float normalized = ( bar.Value - bar.Maximum / 2f ) / ( bar.Maximum / 2f ); return 1 + normalized * normalized * 3; } else { - float normalized = (bar.Value / (bar.Maximum / 2f)); + float normalized = ( bar.Value / ( bar.Maximum / 2f ) ); return normalized * .75f + .25f; } } - static int ExponentToTrackBar( TrackBar bar, float val ) { - if( val >= 1 ) { - float normalized = (float)Math.Sqrt( (val - 1) / 3f ); - return (int)(bar.Maximum / 2f + normalized * (bar.Maximum / 2f)); + private static int ExponentToTrackBar( TrackBar bar, float val ) { + if ( val >= 1 ) { + float normalized = ( float )Math.Sqrt( ( val - 1 ) / 3f ); + return ( int )( bar.Maximum / 2f + normalized * ( bar.Maximum / 2f ) ); } else { - float normalized = (val - .25f) / .75f; - return (int)(normalized * bar.Maximum / 2f); + float normalized = ( val - .25f ) / .75f; + return ( int )( normalized * bar.Maximum / 2f ); } } @@ -949,15 +944,17 @@ private void xAddBeaches_CheckedChanged( object sender, EventArgs e ) { } private void xBlockDB_CheckStateChanged( object sender, EventArgs e ) { - switch( xBlockDB.CheckState ) { + switch ( xBlockDB.CheckState ) { case CheckState.Indeterminate: World.BlockDBEnabled = YesNoAuto.Auto; xBlockDB.Text = "BlockDB (Auto)"; break; + case CheckState.Checked: World.BlockDBEnabled = YesNoAuto.Yes; xBlockDB.Text = "BlockDB (On)"; break; + case CheckState.Unchecked: World.BlockDBEnabled = YesNoAuto.No; xBlockDB.Text = "BlockDB (Off)"; diff --git a/ConfigGUI/ChatPreview.cs b/ConfigGUI/ChatPreview.cs index 18aedcc..35999aa 100644 --- a/ConfigGUI/ChatPreview.cs +++ b/ConfigGUI/ChatPreview.cs @@ -7,26 +7,28 @@ using System.Windows.Forms; using fCraft.ConfigGUI.Properties; - namespace fCraft.ConfigGUI { + sealed partial class ChatPreview : UserControl { - struct ColorPair { + private struct ColorPair { + public ColorPair( int r, int g, int b, int sr, int sg, int sb ) { Foreground = new SolidBrush( System.Drawing.Color.FromArgb( r, g, b ) ); Shadow = new SolidBrush( System.Drawing.Color.FromArgb( sr, sg, sb ) ); } + public readonly Brush Foreground, Shadow; } - static readonly PrivateFontCollection Fonts; - static readonly Font MinecraftFont; - static readonly ColorPair[] ColorPairs; + private static readonly PrivateFontCollection Fonts; + private static readonly Font MinecraftFont; + private static readonly ColorPair[] ColorPairs; unsafe static ChatPreview() { Fonts = new PrivateFontCollection(); - fixed( byte* fontPointer = Resources.MinecraftFont ) { - Fonts.AddMemoryFont( (IntPtr)fontPointer, Resources.MinecraftFont.Length ); + fixed ( byte* fontPointer = Resources.MinecraftFont ) { + Fonts.AddMemoryFont( ( IntPtr )fontPointer, Resources.MinecraftFont.Length ); } MinecraftFont = new Font( Fonts.Families[0], 12, FontStyle.Regular ); ColorPairs = new[]{ @@ -50,14 +52,12 @@ unsafe static ChatPreview() { }; } - public ChatPreview() { InitializeComponent(); DoubleBuffered = true; } - - sealed class TextSegment { + private sealed class TextSegment { public string Text; public ColorPair Color; public int X, Y; @@ -68,26 +68,28 @@ public void Draw( Graphics g ) { } } - static readonly Regex SplitByColorRegex = new Regex( "(&[0-9a-zA-Z])", RegexOptions.Compiled ); - TextSegment[] segments; + private static readonly Regex SplitByColorRegex = new Regex( "(&[0-9a-zA-Z])", RegexOptions.Compiled ); + private TextSegment[] segments; public void SetText( string[] lines ) { List newSegments = new List(); - using( Bitmap b = new Bitmap( 1, 1 ) ) { - using( Graphics g = Graphics.FromImage( b ) ) { // graphics for string mesaurement + using ( Bitmap b = new Bitmap( 1, 1 ) ) { + using ( Graphics g = Graphics.FromImage( b ) ) { // graphics for string mesaurement g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel; int y = 5; - for( int i = 0; i < lines.Length; i++ ) { - if( lines[i] == null || lines[i].Length == 0 ) continue; + for ( int i = 0; i < lines.Length; i++ ) { + if ( lines[i] == null || lines[i].Length == 0 ) + continue; int x = 5; string[] plainTextSegments = SplitByColorRegex.Split( lines[i] ); int color = Color.ParseToIndex( Color.White ); - for( int j = 0; j < plainTextSegments.Length; j++ ) { - if( plainTextSegments[j].Length == 0 ) continue; - if( plainTextSegments[j][0] == '&' ) { + for ( int j = 0; j < plainTextSegments.Length; j++ ) { + if ( plainTextSegments[j].Length == 0 ) + continue; + if ( plainTextSegments[j][0] == '&' ) { color = Color.ParseToIndex( plainTextSegments[j] ); } else { newSegments.Add( new TextSegment { @@ -96,26 +98,24 @@ public void SetText( string[] lines ) { X = x, Y = y } ); - x += (int)g.MeasureString( plainTextSegments[j], MinecraftFont ).Width; + x += ( int )g.MeasureString( plainTextSegments[j], MinecraftFont ).Width; } } y += 20; } - } } segments = newSegments.ToArray(); Invalidate(); } - protected override void OnPaint( PaintEventArgs e ) { e.Graphics.DrawImageUnscaledAndClipped( Resources.ChatBackground, e.ClipRectangle ); e.Graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixel; - if( segments != null && segments.Length > 0 ) { - for( int i = 0; i < segments.Length; i++ ) { + if ( segments != null && segments.Length > 0 ) { + for ( int i = 0; i < segments.Length; i++ ) { segments[i].Draw( e.Graphics ); } } diff --git a/ConfigGUI/ColorPicker.cs b/ConfigGUI/ColorPicker.cs index 420509e..4ae843d 100644 --- a/ConfigGUI/ColorPicker.cs +++ b/ConfigGUI/ColorPicker.cs @@ -3,11 +3,11 @@ using System.Windows.Forms; namespace fCraft.ConfigGUI { + internal sealed partial class ColorPicker : Form { public static readonly Dictionary ColorPairs = new Dictionary(); public int ColorIndex; - static ColorPicker() { ColorPairs.Add( 0, new ColorPair( System.Drawing.Color.White, System.Drawing.Color.Black ) ); ColorPairs.Add( 8, new ColorPair( System.Drawing.Color.White, System.Drawing.Color.DimGray ) ); @@ -27,7 +27,6 @@ static ColorPicker() { ColorPairs.Add( 15, new ColorPair( System.Drawing.Color.Black, System.Drawing.Color.White ) ); } - public ColorPicker( string title, int oldColorIndex ) { InitializeComponent(); Text = title; @@ -52,12 +51,13 @@ public ColorPicker( string title, int oldColorIndex ) { bf.Click += delegate { ColorIndex = 15; DialogResult = DialogResult.OK; Close(); }; } - internal struct ColorPair { + public ColorPair( System.Drawing.Color foreground, System.Drawing.Color background ) { Foreground = foreground; Background = background; } + public System.Drawing.Color Foreground; public System.Drawing.Color Background; } diff --git a/ConfigGUI/CustomPictureBox.cs b/ConfigGUI/CustomPictureBox.cs index d7337d1..deb237b 100644 --- a/ConfigGUI/CustomPictureBox.cs +++ b/ConfigGUI/CustomPictureBox.cs @@ -3,12 +3,14 @@ using System.Windows.Forms; namespace fCraft.ConfigGUI { - sealed class CustomPictureBox : PictureBox { + + internal sealed class CustomPictureBox : PictureBox { + protected override void OnPaint( PaintEventArgs pe ) { - if( Image != null ) { + if ( Image != null ) { pe.Graphics.SmoothingMode = SmoothingMode.HighQuality; pe.Graphics.CompositingQuality = CompositingQuality.HighQuality; - if( Image.Height * 3 > Height || Image.Width * 3 > Width ) { + if ( Image.Height * 3 > Height || Image.Width * 3 > Width ) { pe.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; } else { pe.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor; diff --git a/ConfigGUI/DeleteRankPopup.cs b/ConfigGUI/DeleteRankPopup.cs index 31da1b1..aedbcb0 100644 --- a/ConfigGUI/DeleteRankPopup.cs +++ b/ConfigGUI/DeleteRankPopup.cs @@ -3,13 +3,15 @@ using System.Windows.Forms; namespace fCraft.ConfigGUI { + public sealed partial class DeleteRankPopup : Form { + internal Rank SubstituteRank { get; private set; } public DeleteRankPopup( Rank deletedRank ) { InitializeComponent(); - foreach( Rank rank in RankManager.Ranks ) { - if( rank != deletedRank ) { + foreach ( Rank rank in RankManager.Ranks ) { + if ( rank != deletedRank ) { cSubstitute.Items.Add( MainForm.ToComboBoxOption( rank ) ); } } @@ -17,15 +19,16 @@ public DeleteRankPopup( Rank deletedRank ) { cSubstitute.SelectedIndex = cSubstitute.Items.Count - 1; } - private void cSubstitute_SelectedIndexChanged( object sender, EventArgs e ) { - if( cSubstitute.SelectedIndex < 0 ) return; - foreach( Rank rank in RankManager.Ranks ) { - if( cSubstitute.SelectedItem.ToString() != MainForm.ToComboBoxOption( rank ) ) continue; + if ( cSubstitute.SelectedIndex < 0 ) + return; + foreach ( Rank rank in RankManager.Ranks ) { + if ( cSubstitute.SelectedItem.ToString() != MainForm.ToComboBoxOption( rank ) ) + continue; SubstituteRank = rank; bDelete.Enabled = true; break; } } } -} +} \ No newline at end of file diff --git a/ConfigGUI/KeywordPicker.cs b/ConfigGUI/KeywordPicker.cs index 8f8da85..03180c6 100644 --- a/ConfigGUI/KeywordPicker.cs +++ b/ConfigGUI/KeywordPicker.cs @@ -1,11 +1,13 @@ using System.Windows.Forms; namespace fCraft.ConfigGUI { + public sealed partial class KeywordPicker : Form { public string Result; - readonly ToolTip tips; - static readonly KeywordInfo[] Keywords = new[]{ + private readonly ToolTip tips; + + private static readonly KeywordInfo[] Keywords = new[]{ new KeywordInfo("{SERVER_NAME}", "Server name", "Name of your server, as specified in config." ), new KeywordInfo("{RANK}", "Player's rank", "Player's rank, including prefix and colors (if applicable)." ), new KeywordInfo("{PLAYER_NAME}", "Player's name", "Name of the player, including prefix and colors (if applicable)." ), @@ -17,13 +19,13 @@ public sealed partial class KeywordPicker : Form { new KeywordInfo("{VERSION}", "800Craft version", "Version of 800Craft that this server is running." ) }; - const int ButtonWidth = 150, + private const int ButtonWidth = 150, ButtonHeight = 28; public KeywordPicker() { InitializeComponent(); tips = new ToolTip(); - foreach( KeywordInfo keyword in Keywords ) { + foreach ( KeywordInfo keyword in Keywords ) { Button newButton = new Button { Text = keyword.LongName, Tag = keyword.Keyword, @@ -32,7 +34,7 @@ public KeywordPicker() { }; pFlow.Controls.Add( newButton ); newButton.Click += delegate { - Result = (string)newButton.Tag; + Result = ( string )newButton.Tag; DialogResult = DialogResult.OK; Close(); }; @@ -40,18 +42,18 @@ public KeywordPicker() { } } + private struct KeywordInfo { - struct KeywordInfo { public KeywordInfo( string keyword, string name, string description ) { Keyword = keyword; LongName = name; Description = description; } + public readonly string Keyword, LongName, Description; } - private void pFlow_Paint ( object sender, PaintEventArgs e ) { - + private void pFlow_Paint( object sender, PaintEventArgs e ) { } } } \ No newline at end of file diff --git a/ConfigGUI/MainForm.Adapter.cs b/ConfigGUI/MainForm.Adapter.cs index 8c57f7e..e5e6c29 100644 --- a/ConfigGUI/MainForm.Adapter.cs +++ b/ConfigGUI/MainForm.Adapter.cs @@ -7,33 +7,34 @@ using System.Xml.Linq; using JetBrains.Annotations; - namespace fCraft.ConfigGUI { + // This section handles transfer of settings from Config to the specific UI controls, and vice versa. // Effectively, it's an adapter between Config's and ConfigUI's representations of the settings partial class MainForm { + #region Loading & Applying Config - void LoadConfig() { + private void LoadConfig() { string missingFileMsg = null; - if( !File.Exists( Paths.WorldListFileName ) && !File.Exists( Paths.ConfigFileName ) ) { + if ( !File.Exists( Paths.WorldListFileName ) && !File.Exists( Paths.ConfigFileName ) ) { missingFileMsg = String.Format( "Configuration ({0}) and world list ({1}) were not found. Using defaults.", Paths.ConfigFileName, Paths.WorldListFileName ); - } else if( !File.Exists( Paths.ConfigFileName ) ) { + } else if ( !File.Exists( Paths.ConfigFileName ) ) { missingFileMsg = String.Format( "Configuration ({0}) was not found. Using defaults.", Paths.ConfigFileName ); - } else if( !File.Exists( Paths.WorldListFileName ) ) { + } else if ( !File.Exists( Paths.WorldListFileName ) ) { missingFileMsg = String.Format( "World list ({0}) was not found. Assuming 0 worlds.", Paths.WorldListFileName ); } - if( missingFileMsg != null ) { + if ( missingFileMsg != null ) { MessageBox.Show( missingFileMsg ); } - using( LogRecorder loadLogger = new LogRecorder() ) { - if( Config.Load( false, false ) ) { - if( loadLogger.HasMessages ) { + using ( LogRecorder loadLogger = new LogRecorder() ) { + if ( Config.Load( false, false ) ) { + if ( loadLogger.HasMessages ) { MessageBox.Show( loadLogger.MessageString, "Config loading warnings" ); } } else { @@ -62,56 +63,55 @@ void LoadConfig() { bApply.Enabled = false; } - - void LoadWorldList() { - if( Worlds.Count > 0 ) Worlds.Clear(); - if( !File.Exists( Paths.WorldListFileName ) ) return; + private void LoadWorldList() { + if ( Worlds.Count > 0 ) + Worlds.Clear(); + if ( !File.Exists( Paths.WorldListFileName ) ) + return; try { XDocument doc = XDocument.Load( Paths.WorldListFileName ); XElement root = doc.Root; - if( root == null ) { + if ( root == null ) { MessageBox.Show( "Worlds.xml is empty or corrupted." ); return; } string errorLog = ""; - using( LogRecorder logRecorder = new LogRecorder() ) { - foreach( XElement el in root.Elements( "World" ) ) { + using ( LogRecorder logRecorder = new LogRecorder() ) { + foreach ( XElement el in root.Elements( "World" ) ) { try { Worlds.Add( new WorldListEntry( el ) ); - } catch( Exception ex ) { + } catch ( Exception ex ) { errorLog += ex + Environment.NewLine; } } - if( logRecorder.HasMessages ) { + if ( logRecorder.HasMessages ) { MessageBox.Show( logRecorder.MessageString, "World list loading warnings." ); } } - if( errorLog.Length > 0 ) { + if ( errorLog.Length > 0 ) { MessageBox.Show( "Some errors occured while loading the world list:" + Environment.NewLine + errorLog, "Warning" ); } FillWorldList(); XAttribute mainWorldAttr = root.Attribute( "main" ); - if( mainWorldAttr != null ) { - foreach( WorldListEntry world in Worlds ) { - if( world.Name.Equals(mainWorldAttr.Value, StringComparison.OrdinalIgnoreCase) ) { + if ( mainWorldAttr != null ) { + foreach ( WorldListEntry world in Worlds ) { + if ( world.Name.Equals( mainWorldAttr.Value, StringComparison.OrdinalIgnoreCase ) ) { cMainWorld.SelectedItem = world.Name; break; } } } - - } catch( Exception ex ) { + } catch ( Exception ex ) { MessageBox.Show( "Error occured while loading the world list: " + Environment.NewLine + ex, "Warning" ); } Worlds.ListChanged += SomethingChanged; } - - void ApplyTabGeneral() { + private void ApplyTabGeneral() { HbBox1.Checked = ConfigKey.HbSaverKey.Enabled(); tServerName.Text = ConfigKey.ServerName.GetString(); CustomName.Text = ConfigKey.CustomChatName.GetString(); @@ -124,7 +124,7 @@ void ApplyTabGeneral() { nMaxPlayersPerWorld.Value = ConfigKey.MaxPlayersPerWorld.GetInt(); FillRankList( cDefaultRank, "(lowest rank)" ); - if( ConfigKey.DefaultRank.IsBlank() ) { + if ( ConfigKey.DefaultRank.IsBlank() ) { cDefaultRank.SelectedIndex = 0; } else { RankManager.DefaultRank = Rank.Parse( ConfigKey.DefaultRank.GetString() ); @@ -136,8 +136,8 @@ void ApplyTabGeneral() { MaxCapsValue.Value = ConfigKey.MaxCaps.GetInt(); nUploadBandwidth.Value = ConfigKey.UploadBandwidth.GetInt(); - xAnnouncements.Checked = (ConfigKey.AnnouncementInterval.GetInt() > 0); - if( xAnnouncements.Checked ) { + xAnnouncements.Checked = ( ConfigKey.AnnouncementInterval.GetInt() > 0 ); + if ( xAnnouncements.Checked ) { nAnnouncements.Value = ConfigKey.AnnouncementInterval.GetInt(); } else { nAnnouncements.Value = 1; @@ -150,8 +150,7 @@ void ApplyTabGeneral() { updaterWindow.UpdaterMode = ConfigKey.UpdaterMode.GetEnum(); } - - void ApplyTabChat() { + private void ApplyTabChat() { xRankColorsInChat.Checked = ConfigKey.RankColorsInChat.Enabled(); xRankPrefixesInChat.Checked = ConfigKey.RankPrefixesInChat.Enabled(); xRankPrefixesInList.Checked = ConfigKey.RankPrefixesInList.Enabled(); @@ -163,9 +162,9 @@ void ApplyTabChat() { ApplyColor( bColorSys, colorSys ); Color.Sys = Color.Parse( colorSys ); - colorCustom = Color.ParseToIndex(ConfigKey.CustomChatColor.GetString()); - ApplyColor(CustomColor, colorCustom); - Color.Custom = Color.Parse(colorCustom); + colorCustom = Color.ParseToIndex( ConfigKey.CustomChatColor.GetString() ); + ApplyColor( CustomColor, colorCustom ); + Color.Custom = Color.Parse( colorCustom ); colorHelp = Color.ParseToIndex( ConfigKey.HelpColor.GetString() ); ApplyColor( bColorHelp, colorHelp ); @@ -194,14 +193,13 @@ void ApplyTabChat() { UpdateChatPreview(); } - - void ApplyTabWorlds() { - if( rankNameList == null ) { + private void ApplyTabWorlds() { + if ( rankNameList == null ) { rankNameList = new BindingList { WorldListEntry.DefaultRankOption }; - foreach( Rank rank in RankManager.Ranks ) { - rankNameList.Add( MainForm.ToComboBoxOption(rank) ); + foreach ( Rank rank in RankManager.Ranks ) { + rankNameList.Add( MainForm.ToComboBoxOption( rank ) ); } dgvcAccess.DataSource = rankNameList; dgvcBuild.DataSource = rankNameList; @@ -209,15 +207,14 @@ void ApplyTabWorlds() { LoadWorldList(); dgvWorlds.DataSource = Worlds; - } else { //dgvWorlds.DataSource = null; rankNameList.Clear(); rankNameList.Add( WorldListEntry.DefaultRankOption ); - foreach( Rank rank in RankManager.Ranks ) { - rankNameList.Add( MainForm.ToComboBoxOption(rank) ); + foreach ( Rank rank in RankManager.Ranks ) { + rankNameList.Add( MainForm.ToComboBoxOption( rank ) ); } - foreach( WorldListEntry world in Worlds ) { + foreach ( WorldListEntry world in Worlds ) { world.ReparseRanks(); } Worlds.ResetBindings(); @@ -225,14 +222,14 @@ void ApplyTabWorlds() { } FillRankList( cDefaultBuildRank, "(default rank)" ); - if( ConfigKey.DefaultBuildRank.IsBlank() ) { + if ( ConfigKey.DefaultBuildRank.IsBlank() ) { cDefaultBuildRank.SelectedIndex = 0; } else { RankManager.DefaultBuildRank = Rank.Parse( ConfigKey.DefaultBuildRank.GetString() ); cDefaultBuildRank.SelectedIndex = RankManager.GetIndex( RankManager.DefaultBuildRank ); } - if( Paths.IsDefaultMapPath( ConfigKey.MapPath.GetString() ) ) { + if ( Paths.IsDefaultMapPath( ConfigKey.MapPath.GetString() ) ) { tMapPath.Text = Paths.MapPathDefault; xMapPath.Checked = false; } else { @@ -243,28 +240,27 @@ void ApplyTabWorlds() { xWoMEnableEnvExtensions.Checked = ConfigKey.WoMEnableEnvExtensions.Enabled(); } - - void ApplyTabRanks() { + private void ApplyTabRanks() { selectedRank = null; RebuildRankList(); DisableRankOptions(); } - - void ApplyTabSecurity() { + private void ApplyTabSecurity() { ApplyEnum( cVerifyNames, ConfigKey.VerifyNames, NameVerificationMode.Balanced ); nMaxConnectionsPerIP.Value = ConfigKey.MaxConnectionsPerIP.GetInt(); - xMaxConnectionsPerIP.Checked = (nMaxConnectionsPerIP.Value > 0); + xMaxConnectionsPerIP.Checked = ( nMaxConnectionsPerIP.Value > 0 ); xAllowUnverifiedLAN.Checked = ConfigKey.AllowUnverifiedLAN.Enabled(); nAntispamMessageCount.Value = ConfigKey.AntispamMessageCount.GetInt(); nAntispamInterval.Value = ConfigKey.AntispamInterval.GetInt(); nSpamMute.Value = ConfigKey.AntispamMuteDuration.GetInt(); - xAntispamKicks.Checked = (ConfigKey.AntispamMaxWarnings.GetInt() > 0); + xAntispamKicks.Checked = ( ConfigKey.AntispamMaxWarnings.GetInt() > 0 ); nAntispamMaxWarnings.Value = ConfigKey.AntispamMaxWarnings.GetInt(); - if( !xAntispamKicks.Checked ) nAntispamMaxWarnings.Enabled = false; + if ( !xAntispamKicks.Checked ) + nAntispamMaxWarnings.Enabled = false; xRequireKickReason.Checked = ConfigKey.RequireKickReason.Enabled(); xRequireBanReason.Checked = ConfigKey.RequireBanReason.Enabled(); @@ -275,19 +271,18 @@ void ApplyTabSecurity() { xAnnounceRankChangeReasons.Enabled = xAnnounceRankChanges.Checked; FillRankList( cPatrolledRank, "(default rank)" ); - if( ConfigKey.PatrolledRank.IsBlank() ) { + if ( ConfigKey.PatrolledRank.IsBlank() ) { cPatrolledRank.SelectedIndex = 0; } else { RankManager.PatrolledRank = Rank.Parse( ConfigKey.PatrolledRank.GetString() ); cPatrolledRank.SelectedIndex = RankManager.GetIndex( RankManager.PatrolledRank ); } - xBlockDBEnabled.Checked = ConfigKey.BlockDBEnabled.Enabled(); xBlockDBAutoEnable.Checked = ConfigKey.BlockDBAutoEnable.Enabled(); FillRankList( cBlockDBAutoEnableRank, "(default rank)" ); - if( ConfigKey.BlockDBAutoEnableRank.IsBlank() ) { + if ( ConfigKey.BlockDBAutoEnableRank.IsBlank() ) { cBlockDBAutoEnableRank.SelectedIndex = 0; } else { RankManager.BlockDBAutoEnableRank = Rank.Parse( ConfigKey.BlockDBAutoEnableRank.GetString() ); @@ -295,49 +290,51 @@ void ApplyTabSecurity() { } } - - void ApplyTabSavingAndBackup() { - xSaveInterval.Checked = (ConfigKey.SaveInterval.GetInt() > 0); + private void ApplyTabSavingAndBackup() { + xSaveInterval.Checked = ( ConfigKey.SaveInterval.GetInt() > 0 ); nSaveInterval.Value = ConfigKey.SaveInterval.GetInt(); - if( !xSaveInterval.Checked ) nSaveInterval.Enabled = false; + if ( !xSaveInterval.Checked ) + nSaveInterval.Enabled = false; xBackupOnStartup.Checked = ConfigKey.BackupOnStartup.Enabled(); xBackupOnJoin.Checked = ConfigKey.BackupOnJoin.Enabled(); xBackupOnlyWhenChanged.Checked = ConfigKey.BackupOnlyWhenChanged.Enabled(); - xBackupInterval.Checked = (ConfigKey.DefaultBackupInterval.GetInt() > 0); + xBackupInterval.Checked = ( ConfigKey.DefaultBackupInterval.GetInt() > 0 ); nBackupInterval.Value = ConfigKey.DefaultBackupInterval.GetInt(); - if( !xBackupInterval.Checked ) nBackupInterval.Enabled = false; + if ( !xBackupInterval.Checked ) + nBackupInterval.Enabled = false; - xMaxBackups.Checked = (ConfigKey.MaxBackups.GetInt() > 0); + xMaxBackups.Checked = ( ConfigKey.MaxBackups.GetInt() > 0 ); nMaxBackups.Value = ConfigKey.MaxBackups.GetInt(); - if( !xMaxBackups.Checked ) nMaxBackups.Enabled = false; + if ( !xMaxBackups.Checked ) + nMaxBackups.Enabled = false; - xMaxBackupSize.Checked = (ConfigKey.MaxBackupSize.GetInt() > 0); + xMaxBackupSize.Checked = ( ConfigKey.MaxBackupSize.GetInt() > 0 ); nMaxBackupSize.Value = ConfigKey.MaxBackupSize.GetInt(); - if( !xMaxBackupSize.Checked ) nMaxBackupSize.Enabled = false; + if ( !xMaxBackupSize.Checked ) + nMaxBackupSize.Enabled = false; xBackupDataOnStartup.Checked = ConfigKey.BackupDataOnStartup.Enabled(); } - - void ApplyTabLogging() { - foreach( ListViewItem item in vConsoleOptions.Items ) { + private void ApplyTabLogging() { + foreach ( ListViewItem item in vConsoleOptions.Items ) { item.Checked = Logger.ConsoleOptions[item.Index]; } - foreach( ListViewItem item in vLogFileOptions.Items ) { + foreach ( ListViewItem item in vLogFileOptions.Items ) { item.Checked = Logger.LogFileOptions[item.Index]; } ApplyEnum( cLogMode, ConfigKey.LogMode, LogSplittingType.OneFile ); - xLogLimit.Checked = (ConfigKey.MaxLogs.GetInt() > 0); + xLogLimit.Checked = ( ConfigKey.MaxLogs.GetInt() > 0 ); nLogLimit.Value = ConfigKey.MaxLogs.GetInt(); - if( !xLogLimit.Checked ) nLogLimit.Enabled = false; + if ( !xLogLimit.Checked ) + nLogLimit.Enabled = false; } - - void ApplyTabIRC() { + private void ApplyTabIRC() { xIRCBotEnabled.Checked = ConfigKey.IRCBotEnabled.Enabled(); gIRCNetwork.Enabled = xIRCBotEnabled.Checked; gIRCOptions.Enabled = xIRCBotEnabled.Checked; @@ -359,7 +356,6 @@ void ApplyTabIRC() { xIRCBotForwardFromIRC.Checked = ConfigKey.IRCBotForwardFromIRC.Enabled(); xIRCBotForwardFromServer.Checked = ConfigKey.IRCBotForwardFromServer.Enabled(); - colorIRC = Color.ParseToIndex( ConfigKey.IRCMessageColor.GetString() ); ApplyColor( bColorIRC, colorIRC ); Color.IRC = Color.Parse( colorIRC ); @@ -368,26 +364,34 @@ void ApplyTabIRC() { xIRCBotAnnounceServerEvents.Checked = ConfigKey.IRCBotAnnounceServerEvents.Enabled(); } - - void ApplyTabAdvanced() { + private void ApplyTabAdvanced() { xRelayAllBlockUpdates.Checked = ConfigKey.RelayAllBlockUpdates.Enabled(); xNoPartialPositionUpdates.Checked = ConfigKey.NoPartialPositionUpdates.Enabled(); nTickInterval.Value = ConfigKey.TickInterval.GetInt(); - if( ConfigKey.ProcessPriority.IsBlank() ) { + if ( ConfigKey.ProcessPriority.IsBlank() ) { cProcessPriority.SelectedIndex = 0; // Default } else { - switch( ConfigKey.ProcessPriority.GetEnum() ) { + switch ( ConfigKey.ProcessPriority.GetEnum() ) { case ProcessPriorityClass.High: - cProcessPriority.SelectedIndex = 1; break; + cProcessPriority.SelectedIndex = 1; + break; + case ProcessPriorityClass.AboveNormal: - cProcessPriority.SelectedIndex = 2; break; + cProcessPriority.SelectedIndex = 2; + break; + case ProcessPriorityClass.Normal: - cProcessPriority.SelectedIndex = 3; break; + cProcessPriority.SelectedIndex = 3; + break; + case ProcessPriorityClass.BelowNormal: - cProcessPriority.SelectedIndex = 4; break; + cProcessPriority.SelectedIndex = 4; + break; + case ProcessPriorityClass.Idle: - cProcessPriority.SelectedIndex = 5; break; + cProcessPriority.SelectedIndex = 5; + break; } } @@ -397,19 +401,19 @@ void ApplyTabAdvanced() { xLowLatencyMode.Checked = ConfigKey.LowLatencyMode.Enabled(); xSubmitCrashReports.Checked = ConfigKey.SubmitCrashReports.Enabled(); - if( ConfigKey.MaxUndo.GetInt() > 0 ) { + if ( ConfigKey.MaxUndo.GetInt() > 0 ) { xMaxUndo.Checked = true; nMaxUndo.Value = ConfigKey.MaxUndo.GetInt(); } else { xMaxUndo.Checked = false; - nMaxUndo.Value = (int)ConfigKey.MaxUndo.GetDefault(); + nMaxUndo.Value = ( int )ConfigKey.MaxUndo.GetDefault(); } nMaxUndoStates.Value = ConfigKey.MaxUndoStates.GetInt(); tConsoleName.Text = ConfigKey.ConsoleName.GetString(); tIP.Text = ConfigKey.IP.GetString(); - if( ConfigKey.IP.IsBlank() || ConfigKey.IP.IsDefault() ) { + if ( ConfigKey.IP.IsBlank() || ConfigKey.IP.IsDefault() ) { tIP.Enabled = false; xIP.Checked = false; } else { @@ -418,45 +422,45 @@ void ApplyTabAdvanced() { } } - - static void ApplyEnum( [NotNull] ComboBox box, ConfigKey key, TEnum def ) where TEnum : struct { - if( box == null ) throw new ArgumentNullException( "box" ); - if( !typeof( TEnum ).IsEnum ) throw new ArgumentException( "Enum type required" ); + private static void ApplyEnum( [NotNull] ComboBox box, ConfigKey key, TEnum def ) where TEnum : struct { + if ( box == null ) + throw new ArgumentNullException( "box" ); + if ( !typeof( TEnum ).IsEnum ) + throw new ArgumentException( "Enum type required" ); try { - if( key.IsBlank() ) { - box.SelectedIndex = (int)(object)def; + if ( key.IsBlank() ) { + box.SelectedIndex = ( int )( object )def; } else { - box.SelectedIndex = (int)Enum.Parse( typeof( TEnum ), key.GetString(), true ); + box.SelectedIndex = ( int )Enum.Parse( typeof( TEnum ), key.GetString(), true ); } - } catch( ArgumentException ) { - box.SelectedIndex = (int)(object)def; + } catch ( ArgumentException ) { + box.SelectedIndex = ( int )( object )def; } } - #endregion - + #endregion Loading & Applying Config #region Saving Config - void SaveConfig() { + private void SaveConfig() { // General - ConfigKey.HbSaverKey.TrySetValue(HbBox1.Checked); + ConfigKey.HbSaverKey.TrySetValue( HbBox1.Checked ); ConfigKey.ServerName.TrySetValue( tServerName.Text ); - ConfigKey.CustomChatName.TrySetValue(CustomName.Text); - ConfigKey.SwearName.TrySetValue(SwearBox.Text); - ConfigKey.CustomAliasName.TrySetValue(CustomAliases.Text); + ConfigKey.CustomChatName.TrySetValue( CustomName.Text ); + ConfigKey.SwearName.TrySetValue( SwearBox.Text ); + ConfigKey.CustomAliasName.TrySetValue( CustomAliases.Text ); ConfigKey.MOTD.TrySetValue( tMOTD.Text ); ConfigKey.MaxPlayers.TrySetValue( nMaxPlayers.Value ); ConfigKey.MaxPlayersPerWorld.TrySetValue( nMaxPlayersPerWorld.Value ); - if( cDefaultRank.SelectedIndex == 0 ) { + if ( cDefaultRank.SelectedIndex == 0 ) { ConfigKey.DefaultRank.TrySetValue( "" ); } else { ConfigKey.DefaultRank.TrySetValue( RankManager.DefaultRank.FullName ); } ConfigKey.IsPublic.TrySetValue( cPublic.SelectedIndex == 0 ); ConfigKey.Port.TrySetValue( nPort.Value ); - ConfigKey.MaxCaps.TrySetValue(MaxCapsValue.Value); - if( xIP.Checked ) { + ConfigKey.MaxCaps.TrySetValue( MaxCapsValue.Value ); + if ( xIP.Checked ) { ConfigKey.IP.TrySetValue( tIP.Text ); } else { ConfigKey.IP.ResetValue(); @@ -464,8 +468,10 @@ void SaveConfig() { ConfigKey.UploadBandwidth.TrySetValue( nUploadBandwidth.Value ); - if( xAnnouncements.Checked ) ConfigKey.AnnouncementInterval.TrySetValue( nAnnouncements.Value ); - else ConfigKey.AnnouncementInterval.TrySetValue( 0 ); + if ( xAnnouncements.Checked ) + ConfigKey.AnnouncementInterval.TrySetValue( nAnnouncements.Value ); + else + ConfigKey.AnnouncementInterval.TrySetValue( 0 ); // UpdaterSettingsWindow ConfigKey.UpdaterMode.TrySetValue( updaterWindow.UpdaterMode ); @@ -473,10 +479,9 @@ void SaveConfig() { ConfigKey.RunBeforeUpdate.TrySetValue( updaterWindow.RunBeforeUpdate ); ConfigKey.RunAfterUpdate.TrySetValue( updaterWindow.RunAfterUpdate ); - // Chat ConfigKey.SystemMessageColor.TrySetValue( Color.GetName( colorSys ) ); - ConfigKey.CustomChatColor.TrySetValue(Color.GetName(colorCustom)); + ConfigKey.CustomChatColor.TrySetValue( Color.GetName( colorCustom ) ); ConfigKey.HelpColor.TrySetValue( Color.GetName( colorHelp ) ); ConfigKey.SayColor.TrySetValue( Color.GetName( colorSay ) ); ConfigKey.AnnouncementColor.TrySetValue( Color.GetName( colorAnnouncement ) ); @@ -490,24 +495,24 @@ void SaveConfig() { ConfigKey.RankPrefixesInList.TrySetValue( xRankPrefixesInList.Checked ); ConfigKey.ShowConnectionMessages.TrySetValue( xShowConnectionMessages.Checked ); - // Worlds - if( cDefaultBuildRank.SelectedIndex == 0 ) { + if ( cDefaultBuildRank.SelectedIndex == 0 ) { ConfigKey.DefaultBuildRank.TrySetValue( "" ); } else { ConfigKey.DefaultBuildRank.TrySetValue( RankManager.DefaultBuildRank.FullName ); } - if( xMapPath.Checked ) ConfigKey.MapPath.TrySetValue( tMapPath.Text ); - else ConfigKey.MapPath.TrySetValue( ConfigKey.MapPath.GetDefault() ); + if ( xMapPath.Checked ) + ConfigKey.MapPath.TrySetValue( tMapPath.Text ); + else + ConfigKey.MapPath.TrySetValue( ConfigKey.MapPath.GetDefault() ); ConfigKey.WoMEnableEnvExtensions.TrySetValue( xWoMEnableEnvExtensions.Checked ); - // Security WriteEnum( cVerifyNames, ConfigKey.VerifyNames ); - if( xMaxConnectionsPerIP.Checked ) { + if ( xMaxConnectionsPerIP.Checked ) { ConfigKey.MaxConnectionsPerIP.TrySetValue( nMaxConnectionsPerIP.Value ); } else { ConfigKey.MaxConnectionsPerIP.TrySetValue( 0 ); @@ -518,8 +523,10 @@ void SaveConfig() { ConfigKey.AntispamInterval.TrySetValue( nAntispamInterval.Value ); ConfigKey.AntispamMuteDuration.TrySetValue( nSpamMute.Value ); - if( xAntispamKicks.Checked ) ConfigKey.AntispamMaxWarnings.TrySetValue( nAntispamMaxWarnings.Value ); - else ConfigKey.AntispamMaxWarnings.TrySetValue( 0 ); + if ( xAntispamKicks.Checked ) + ConfigKey.AntispamMaxWarnings.TrySetValue( nAntispamMaxWarnings.Value ); + else + ConfigKey.AntispamMaxWarnings.TrySetValue( 0 ); ConfigKey.RequireKickReason.TrySetValue( xRequireKickReason.Checked ); ConfigKey.RequireBanReason.TrySetValue( xRequireBanReason.Checked ); @@ -528,7 +535,7 @@ void SaveConfig() { ConfigKey.AnnounceRankChanges.TrySetValue( xAnnounceRankChanges.Checked ); ConfigKey.AnnounceRankChangeReasons.TrySetValue( xAnnounceRankChangeReasons.Checked ); - if( cPatrolledRank.SelectedIndex == 0 ) { + if ( cPatrolledRank.SelectedIndex == 0 ) { ConfigKey.PatrolledRank.TrySetValue( "" ); } else { ConfigKey.PatrolledRank.TrySetValue( RankManager.PatrolledRank.FullName ); @@ -536,42 +543,49 @@ void SaveConfig() { ConfigKey.BlockDBEnabled.TrySetValue( xBlockDBEnabled.Checked ); ConfigKey.BlockDBAutoEnable.TrySetValue( xBlockDBAutoEnable.Checked ); - if( cBlockDBAutoEnableRank.SelectedIndex == 0 ) { + if ( cBlockDBAutoEnableRank.SelectedIndex == 0 ) { ConfigKey.BlockDBAutoEnableRank.TrySetValue( "" ); } else { ConfigKey.BlockDBAutoEnableRank.TrySetValue( RankManager.BlockDBAutoEnableRank.FullName ); } - // Saving & Backups - if( xSaveInterval.Checked ) ConfigKey.SaveInterval.TrySetValue( nSaveInterval.Value ); - else ConfigKey.SaveInterval.TrySetValue( 0 ); + if ( xSaveInterval.Checked ) + ConfigKey.SaveInterval.TrySetValue( nSaveInterval.Value ); + else + ConfigKey.SaveInterval.TrySetValue( 0 ); ConfigKey.BackupOnStartup.TrySetValue( xBackupOnStartup.Checked ); ConfigKey.BackupOnJoin.TrySetValue( xBackupOnJoin.Checked ); ConfigKey.BackupOnlyWhenChanged.TrySetValue( xBackupOnlyWhenChanged.Checked ); - if( xBackupInterval.Checked ) ConfigKey.DefaultBackupInterval.TrySetValue( nBackupInterval.Value ); - else ConfigKey.DefaultBackupInterval.TrySetValue( 0 ); - if( xMaxBackups.Checked ) ConfigKey.MaxBackups.TrySetValue( nMaxBackups.Value ); - else ConfigKey.MaxBackups.TrySetValue( 0 ); - if( xMaxBackupSize.Checked ) ConfigKey.MaxBackupSize.TrySetValue( nMaxBackupSize.Value ); - else ConfigKey.MaxBackupSize.TrySetValue( 0 ); + if ( xBackupInterval.Checked ) + ConfigKey.DefaultBackupInterval.TrySetValue( nBackupInterval.Value ); + else + ConfigKey.DefaultBackupInterval.TrySetValue( 0 ); + if ( xMaxBackups.Checked ) + ConfigKey.MaxBackups.TrySetValue( nMaxBackups.Value ); + else + ConfigKey.MaxBackups.TrySetValue( 0 ); + if ( xMaxBackupSize.Checked ) + ConfigKey.MaxBackupSize.TrySetValue( nMaxBackupSize.Value ); + else + ConfigKey.MaxBackupSize.TrySetValue( 0 ); ConfigKey.BackupDataOnStartup.TrySetValue( xBackupDataOnStartup.Checked ); - // Logging WriteEnum( cLogMode, ConfigKey.LogMode ); - if( xLogLimit.Checked ) ConfigKey.MaxLogs.TrySetValue( nLogLimit.Value ); - else ConfigKey.MaxLogs.TrySetValue( "0" ); - foreach( ListViewItem item in vConsoleOptions.Items ) { + if ( xLogLimit.Checked ) + ConfigKey.MaxLogs.TrySetValue( nLogLimit.Value ); + else + ConfigKey.MaxLogs.TrySetValue( "0" ); + foreach ( ListViewItem item in vConsoleOptions.Items ) { Logger.ConsoleOptions[item.Index] = item.Checked; } - foreach( ListViewItem item in vLogFileOptions.Items ) { + foreach ( ListViewItem item in vLogFileOptions.Items ) { Logger.LogFileOptions[item.Index] = item.Checked; } - // IRC ConfigKey.IRCBotEnabled.TrySetValue( xIRCBotEnabled.Checked ); @@ -595,7 +609,6 @@ void SaveConfig() { ConfigKey.IRCMessageColor.TrySetValue( Color.GetName( colorIRC ) ); ConfigKey.IRCUseColor.TrySetValue( xIRCUseColor.Checked ); - // advanced ConfigKey.SubmitCrashReports.TrySetValue( xSubmitCrashReports.Checked ); @@ -603,27 +616,40 @@ void SaveConfig() { ConfigKey.NoPartialPositionUpdates.TrySetValue( xNoPartialPositionUpdates.Checked ); ConfigKey.TickInterval.TrySetValue( Convert.ToInt32( nTickInterval.Value ) ); - switch( cProcessPriority.SelectedIndex ) { + switch ( cProcessPriority.SelectedIndex ) { case 0: - ConfigKey.ProcessPriority.ResetValue(); break; + ConfigKey.ProcessPriority.ResetValue(); + break; + case 1: - ConfigKey.ProcessPriority.TrySetValue( ProcessPriorityClass.High ); break; + ConfigKey.ProcessPriority.TrySetValue( ProcessPriorityClass.High ); + break; + case 2: - ConfigKey.ProcessPriority.TrySetValue( ProcessPriorityClass.AboveNormal ); break; + ConfigKey.ProcessPriority.TrySetValue( ProcessPriorityClass.AboveNormal ); + break; + case 3: - ConfigKey.ProcessPriority.TrySetValue( ProcessPriorityClass.Normal ); break; + ConfigKey.ProcessPriority.TrySetValue( ProcessPriorityClass.Normal ); + break; + case 4: - ConfigKey.ProcessPriority.TrySetValue( ProcessPriorityClass.BelowNormal ); break; + ConfigKey.ProcessPriority.TrySetValue( ProcessPriorityClass.BelowNormal ); + break; + case 5: - ConfigKey.ProcessPriority.TrySetValue( ProcessPriorityClass.Idle ); break; + ConfigKey.ProcessPriority.TrySetValue( ProcessPriorityClass.Idle ); + break; } ConfigKey.BlockUpdateThrottling.TrySetValue( Convert.ToInt32( nThrottling.Value ) ); ConfigKey.LowLatencyMode.TrySetValue( xLowLatencyMode.Checked ); - if( xMaxUndo.Checked ) ConfigKey.MaxUndo.TrySetValue( Convert.ToInt32( nMaxUndo.Value ) ); - else ConfigKey.MaxUndo.TrySetValue( 0 ); + if ( xMaxUndo.Checked ) + ConfigKey.MaxUndo.TrySetValue( Convert.ToInt32( nMaxUndo.Value ) ); + else + ConfigKey.MaxUndo.TrySetValue( 0 ); ConfigKey.MaxUndoStates.TrySetValue( Convert.ToInt32( nMaxUndoStates.Value ) ); ConfigKey.ConsoleName.TrySetValue( tConsoleName.Text ); @@ -631,22 +657,21 @@ void SaveConfig() { SaveWorldList(); } - - void SaveWorldList() { + private void SaveWorldList() { const string worldListTempFileName = Paths.WorldListFileName + ".tmp"; try { XDocument doc = new XDocument(); XElement root = new XElement( "fCraftWorldList" ); - foreach( WorldListEntry world in Worlds ) { + foreach ( WorldListEntry world in Worlds ) { root.Add( world.Serialize() ); } - if( cMainWorld.SelectedItem != null ) { + if ( cMainWorld.SelectedItem != null ) { root.Add( new XAttribute( "main", cMainWorld.SelectedItem ) ); } doc.Add( root ); doc.Save( worldListTempFileName ); Paths.MoveOrReplace( worldListTempFileName, Paths.WorldListFileName ); - } catch( Exception ex ) { + } catch ( Exception ex ) { MessageBox.Show( String.Format( "An error occured while trying to save world list ({0}): {1}{2}", Paths.WorldListFileName, Environment.NewLine, @@ -654,20 +679,21 @@ void SaveWorldList() { } } - - static void WriteEnum( [NotNull] ComboBox box, ConfigKey key ) where TEnum : struct { - if( box == null ) throw new ArgumentNullException( "box" ); - if( !typeof( TEnum ).IsEnum ) throw new ArgumentException( "Enum type required" ); + private static void WriteEnum( [NotNull] ComboBox box, ConfigKey key ) where TEnum : struct { + if ( box == null ) + throw new ArgumentNullException( "box" ); + if ( !typeof( TEnum ).IsEnum ) + throw new ArgumentException( "Enum type required" ); try { - TEnum val = (TEnum)Enum.Parse( typeof( TEnum ), box.SelectedIndex.ToString(), true ); + TEnum val = ( TEnum )Enum.Parse( typeof( TEnum ), box.SelectedIndex.ToString(), true ); key.TrySetValue( val ); - } catch( ArgumentException ) { + } catch ( ArgumentException ) { Logger.Log( LogType.Error, "ConfigUI.WriteEnum<{0}>: Could not parse value for {1}. Using default ({2}).", typeof( TEnum ).Name, key, key.GetString() ); } } - #endregion + #endregion Saving Config } } \ No newline at end of file diff --git a/ConfigGUI/MainForm.ToolTips.cs b/ConfigGUI/MainForm.ToolTips.cs index cc643b6..220f1ca 100644 --- a/ConfigGUI/MainForm.ToolTips.cs +++ b/ConfigGUI/MainForm.ToolTips.cs @@ -1,15 +1,15 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft.ConfigGUI { - partial class MainForm { - void FillToolTipsGeneral() { + partial class MainForm { + private void FillToolTipsGeneral() { toolTip.SetToolTip( lServerName, ConfigKey.ServerName.GetDescription() ); toolTip.SetToolTip( tServerName, ConfigKey.ServerName.GetDescription() ); - toolTip.SetToolTip(CustomName, ConfigKey.CustomChatName.GetDescription()); - toolTip.SetToolTip(CustomAliases, ConfigKey.CustomAliasName.GetDescription()); - toolTip.SetToolTip(SwearBox, ConfigKey.SwearName.GetDescription()); + toolTip.SetToolTip( CustomName, ConfigKey.CustomChatName.GetDescription() ); + toolTip.SetToolTip( CustomAliases, ConfigKey.CustomAliasName.GetDescription() ); + toolTip.SetToolTip( SwearBox, ConfigKey.SwearName.GetDescription() ); toolTip.SetToolTip( lMOTD, ConfigKey.MOTD.GetDescription() ); toolTip.SetToolTip( tMOTD, ConfigKey.MOTD.GetDescription() ); @@ -68,19 +68,16 @@ You can include any color codes in the announcements. {SERVER_NAME} = server name (as defined in config) {RANK} = connecting player's rank" ); - toolTip.SetToolTip(SwearEditor, + toolTip.SetToolTip( SwearEditor, @"Edit the list of Swearwords (swearwords.txt). -Each swearword should be on a seperate line."); +Each swearword should be on a seperate line." ); - toolTip.SetToolTip(ReqsEditor, + toolTip.SetToolTip( ReqsEditor, @"Edit the list of requirements for the ranks -on your server."); - +on your server." ); } - - void FillToolTipsChat() { - + private void FillToolTipsChat() { toolTip.SetToolTip( xRankColorsInChat, ConfigKey.RankColorsInChat.GetDescription() ); toolTip.SetToolTip( xRankColorsInWorldNames, ConfigKey.RankColorsInWorldNames.GetDescription() ); @@ -115,8 +112,7 @@ void FillToolTipsChat() { toolTip.SetToolTip( lColorWarning, ConfigKey.WarningColor.GetDescription() ); } - - void FillToolTipsWorlds() { + private void FillToolTipsWorlds() { toolTip.SetToolTip( bAddWorld, "Add a new world to the list." ); toolTip.SetToolTip( bWorldEdit, "Edit or replace an existing world." ); toolTip.SetToolTip( cMainWorld, "Main world is the first world that players see when they join the server." ); @@ -131,9 +127,7 @@ void FillToolTipsWorlds() { toolTip.SetToolTip( xWoMEnableEnvExtensions, ConfigKey.WoMEnableEnvExtensions.GetDescription() ); } - - void FillToolTipsRanks() { - + private void FillToolTipsRanks() { toolTip.SetToolTip( xAllowSecurityCircumvention, @"Allows players to manupulate whitelists/blacklists or rank requirements in order to join restricted worlds, or to build in worlds/zones. Normally @@ -172,8 +166,6 @@ void FillToolTipsRanks() { toolTip.SetToolTip( lPrefix, tipPrefix ); toolTip.SetToolTip( tPrefix, tipPrefix ); - - toolTip.SetToolTip( permissionLimitBoxes[Permission.Kick], @"Limit on who can be kicked by players of this rank. By default, players can only kick players of same or lower rank." ); @@ -214,8 +206,6 @@ void FillToolTipsRanks() { @"Limit on whose actions players of this rank can undo. By default, players can only undo actions of players of same or lower rank." ); - - toolTip.SetToolTip( xReserveSlot, @"Allows players of this rank to join the server even if it reached the maximum number of players." ); @@ -251,17 +241,14 @@ allowed to affect with drawing or copy/paste commands toolTip.SetToolTip( nDrawLimit, tipDrawLimit ); toolTip.SetToolTip( lDrawLimitUnits, tipDrawLimit ); - - - - vPermissions.Items[(int)Permission.Ban].ToolTipText = + vPermissions.Items[( int )Permission.Ban].ToolTipText = @"Ability to ban/unban other players from the server. Affected commands: /Ban /Banx /Unban"; - vPermissions.Items[(int)Permission.BanAll].ToolTipText = + vPermissions.Items[( int )Permission.BanAll].ToolTipText = @"Ability to ban/unban a player account, his IP, and all other accounts that used the IP. BanAll/UnbanAll commands can be used on players who keep evading bans. Required permissions: Ban & BanIP @@ -269,51 +256,51 @@ allowed to affect with drawing or copy/paste commands /BanAll /UnbanAll"; - vPermissions.Items[(int)Permission.BanIP].ToolTipText = + vPermissions.Items[( int )Permission.BanIP].ToolTipText = @"Ability to ban/unban players by IP. Required permission: Ban Affected commands: /BanIP /UnbanIP"; - - vPermissions.Items[(int)Permission.Basscannon].ToolTipText = + + vPermissions.Items[( int )Permission.Basscannon].ToolTipText = @"Ability to kick a player with stlye. Affected command: /Basscannon"; - vPermissions.Items[(int)Permission.Bring].ToolTipText = + vPermissions.Items[( int )Permission.Bring].ToolTipText = @"Ability to bring/summon other players to your location. This works a bit like reverse-teleport - other player is sent to you. Affected commands: /Bring /BringAll"; - vPermissions.Items[(int)Permission.BringAll].ToolTipText = + vPermissions.Items[( int )Permission.BringAll].ToolTipText = @"Ability to bring/summon many players at a time to your location. Affected command: /BringAll"; - - vPermissions.Items[(int)Permission.BroMode].ToolTipText = + + vPermissions.Items[( int )Permission.BroMode].ToolTipText = @"Ability to activate BroMode. Affected command: /BroMode"; - vPermissions.Items[(int)Permission.Build].ToolTipText = + vPermissions.Items[( int )Permission.Build].ToolTipText = @"Ability to place blocks on maps. This is a baseline permission that can be overridden by world-specific and zone-specific permissions."; - vPermissions.Items[(int)Permission.Chat].ToolTipText = + vPermissions.Items[( int )Permission.Chat].ToolTipText = @"Ability to chat and PM players. Note that players without this permission can still type in commands, receive PMs, and read chat. Affected commands: /Say @ (pm) @@ (rank chat)"; - - vPermissions.Items[(int)Permission.ChatWithCaps].ToolTipText = + + vPermissions.Items[( int )Permission.ChatWithCaps].ToolTipText = @"Ability to chat with caps without restrictions."; - vPermissions.Items[(int)Permission.CopyAndPaste].ToolTipText = + vPermissions.Items[( int )Permission.CopyAndPaste].ToolTipText = @"Ability to copy (or cut) and paste blocks. The total number of blocks that can be copied or pasted at a time is affected by the draw limit. @@ -324,23 +311,23 @@ the draw limit. /Paste, /PasteNot /Rotate"; - vPermissions.Items[(int)Permission.Delete].ToolTipText = + vPermissions.Items[( int )Permission.Delete].ToolTipText = @"Ability to delete or replace blocks on maps. This is a baseline permission that can be overridden by world-specific and zone-specific permissions."; - vPermissions.Items[(int)Permission.DeleteAdmincrete].ToolTipText = + vPermissions.Items[( int )Permission.DeleteAdmincrete].ToolTipText = @"Ability to delete admincrete (aka adminium) blocks. Even if someone has this permission, it can be overridden by world-specific and zone-specific permissions. Required permission: Delete"; - vPermissions.Items[(int)Permission.Demote].ToolTipText = + vPermissions.Items[( int )Permission.Demote].ToolTipText = @"Ability to demote other players to a lower rank. Affected commands: /Rank /MassRank"; - vPermissions.Items[(int)Permission.Draw].ToolTipText = + vPermissions.Items[( int )Permission.Draw].ToolTipText = @"Ability to use drawing tools (commands capable of affecting many blocks at once). This permission can be overridden by world-specific and zone-specific permissions. @@ -352,7 +339,7 @@ the draw limit. /Replace and /ReplaceNot /Undo and /Redo"; - vPermissions.Items[(int)Permission.DrawAdvanced].ToolTipText = + vPermissions.Items[( int )Permission.DrawAdvanced].ToolTipText = @"Ability to use advanced drawing tools, such as brushes. Required permission: Build, Delete, Draw Affected commands: @@ -362,7 +349,7 @@ the draw limit. /Sphere and /SphereH /Torus"; - vPermissions.Items[(int)Permission.EditPlayerDB].ToolTipText = + vPermissions.Items[( int )Permission.EditPlayerDB].ToolTipText = @"Ability to edit the player database directly. This also adds the ability to promote/demote players by name, even if they have not visited the server yet. Also allows to manipulate players' records, and to promote/demote players in batches. @@ -374,85 +361,85 @@ the draw limit. /Nick /InfoSwap /DumpStats"; - - vPermissions.Items[(int)Permission.Fireworks].ToolTipText = + + vPermissions.Items[( int )Permission.Fireworks].ToolTipText = @"Ability to create fireworks. Affected command: /Firework"; - vPermissions.Items[(int)Permission.Freeze].ToolTipText = + vPermissions.Items[( int )Permission.Freeze].ToolTipText = @"Ability to freeze/unfreeze players. Frozen players cannot move or build/delete. Affected commands: /Freeze /Unfreeze"; - - vPermissions.Items[(int)Permission.Gtfo].ToolTipText = + + vPermissions.Items[( int )Permission.Gtfo].ToolTipText = @"Ability to kick a player without saving it to the DB. Affected command: /Gtfo"; - - vPermissions.Items[(int)Permission.Gun].ToolTipText = + + vPermissions.Items[( int )Permission.Gun].ToolTipText = @"Ability to use a gun. Affected command: /Gun"; - vPermissions.Items[(int)Permission.Hide].ToolTipText = + vPermissions.Items[( int )Permission.Hide].ToolTipText = @"Ability to appear hidden from other players. You can still chat, build/delete blocks, use all commands, and join worlds while hidden. Hidden players are completely invisible to other players. Affected commands: /Hide /Unhide"; - - vPermissions.Items[(int)Permission.HideRanks].ToolTipText = + + vPermissions.Items[( int )Permission.HideRanks].ToolTipText = @"Ability to hide ranks from the /ranks list. Affected command: /RankHide"; - - vPermissions.Items[(int)Permission.HighFive].ToolTipText = + + vPermissions.Items[( int )Permission.HighFive].ToolTipText = @"Ability to give a player a HighFive. Affected command: /High5"; - vPermissions.Items[(int)Permission.Import].ToolTipText = + vPermissions.Items[( int )Permission.Import].ToolTipText = @"Ability to import rank and ban lists from files. Useful if you are switching from another server software. Affected commands: /Import"; - - vPermissions.Items[(int)Permission.Immortal].ToolTipText = + + vPermissions.Items[( int )Permission.Immortal].ToolTipText = @"Ability to become immortal. Affected command: /Immortal"; - vPermissions.Items[(int)Permission.Kick].ToolTipText = + vPermissions.Items[( int )Permission.Kick].ToolTipText = @"Ability to kick players from the server. Affected commands: /Kick"; - - vPermissions.Items[(int)Permission.Kill].ToolTipText = + + vPermissions.Items[( int )Permission.Kill].ToolTipText = @"Ability to kill players. Affected command: /Kill"; - - vPermissions.Items[(int)Permission.Lock].ToolTipText = + + vPermissions.Items[( int )Permission.Lock].ToolTipText = @"Ability to lock/unlock maps (locking puts a world into read-only state.) Affected commands: /WLock /WUnlock"; - vPermissions.Items[(int)Permission.MakeVoteKicks].ToolTipText = + vPermissions.Items[( int )Permission.MakeVoteKicks].ToolTipText = @"Ability to vote to kick a player. Affected command: /Vote"; - - vPermissions.Items[(int)Permission.MakeVotes].ToolTipText = + + vPermissions.Items[( int )Permission.MakeVotes].ToolTipText = @"Ability to create votes. Affected command: /Vote"; - vPermissions.Items[(int)Permission.ManageWorlds].ToolTipText = + vPermissions.Items[( int )Permission.ManageWorlds].ToolTipText = @"Ability to manipulate the world list: adding, renaming, and deleting worlds, loading/saving maps, change per-world permissions, and using the map generator. Affected commands: @@ -464,194 +451,193 @@ are switching from another server software. /WFlush /Gen"; - - vPermissions.Items[(int)Permission.ManageBlockDB].ToolTipText = + vPermissions.Items[( int )Permission.ManageBlockDB].ToolTipText = @"Ability to enable/disable, clear, and configure BlockDB. Affected command: /BlockDB"; - - vPermissions.Items[(int)Permission.ManagePortal].ToolTipText = + + vPermissions.Items[( int )Permission.ManagePortal].ToolTipText = @"Ability to create, edit, and delete portals. Affected command: /Portal"; - vPermissions.Items[(int)Permission.ManageZones].ToolTipText = + vPermissions.Items[( int )Permission.ManageZones].ToolTipText = @"Ability to manipulate zones: adding, editing, renaming, and removing zones. Affected commands: /ZAdd /ZEdit /ZRemove /ZRename"; - - vPermissions.Items[(int)Permission.Moderation].ToolTipText = + + vPermissions.Items[( int )Permission.Moderation].ToolTipText = @"Ability to mute everyone in the server, useful for announcements. Affected command: /Moderate"; - vPermissions.Items[(int)Permission.Mute].ToolTipText = -@"Ability to temporarily mute players. Muted players cannot write chat or + vPermissions.Items[( int )Permission.Mute].ToolTipText = +@"Ability to temporarily mute players. Muted players cannot write chat or send PMs, but they can still type in commands, receive PMs, and read chat. Affected commands: /Mute /Unmute"; - vPermissions.Items[(int)Permission.Patrol].ToolTipText = + vPermissions.Items[( int )Permission.Patrol].ToolTipText = @"Ability to patrol lower-ranked players. ""Patrolling"" means teleporting to other players to check on them, usually while hidden. Required permission: Teleport Affected commands: /Patrol /SpecPatrol"; - - vPermissions.Items[(int)Permission.Physics].ToolTipText = + + vPermissions.Items[( int )Permission.Physics].ToolTipText = @"Ability to activate Physics on a world. Affected command: /Physics"; - vPermissions.Items[(int)Permission.PlaceAdmincrete].ToolTipText = + vPermissions.Items[( int )Permission.PlaceAdmincrete].ToolTipText = @"Ability to place admincrete/adminium. This also affects draw commands. Required permission: Build Affected commands: /Solid /Bind"; - vPermissions.Items[(int)Permission.PlaceGrass].ToolTipText = + vPermissions.Items[( int )Permission.PlaceGrass].ToolTipText = @"Ability to place grass blocks. This also affects draw commands. Required permission: Build Affected commands: /Grass /Bind"; - vPermissions.Items[(int)Permission.PlaceLava].ToolTipText = + vPermissions.Items[( int )Permission.PlaceLava].ToolTipText = @"Ability to place lava blocks. This also affects draw commands. Required permission: Build Affected commands: /Lava /Bind"; - vPermissions.Items[(int)Permission.PlaceWater].ToolTipText = + vPermissions.Items[( int )Permission.PlaceWater].ToolTipText = @"Ability to place water blocks. This also affects draw commands. Required permission: Build Affected commands: /Water /Bind"; - - vPermissions.Items[(int)Permission.Possess].ToolTipText = -@"Ability to possess a player. + + vPermissions.Items[( int )Permission.Possess].ToolTipText = + @"Ability to possess a player. Affected commands: /Possess /unpossess"; - vPermissions.Items[(int)Permission.Promote].ToolTipText = + vPermissions.Items[( int )Permission.Promote].ToolTipText = @"Ability to promote players to a higher rank. Affected commands: /Rank"; - - vPermissions.Items[(int)Permission.RageQuit].ToolTipText = + + vPermissions.Items[( int )Permission.RageQuit].ToolTipText = @"Ability to ragequit from the server. Affected command: /Ragequit"; - - vPermissions.Items[(int)Permission.ReadAdminChat].ToolTipText = + + vPermissions.Items[( int )Permission.ReadAdminChat].ToolTipText = @"Ability to read Admin chat."; - vPermissions.Items[(int)Permission.ReadCustomChat].ToolTipText = + vPermissions.Items[( int )Permission.ReadCustomChat].ToolTipText = @"Ability to read Custom chat."; - vPermissions.Items[(int)Permission.ReadStaffChat].ToolTipText = + vPermissions.Items[( int )Permission.ReadStaffChat].ToolTipText = @"Ability to read staff chat."; - vPermissions.Items[(int)Permission.Realm].ToolTipText = + vPermissions.Items[( int )Permission.Realm].ToolTipText = @"Ability to create realms. Affected command: /Realm"; - vPermissions.Items[(int)Permission.ReloadConfig].ToolTipText = + vPermissions.Items[( int )Permission.ReloadConfig].ToolTipText = @"Ability to reload the configuration file without restarting. Affected commands: /Reload"; - vPermissions.Items[(int)Permission.Say].ToolTipText = + vPermissions.Items[( int )Permission.Say].ToolTipText = @"Ability to use /Say command. Required permission: Chat Affected commands: /Say"; - vPermissions.Items[(int)Permission.SetSpawn].ToolTipText = + vPermissions.Items[( int )Permission.SetSpawn].ToolTipText = @"Ability to change the spawn point of a world or a player. Affected commands: /SetSpawn"; - vPermissions.Items[(int)Permission.ShutdownServer].ToolTipText = + vPermissions.Items[( int )Permission.ShutdownServer].ToolTipText = @"Ability to shut down or restart the server remotely. Useful for servers that run on dedicated machines. Affected commands: /Shutdown /Restart"; - - vPermissions.Items[(int)Permission.Slap].ToolTipText = + + vPermissions.Items[( int )Permission.Slap].ToolTipText = @"Ability to slap players. Affected command: /Slap"; - vPermissions.Items[(int)Permission.Spectate].ToolTipText = + vPermissions.Items[( int )Permission.Spectate].ToolTipText = @"Ability to spectate/follow other players in first-person view. Affected commands: /Spectate"; - - vPermissions.Items[(int)Permission.Swear].ToolTipText = + + vPermissions.Items[( int )Permission.Swear].ToolTipText = @"Ability to use swear words without restrictions"; - vPermissions.Items[(int)Permission.Teleport].ToolTipText = + vPermissions.Items[( int )Permission.Teleport].ToolTipText = @"Ability to teleport to other players. Affected commands: /TP"; - - vPermissions.Items[(int)Permission.TempBan].ToolTipText = + + vPermissions.Items[( int )Permission.TempBan].ToolTipText = @"Ability to temporarily ban a player. Affected command: /Tempban"; - - vPermissions.Items[(int)Permission.Tower].ToolTipText = + + vPermissions.Items[( int )Permission.Tower].ToolTipText = @"Ability to create a Tower. Affected command: /Tower"; - - vPermissions.Items[(int)Permission.Troll].ToolTipText = + + vPermissions.Items[( int )Permission.Troll].ToolTipText = @"Ability to troll players. Affected command: /Troll"; - vPermissions.Items[(int)Permission.UndoOthersActions].ToolTipText = + vPermissions.Items[( int )Permission.UndoOthersActions].ToolTipText = @"Ability to undo actions of other players, using the BlockDB. Affected commands: /UndoArea /UndoPlayer"; - vPermissions.Items[(int)Permission.UseColorCodes].ToolTipText = + vPermissions.Items[( int )Permission.UseColorCodes].ToolTipText = @"Ability to use color codes in chat messages."; - - vPermissions.Items[(int)Permission.UsePortal].ToolTipText = + + vPermissions.Items[( int )Permission.UsePortal].ToolTipText = @"Ability to use portals (not be confused with ManagePortal)."; - vPermissions.Items[(int)Permission.UseSpeedHack].ToolTipText = + vPermissions.Items[( int )Permission.UseSpeedHack].ToolTipText = @"Ability to move at a faster-than-normal rate (using hacks). WARNING: Speedhack detection is often inaccurate, and may produce many false positives - especially on laggy servers."; - vPermissions.Items[(int)Permission.Warn].ToolTipText = + vPermissions.Items[( int )Permission.Warn].ToolTipText = @"Ability to warn a player. Affected command: /Warn"; - vPermissions.Items[(int)Permission.ViewOthersInfo].ToolTipText = + vPermissions.Items[( int )Permission.ViewOthersInfo].ToolTipText = @"Ability to view extended information about other players. Affected commands: /Info /BanInfo /Where"; - vPermissions.Items[(int)Permission.ViewPlayerIPs].ToolTipText = + vPermissions.Items[( int )Permission.ViewPlayerIPs].ToolTipText = @"Ability to view players' IP addresses. Affected commands: /Info @@ -659,8 +645,7 @@ are switching from another server software. /BanIP, /BanAll, /UnbanIP, /UnbanAll"; } - - void FillToolTipsSecurity() { + private void FillToolTipsSecurity() { toolTip.SetToolTip( lVerifyNames, ConfigKey.VerifyNames.GetDescription() ); toolTip.SetToolTip( cVerifyNames, ConfigKey.VerifyNames.GetDescription() ); @@ -677,7 +662,6 @@ void FillToolTipsSecurity() { toolTip.SetToolTip( xAnnounceRankChanges, ConfigKey.AnnounceRankChanges.GetDescription() ); toolTip.SetToolTip( xAnnounceRankChangeReasons, ConfigKey.AnnounceRankChanges.GetDescription() ); - toolTip.SetToolTip( lPatrolledRank, ConfigKey.PatrolledRank.GetDescription() ); toolTip.SetToolTip( cPatrolledRank, ConfigKey.PatrolledRank.GetDescription() ); toolTip.SetToolTip( lPatrolledRankAndBelow, ConfigKey.PatrolledRank.GetDescription() ); @@ -696,9 +680,7 @@ void FillToolTipsSecurity() { toolTip.SetToolTip( cBlockDBAutoEnableRank, ConfigKey.BlockDBAutoEnableRank.GetDescription() ); } - - void FillToolTipsSavingAndBackup() { - + private void FillToolTipsSavingAndBackup() { toolTip.SetToolTip( xSaveInterval, ConfigKey.SaveInterval.GetDescription() ); toolTip.SetToolTip( nSaveInterval, ConfigKey.SaveInterval.GetDescription() ); toolTip.SetToolTip( lSaveIntervalUnits, ConfigKey.SaveInterval.GetDescription() ); @@ -722,8 +704,7 @@ void FillToolTipsSavingAndBackup() { toolTip.SetToolTip( lMaxBackupSize, ConfigKey.MaxBackupSize.GetDescription() ); } - - void FillToolTipsLogging() { + private void FillToolTipsLogging() { toolTip.SetToolTip( lLogMode, ConfigKey.LogMode.GetDescription() ); toolTip.SetToolTip( cLogMode, ConfigKey.LogMode.GetDescription() ); @@ -731,33 +712,32 @@ void FillToolTipsLogging() { toolTip.SetToolTip( nLogLimit, ConfigKey.MaxLogs.GetDescription() ); toolTip.SetToolTip( lLogLimitUnits, ConfigKey.MaxLogs.GetDescription() ); - vLogFileOptions.Items[(int)LogType.ConsoleInput].ToolTipText = "Commands typed in from the server console."; - vLogFileOptions.Items[(int)LogType.ConsoleOutput].ToolTipText = + vLogFileOptions.Items[( int )LogType.ConsoleInput].ToolTipText = "Commands typed in from the server console."; + vLogFileOptions.Items[( int )LogType.ConsoleOutput].ToolTipText = @"Things sent directly in response to console input, e.g. output of commands called from console."; - vLogFileOptions.Items[(int)LogType.Debug].ToolTipText = "Technical information that may be useful to find bugs."; - vLogFileOptions.Items[(int)LogType.Error].ToolTipText = "Major errors and problems."; - vLogFileOptions.Items[(int)LogType.SeriousError].ToolTipText = "Errors that prevent server from starting or result in crashes."; - vLogFileOptions.Items[(int)LogType.GlobalChat].ToolTipText = "Normal chat messages written by players."; - vLogFileOptions.Items[(int)LogType.IRC].ToolTipText = + vLogFileOptions.Items[( int )LogType.Debug].ToolTipText = "Technical information that may be useful to find bugs."; + vLogFileOptions.Items[( int )LogType.Error].ToolTipText = "Major errors and problems."; + vLogFileOptions.Items[( int )LogType.SeriousError].ToolTipText = "Errors that prevent server from starting or result in crashes."; + vLogFileOptions.Items[( int )LogType.GlobalChat].ToolTipText = "Normal chat messages written by players."; + vLogFileOptions.Items[( int )LogType.IRC].ToolTipText = @"IRC-related status and error messages. Does not include IRC chatter (see IRCChat)."; - vLogFileOptions.Items[(int)LogType.PrivateChat].ToolTipText = "PMs (Private Messages) exchanged between players (@player message)."; - vLogFileOptions.Items[(int)LogType.RankChat].ToolTipText = "Rank-wide messages (@@rank message)."; - vLogFileOptions.Items[(int)LogType.SuspiciousActivity].ToolTipText = "Suspicious activity - hack attempts, failed logins, unverified names."; - vLogFileOptions.Items[(int)LogType.SystemActivity].ToolTipText = "Status messages regarding normal system activity."; - vLogFileOptions.Items[(int)LogType.UserActivity].ToolTipText = "Status messages regarding players' actions."; - vLogFileOptions.Items[(int)LogType.UserCommand].ToolTipText = "Commands types in by players."; - vLogFileOptions.Items[(int)LogType.Warning].ToolTipText = "Minor, recoverable errors and problems."; - vLogFileOptions.Items[(int)LogType.ChangedWorld].ToolTipText = "Logs when a player changes world."; - - for( int i = 0; i < vConsoleOptions.Items.Count; i++ ) { + vLogFileOptions.Items[( int )LogType.PrivateChat].ToolTipText = "PMs (Private Messages) exchanged between players (@player message)."; + vLogFileOptions.Items[( int )LogType.RankChat].ToolTipText = "Rank-wide messages (@@rank message)."; + vLogFileOptions.Items[( int )LogType.SuspiciousActivity].ToolTipText = "Suspicious activity - hack attempts, failed logins, unverified names."; + vLogFileOptions.Items[( int )LogType.SystemActivity].ToolTipText = "Status messages regarding normal system activity."; + vLogFileOptions.Items[( int )LogType.UserActivity].ToolTipText = "Status messages regarding players' actions."; + vLogFileOptions.Items[( int )LogType.UserCommand].ToolTipText = "Commands types in by players."; + vLogFileOptions.Items[( int )LogType.Warning].ToolTipText = "Minor, recoverable errors and problems."; + vLogFileOptions.Items[( int )LogType.ChangedWorld].ToolTipText = "Logs when a player changes world."; + + for ( int i = 0; i < vConsoleOptions.Items.Count; i++ ) { vConsoleOptions.Items[i].ToolTipText = vLogFileOptions.Items[i].ToolTipText; } } - - void FillToolTipsIRC() { + private void FillToolTipsIRC() { toolTip.SetToolTip( xIRCBotEnabled, ConfigKey.IRCBotEnabled.GetDescription() ); const string tipIRCList = @@ -804,8 +784,7 @@ void FillToolTipsIRC() { toolTip.SetToolTip( xIRCUseColor, ConfigKey.IRCUseColor.GetDescription() ); } - - void FillToolTipsAdvanced() { + private void FillToolTipsAdvanced() { toolTip.SetToolTip( xRelayAllBlockUpdates, ConfigKey.RelayAllBlockUpdates.GetDescription() ); toolTip.SetToolTip( xNoPartialPositionUpdates, ConfigKey.NoPartialPositionUpdates.GetDescription() ); diff --git a/ConfigGUI/MainForm.cs b/ConfigGUI/MainForm.cs index 6898067..6fe984f 100644 --- a/ConfigGUI/MainForm.cs +++ b/ConfigGUI/MainForm.cs @@ -5,24 +5,23 @@ using System.Diagnostics; using System.Drawing; using System.IO; -using System.Text; using System.Linq; using System.Net; using System.Net.Sockets; +using System.Text; using System.Windows.Forms; using fCraft.GUI; using JetBrains.Annotations; - namespace fCraft.ConfigGUI { + public sealed partial class MainForm : Form { - static MainForm instance; - readonly Font bold; - Rank selectedRank; - readonly UpdaterSettingsPopup updaterWindow = new UpdaterSettingsPopup(); + private static MainForm instance; + private readonly Font bold; + private Rank selectedRank; + private readonly UpdaterSettingsPopup updaterWindow = new UpdaterSettingsPopup(); internal static readonly SortableBindingList Worlds = new SortableBindingList(); - #region Initialization public MainForm() { @@ -36,8 +35,7 @@ public MainForm() { Text = "800Craft Configuration (" + Updater.CurrentRelease.VersionString + ")"; } - - void Init( object sender, EventArgs e ) { + private void Init( object sender, EventArgs e ) { // fills Permission and LogType lists FillEnumLists(); @@ -72,31 +70,29 @@ void Init( object sender, EventArgs e ) { bChangelog.Enabled = File.Exists( ChangelogFileName ); } - - void FillEnumLists() { - foreach( Permission permission in Enum.GetValues( typeof( Permission ) ) ) { + private void FillEnumLists() { + foreach ( Permission permission in Enum.GetValues( typeof( Permission ) ) ) { ListViewItem item = new ListViewItem( permission.ToString() ) { Tag = permission }; vPermissions.Items.Add( item ); } - foreach( LogType type in Enum.GetValues( typeof( LogType ) ) ) { - if( type == LogType.Trace ) continue; + foreach ( LogType type in Enum.GetValues( typeof( LogType ) ) ) { + if ( type == LogType.Trace ) + continue; ListViewItem item = new ListViewItem( type.ToString() ) { Tag = type }; vLogFileOptions.Items.Add( item ); - vConsoleOptions.Items.Add( (ListViewItem)item.Clone() ); + vConsoleOptions.Items.Add( ( ListViewItem )item.Clone() ); } } - - void FillWorldList() { + private void FillWorldList() { cMainWorld.Items.Clear(); - foreach( WorldListEntry world in Worlds ) { + foreach ( WorldListEntry world in Worlds ) { cMainWorld.Items.Add( world.Name ); } } - #endregion - + #endregion Initialization #region Input Handlers @@ -122,18 +118,18 @@ private void bPortCheck_Click( object sender, EventArgs e ) { TcpListener listener = null; try { - listener = new TcpListener( IPAddress.Any, (int)nPort.Value ); + listener = new TcpListener( IPAddress.Any, ( int )nPort.Value ); listener.Start(); - HttpWebRequest request = (HttpWebRequest)WebRequest.Create( "http://www.utorrent.com/testport?plain=1&port=" + nPort.Value ); - HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + HttpWebRequest request = ( HttpWebRequest )WebRequest.Create( "http://www.utorrent.com/testport?plain=1&port=" + nPort.Value ); + HttpWebResponse response = ( HttpWebResponse )request.GetResponse(); - if( response.StatusCode == HttpStatusCode.OK ) { - using( Stream stream = response.GetResponseStream() ) { - if( stream != null ) { + if ( response.StatusCode == HttpStatusCode.OK ) { + using ( Stream stream = response.GetResponseStream() ) { + if ( stream != null ) { StreamReader reader = new StreamReader( stream ); string returnMessage = reader.ReadLine(); - if( returnMessage != null && returnMessage.StartsWith( "ok" ) ) { + if ( returnMessage != null && returnMessage.StartsWith( "ok" ) ) { MessageBox.Show( "Port " + nPort.Value + " is open!", "Port check success" ); return; } @@ -141,11 +137,10 @@ private void bPortCheck_Click( object sender, EventArgs e ) { } } MessageBox.Show( "Port " + nPort.Value + " is closed. You will need to set up forwarding.", "Port check failed" ); - } catch { MessageBox.Show( "Could not start listening on port " + nPort.Value + ". Another program may be using the port.", "Port check failed" ); } finally { - if( listener != null ) { + if ( listener != null ) { listener.Stop(); } Enabled = true; @@ -155,7 +150,7 @@ private void bPortCheck_Click( object sender, EventArgs e ) { private void tIP_Validating( object sender, CancelEventArgs e ) { IPAddress IP; - if( Server.IsIP( tIP.Text ) && IPAddress.TryParse( tIP.Text, out IP ) ) { + if ( Server.IsIP( tIP.Text ) && IPAddress.TryParse( tIP.Text, out IP ) ) { tIP.ForeColor = SystemColors.ControlText; } else { tIP.ForeColor = System.Drawing.Color.Red; @@ -176,19 +171,19 @@ private void bGreeting_Click( object sender, EventArgs e ) { private void bShowAdvancedUpdaterSettings_Click( object sender, EventArgs e ) { updaterWindow.ShowDialog(); - cUpdaterMode.SelectedIndex = (int)updaterWindow.UpdaterMode; + cUpdaterMode.SelectedIndex = ( int )updaterWindow.UpdaterMode; } private void cUpdaterMode_SelectedIndexChanged( object sender, EventArgs e ) { - updaterWindow.UpdaterMode = (UpdaterMode)cUpdaterMode.SelectedIndex; + updaterWindow.UpdaterMode = ( UpdaterMode )cUpdaterMode.SelectedIndex; } private void bOpenWiki_Click( object sender, EventArgs e ) { - Process.Start("http://www.minecraftwiki.net/wiki/Custom_servers/800Craft"); + Process.Start( "http://www.minecraftwiki.net/wiki/Custom_servers/800Craft" ); } private void bReportABug_Click( object sender, EventArgs e ) { - Process.Start("http://forums.au70.net/index.php/forum/32-800craft-server-software/"); + Process.Start( "http://forums.au70.net/index.php/forum/32-800craft-server-software/" ); } private void nMaxPlayerPerWorld_Validating( object sender, CancelEventArgs e ) { @@ -203,13 +198,12 @@ private void bCredits_Click( object sender, EventArgs e ) { new AboutWindow().Show(); } - #endregion - + #endregion General #region Worlds - void WorldListErrorHandler( object sender, DataGridViewDataErrorEventArgs e ) { - if( e.Exception is FormatException ) { + private void WorldListErrorHandler( object sender, DataGridViewDataErrorEventArgs e ) { + if ( e.Exception is FormatException ) { string columnName = dgvWorlds.Columns[e.ColumnIndex].HeaderText; MessageBox.Show( e.Exception.Message, "Error editing " + columnName ); } else { @@ -219,14 +213,14 @@ void WorldListErrorHandler( object sender, DataGridViewDataErrorEventArgs e ) { private void bAddWorld_Click( object sender, EventArgs e ) { AddWorldPopup popup = new AddWorldPopup( null ); - if( popup.ShowDialog() == DialogResult.OK ) { + if ( popup.ShowDialog() == DialogResult.OK ) { Worlds.Add( popup.World ); popup.World.LoadedBy = WorldListEntry.WorldInfoSignature; popup.World.LoadedOn = DateTime.UtcNow; } - if( cMainWorld.SelectedItem == null ) { + if ( cMainWorld.SelectedItem == null ) { FillWorldList(); - if( cMainWorld.Items.Count > 0 ) { + if ( cMainWorld.Items.Count > 0 ) { cMainWorld.SelectedIndex = 0; } } else { @@ -238,7 +232,7 @@ private void bAddWorld_Click( object sender, EventArgs e ) { private void bWorldEdit_Click( object sender, EventArgs e ) { AddWorldPopup popup = new AddWorldPopup( Worlds[dgvWorlds.SelectedRows[0].Index] ); - if( popup.ShowDialog() == DialogResult.OK ) { + if ( popup.ShowDialog() == DialogResult.OK ) { string oldName = Worlds[dgvWorlds.SelectedRows[0].Index].Name; Worlds[dgvWorlds.SelectedRows[0].Index] = popup.World; HandleWorldRename( oldName, popup.World.Name ); @@ -246,28 +240,28 @@ private void bWorldEdit_Click( object sender, EventArgs e ) { } private void dgvWorlds_Click( object sender, EventArgs e ) { - bool oneRowSelected = (dgvWorlds.SelectedRows.Count == 1); + bool oneRowSelected = ( dgvWorlds.SelectedRows.Count == 1 ); bWorldDelete.Enabled = oneRowSelected; bWorldEdit.Enabled = oneRowSelected; } private void bWorldDel_Click( object sender, EventArgs e ) { - if( dgvWorlds.SelectedRows.Count > 0 ) { + if ( dgvWorlds.SelectedRows.Count > 0 ) { WorldListEntry world = Worlds[dgvWorlds.SelectedRows[0].Index]; // prompt to delete map file, if it exists - if( File.Exists( world.FullFileName ) ) { + if ( File.Exists( world.FullFileName ) ) { string promptMessage = String.Format( "Are you sure you want to delete world \"{0}\"?", world.Name ); - if( MessageBox.Show( promptMessage, "Deleting a world", MessageBoxButtons.YesNo ) == DialogResult.No ) { + if ( MessageBox.Show( promptMessage, "Deleting a world", MessageBoxButtons.YesNo ) == DialogResult.No ) { return; } string fileDeleteWarning = "Do you want to delete the map file (" + world.FileName + ") as well?"; - if( MessageBox.Show( fileDeleteWarning, "Warning", MessageBoxButtons.YesNo ) == DialogResult.Yes ) { + if ( MessageBox.Show( fileDeleteWarning, "Warning", MessageBoxButtons.YesNo ) == DialogResult.Yes ) { try { File.Delete( world.FullFileName ); - } catch( Exception ex ) { + } catch ( Exception ex ) { MessageBox.Show( "You have to delete the file (" + world.FileName + ") manually. " + "An error occured while trying to delete it automatically:" + Environment.NewLine + ex, "Could not delete map file" ); @@ -277,20 +271,19 @@ private void bWorldDel_Click( object sender, EventArgs e ) { Worlds.Remove( world ); - if( cMainWorld.SelectedItem == null ) { + if ( cMainWorld.SelectedItem == null ) { // deleting non-main world FillWorldList(); - if( cMainWorld.Items.Count > 0 ) { + if ( cMainWorld.Items.Count > 0 ) { cMainWorld.SelectedIndex = 0; } - } else { // deleting main world string mainWorldName = cMainWorld.SelectedItem.ToString(); FillWorldList(); - if( mainWorldName == world.Name ) { + if ( mainWorldName == world.Name ) { MessageBox.Show( "Main world has been reset." ); - if( cMainWorld.Items.Count > 0 ) { + if ( cMainWorld.Items.Count > 0 ) { cMainWorld.SelectedIndex = 0; } } else { @@ -305,18 +298,17 @@ private void bMapPath_Click( object sender, EventArgs e ) { SelectedPath = tMapPath.Text, Description = "Select a directory to save map files to" }; - if( dialog.ShowDialog() == DialogResult.OK ) { + if ( dialog.ShowDialog() == DialogResult.OK ) { tMapPath.Text = dialog.SelectedPath; } } - #endregion - + #endregion Worlds #region Security private void cVerifyNames_SelectedIndexChanged( object sender, EventArgs e ) { - xAllowUnverifiedLAN.Enabled = (cVerifyNames.SelectedIndex != 0); + xAllowUnverifiedLAN.Enabled = ( cVerifyNames.SelectedIndex != 0 ); xAllowUnverifiedLAN.Checked = !xAllowUnverifiedLAN.Enabled; } @@ -324,13 +316,12 @@ private void xMaxConnectionsPerIP_CheckedChanged( object sender, EventArgs e ) { nMaxConnectionsPerIP.Enabled = xMaxConnectionsPerIP.Checked; } - #endregion - + #endregion Security #region Logging private void vConsoleOptions_ItemChecked( object sender, ItemCheckedEventArgs e ) { - if( e.Item.Checked ) { + if ( e.Item.Checked ) { e.Item.Font = bold; } else { e.Item.Font = vConsoleOptions.Font; @@ -338,7 +329,7 @@ private void vConsoleOptions_ItemChecked( object sender, ItemCheckedEventArgs e } private void vLogFileOptions_ItemChecked( object sender, ItemCheckedEventArgs e ) { - if( e.Item.Checked ) { + if ( e.Item.Checked ) { e.Item.Font = bold; } else { e.Item.Font = vLogFileOptions.Font; @@ -349,8 +340,7 @@ private void xLogLimit_CheckedChanged( object sender, EventArgs e ) { nLogLimit.Enabled = xLogLimit.Checked; } - #endregion - + #endregion Logging #region Saving & Backup @@ -370,8 +360,7 @@ private void xMaxBackupSize_CheckedChanged( object sender, EventArgs e ) { nMaxBackupSize.Enabled = xMaxBackupSize.Checked; } - #endregion - + #endregion Saving & Backup #region IRC @@ -383,9 +372,8 @@ private void xIRC_CheckedChanged( object sender, EventArgs e ) { xIRCListShowNonEnglish.Enabled = xIRCBotEnabled.Checked; } - - struct IRCNetwork { - const int DefaultIRCPort = 6667; + private struct IRCNetwork { + private const int DefaultIRCPort = 6667; public readonly string Name, Host; public readonly int Port; @@ -403,7 +391,7 @@ public IRCNetwork( string name, string host, int port, bool isNonEnglish ) { } } - static readonly IRCNetwork[] IRCNetworks = new[]{ + private static readonly IRCNetwork[] IRCNetworks = new[]{ new IRCNetwork("FreeNode", "chat.freenode.net"), new IRCNetwork("QuakeNet", "irc.quakenet.org"), new IRCNetwork("IRCnet", "irc.belwue.de"), @@ -487,9 +475,10 @@ public IRCNetwork( string name, string host, int port, bool isNonEnglish ) { }.OrderBy( network => network.Name ).ToArray(); private void cIRCList_SelectedIndexChanged( object sender, EventArgs e ) { - if( cIRCList.SelectedIndex < 0 ) return; - string selectedNetwork = (string)cIRCList.Items[cIRCList.SelectedIndex]; - IRCNetwork network = IRCNetworks.First( n => (n.Name == selectedNetwork) ); + if ( cIRCList.SelectedIndex < 0 ) + return; + string selectedNetwork = ( string )cIRCList.Items[cIRCList.SelectedIndex]; + IRCNetwork network = IRCNetworks.First( n => ( n.Name == selectedNetwork ) ); tIRCBotNetwork.Text = network.Host; nIRCBotPort.Value = network.Port; } @@ -498,10 +487,10 @@ private void xIRCListShowNonEnglish_CheckedChanged( object sender, EventArgs e ) FillIRCNetworkList( xIRCListShowNonEnglish.Checked ); } - void FillIRCNetworkList( bool showNonEnglishNetworks ) { + private void FillIRCNetworkList( bool showNonEnglishNetworks ) { cIRCList.Items.Clear(); - foreach( IRCNetwork network in IRCNetworks ) { - if( showNonEnglishNetworks || !network.IsNonEnglish ) { + foreach ( IRCNetwork network in IRCNetworks ) { + if ( showNonEnglishNetworks || !network.IsNonEnglish ) { cIRCList.Items.Add( network.Name ); } } @@ -512,14 +501,13 @@ private void xIRCRegisteredNick_CheckedChanged( object sender, EventArgs e ) { tIRCNickServMessage.Enabled = xIRCRegisteredNick.Checked; } - #endregion - + #endregion IRC #region Advanced private void nMaxUndo_ValueChanged( object sender, EventArgs e ) { - if( xMaxUndo.Checked ) { - decimal maxMemUsage = Math.Ceiling( nMaxUndoStates.Value * (nMaxUndo.Value * 8) / (1024 * 1024) ); + if ( xMaxUndo.Checked ) { + decimal maxMemUsage = Math.Ceiling( nMaxUndoStates.Value * ( nMaxUndo.Value * 8 ) / ( 1024 * 1024 ) ); lMaxUndoUnits.Text = String.Format( "blocks each (up to {0} MB of RAM per player)", maxMemUsage ); } else { lMaxUndoUnits.Text = "blocks each"; @@ -536,29 +524,28 @@ private void xMapPath_CheckedChanged( object sender, EventArgs e ) { bMapPath.Enabled = xMapPath.Checked; } - #endregion + #endregion Advanced private void xAnnounceRankChanges_CheckedChanged( object sender, EventArgs e ) { xAnnounceRankChangeReasons.Enabled = xAnnounceRankChanges.Checked; } - #endregion - + #endregion Input Handlers #region Ranks - BindingList rankNameList; + private BindingList rankNameList; - void SelectRank( Rank rank ) { - if( rank == null ) { - if( vRanks.SelectedIndex != -1 ) { + private void SelectRank( Rank rank ) { + if ( rank == null ) { + if ( vRanks.SelectedIndex != -1 ) { vRanks.ClearSelected(); return; } DisableRankOptions(); return; } - if( vRanks.SelectedIndex != rank.Index ) { + if ( vRanks.SelectedIndex != rank.Index ) { vRanks.SelectedIndex = rank.Index; return; } @@ -569,7 +556,7 @@ void SelectRank( Rank rank ) { tPrefix.Text = rank.Prefix; - foreach( var box in permissionLimitBoxes.Values ) { + foreach ( var box in permissionLimitBoxes.Values ) { box.SelectRank( rank ); } @@ -578,28 +565,28 @@ void SelectRank( Rank rank ) { xKickIdle.Checked = rank.IdleKickTimer > 0; nKickIdle.Value = rank.IdleKickTimer; nKickIdle.Enabled = xKickIdle.Checked; - xAntiGrief.Checked = (rank.AntiGriefBlocks > 0 && rank.AntiGriefSeconds > 0); + xAntiGrief.Checked = ( rank.AntiGriefBlocks > 0 && rank.AntiGriefSeconds > 0 ); nAntiGriefBlocks.Value = rank.AntiGriefBlocks; nAntiGriefBlocks.Enabled = xAntiGrief.Checked; nAntiGriefSeconds.Value = rank.AntiGriefSeconds; nAntiGriefSeconds.Enabled = xAntiGrief.Checked; - xDrawLimit.Checked = (rank.DrawLimit > 0); + xDrawLimit.Checked = ( rank.DrawLimit > 0 ); nDrawLimit.Value = rank.DrawLimit; nCopyPasteSlots.Value = rank.CopySlots; nFillLimit.Value = rank.FillLimit; xAllowSecurityCircumvention.Checked = rank.AllowSecurityCircumvention; - foreach( ListViewItem item in vPermissions.Items ) { + foreach ( ListViewItem item in vPermissions.Items ) { item.Checked = rank.Permissions[item.Index]; - if( item.Checked ) { + if ( item.Checked ) { item.Font = bold; } else { item.Font = vPermissions.Font; } } - foreach( ListViewItem item in vPermissions.Items ) { - CheckPermissionConsistency( (Permission)item.Tag, item.Checked ); + foreach ( ListViewItem item in vPermissions.Items ) { + CheckPermissionConsistency( ( Permission )item.Tag, item.Checked ); } xDrawLimit.Enabled = rank.Can( Permission.Draw ) || rank.Can( Permission.CopyAndPaste ); @@ -611,14 +598,13 @@ void SelectRank( Rank rank ) { vPermissions.Enabled = true; bDeleteRank.Enabled = true; - bRaiseRank.Enabled = (selectedRank != RankManager.HighestRank); - bLowerRank.Enabled = (selectedRank != RankManager.LowestRank); + bRaiseRank.Enabled = ( selectedRank != RankManager.HighestRank ); + bLowerRank.Enabled = ( selectedRank != RankManager.LowestRank ); } - - void RebuildRankList() { + private void RebuildRankList() { vRanks.Items.Clear(); - foreach( Rank rank in RankManager.Ranks ) { + foreach ( Rank rank in RankManager.Ranks ) { vRanks.Items.Add( MainForm.ToComboBoxOption( rank ) ); } @@ -631,19 +617,18 @@ void RebuildRankList() { FillRankList( cBlockDBAutoEnableRank, "(default rank)" ); cBlockDBAutoEnableRank.SelectedIndex = RankManager.GetIndex( RankManager.BlockDBAutoEnableRank ); - if( selectedRank != null ) { + if ( selectedRank != null ) { vRanks.SelectedIndex = selectedRank.Index; } SelectRank( selectedRank ); - foreach( var box in permissionLimitBoxes.Values ) { + foreach ( var box in permissionLimitBoxes.Values ) { box.RebuildList(); box.SelectRank( selectedRank ); } } - - void DisableRankOptions() { + private void DisableRankOptions() { selectedRank = null; bDeleteRank.Enabled = false; bRaiseRank.Enabled = false; @@ -652,7 +637,7 @@ void DisableRankOptions() { bColorRank.Text = ""; tPrefix.Text = ""; - foreach( var box in permissionLimitBoxes.Values ) { + foreach ( var box in permissionLimitBoxes.Values ) { box.SelectRank( null ); } @@ -667,7 +652,7 @@ void DisableRankOptions() { xAllowSecurityCircumvention.Checked = false; nCopyPasteSlots.Value = 0; nFillLimit.Value = 32; - foreach( ListViewItem item in vPermissions.Items ) { + foreach ( ListViewItem item in vPermissions.Items ) { item.Checked = false; item.Font = vPermissions.Font; } @@ -676,22 +661,22 @@ void DisableRankOptions() { vPermissions.Enabled = false; } - - static void FillRankList( [NotNull] ComboBox box, string firstItem ) { - if( box == null ) throw new ArgumentNullException( "box" ); + private static void FillRankList( [NotNull] ComboBox box, string firstItem ) { + if ( box == null ) + throw new ArgumentNullException( "box" ); box.Items.Clear(); box.Items.Add( firstItem ); - foreach( Rank rank in RankManager.Ranks ) { - box.Items.Add( MainForm.ToComboBoxOption(rank) ); + foreach ( Rank rank in RankManager.Ranks ) { + box.Items.Add( MainForm.ToComboBoxOption( rank ) ); } } - #region Ranks Input Handlers private void bAddRank_Click( object sender, EventArgs e ) { int number = 1; - while( RankManager.RanksByName.ContainsKey( "rank" + number ) ) number++; + while ( RankManager.RanksByName.ContainsKey( "rank" + number ) ) + number++; Rank rank = new Rank( "rank" + number, RankManager.GenerateID() ); @@ -701,90 +686,92 @@ private void bAddRank_Click( object sender, EventArgs e ) { RebuildRankList(); SelectRank( rank ); - rankNameList.Insert( rank.Index + 1, MainForm.ToComboBoxOption(rank) ); + rankNameList.Insert( rank.Index + 1, MainForm.ToComboBoxOption( rank ) ); } private void bDeleteRank_Click( object sender, EventArgs e ) { - if( vRanks.SelectedItem != null ) { + if ( vRanks.SelectedItem != null ) { selectedRank = null; int index = vRanks.SelectedIndex; Rank deletedRank = RankManager.FindRank( index ); - if( deletedRank == null ) return; + if ( deletedRank == null ) + return; string messages = ""; // Ask for substitute rank DeleteRankPopup popup = new DeleteRankPopup( deletedRank ); - if( popup.ShowDialog() != DialogResult.OK ) return; + if ( popup.ShowDialog() != DialogResult.OK ) + return; Rank replacementRank = popup.SubstituteRank; // Update default rank - if( RankManager.DefaultRank == deletedRank ) { + if ( RankManager.DefaultRank == deletedRank ) { RankManager.DefaultRank = replacementRank; messages += "DefaultRank has been changed to \"" + replacementRank.Name + "\"" + Environment.NewLine; } // Update defaultbuild rank - if( RankManager.DefaultBuildRank == deletedRank ) { + if ( RankManager.DefaultBuildRank == deletedRank ) { RankManager.DefaultBuildRank = replacementRank; messages += "DefaultBuildRank has been changed to \"" + replacementRank.Name + "\"" + Environment.NewLine; } // Update patrolled rank - if( RankManager.PatrolledRank == deletedRank ) { + if ( RankManager.PatrolledRank == deletedRank ) { RankManager.PatrolledRank = replacementRank; messages += "PatrolledRank has been changed to \"" + replacementRank.Name + "\"" + Environment.NewLine; } // Update patrolled rank - if( RankManager.BlockDBAutoEnableRank == deletedRank ) { + if ( RankManager.BlockDBAutoEnableRank == deletedRank ) { RankManager.BlockDBAutoEnableRank = replacementRank; messages += "BlockDBAutoEnableRank has been changed to \"" + replacementRank.Name + "\"" + Environment.NewLine; } // Delete rank - if( RankManager.DeleteRank( deletedRank, replacementRank ) ) { + if ( RankManager.DeleteRank( deletedRank, replacementRank ) ) { messages += "Some of the rank limits for kick, ban, promote, and/or demote have been reset." + Environment.NewLine; } vRanks.Items.RemoveAt( index ); // Update world permissions string worldUpdates = ""; - foreach( WorldListEntry world in Worlds ) { - if( world.AccessPermission == MainForm.ToComboBoxOption(deletedRank) ) { - world.AccessPermission = MainForm.ToComboBoxOption(replacementRank); + foreach ( WorldListEntry world in Worlds ) { + if ( world.AccessPermission == MainForm.ToComboBoxOption( deletedRank ) ) { + world.AccessPermission = MainForm.ToComboBoxOption( replacementRank ); worldUpdates += " - " + world.Name + ": access permission changed to " + replacementRank.Name + Environment.NewLine; } - if( world.BuildPermission == MainForm.ToComboBoxOption(deletedRank) ) { - world.BuildPermission = MainForm.ToComboBoxOption(replacementRank); + if ( world.BuildPermission == MainForm.ToComboBoxOption( deletedRank ) ) { + world.BuildPermission = MainForm.ToComboBoxOption( replacementRank ); worldUpdates += " - " + world.Name + ": build permission changed to " + replacementRank.Name + Environment.NewLine; } } rankNameList.RemoveAt( index + 1 ); - if( worldUpdates.Length > 0 ) { + if ( worldUpdates.Length > 0 ) { messages += "The following worlds were affected:" + Environment.NewLine + worldUpdates; } - if( messages.Length > 0 ) { + if ( messages.Length > 0 ) { MessageBox.Show( messages, "Warning" ); } RebuildRankList(); - if( index < vRanks.Items.Count ) { + if ( index < vRanks.Items.Count ) { vRanks.SelectedIndex = index; } } } - private void tPrefix_Validating( object sender, CancelEventArgs e ) { - if( selectedRank == null ) return; + if ( selectedRank == null ) + return; tPrefix.Text = tPrefix.Text.Trim(); - if( tPrefix.Text.Length > 0 && !Rank.IsValidPrefix( tPrefix.Text ) ) { + if ( tPrefix.Text.Length > 0 && !Rank.IsValidPrefix( tPrefix.Text ) ) { MessageBox.Show( "Invalid prefix character!\n" + "Prefixes may only contain characters that are allowed in chat (except space).", "Warning" ); tPrefix.ForeColor = System.Drawing.Color.Red; @@ -792,9 +779,10 @@ private void tPrefix_Validating( object sender, CancelEventArgs e ) { } else { tPrefix.ForeColor = SystemColors.ControlText; } - if( selectedRank.Prefix == tPrefix.Text ) return; + if ( selectedRank.Prefix == tPrefix.Text ) + return; - string oldName = MainForm.ToComboBoxOption(selectedRank); + string oldName = MainForm.ToComboBoxOption( selectedRank ); // To avoid DataErrors in World tab's DataGridView while renaming a rank, // the new name is first added to the list of options (without removing the old name) @@ -810,49 +798,55 @@ private void tPrefix_Validating( object sender, CancelEventArgs e ) { } private void xReserveSlot_CheckedChanged( object sender, EventArgs e ) { - if( selectedRank == null ) return; + if ( selectedRank == null ) + return; selectedRank.ReservedSlot = xReserveSlot.Checked; } private void nKickIdle_ValueChanged( object sender, EventArgs e ) { - if( selectedRank == null || !xKickIdle.Checked ) return; + if ( selectedRank == null || !xKickIdle.Checked ) + return; selectedRank.IdleKickTimer = Convert.ToInt32( nKickIdle.Value ); } private void nAntiGriefBlocks_ValueChanged( object sender, EventArgs e ) { - if( selectedRank == null || !xAntiGrief.Checked ) return; + if ( selectedRank == null || !xAntiGrief.Checked ) + return; selectedRank.AntiGriefBlocks = Convert.ToInt32( nAntiGriefBlocks.Value ); } private void nAntiGriefSeconds_ValueChanged( object sender, EventArgs e ) { - if( selectedRank == null || !xAntiGrief.Checked ) return; + if ( selectedRank == null || !xAntiGrief.Checked ) + return; selectedRank.AntiGriefSeconds = Convert.ToInt32( nAntiGriefSeconds.Value ); } private void nDrawLimit_ValueChanged( object sender, EventArgs e ) { - if( selectedRank == null || !xDrawLimit.Checked ) return; + if ( selectedRank == null || !xDrawLimit.Checked ) + return; selectedRank.DrawLimit = Convert.ToInt32( nDrawLimit.Value ); double cubed = Math.Pow( Convert.ToDouble( nDrawLimit.Value ), 1 / 3d ); lDrawLimitUnits.Text = String.Format( "blocks ({0:0}\u00B3)", cubed ); } private void nCopyPasteSlots_ValueChanged( object sender, EventArgs e ) { - if( selectedRank == null ) return; + if ( selectedRank == null ) + return; selectedRank.CopySlots = Convert.ToInt32( nCopyPasteSlots.Value ); } private void xAllowSecurityCircumvention_CheckedChanged( object sender, EventArgs e ) { - if( selectedRank == null ) return; + if ( selectedRank == null ) + return; selectedRank.AllowSecurityCircumvention = xAllowSecurityCircumvention.Checked; } - private void xSpamChatKick_CheckedChanged( object sender, EventArgs e ) { nAntispamMaxWarnings.Enabled = xAntispamKicks.Checked; } private void vRanks_SelectedIndexChanged( object sender, EventArgs e ) { - if( vRanks.SelectedIndex != -1 ) { + if ( vRanks.SelectedIndex != -1 ) { SelectRank( RankManager.FindRank( vRanks.SelectedIndex ) ); } else { DisableRankOptions(); @@ -860,8 +854,9 @@ private void vRanks_SelectedIndexChanged( object sender, EventArgs e ) { } private void xKickIdle_CheckedChanged( object sender, EventArgs e ) { - if( selectedRank == null ) return; - if( xKickIdle.Checked ) { + if ( selectedRank == null ) + return; + if ( xKickIdle.Checked ) { nKickIdle.Value = selectedRank.IdleKickTimer; } else { nKickIdle.Value = 0; @@ -871,8 +866,9 @@ private void xKickIdle_CheckedChanged( object sender, EventArgs e ) { } private void xAntiGrief_CheckedChanged( object sender, EventArgs e ) { - if( selectedRank == null ) return; - if( xAntiGrief.Checked ) { + if ( selectedRank == null ) + return; + if ( xAntiGrief.Checked ) { nAntiGriefBlocks.Value = selectedRank.AntiGriefBlocks; nAntiGriefSeconds.Value = selectedRank.AntiGriefSeconds; } else { @@ -886,8 +882,9 @@ private void xAntiGrief_CheckedChanged( object sender, EventArgs e ) { } private void xDrawLimit_CheckedChanged( object sender, EventArgs e ) { - if( selectedRank == null ) return; - if( xDrawLimit.Checked ) { + if ( selectedRank == null ) + return; + if ( xDrawLimit.Checked ) { nDrawLimit.Value = selectedRank.DrawLimit; double cubed = Math.Pow( Convert.ToDouble( nDrawLimit.Value ), 1 / 3d ); lDrawLimitUnits.Text = String.Format( "blocks ({0:0}\u00B3)", cubed ); @@ -901,81 +898,84 @@ private void xDrawLimit_CheckedChanged( object sender, EventArgs e ) { private void vPermissions_ItemChecked( object sender, ItemCheckedEventArgs e ) { bool check = e.Item.Checked; - if( check ) { + if ( check ) { e.Item.Font = bold; } else { e.Item.Font = vPermissions.Font; } - if( selectedRank == null ) return; + if ( selectedRank == null ) + return; - Permission permission = (Permission)e.Item.Tag; + Permission permission = ( Permission )e.Item.Tag; CheckPermissionConsistency( permission, check ); - selectedRank.Permissions[(int)e.Item.Tag] = e.Item.Checked; + selectedRank.Permissions[( int )e.Item.Tag] = e.Item.Checked; } - void CheckPermissionConsistency( Permission permission, bool check ) { - switch( permission ) { + private void CheckPermissionConsistency( Permission permission, bool check ) { + switch ( permission ) { case Permission.Chat: - if( !check ) { - vPermissions.Items[(int)Permission.Say].Checked = false; - vPermissions.Items[(int)Permission.Say].ForeColor = SystemColors.GrayText; - vPermissions.Items[(int)Permission.UseColorCodes].Checked = false; - vPermissions.Items[(int)Permission.UseColorCodes].ForeColor = SystemColors.GrayText; + if ( !check ) { + vPermissions.Items[( int )Permission.Say].Checked = false; + vPermissions.Items[( int )Permission.Say].ForeColor = SystemColors.GrayText; + vPermissions.Items[( int )Permission.UseColorCodes].Checked = false; + vPermissions.Items[( int )Permission.UseColorCodes].ForeColor = SystemColors.GrayText; } else { - vPermissions.Items[(int)Permission.Say].ForeColor = SystemColors.ControlText; - vPermissions.Items[(int)Permission.UseColorCodes].ForeColor = SystemColors.ControlText; + vPermissions.Items[( int )Permission.Say].ForeColor = SystemColors.ControlText; + vPermissions.Items[( int )Permission.UseColorCodes].ForeColor = SystemColors.ControlText; } break; case Permission.Say: - if( check ) vPermissions.Items[(int)Permission.Chat].Checked = true; + if ( check ) + vPermissions.Items[( int )Permission.Chat].Checked = true; break; case Permission.UseColorCodes: - if( check ) vPermissions.Items[(int)Permission.Chat].Checked = true; + if ( check ) + vPermissions.Items[( int )Permission.Chat].Checked = true; break; case Permission.Ban: - if( !check ) { - vPermissions.Items[(int)Permission.BanIP].Checked = false; - vPermissions.Items[(int)Permission.BanIP].ForeColor = SystemColors.GrayText; - vPermissions.Items[(int)Permission.BanAll].Checked = false; - vPermissions.Items[(int)Permission.BanAll].ForeColor = SystemColors.GrayText; + if ( !check ) { + vPermissions.Items[( int )Permission.BanIP].Checked = false; + vPermissions.Items[( int )Permission.BanIP].ForeColor = SystemColors.GrayText; + vPermissions.Items[( int )Permission.BanAll].Checked = false; + vPermissions.Items[( int )Permission.BanAll].ForeColor = SystemColors.GrayText; } else { - vPermissions.Items[(int)Permission.BanIP].ForeColor = SystemColors.ControlText; - vPermissions.Items[(int)Permission.BanAll].ForeColor = SystemColors.ControlText; + vPermissions.Items[( int )Permission.BanIP].ForeColor = SystemColors.ControlText; + vPermissions.Items[( int )Permission.BanAll].ForeColor = SystemColors.ControlText; } break; case Permission.BanIP: - if( check ) { - vPermissions.Items[(int)Permission.Ban].Checked = true; - vPermissions.Items[(int)Permission.BanAll].ForeColor = SystemColors.ControlText; + if ( check ) { + vPermissions.Items[( int )Permission.Ban].Checked = true; + vPermissions.Items[( int )Permission.BanAll].ForeColor = SystemColors.ControlText; } else { - vPermissions.Items[(int)Permission.BanAll].Checked = false; - vPermissions.Items[(int)Permission.BanAll].ForeColor = SystemColors.GrayText; + vPermissions.Items[( int )Permission.BanAll].Checked = false; + vPermissions.Items[( int )Permission.BanAll].ForeColor = SystemColors.GrayText; } break; case Permission.BanAll: - if( check ) { - vPermissions.Items[(int)Permission.Ban].Checked = true; - vPermissions.Items[(int)Permission.BanIP].Checked = true; + if ( check ) { + vPermissions.Items[( int )Permission.Ban].Checked = true; + vPermissions.Items[( int )Permission.BanIP].Checked = true; } break; case Permission.Draw: - xDrawLimit.Enabled = vPermissions.Items[(int)Permission.Draw].Checked || - vPermissions.Items[(int)Permission.CopyAndPaste].Checked; - if( check ) { - vPermissions.Items[(int)Permission.DrawAdvanced].ForeColor = SystemColors.ControlText; - vPermissions.Items[(int)Permission.CopyAndPaste].ForeColor = SystemColors.ControlText; + xDrawLimit.Enabled = vPermissions.Items[( int )Permission.Draw].Checked || + vPermissions.Items[( int )Permission.CopyAndPaste].Checked; + if ( check ) { + vPermissions.Items[( int )Permission.DrawAdvanced].ForeColor = SystemColors.ControlText; + vPermissions.Items[( int )Permission.CopyAndPaste].ForeColor = SystemColors.ControlText; } else { - vPermissions.Items[(int)Permission.DrawAdvanced].Checked = false; - vPermissions.Items[(int)Permission.DrawAdvanced].ForeColor = SystemColors.GrayText; - vPermissions.Items[(int)Permission.CopyAndPaste].Checked = false; - vPermissions.Items[(int)Permission.CopyAndPaste].ForeColor = SystemColors.GrayText; + vPermissions.Items[( int )Permission.DrawAdvanced].Checked = false; + vPermissions.Items[( int )Permission.DrawAdvanced].ForeColor = SystemColors.GrayText; + vPermissions.Items[( int )Permission.CopyAndPaste].Checked = false; + vPermissions.Items[( int )Permission.CopyAndPaste].ForeColor = SystemColors.GrayText; } break; @@ -986,59 +986,61 @@ void CheckPermissionConsistency( Permission permission, bool check ) { break; case Permission.CopyAndPaste: - xDrawLimit.Enabled = vPermissions.Items[(int)Permission.Draw].Checked || - vPermissions.Items[(int)Permission.CopyAndPaste].Checked; + xDrawLimit.Enabled = vPermissions.Items[( int )Permission.Draw].Checked || + vPermissions.Items[( int )Permission.CopyAndPaste].Checked; lCopyPasteSlots.Enabled = check; nCopyPasteSlots.Enabled = check; break; case Permission.ManageWorlds: case Permission.ManageZones: - xAllowSecurityCircumvention.Enabled = vPermissions.Items[(int)Permission.ManageWorlds].Checked || - vPermissions.Items[(int)Permission.ManageZones].Checked; + xAllowSecurityCircumvention.Enabled = vPermissions.Items[( int )Permission.ManageWorlds].Checked || + vPermissions.Items[( int )Permission.ManageZones].Checked; break; case Permission.Teleport: - if( !check ) { - vPermissions.Items[(int)Permission.Patrol].Checked = false; - vPermissions.Items[(int)Permission.Patrol].ForeColor = SystemColors.GrayText; + if ( !check ) { + vPermissions.Items[( int )Permission.Patrol].Checked = false; + vPermissions.Items[( int )Permission.Patrol].ForeColor = SystemColors.GrayText; } else { - vPermissions.Items[(int)Permission.Patrol].ForeColor = SystemColors.ControlText; + vPermissions.Items[( int )Permission.Patrol].ForeColor = SystemColors.ControlText; } break; case Permission.Patrol: - if( check ) vPermissions.Items[(int)Permission.Teleport].Checked = true; + if ( check ) + vPermissions.Items[( int )Permission.Teleport].Checked = true; break; case Permission.Delete: - if( !check ) { - vPermissions.Items[(int)Permission.DeleteAdmincrete].Checked = false; - vPermissions.Items[(int)Permission.DeleteAdmincrete].ForeColor = SystemColors.GrayText; + if ( !check ) { + vPermissions.Items[( int )Permission.DeleteAdmincrete].Checked = false; + vPermissions.Items[( int )Permission.DeleteAdmincrete].ForeColor = SystemColors.GrayText; } else { - vPermissions.Items[(int)Permission.DeleteAdmincrete].ForeColor = SystemColors.ControlText; + vPermissions.Items[( int )Permission.DeleteAdmincrete].ForeColor = SystemColors.ControlText; } break; case Permission.DeleteAdmincrete: - if( check ) vPermissions.Items[(int)Permission.Delete].Checked = true; + if ( check ) + vPermissions.Items[( int )Permission.Delete].Checked = true; break; case Permission.Build: - if( !check ) { - vPermissions.Items[(int)Permission.PlaceAdmincrete].Checked = false; - vPermissions.Items[(int)Permission.PlaceAdmincrete].ForeColor = SystemColors.GrayText; - vPermissions.Items[(int)Permission.PlaceGrass].Checked = false; - vPermissions.Items[(int)Permission.PlaceGrass].ForeColor = SystemColors.GrayText; - vPermissions.Items[(int)Permission.PlaceLava].Checked = false; - vPermissions.Items[(int)Permission.PlaceLava].ForeColor = SystemColors.GrayText; - vPermissions.Items[(int)Permission.PlaceWater].Checked = false; - vPermissions.Items[(int)Permission.PlaceWater].ForeColor = SystemColors.GrayText; + if ( !check ) { + vPermissions.Items[( int )Permission.PlaceAdmincrete].Checked = false; + vPermissions.Items[( int )Permission.PlaceAdmincrete].ForeColor = SystemColors.GrayText; + vPermissions.Items[( int )Permission.PlaceGrass].Checked = false; + vPermissions.Items[( int )Permission.PlaceGrass].ForeColor = SystemColors.GrayText; + vPermissions.Items[( int )Permission.PlaceLava].Checked = false; + vPermissions.Items[( int )Permission.PlaceLava].ForeColor = SystemColors.GrayText; + vPermissions.Items[( int )Permission.PlaceWater].Checked = false; + vPermissions.Items[( int )Permission.PlaceWater].ForeColor = SystemColors.GrayText; } else { - vPermissions.Items[(int)Permission.PlaceAdmincrete].ForeColor = SystemColors.ControlText; - vPermissions.Items[(int)Permission.PlaceGrass].ForeColor = SystemColors.ControlText; - vPermissions.Items[(int)Permission.PlaceLava].ForeColor = SystemColors.ControlText; - vPermissions.Items[(int)Permission.PlaceWater].ForeColor = SystemColors.ControlText; + vPermissions.Items[( int )Permission.PlaceAdmincrete].ForeColor = SystemColors.ControlText; + vPermissions.Items[( int )Permission.PlaceGrass].ForeColor = SystemColors.ControlText; + vPermissions.Items[( int )Permission.PlaceLava].ForeColor = SystemColors.ControlText; + vPermissions.Items[( int )Permission.PlaceWater].ForeColor = SystemColors.ControlText; } break; @@ -1046,56 +1048,54 @@ void CheckPermissionConsistency( Permission permission, bool check ) { case Permission.PlaceGrass: case Permission.PlaceLava: case Permission.PlaceWater: - if( check ) vPermissions.Items[(int)Permission.Build].Checked = true; + if ( check ) + vPermissions.Items[( int )Permission.Build].Checked = true; break; case Permission.Bring: - if( !check ) { - vPermissions.Items[(int)Permission.BringAll].Checked = false; - vPermissions.Items[(int)Permission.BringAll].ForeColor = SystemColors.GrayText; + if ( !check ) { + vPermissions.Items[( int )Permission.BringAll].Checked = false; + vPermissions.Items[( int )Permission.BringAll].ForeColor = SystemColors.GrayText; } else { - vPermissions.Items[(int)Permission.BringAll].ForeColor = SystemColors.ControlText; + vPermissions.Items[( int )Permission.BringAll].ForeColor = SystemColors.ControlText; } break; case Permission.BringAll: - if( check ) vPermissions.Items[(int)Permission.Bring].Checked = true; + if ( check ) + vPermissions.Items[( int )Permission.Bring].Checked = true; break; - } - if( permissionLimitBoxes.ContainsKey( permission ) ) { + if ( permissionLimitBoxes.ContainsKey( permission ) ) { permissionLimitBoxes[permission].PermissionToggled( check ); } } private void tRankName_Validating( object sender, CancelEventArgs e ) { tRankName.ForeColor = SystemColors.ControlText; - if( selectedRank == null ) return; + if ( selectedRank == null ) + return; string newName = tRankName.Text.Trim(); - if( newName == selectedRank.Name ) { + if ( newName == selectedRank.Name ) { return; - - } else if( newName.Length == 0 ) { + } else if ( newName.Length == 0 ) { MessageBox.Show( "Rank name cannot be blank." ); tRankName.ForeColor = System.Drawing.Color.Red; e.Cancel = true; - - } else if( !Rank.IsValidRankName( newName ) ) { + } else if ( !Rank.IsValidRankName( newName ) ) { MessageBox.Show( "Rank name can only contain letters, digits, and underscores." ); tRankName.ForeColor = System.Drawing.Color.Red; e.Cancel = true; - - } else if( !RankManager.CanRenameRank( selectedRank, newName ) ) { + } else if ( !RankManager.CanRenameRank( selectedRank, newName ) ) { MessageBox.Show( "There is already another rank named \"" + newName + "\".\n" + "Duplicate rank names are not allowed." ); tRankName.ForeColor = System.Drawing.Color.Red; e.Cancel = true; - } else { - string oldName = MainForm.ToComboBoxOption(selectedRank); + string oldName = MainForm.ToComboBoxOption( selectedRank ); // To avoid DataErrors in World tab's DataGridView while renaming a rank, // the new name is first added to the list of options (without removing the old name) @@ -1111,29 +1111,29 @@ private void tRankName_Validating( object sender, CancelEventArgs e ) { } } - private void bRaiseRank_Click( object sender, EventArgs e ) { - if( selectedRank == null ) return; - if( RankManager.RaiseRank( selectedRank ) ) { + if ( selectedRank == null ) + return; + if ( RankManager.RaiseRank( selectedRank ) ) { RebuildRankList(); - rankNameList.Insert( selectedRank.Index + 1, MainForm.ToComboBoxOption(selectedRank) ); + rankNameList.Insert( selectedRank.Index + 1, MainForm.ToComboBoxOption( selectedRank ) ); rankNameList.RemoveAt( selectedRank.Index + 3 ); } } private void bLowerRank_Click( object sender, EventArgs e ) { - if( selectedRank == null ) return; - if( RankManager.LowerRank( selectedRank ) ) { + if ( selectedRank == null ) + return; + if ( RankManager.LowerRank( selectedRank ) ) { RebuildRankList(); - rankNameList.Insert( selectedRank.Index + 2, MainForm.ToComboBoxOption(selectedRank) ); + rankNameList.Insert( selectedRank.Index + 2, MainForm.ToComboBoxOption( selectedRank ) ); rankNameList.RemoveAt( selectedRank.Index ); } } - #endregion - - #endregion + #endregion Ranks Input Handlers + #endregion Ranks #region Apply / Save / Cancel Buttons @@ -1146,19 +1146,19 @@ private void bSave_Click( object sender, EventArgs e ) { Application.Exit(); } - void SaveEverything() { - using( LogRecorder applyLogger = new LogRecorder() ) { + private void SaveEverything() { + using ( LogRecorder applyLogger = new LogRecorder() ) { SaveConfig(); - if( applyLogger.HasMessages ) { + if ( applyLogger.HasMessages ) { MessageBox.Show( applyLogger.MessageString, "Some problems were encountered with the selected values." ); return; } } - using( LogRecorder saveLogger = new LogRecorder() ) { - if( Config.Save() ) { + using ( LogRecorder saveLogger = new LogRecorder() ) { + if ( Config.Save() ) { bApply.Enabled = false; } - if( saveLogger.HasMessages ) { + if ( saveLogger.HasMessages ) { MessageBox.Show( saveLogger.MessageString, "Some problems were encountered while saving." ); } } @@ -1168,14 +1168,14 @@ private void bCancel_Click( object sender, EventArgs e ) { Application.Exit(); } - #endregion - + #endregion Apply / Save / Cancel Buttons #region Reset private void bResetAll_Click( object sender, EventArgs e ) { - if( MessageBox.Show( "Are you sure you want to reset everything to defaults?", "Warning", - MessageBoxButtons.OKCancel ) != DialogResult.OK ) return; + if ( MessageBox.Show( "Are you sure you want to reset everything to defaults?", "Warning", + MessageBoxButtons.OKCancel ) != DialogResult.OK ) + return; Config.LoadDefaults(); Config.ResetRanks(); Config.ResetLogOptions(); @@ -1192,44 +1192,53 @@ private void bResetAll_Click( object sender, EventArgs e ) { } private void bResetTab_Click( object sender, EventArgs e ) { - if( MessageBox.Show( "Are you sure you want to reset this tab to defaults?", "Warning", - MessageBoxButtons.OKCancel ) != DialogResult.OK ) return; - switch( tabs.SelectedIndex ) { + if ( MessageBox.Show( "Are you sure you want to reset this tab to defaults?", "Warning", + MessageBoxButtons.OKCancel ) != DialogResult.OK ) + return; + switch ( tabs.SelectedIndex ) { case 0:// General Config.LoadDefaults( ConfigSection.General ); ApplyTabGeneral(); break; + case 1: // Chat Config.LoadDefaults( ConfigSection.Chat ); ApplyTabChat(); break; + case 2:// Worlds Config.LoadDefaults( ConfigSection.Worlds ); ApplyTabWorlds(); // also reloads world list break; + case 3:// Ranks Config.ResetRanks(); ApplyTabWorlds(); ApplyTabRanks(); RebuildRankList(); break; + case 4:// Security Config.LoadDefaults( ConfigSection.Security ); ApplyTabSecurity(); break; + case 5:// Saving and Backup Config.LoadDefaults( ConfigSection.SavingAndBackup ); ApplyTabSavingAndBackup(); break; + case 6:// Logging Config.LoadDefaults( ConfigSection.Logging ); Config.ResetLogOptions(); ApplyTabLogging(); break; + case 7:// IRC Config.LoadDefaults( ConfigSection.IRC ); ApplyTabIRC(); break; + case 8:// Advanced Config.LoadDefaults( ConfigSection.Logging ); ApplyTabAdvanced(); @@ -1237,48 +1246,46 @@ private void bResetTab_Click( object sender, EventArgs e ) { } } - #endregion - + #endregion Reset #region Utils #region Change Detection - void SomethingChanged( object sender, EventArgs args ) { + private void SomethingChanged( object sender, EventArgs args ) { bApply.Enabled = true; } - - void AddChangeHandler( Control c, EventHandler handler ) { - if( c is CheckBox ) { - ((CheckBox)c).CheckedChanged += handler; - } else if( c is ComboBox ) { - ((ComboBox)c).SelectedIndexChanged += handler; - } else if( c is ListView ) { - ((ListView)c).ItemChecked += (( o, e ) => handler( o, e )); - } else if( c is NumericUpDown ) { - ((NumericUpDown)c).ValueChanged += handler; - } else if( c is ListBox ) { - ((ListBox)c).SelectedIndexChanged += handler; - } else if( c is TextBoxBase ) { + private void AddChangeHandler( Control c, EventHandler handler ) { + if ( c is CheckBox ) { + ( ( CheckBox )c ).CheckedChanged += handler; + } else if ( c is ComboBox ) { + ( ( ComboBox )c ).SelectedIndexChanged += handler; + } else if ( c is ListView ) { + ( ( ListView )c ).ItemChecked += ( ( o, e ) => handler( o, e ) ); + } else if ( c is NumericUpDown ) { + ( ( NumericUpDown )c ).ValueChanged += handler; + } else if ( c is ListBox ) { + ( ( ListBox )c ).SelectedIndexChanged += handler; + } else if ( c is TextBoxBase ) { c.TextChanged += handler; - } else if( c is ButtonBase ) { - if( c != bPortCheck && c != bMeasure ) { + } else if ( c is ButtonBase ) { + if ( c != bPortCheck && c != bMeasure ) { c.Click += handler; } } - foreach( Control child in c.Controls ) { + foreach ( Control child in c.Controls ) { AddChangeHandler( child, handler ); } } - #endregion - + #endregion Change Detection #region Colors - int colorSys, colorSay, colorHelp, colorAnnouncement, colorPM, colorIRC, colorMe, colorWarning, colorCustom; - void ApplyColor( Button button, int color ) { + private int colorSys, colorSay, colorHelp, colorAnnouncement, colorPM, colorIRC, colorMe, colorWarning, colorCustom; + + private void ApplyColor( Button button, int color ) { button.Text = Color.GetName( color ); button.BackColor = ColorPicker.ColorPairs[color].Background; button.ForeColor = ColorPicker.ColorPairs[color].Foreground; @@ -1356,14 +1363,13 @@ private void bColorRank_Click( object sender, EventArgs e ) { selectedRank.Color = Color.Parse( picker.ColorIndex ); } - - void HandleTabChatChange( object sender, EventArgs args ) { + private void HandleTabChatChange( object sender, EventArgs args ) { UpdateChatPreview(); } - void UpdateChatPreview() { + private void UpdateChatPreview() { List lines = new List(); - if( xShowConnectionMessages.Checked ) { + if ( xShowConnectionMessages.Checked ) { lines.Add( String.Format( "&SPlayer {0}{1}Notch&S connected, joined {2}{3}main", xRankColorsInChat.Checked ? RankManager.HighestRank.Color : "", xRankPrefixesInChat.Checked ? RankManager.HighestRank.Prefix : "", @@ -1377,9 +1383,9 @@ void UpdateChatPreview() { xRankPrefixesInChat.Checked ? RankManager.HighestRank.Prefix : "" ) ); lines.Add( "&Pfrom Notch: This is a private message / whisper" ); lines.Add( "&M*Notch is using /Me to write this" ); - if( xShowJoinedWorldMessages.Checked ) { + if ( xShowJoinedWorldMessages.Checked ) { Rank midRank = RankManager.LowestRank; - if( RankManager.LowestRank.NextRankUp != null ) { + if ( RankManager.LowestRank.NextRankUp != null ) { midRank = RankManager.LowestRank.NextRankUp; } @@ -1390,7 +1396,7 @@ void UpdateChatPreview() { xRankPrefixesInChat.Checked ? midRank.Prefix : "" ) ); } lines.Add( "&SUnknown command \"kikc\", see &H/Commands" ); - if( xAnnounceKickAndBanReasons.Checked ) { + if ( xAnnounceKickAndBanReasons.Checked ) { lines.Add( String.Format( "&W{0}{1}Notch&W was kicked by {0}{1}gamer1&W: Reason goes here", xRankColorsInChat.Checked ? RankManager.HighestRank.Color : "", xRankPrefixesInChat.Checked ? RankManager.HighestRank.Prefix : "" ) ); @@ -1400,7 +1406,7 @@ void UpdateChatPreview() { xRankPrefixesInChat.Checked ? RankManager.HighestRank.Prefix : "" ) ); } - if( xShowConnectionMessages.Checked ) { + if ( xShowConnectionMessages.Checked ) { lines.Add( String.Format( "&S{0}{1}Notch&S left the server.", xRankColorsInChat.Checked ? RankManager.HighestRank.Color : "", xRankPrefixesInChat.Checked ? RankManager.HighestRank.Prefix : "" ) ); @@ -1409,36 +1415,33 @@ void UpdateChatPreview() { chatPreview.SetText( lines.ToArray() ); } - #endregion - + #endregion Colors private void bRules_Click( object sender, EventArgs e ) { TextEditorPopup popup = new TextEditorPopup( Paths.RulesFileName, "Use common sense!" ); popup.ShowDialog(); } - internal static bool IsWorldNameTaken( string name ) { return Worlds.Any( world => world.Name.Equals( name, StringComparison.OrdinalIgnoreCase ) ); } - - void CheckMaxPlayersPerWorldValue() { - if( nMaxPlayersPerWorld.Value > nMaxPlayers.Value ) { + private void CheckMaxPlayersPerWorldValue() { + if ( nMaxPlayersPerWorld.Value > nMaxPlayers.Value ) { nMaxPlayersPerWorld.Value = nMaxPlayers.Value; } nMaxPlayersPerWorld.Maximum = Math.Min( 128, nMaxPlayers.Value ); } - internal static void HandleWorldRename( string from, string to ) { - if( instance.cMainWorld.Items.Count == 0 ) return; - if( instance.cMainWorld.SelectedItem == null ) { + if ( instance.cMainWorld.Items.Count == 0 ) + return; + if ( instance.cMainWorld.SelectedItem == null ) { instance.cMainWorld.SelectedIndex = 0; } else { string mainWorldName = instance.cMainWorld.SelectedItem.ToString(); instance.FillWorldList(); - if( mainWorldName == from ) { + if ( mainWorldName == from ) { instance.cMainWorld.SelectedItem = to; } else { instance.cMainWorld.SelectedItem = mainWorldName; @@ -1446,12 +1449,12 @@ internal static void HandleWorldRename( string from, string to ) { } } - #endregion - + #endregion Utils private void ConfigUI_FormClosing( object sender, FormClosingEventArgs e ) { - if( !bApply.Enabled ) return; - switch( MessageBox.Show( "Would you like to save the changes before exiting?", "Warning", MessageBoxButtons.YesNoCancel ) ) { + if ( !bApply.Enabled ) + return; + switch ( MessageBox.Show( "Would you like to save the changes before exiting?", "Warning", MessageBoxButtons.YesNoCancel ) ) { case DialogResult.Yes: SaveEverything(); return; @@ -1462,12 +1465,11 @@ private void ConfigUI_FormClosing( object sender, FormClosingEventArgs e ) { } } + private readonly Dictionary permissionLimitBoxes = new Dictionary(); - readonly Dictionary permissionLimitBoxes = new Dictionary(); - - const string DefaultPermissionLimitString = "(own rank)"; - void FillPermissionLimitBoxes() { + private const string DefaultPermissionLimitString = "(own rank)"; + private void FillPermissionLimitBoxes() { permissionLimitBoxes[Permission.Kick] = new PermissionLimitBox( "Kick limit", Permission.Kick, DefaultPermissionLimitString ); permissionLimitBoxes[Permission.Ban] = new PermissionLimitBox( "Ban limit", Permission.Ban, DefaultPermissionLimitString ); permissionLimitBoxes[Permission.Promote] = new PermissionLimitBox( "Promote limit", Permission.Promote, DefaultPermissionLimitString ); @@ -1478,18 +1480,17 @@ void FillPermissionLimitBoxes() { permissionLimitBoxes[Permission.Bring] = new PermissionLimitBox( "Bring limit", Permission.Bring, DefaultPermissionLimitString ); permissionLimitBoxes[Permission.Spectate] = new PermissionLimitBox( "Spectate limit", Permission.Spectate, DefaultPermissionLimitString ); permissionLimitBoxes[Permission.UndoOthersActions] = new PermissionLimitBox( "Undo limit", Permission.UndoOthersActions, DefaultPermissionLimitString ); - permissionLimitBoxes[Permission.Slap] = new PermissionLimitBox("Slap limit", Permission.Slap, DefaultPermissionLimitString); - permissionLimitBoxes[Permission.Kill] = new PermissionLimitBox("Kill limit", Permission.Kill, DefaultPermissionLimitString); - permissionLimitBoxes[Permission.Possess] = new PermissionLimitBox("Possess limit", Permission.Possess, DefaultPermissionLimitString); - permissionLimitBoxes[Permission.Warn] = new PermissionLimitBox("Warn limit", Permission.Warn, DefaultPermissionLimitString); - permissionLimitBoxes[Permission.Gtfo] = new PermissionLimitBox("Gtfo limit", Permission.Gtfo, DefaultPermissionLimitString); + permissionLimitBoxes[Permission.Slap] = new PermissionLimitBox( "Slap limit", Permission.Slap, DefaultPermissionLimitString ); + permissionLimitBoxes[Permission.Kill] = new PermissionLimitBox( "Kill limit", Permission.Kill, DefaultPermissionLimitString ); + permissionLimitBoxes[Permission.Possess] = new PermissionLimitBox( "Possess limit", Permission.Possess, DefaultPermissionLimitString ); + permissionLimitBoxes[Permission.Warn] = new PermissionLimitBox( "Warn limit", Permission.Warn, DefaultPermissionLimitString ); + permissionLimitBoxes[Permission.Gtfo] = new PermissionLimitBox( "Gtfo limit", Permission.Gtfo, DefaultPermissionLimitString ); - foreach( var box in permissionLimitBoxes.Values ) { + foreach ( var box in permissionLimitBoxes.Values ) { permissionLimitBoxContainer.Controls.Add( box ); } } - private void cDefaultRank_SelectedIndexChanged( object sender, EventArgs e ) { RankManager.DefaultRank = RankManager.FindRank( cDefaultRank.SelectedIndex - 1 ); } @@ -1516,33 +1517,35 @@ private void xBlockDBAutoEnable_CheckedChanged( object sender, EventArgs e ) { } private void nFillLimit_ValueChanged( object sender, EventArgs e ) { - if( selectedRank == null ) return; + if ( selectedRank == null ) + return; selectedRank.FillLimit = Convert.ToInt32( nFillLimit.Value ); } - const string ReadmeFileName = "README.txt"; + private const string ReadmeFileName = "README.txt"; + private void bReadme_Click( object sender, EventArgs e ) { try { - if( File.Exists( ReadmeFileName ) ) { + if ( File.Exists( ReadmeFileName ) ) { Process.Start( ReadmeFileName ); } - } catch( Exception ) { } + } catch ( Exception ) { } } - const string ChangelogFileName = "CHANGELOG.txt"; + private const string ChangelogFileName = "CHANGELOG.txt"; + private void bChangelog_Click( object sender, EventArgs e ) { try { - if( File.Exists( ChangelogFileName ) ) { + if ( File.Exists( ChangelogFileName ) ) { Process.Start( ChangelogFileName ); } - } catch( Exception ) { } + } catch ( Exception ) { } } public static bool usePrefixes = false; - - public static string ToComboBoxOption( Rank rank) { - if( usePrefixes ) { + public static string ToComboBoxOption( Rank rank ) { + if ( usePrefixes ) { return String.Format( "{0,1}{1}", rank.Prefix, rank.Name ); } else { return rank.Name; @@ -1556,130 +1559,96 @@ private void xRankPrefixesInChat_CheckedChanged( object sender, EventArgs e ) { RebuildRankList(); } - private void label1_Click(object sender, EventArgs e) - { - + private void label1_Click( object sender, EventArgs e ) { } - private void button1_Click(object sender, EventArgs e) - { - ColorPicker picker = new ColorPicker("Custom Chat command color", colorCustom); + private void button1_Click( object sender, EventArgs e ) { + ColorPicker picker = new ColorPicker( "Custom Chat command color", colorCustom ); picker.ShowDialog(); colorCustom = picker.ColorIndex; - ApplyColor(CustomColor, colorCustom); - Color.Custom = Color.Parse(colorCustom); + ApplyColor( CustomColor, colorCustom ); + Color.Custom = Color.Parse( colorCustom ); } - private void label1_Click_1(object sender, EventArgs e) - { - + private void label1_Click_1( object sender, EventArgs e ) { } - private void label2_Click(object sender, EventArgs e) - { - + private void label2_Click( object sender, EventArgs e ) { } - private void tServerName_TextChanged(object sender, EventArgs e) - { - + private void tServerName_TextChanged( object sender, EventArgs e ) { } - private void CustomName_TextChanged(object sender, EventArgs e) - { - + private void CustomName_TextChanged( object sender, EventArgs e ) { } - private void CustomAliases_TextChanged(object sender, EventArgs e) - { - + private void CustomAliases_TextChanged( object sender, EventArgs e ) { } - private void SwearBox_TextChanged(object sender, EventArgs e) - { - + private void SwearBox_TextChanged( object sender, EventArgs e ) { } - private void MaxCapsValue_ValueChanged(object sender, EventArgs e) - { - + private void MaxCapsValue_ValueChanged( object sender, EventArgs e ) { } - private void nPort_ValueChanged(object sender, EventArgs e) - { - + private void nPort_ValueChanged( object sender, EventArgs e ) { } - private void HbBox1_CheckedChanged(object sender, EventArgs e) - { - + private void HbBox1_CheckedChanged( object sender, EventArgs e ) { } - private void lCrashReportDisclaimer_Click(object sender, EventArgs e) - { - + private void lCrashReportDisclaimer_Click( object sender, EventArgs e ) { } - private void vConsoleOptions_SelectedIndexChanged(object sender, EventArgs e) - { - + private void vConsoleOptions_SelectedIndexChanged( object sender, EventArgs e ) { } - private void SwearEditor_Click(object sender, EventArgs e) - { - if (!File.Exists(Paths.SwearWordsFileName)) - { + private void SwearEditor_Click( object sender, EventArgs e ) { + if ( !File.Exists( Paths.SwearWordsFileName ) ) { StringBuilder sb = new StringBuilder(); - sb.AppendLine("#This txt file should be filled with bad words that you want to be filtered out"); - sb.AppendLine("#I have included some examples, excuse my language :P"); - sb.AppendLine("fuck"); - sb.AppendLine("fucking"); - sb.AppendLine("fucked"); - sb.AppendLine("dick"); - sb.AppendLine("bitch"); - sb.AppendLine("shit"); - sb.AppendLine("shitting"); - sb.AppendLine("shithead"); - sb.AppendLine("cunt"); - sb.AppendLine("nigger"); - sb.AppendLine("wanker"); - sb.AppendLine("wank"); - sb.AppendLine("wanking"); - sb.AppendLine("piss"); - File.WriteAllText("SwearWords.txt", sb.ToString()); + sb.AppendLine( "#This txt file should be filled with bad words that you want to be filtered out" ); + sb.AppendLine( "#I have included some examples, excuse my language :P" ); + sb.AppendLine( "fuck" ); + sb.AppendLine( "fucking" ); + sb.AppendLine( "fucked" ); + sb.AppendLine( "dick" ); + sb.AppendLine( "bitch" ); + sb.AppendLine( "shit" ); + sb.AppendLine( "shitting" ); + sb.AppendLine( "shithead" ); + sb.AppendLine( "cunt" ); + sb.AppendLine( "nigger" ); + sb.AppendLine( "wanker" ); + sb.AppendLine( "wank" ); + sb.AppendLine( "wanking" ); + sb.AppendLine( "piss" ); + File.WriteAllText( "SwearWords.txt", sb.ToString() ); } - Process.Start(Paths.SwearWordsFileName); + Process.Start( Paths.SwearWordsFileName ); } - private void ReqsEditor_Click(object sender, EventArgs e) - { - if (!System.IO.Directory.Exists(Paths.ReqPath)) - { - System.IO.Directory.CreateDirectory(Paths.ReqPath); - System.IO.Path.Combine(Paths.ReqPath, "howto.txt"); - File.WriteAllText(Path.Combine(Paths.ReqPath, "howto.txt"), + private void ReqsEditor_Click( object sender, EventArgs e ) { + if ( !System.IO.Directory.Exists( Paths.ReqPath ) ) { + System.IO.Directory.CreateDirectory( Paths.ReqPath ); + System.IO.Path.Combine( Paths.ReqPath, "howto.txt" ); + File.WriteAllText( Path.Combine( Paths.ReqPath, "howto.txt" ), "This folder is where you list the requirements " + "for your server's ranks. You can either list all of the requirements " + "here or you can split it into sections by creating text documents in " + "this same directory (requirements folder) (sections are the most preferable).\n Make sure " + "the text documents are the same name of the rank you are listing " + - "the requirements for. If you wish to use color codes use & instead of %"); - Process.Start(Paths.ReqTextPath); - } - - else if (!System.IO.File.Exists(Paths.ReqTextPath)) - { - Process.Start(Paths.ReqDirectory); - } - - else - { - Process.Start(Paths.ReqTextPath); + "the requirements for. If you wish to use color codes use & instead of %" ); + Process.Start( Paths.ReqTextPath ); + } else if ( !System.IO.File.Exists( Paths.ReqTextPath ) ) { + Process.Start( Paths.ReqDirectory ); + } else { + Process.Start( Paths.ReqTextPath ); } } - private void HiddenBox_CheckedChanged ( object sender, EventArgs e ) { - if ( selectedRank == null ) return; + private void HiddenBox_CheckedChanged( object sender, EventArgs e ) { + if ( selectedRank == null ) + return; selectedRank.IsHidden = HiddenBox.Checked; } } diff --git a/ConfigGUI/PermissionLimitBox.cs b/ConfigGUI/PermissionLimitBox.cs index de37873..ffea963 100644 --- a/ConfigGUI/PermissionLimitBox.cs +++ b/ConfigGUI/PermissionLimitBox.cs @@ -3,6 +3,7 @@ using System.Windows.Forms; namespace fCraft.ConfigGUI { + public sealed partial class PermissionLimitBox : UserControl { public Permission Permission { get; private set; } @@ -15,7 +16,7 @@ public PermissionLimitBox( string labelText, Permission permission, string first InitializeComponent(); label.Text = labelText; - label.Left = (comboBox.Left - comboBox.Margin.Left) - (label.Width + label.Margin.Right); + label.Left = ( comboBox.Left - comboBox.Margin.Left ) - ( label.Width + label.Margin.Right ); Permission = permission; FirstItem = firstItem; @@ -24,35 +25,32 @@ public PermissionLimitBox( string labelText, Permission permission, string first comboBox.SelectedIndexChanged += OnPermissionLimitChanged; } - - void OnPermissionLimitChanged( object sender, EventArgs args ) { - if( Rank == null ) return; + private void OnPermissionLimitChanged( object sender, EventArgs args ) { + if ( Rank == null ) + return; Rank rankLimit = RankManager.FindRank( comboBox.SelectedIndex - 1 ); - if( rankLimit == null ) { + if ( rankLimit == null ) { Rank.ResetLimit( Permission ); } else { Rank.SetLimit( Permission, rankLimit ); } } - public void Reset() { comboBox.SelectedIndex = 0; } - public void RebuildList() { comboBox.Items.Clear(); comboBox.Items.Add( FirstItem ); - foreach( Rank rank in RankManager.Ranks ) { + foreach ( Rank rank in RankManager.Ranks ) { comboBox.Items.Add( MainForm.ToComboBoxOption( rank ) ); } } - public void SelectRank( Rank rank ) { Rank = rank; - if( rank == null ) { + if ( rank == null ) { comboBox.SelectedIndex = -1; Visible = false; } else { @@ -61,7 +59,6 @@ public void SelectRank( Rank rank ) { } } - public void PermissionToggled( bool isOn ) { Visible = isOn; } diff --git a/ConfigGUI/Program.cs b/ConfigGUI/Program.cs index d6aaf09..84a4104 100644 --- a/ConfigGUI/Program.cs +++ b/ConfigGUI/Program.cs @@ -20,13 +20,16 @@ * THE SOFTWARE. * */ + using System; using System.Windows.Forms; namespace fCraft.ConfigGUI { - static class Program { + + internal static class Program { + [STAThread] - static void Main() { + private static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault( false ); #if DEBUG @@ -34,9 +37,9 @@ static void Main() { #else try { Application.Run( new MainForm() ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.LogAndReportCrash( "Error in ConfigGUI", "ConfigGUI", ex, true ); - if( !Server.HasArg( ArgKey.ExitOnCrash ) ) { + if ( !Server.HasArg( ArgKey.ExitOnCrash ) ) { MessageBox.Show( ex.ToString(), "fCraft ConfigGUI has crashed" ); } } diff --git a/ConfigGUI/Properties/AssemblyInfo.cs b/ConfigGUI/Properties/AssemblyInfo.cs index e136ddf..3d2e248 100644 --- a/ConfigGUI/Properties/AssemblyInfo.cs +++ b/ConfigGUI/Properties/AssemblyInfo.cs @@ -3,20 +3,20 @@ using System.Resources; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("800Craft ConfigGUI")] -[assembly: AssemblyDescription("800Craft graphical configuration tool")] +[assembly: AssemblyTitle( "800Craft ConfigGUI" )] +[assembly: AssemblyDescription( "800Craft graphical configuration tool" )] [assembly: AssemblyConfiguration( "" )] -[assembly: AssemblyCompany("au70.net")] -[assembly: AssemblyProduct("800Craft ConfigGUI")] -[assembly: AssemblyCopyright("")] +[assembly: AssemblyCompany( "au70.net" )] +[assembly: AssemblyProduct( "800Craft ConfigGUI" )] +[assembly: AssemblyCopyright( "" )] [assembly: AssemblyTrademark( "" )] [assembly: AssemblyCulture( "" )] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible( false )] @@ -26,15 +26,14 @@ // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -// You can specify all the values or you can default the Build and Revision Numbers +// You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion( "0.6.1.7" )] [assembly: AssemblyFileVersion( "0.6.1.7" )] - [assembly: CLSCompliant( false )] [assembly: NeutralResourcesLanguage( "en-US" )] \ No newline at end of file diff --git a/ConfigGUI/SortableBindingList.cs b/ConfigGUI/SortableBindingList.cs index d106719..187711e 100644 --- a/ConfigGUI/SortableBindingList.cs +++ b/ConfigGUI/SortableBindingList.cs @@ -20,7 +20,6 @@ public void Sort() { ApplySortCore( sort, dir ); } - public void Sort( string property ) { /* Get the PD */ sort = FindPropertyDescriptor( property ); @@ -29,7 +28,6 @@ public void Sort( string property ) { ApplySortCore( sort, dir ); } - public void Sort( string property, ListSortDirection direction ) { /* Get the sort property */ sort = FindPropertyDescriptor( property ); @@ -39,8 +37,7 @@ public void Sort( string property, ListSortDirection direction ) { ApplySortCore( sort, dir ); } - #endregion - + #endregion BindingList Public Sorting API #region BindingList Sorting Overrides @@ -48,11 +45,10 @@ protected override bool SupportsSortingCore { get { return true; } } - protected override void ApplySortCore( PropertyDescriptor prop, ListSortDirection direction ) { List items = Items as List; - if( null != items ) { + if ( null != items ) { PropertyComparer pc = new PropertyComparer( prop, direction ); items.Sort( pc ); @@ -64,31 +60,28 @@ protected override void ApplySortCore( PropertyDescriptor prop, ListSortDirectio } } - protected override bool IsSortedCore { get { return isSorted; } } - protected override void RemoveSortCore() { isSorted = false; } - #endregion - + #endregion BindingList Sorting Overrides #region BindingList Private Sorting API - static PropertyDescriptor FindPropertyDescriptor( string property ) { + private static PropertyDescriptor FindPropertyDescriptor( string property ) { PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties( typeof( T ) ); PropertyDescriptor prop = pdc.Find( property, true ); return prop; } - #endregion - + #endregion BindingList Private Sorting API #region PropertyComparer + internal sealed class PropertyComparer : IComparer { /* * The following code contains code implemented by Rockford Lhotka: @@ -108,11 +101,11 @@ public int Compare( TKey xVal, TKey yVal ) { object xValue = GetPropertyValue( xVal, property.Name ); object yValue = GetPropertyValue( yVal, property.Name ); - foreach( Attribute att in property.Attributes ) { + foreach ( Attribute att in property.Attributes ) { var sortableAtt = att as SortablePropertyAttribute; - if( sortableAtt != null ) { + if ( sortableAtt != null ) { int comparisonResult = sortableAtt.Compare( property.Name, xVal, yVal ); - if( direction == ListSortDirection.Ascending ) { + if ( direction == ListSortDirection.Ascending ) { return comparisonResult; } else { return -comparisonResult; @@ -121,7 +114,7 @@ public int Compare( TKey xVal, TKey yVal ) { } /* Determine sort order */ - if( direction == ListSortDirection.Ascending ) { + if ( direction == ListSortDirection.Ascending ) { return CompareAscending( xValue, yValue ); } else { return CompareDescending( xValue, yValue ); @@ -137,31 +130,33 @@ public int GetHashCode( TKey obj ) { } /* Compare two property values of any type */ - static int CompareAscending( object xValue, object yValue ) { + + private static int CompareAscending( object xValue, object yValue ) { int result; /* If values implement IComparer */ - if( xValue is IComparable ) { - result = ((IComparable)xValue).CompareTo( yValue ); + if ( xValue is IComparable ) { + result = ( ( IComparable )xValue ).CompareTo( yValue ); } - /* If values don't implement IComparer but are equivalent */ - else if( xValue.Equals( yValue ) ) { + /* If values don't implement IComparer but are equivalent */ + else if ( xValue.Equals( yValue ) ) { result = 0; } /* Values don't implement IComparer and are not equivalent, so compare as string values */ - else result = xValue.ToString().CompareTo( yValue.ToString() ); + else + result = xValue.ToString().CompareTo( yValue.ToString() ); /* Return result */ return result; } - static int CompareDescending( object xValue, object yValue ) { + private static int CompareDescending( object xValue, object yValue ) { /* Return result adjusted for ascending or descending sort order ie multiplied by 1 for ascending or -1 for descending */ return CompareAscending( xValue, yValue ) * -1; } - static object GetPropertyValue( TKey value, string property ) { + private static object GetPropertyValue( TKey value, string property ) { /* Get property */ PropertyInfo propertyInfo = value.GetType().GetProperty( property ); @@ -169,24 +164,28 @@ static object GetPropertyValue( TKey value, string property ) { return propertyInfo.GetValue( value, null ); } } - #endregion - } + #endregion PropertyComparer + } [AttributeUsage( AttributeTargets.Property )] public sealed class SortablePropertyAttribute : Attribute { + public SortablePropertyAttribute( Type type, string comparerMethodName ) { - if( type == null ) throw new ArgumentNullException( "type" ); - if( comparerMethodName == null ) throw new ArgumentNullException( "comparerMethodName" ); + if ( type == null ) + throw new ArgumentNullException( "type" ); + if ( comparerMethodName == null ) + throw new ArgumentNullException( "comparerMethodName" ); method = type.GetMethod( comparerMethodName ); - if( method == null ) throw new ArgumentException( "No such method", "comparerMethodName" ); + if ( method == null ) + throw new ArgumentException( "No such method", "comparerMethodName" ); } + private readonly MethodInfo method; - readonly MethodInfo method; public int Compare( string propertyName, object a, object b ) { object[] methodArgs = new[] { propertyName, a, b }; - return (int)method.Invoke( null, methodArgs ); + return ( int )method.Invoke( null, methodArgs ); } } -} +} \ No newline at end of file diff --git a/ConfigGUI/TextEditorPopup.cs b/ConfigGUI/TextEditorPopup.cs index 7ed579a..9730329 100644 --- a/ConfigGUI/TextEditorPopup.cs +++ b/ConfigGUI/TextEditorPopup.cs @@ -5,10 +5,12 @@ using System.Windows.Forms; namespace fCraft.ConfigGUI { + public sealed partial class TextEditorPopup : Form { + public string OriginalText { get; private set; } - public string FileName { get; private set; } + public string FileName { get; private set; } public TextEditorPopup( string fileName, string defaultValue ) { InitializeComponent(); @@ -16,7 +18,7 @@ public TextEditorPopup( string fileName, string defaultValue ) { FileName = fileName; Text = "Editing " + FileName; - if( File.Exists( fileName ) ) { + if ( File.Exists( fileName ) ) { OriginalText = File.ReadAllText( fileName ); } else { OriginalText = defaultValue; @@ -26,11 +28,10 @@ public TextEditorPopup( string fileName, string defaultValue ) { lWarning.Visible = ContainsLongLines(); } - bool ContainsLongLines() { - return tText.Lines.Any( line => (line.Length > 62) ); + private bool ContainsLongLines() { + return tText.Lines.Any( line => ( line.Length > 62 ) ); } - private void tRules_KeyDown( object sender, KeyEventArgs e ) { lWarning.Visible = ContainsLongLines(); } @@ -40,10 +41,12 @@ private void bOK_Click( object sender, EventArgs e ) { Close(); } - ColorPicker colorPicker; + private ColorPicker colorPicker; + private void bInsertColor_Click( object sender, EventArgs e ) { - if( colorPicker == null ) colorPicker = new ColorPicker("Insert color",0); - if( colorPicker.ShowDialog() == DialogResult.OK){ + if ( colorPicker == null ) + colorPicker = new ColorPicker( "Insert color", 0 ); + if ( colorPicker.ShowDialog() == DialogResult.OK ) { string colorToInsert = Color.Parse( colorPicker.ColorIndex ); int selectionStart = tText.SelectionStart; tText.Paste( colorToInsert ); @@ -52,10 +55,12 @@ private void bInsertColor_Click( object sender, EventArgs e ) { } } - KeywordPicker keywordPicker; + private KeywordPicker keywordPicker; + private void bInsertKeyword_Click( object sender, EventArgs e ) { - if( keywordPicker == null ) keywordPicker = new KeywordPicker(); - if( keywordPicker.ShowDialog() == DialogResult.OK ) { + if ( keywordPicker == null ) + keywordPicker = new KeywordPicker(); + if ( keywordPicker.ShowDialog() == DialogResult.OK ) { int selectionStart = tText.SelectionStart; tText.Paste( keywordPicker.Result ); tText.Select( selectionStart, keywordPicker.Result.Length ); @@ -67,4 +72,4 @@ private void bReset_Click( object sender, EventArgs e ) { tText.Text = OriginalText; } } -} +} \ No newline at end of file diff --git a/ConfigGUI/UpdaterSettingsPopup.cs b/ConfigGUI/UpdaterSettingsPopup.cs index 5d80842..5011135 100644 --- a/ConfigGUI/UpdaterSettingsPopup.cs +++ b/ConfigGUI/UpdaterSettingsPopup.cs @@ -3,41 +3,56 @@ using System.Windows.Forms; namespace fCraft.ConfigGUI { + public sealed partial class UpdaterSettingsPopup : Form { public string RunBeforeUpdate { get { - if( xRunBeforeUpdate.Checked) return tRunBeforeUpdate.Text; - else return ""; + if ( xRunBeforeUpdate.Checked ) + return tRunBeforeUpdate.Text; + else + return ""; } set { tRunBeforeUpdate.Text = value; } } public string RunAfterUpdate { get { - if( xRunAfterUpdate.Checked ) return tRunAfterUpdate.Text; - else return ""; + if ( xRunAfterUpdate.Checked ) + return tRunAfterUpdate.Text; + else + return ""; } set { tRunAfterUpdate.Text = value; } } public UpdaterMode UpdaterMode { get { - if( rDisabled.Checked ) return UpdaterMode.Disabled; - if( rNotify.Checked ) return UpdaterMode.Notify; - if( rPrompt.Checked ) return UpdaterMode.Prompt; + if ( rDisabled.Checked ) + return UpdaterMode.Disabled; + if ( rNotify.Checked ) + return UpdaterMode.Notify; + if ( rPrompt.Checked ) + return UpdaterMode.Prompt; return UpdaterMode.Auto; } set { - switch( value ) { + switch ( value ) { case UpdaterMode.Disabled: - rDisabled.Checked = true; break; + rDisabled.Checked = true; + break; + case UpdaterMode.Notify: - rNotify.Checked = true; break; + rNotify.Checked = true; + break; + case UpdaterMode.Prompt: - rPrompt.Checked = true; break; + rPrompt.Checked = true; + break; + case UpdaterMode.Auto: - rAutomatic.Checked = true; break; + rAutomatic.Checked = true; + break; } } } @@ -47,9 +62,9 @@ public bool BackupBeforeUpdate { set { xBackupBeforeUpdating.Checked = value; } } - string oldRunBeforeUpdate, oldRunAfterUpdate; - UpdaterMode oldUpdaterMode; - bool oldBackupBeforeUpdate; + private string oldRunBeforeUpdate, oldRunAfterUpdate; + private UpdaterMode oldUpdaterMode; + private bool oldBackupBeforeUpdate; public UpdaterSettingsPopup() { InitializeComponent(); @@ -60,7 +75,7 @@ public UpdaterSettingsPopup() { oldBackupBeforeUpdate = BackupBeforeUpdate; }; FormClosed += delegate { - if( DialogResult != DialogResult.OK ) { + if ( DialogResult != DialogResult.OK ) { RunBeforeUpdate = oldRunBeforeUpdate; RunAfterUpdate = oldRunAfterUpdate; UpdaterMode = oldUpdaterMode; @@ -81,15 +96,14 @@ private void rDisabled_CheckedChanged( object sender, EventArgs e ) { gOptions.Enabled = !rDisabled.Checked; } - private void tRunBeforeUpdate_TextChanged( object sender, EventArgs e ) { - if( tRunBeforeUpdate.Text.Length > 0 ) { + if ( tRunBeforeUpdate.Text.Length > 0 ) { xRunBeforeUpdate.Checked = true; } } private void tRunAfterUpdate_TextChanged( object sender, EventArgs e ) { - if( tRunAfterUpdate.Text.Length > 0 ) { + if ( tRunAfterUpdate.Text.Length > 0 ) { xRunAfterUpdate.Checked = true; } } diff --git a/ConfigGUI/WorldListEntry.cs b/ConfigGUI/WorldListEntry.cs index f404bb6..0f3a955 100644 --- a/ConfigGUI/WorldListEntry.cs +++ b/ConfigGUI/WorldListEntry.cs @@ -1,36 +1,33 @@ using System; using System.IO; +using System.Linq; using System.Windows.Forms; using System.Xml.Linq; using fCraft.MapConversion; -using System.Linq; using JetBrains.Annotations; -namespace fCraft.ConfigGUI -{ +namespace fCraft.ConfigGUI { + /// /// A wrapper for per-World metadata, designed to be usable with SortableBindingList. /// All these properties map directly to the UI controls. /// - sealed class WorldListEntry : ICloneable - { + internal sealed class WorldListEntry : ICloneable { public const string WorldInfoSignature = "(ConfigGUI)"; public const string DefaultRankOption = "(everyone)"; - const string MapFileExtension = ".fcm"; + private const string MapFileExtension = ".fcm"; internal bool LoadingFailed { get; private set; } - - public WorldListEntry([NotNull] string newName) - { - if (newName == null) throw new ArgumentNullException("newName"); + public WorldListEntry( [NotNull] string newName ) { + if ( newName == null ) + throw new ArgumentNullException( "newName" ); name = newName; } - - public WorldListEntry([NotNull] WorldListEntry original) - { - if (original == null) throw new ArgumentNullException("original"); + public WorldListEntry( [NotNull] WorldListEntry original ) { + if ( original == null ) + throw new ArgumentNullException( "original" ); name = original.Name; Hidden = original.Hidden; Backup = original.Backup; @@ -38,8 +35,8 @@ public WorldListEntry([NotNull] WorldListEntry original) blockDBIsPreloaded = original.blockDBIsPreloaded; blockDBLimit = original.blockDBLimit; blockDBTimeLimit = original.blockDBTimeLimit; - accessSecurity = new SecurityController(original.accessSecurity); - buildSecurity = new SecurityController(original.buildSecurity); + accessSecurity = new SecurityController( original.accessSecurity ); + buildSecurity = new SecurityController( original.buildSecurity ); LoadedBy = original.LoadedBy; LoadedOn = original.LoadedOn; MapChangedBy = original.MapChangedBy; @@ -47,270 +44,199 @@ public WorldListEntry([NotNull] WorldListEntry original) environmentEl = original.environmentEl; } - - public WorldListEntry([NotNull] XElement el) - { - if (el == null) throw new ArgumentNullException("el"); + public WorldListEntry( [NotNull] XElement el ) { + if ( el == null ) + throw new ArgumentNullException( "el" ); XAttribute temp; - if ((temp = el.Attribute("name")) == null) - { - throw new FormatException("WorldListEntity: Cannot parse XML: Unnamed worlds are not allowed."); + if ( ( temp = el.Attribute( "name" ) ) == null ) { + throw new FormatException( "WorldListEntity: Cannot parse XML: Unnamed worlds are not allowed." ); } - if (!World.IsValidName(temp.Value)) - { - throw new FormatException("WorldListEntity: Cannot parse XML: Invalid world name skipped \"" + temp.Value + "\"."); + if ( !World.IsValidName( temp.Value ) ) { + throw new FormatException( "WorldListEntity: Cannot parse XML: Invalid world name skipped \"" + temp.Value + "\"." ); } name = temp.Value; - if ((temp = el.Attribute("hidden")) != null && !String.IsNullOrEmpty(temp.Value)) - { + if ( ( temp = el.Attribute( "hidden" ) ) != null && !String.IsNullOrEmpty( temp.Value ) ) { bool hidden; - if (Boolean.TryParse(temp.Value, out hidden)) - { + if ( Boolean.TryParse( temp.Value, out hidden ) ) { Hidden = hidden; + } else { + throw new FormatException( "WorldListEntity: Cannot parse XML: Invalid value for \"hidden\" attribute." ); } - else - { - throw new FormatException("WorldListEntity: Cannot parse XML: Invalid value for \"hidden\" attribute."); - } - } - else - { + } else { Hidden = false; } - if ((temp = el.Attribute("backup")) != null) - { + if ( ( temp = el.Attribute( "backup" ) ) != null ) { TimeSpan realBackupTimer; - if (temp.Value.ToTimeSpan(out realBackupTimer)) - { - Backup = BackupNameFromValue(realBackupTimer); - } - else - { - Logger.Log(LogType.Error, - "WorldListEntity: Cannot parse backup settings for world \"{0}\". Assuming default.", name); + if ( temp.Value.ToTimeSpan( out realBackupTimer ) ) { + Backup = BackupNameFromValue( realBackupTimer ); + } else { + Logger.Log( LogType.Error, + "WorldListEntity: Cannot parse backup settings for world \"{0}\". Assuming default.", name ); Backup = BackupEnumNames[0]; } - } - else - { + } else { Backup = BackupEnumNames[0]; } XElement tempEl; - if ((tempEl = el.Element(WorldManager.AccessSecurityXmlTagName)) != null || - (tempEl = el.Element("accessSecurity")) != null) - { - accessSecurity = new SecurityController(tempEl, false); + if ( ( tempEl = el.Element( WorldManager.AccessSecurityXmlTagName ) ) != null || + ( tempEl = el.Element( "accessSecurity" ) ) != null ) { + accessSecurity = new SecurityController( tempEl, false ); } - if ((tempEl = el.Element(WorldManager.BuildSecurityXmlTagName)) != null || - (tempEl = el.Element("buildSecurity")) != null) - { - buildSecurity = new SecurityController(tempEl, false); + if ( ( tempEl = el.Element( WorldManager.BuildSecurityXmlTagName ) ) != null || + ( tempEl = el.Element( "buildSecurity" ) ) != null ) { + buildSecurity = new SecurityController( tempEl, false ); } - XElement blockEl = el.Element(BlockDB.XmlRootName); - if (blockEl == null) - { + XElement blockEl = el.Element( BlockDB.XmlRootName ); + if ( blockEl == null ) { BlockDBEnabled = YesNoAuto.Auto; - } - else - { - if ((temp = blockEl.Attribute("enabled")) != null) - { + } else { + if ( ( temp = blockEl.Attribute( "enabled" ) ) != null ) { YesNoAuto enabledStateTemp; - if (EnumUtil.TryParse(temp.Value, out enabledStateTemp, true)) - { + if ( EnumUtil.TryParse( temp.Value, out enabledStateTemp, true ) ) { BlockDBEnabled = enabledStateTemp; - } - else - { - Logger.Log(LogType.Warning, + } else { + Logger.Log( LogType.Warning, "WorldListEntity: Could not parse BlockDB \"enabled\" attribute of world \"{0}\", assuming \"Auto\".", - name); + name ); BlockDBEnabled = YesNoAuto.Auto; } } - if ((temp = blockEl.Attribute("preload")) != null) - { + if ( ( temp = blockEl.Attribute( "preload" ) ) != null ) { bool isPreloaded; - if (Boolean.TryParse(temp.Value, out isPreloaded)) - { + if ( Boolean.TryParse( temp.Value, out isPreloaded ) ) { blockDBIsPreloaded = isPreloaded; - } - else - { - Logger.Log(LogType.Warning, + } else { + Logger.Log( LogType.Warning, "WorldListEntity: Could not parse BlockDB \"preload\" attribute of world \"{0}\", assuming NOT preloaded.", - name); + name ); } } - if ((temp = blockEl.Attribute("limit")) != null) - { + if ( ( temp = blockEl.Attribute( "limit" ) ) != null ) { int limit; - if (Int32.TryParse(temp.Value, out limit)) - { + if ( Int32.TryParse( temp.Value, out limit ) ) { blockDBLimit = limit; - } - else - { - Logger.Log(LogType.Warning, + } else { + Logger.Log( LogType.Warning, "WorldListEntity: Could not parse BlockDB \"limit\" attribute of world \"{0}\", assuming NO limit.", - name); + name ); } } - if ((temp = blockEl.Attribute("timeLimit")) != null) - { + if ( ( temp = blockEl.Attribute( "timeLimit" ) ) != null ) { int timeLimitSeconds; - if (Int32.TryParse(temp.Value, out timeLimitSeconds)) - { - blockDBTimeLimit = TimeSpan.FromSeconds(timeLimitSeconds); - } - else - { - Logger.Log(LogType.Warning, + if ( Int32.TryParse( temp.Value, out timeLimitSeconds ) ) { + blockDBTimeLimit = TimeSpan.FromSeconds( timeLimitSeconds ); + } else { + Logger.Log( LogType.Warning, "WorldListEntity: Could not parse BlockDB \"timeLimit\" attribute of world \"{0}\", assuming NO time limit.", - name); + name ); } } } - if ((tempEl = el.Element("LoadedBy")) != null) - { + if ( ( tempEl = el.Element( "LoadedBy" ) ) != null ) { LoadedBy = tempEl.Value; } - if ((tempEl = el.Element("MapChangedBy")) != null) - { + if ( ( tempEl = el.Element( "MapChangedBy" ) ) != null ) { MapChangedBy = tempEl.Value; } - if ((tempEl = el.Element("LoadedOn")) != null) - { - if (!tempEl.Value.ToDateTime(ref LoadedOn)) - { + if ( ( tempEl = el.Element( "LoadedOn" ) ) != null ) { + if ( !tempEl.Value.ToDateTime( ref LoadedOn ) ) { LoadedOn = DateTime.MinValue; } } - if ((tempEl = el.Element("MapChangedOn")) != null) - { - if (!tempEl.Value.ToDateTime(ref MapChangedOn)) - { + if ( ( tempEl = el.Element( "MapChangedOn" ) ) != null ) { + if ( !tempEl.Value.ToDateTime( ref MapChangedOn ) ) { MapChangedOn = DateTime.MinValue; } } - environmentEl = el.Element(WorldManager.EnvironmentXmlTagName); + environmentEl = el.Element( WorldManager.EnvironmentXmlTagName ); } public string LoadedBy, MapChangedBy; public DateTime LoadedOn, MapChangedOn; - readonly XElement environmentEl; - + private readonly XElement environmentEl; #region List Properties - string name; - [SortableProperty(typeof(WorldListEntry), "Compare")] - public string Name - { - get - { + private string name; + + [SortableProperty( typeof( WorldListEntry ), "Compare" )] + public string Name { + get { return name; } - set - { - if (name == value) return; - if (!World.IsValidName(value)) - { - throw new FormatException("Invalid world name"); - - } - else if (!value.Equals(name, StringComparison.OrdinalIgnoreCase) && MainForm.IsWorldNameTaken(value)) - { - throw new FormatException("Duplicate world names are not allowed."); - - } - else - { + set { + if ( name == value ) + return; + if ( !World.IsValidName( value ) ) { + throw new FormatException( "Invalid world name" ); + } else if ( !value.Equals( name, StringComparison.OrdinalIgnoreCase ) && MainForm.IsWorldNameTaken( value ) ) { + throw new FormatException( "Duplicate world names are not allowed." ); + } else { string oldName = name; - string oldFileName = Path.Combine(Paths.MapPath, oldName + ".fcm"); - string newFileName = Path.Combine(Paths.MapPath, value + ".fcm"); - if (File.Exists(oldFileName)) - { + string oldFileName = Path.Combine( Paths.MapPath, oldName + ".fcm" ); + string newFileName = Path.Combine( Paths.MapPath, value + ".fcm" ); + if ( File.Exists( oldFileName ) ) { bool isSameFile; - if (MonoCompat.IsCaseSensitive) - { - isSameFile = newFileName.Equals(oldFileName, StringComparison.Ordinal); - } - else - { - isSameFile = newFileName.Equals(oldFileName, StringComparison.OrdinalIgnoreCase); + if ( MonoCompat.IsCaseSensitive ) { + isSameFile = newFileName.Equals( oldFileName, StringComparison.Ordinal ); + } else { + isSameFile = newFileName.Equals( oldFileName, StringComparison.OrdinalIgnoreCase ); } - if (File.Exists(newFileName) && !isSameFile) - { - string messageText = String.Format("Map file \"{0}\" already exists. Overwrite?", value + ".fcm"); - var result = MessageBox.Show(messageText, "", MessageBoxButtons.OKCancel); - if (result == DialogResult.Cancel) return; + if ( File.Exists( newFileName ) && !isSameFile ) { + string messageText = String.Format( "Map file \"{0}\" already exists. Overwrite?", value + ".fcm" ); + var result = MessageBox.Show( messageText, "", MessageBoxButtons.OKCancel ); + if ( result == DialogResult.Cancel ) + return; } - Paths.ForceRename(oldFileName, newFileName); + Paths.ForceRename( oldFileName, newFileName ); } name = value; - if (oldName != null) - { - MainForm.HandleWorldRename(oldName, name); + if ( oldName != null ) { + MainForm.HandleWorldRename( oldName, name ); } } } } - - [SortableProperty(typeof(WorldListEntry), "Compare")] - public string Description - { - get - { + [SortableProperty( typeof( WorldListEntry ), "Compare" )] + public string Description { + get { Map mapHeader = MapHeader; - if (LoadingFailed) - { + if ( LoadingFailed ) { return "(cannot load file)"; - } - else - { - return String.Format("{0} × {1} × {2}", + } else { + return String.Format( "{0} × {1} × {2}", mapHeader.Width, mapHeader.Length, - mapHeader.Height); + mapHeader.Height ); } } } - public bool Hidden { get; set; } + private readonly SecurityController accessSecurity = new SecurityController(); + private string accessRankString; - readonly SecurityController accessSecurity = new SecurityController(); - string accessRankString; - public string AccessPermission - { - get - { - if (accessSecurity.HasRankRestriction) - { - return MainForm.ToComboBoxOption(accessSecurity.MinRank); - } - else - { + public string AccessPermission { + get { + if ( accessSecurity.HasRankRestriction ) { + return MainForm.ToComboBoxOption( accessSecurity.MinRank ); + } else { return DefaultRankOption; } } - set - { - foreach (Rank rank in RankManager.Ranks) - { - if (MainForm.ToComboBoxOption(rank) == value) - { + set { + foreach ( Rank rank in RankManager.Ranks ) { + if ( MainForm.ToComboBoxOption( rank ) == value ) { accessSecurity.MinRank = rank; accessRankString = rank.FullName; return; @@ -321,28 +247,20 @@ public string AccessPermission } } + private readonly SecurityController buildSecurity = new SecurityController(); + private string buildRankString; - readonly SecurityController buildSecurity = new SecurityController(); - string buildRankString; - public string BuildPermission - { - get - { - if (buildSecurity.HasRankRestriction) - { - return MainForm.ToComboBoxOption(buildSecurity.MinRank); - } - else - { + public string BuildPermission { + get { + if ( buildSecurity.HasRankRestriction ) { + return MainForm.ToComboBoxOption( buildSecurity.MinRank ); + } else { return DefaultRankOption; } } - set - { - foreach (Rank rank in RankManager.Ranks) - { - if (MainForm.ToComboBoxOption(rank) == value) - { + set { + foreach ( Rank rank in RankManager.Ranks ) { + if ( MainForm.ToComboBoxOption( rank ) == value ) { buildSecurity.MinRank = rank; buildRankString = rank.FullName; return; @@ -353,102 +271,85 @@ public string BuildPermission } } - public string Backup { get; set; } - #endregion + #endregion List Properties - - internal XElement Serialize() - { - XElement element = new XElement("World"); - element.Add(new XAttribute("name", Name)); - element.Add(new XAttribute("hidden", Hidden)); - if (Backup != BackupEnumNames[0]) - { - element.Add(new XAttribute("backup", BackupValueFromName(Backup).ToTickString())); + internal XElement Serialize() { + XElement element = new XElement( "World" ); + element.Add( new XAttribute( "name", Name ) ); + element.Add( new XAttribute( "hidden", Hidden ) ); + if ( Backup != BackupEnumNames[0] ) { + element.Add( new XAttribute( "backup", BackupValueFromName( Backup ).ToTickString() ) ); } - element.Add(accessSecurity.Serialize(WorldManager.AccessSecurityXmlTagName)); - element.Add(buildSecurity.Serialize(WorldManager.BuildSecurityXmlTagName)); - XElement blockDB = new XElement(BlockDB.XmlRootName); - blockDB.Add(new XAttribute("enabled", BlockDBEnabled)); - blockDB.Add(new XAttribute("preload", blockDBIsPreloaded)); - blockDB.Add(new XAttribute("limit", blockDBLimit)); - blockDB.Add(new XAttribute("timeLimit", (int)blockDBTimeLimit.TotalSeconds)); - element.Add(blockDB); - - if (environmentEl != null) element.Add(environmentEl); - - if (!String.IsNullOrEmpty(LoadedBy)) element.Add(new XElement("LoadedBy", LoadedBy)); - if (!String.IsNullOrEmpty(MapChangedBy)) element.Add(new XElement("MapChangedBy", MapChangedBy)); - if (LoadedOn != DateTime.MinValue) element.Add(new XElement("LoadedOn", LoadedOn)); - if (MapChangedOn != DateTime.MinValue) element.Add(new XElement("MapChangedOn", MapChangedOn)); + element.Add( accessSecurity.Serialize( WorldManager.AccessSecurityXmlTagName ) ); + element.Add( buildSecurity.Serialize( WorldManager.BuildSecurityXmlTagName ) ); + XElement blockDB = new XElement( BlockDB.XmlRootName ); + blockDB.Add( new XAttribute( "enabled", BlockDBEnabled ) ); + blockDB.Add( new XAttribute( "preload", blockDBIsPreloaded ) ); + blockDB.Add( new XAttribute( "limit", blockDBLimit ) ); + blockDB.Add( new XAttribute( "timeLimit", ( int )blockDBTimeLimit.TotalSeconds ) ); + element.Add( blockDB ); + + if ( environmentEl != null ) + element.Add( environmentEl ); + + if ( !String.IsNullOrEmpty( LoadedBy ) ) + element.Add( new XElement( "LoadedBy", LoadedBy ) ); + if ( !String.IsNullOrEmpty( MapChangedBy ) ) + element.Add( new XElement( "MapChangedBy", MapChangedBy ) ); + if ( LoadedOn != DateTime.MinValue ) + element.Add( new XElement( "LoadedOn", LoadedOn ) ); + if ( MapChangedOn != DateTime.MinValue ) + element.Add( new XElement( "MapChangedOn", MapChangedOn ) ); return element; } - - public void ReparseRanks() - { - Rank accessMinRank = Rank.Parse(accessRankString); - if (accessMinRank != null) - { + public void ReparseRanks() { + Rank accessMinRank = Rank.Parse( accessRankString ); + if ( accessMinRank != null ) { accessSecurity.MinRank = accessMinRank; - } - else - { + } else { accessSecurity.ResetMinRank(); } - Rank buildMinRank = Rank.Parse(buildRankString); - if (buildMinRank != null) - { + Rank buildMinRank = Rank.Parse( buildRankString ); + if ( buildMinRank != null ) { buildSecurity.MinRank = buildMinRank; - } - else - { + } else { buildSecurity.ResetMinRank(); } } + private Map cachedMapHeader; - Map cachedMapHeader; - internal Map MapHeader - { - get - { - if (cachedMapHeader == null && !LoadingFailed) - { - string fullFileName = Path.Combine(Paths.MapPath, name + ".fcm"); - LoadingFailed = !MapUtility.TryLoadHeader(fullFileName, out cachedMapHeader); + internal Map MapHeader { + get { + if ( cachedMapHeader == null && !LoadingFailed ) { + string fullFileName = Path.Combine( Paths.MapPath, name + ".fcm" ); + LoadingFailed = !MapUtility.TryLoadHeader( fullFileName, out cachedMapHeader ); } return cachedMapHeader; } } - - internal string FileName - { + internal string FileName { get { return Name + MapFileExtension; } } - - internal string FullFileName - { - get { return Path.Combine(Paths.MapPath, Name + MapFileExtension); } + internal string FullFileName { + get { return Path.Combine( Paths.MapPath, Name + MapFileExtension ); } } - #region Backup - public static string BackupNameFromValue(TimeSpan value) - { - TimeSpan closestMatch = BackupEnumValues.OrderBy(t => Math.Abs(value.Subtract(t).Ticks)).First(); - return BackupEnumNames[Array.IndexOf(BackupEnumValues, closestMatch)]; + public static string BackupNameFromValue( TimeSpan value ) { + TimeSpan closestMatch = BackupEnumValues.OrderBy( t => Math.Abs( value.Subtract( t ).Ticks ) ).First(); + return BackupEnumNames[Array.IndexOf( BackupEnumValues, closestMatch )]; } - public static TimeSpan BackupValueFromName(string name) - { - return BackupEnumValues[Array.IndexOf(BackupEnumNames, name)]; + public static TimeSpan BackupValueFromName( string name ) { + return BackupEnumValues[Array.IndexOf( BackupEnumNames, name )]; } public static readonly string[] BackupEnumNames = new[] { @@ -471,7 +372,7 @@ public static TimeSpan BackupValueFromName(string name) "48 Hours" }; - static readonly TimeSpan[] BackupEnumValues = new[] { + private static readonly TimeSpan[] BackupEnumValues = new[] { TimeSpan.FromSeconds(-1), // default TimeSpan.Zero, TimeSpan.FromMinutes(5), @@ -491,38 +392,36 @@ public static TimeSpan BackupValueFromName(string name) TimeSpan.FromHours(48) }; - #endregion - + #endregion Backup public YesNoAuto BlockDBEnabled { get; set; } - readonly bool blockDBIsPreloaded; - readonly int blockDBLimit; - TimeSpan blockDBTimeLimit; + private readonly bool blockDBIsPreloaded; + private readonly int blockDBLimit; + private TimeSpan blockDBTimeLimit; - public object Clone() - { - return new WorldListEntry(this); + public object Clone() { + return new WorldListEntry( this ); } - // Comparison method used to customize sorting [UsedImplicitly] - public static object Compare(string propertyName, object a, object b) - { - WorldListEntry entry1 = (WorldListEntry)a; - WorldListEntry entry2 = (WorldListEntry)b; - switch (propertyName) - { + public static object Compare( string propertyName, object a, object b ) { + WorldListEntry entry1 = ( WorldListEntry )a; + WorldListEntry entry2 = ( WorldListEntry )b; + switch ( propertyName ) { case "Description": - if (entry1.MapHeader == null && entry2.MapHeader == null) return 0; - if (entry1.MapHeader == null) return -1; - if (entry2.MapHeader == null) return 1; + if ( entry1.MapHeader == null && entry2.MapHeader == null ) + return 0; + if ( entry1.MapHeader == null ) + return -1; + if ( entry2.MapHeader == null ) + return 1; int volumeDifference = entry1.MapHeader.Volume - entry2.MapHeader.Volume; - return Math.Min(1, Math.Max(-1, volumeDifference)); + return Math.Min( 1, Math.Max( -1, volumeDifference ) ); case "Name": - return StringComparer.OrdinalIgnoreCase.Compare(entry1.name, entry2.name); + return StringComparer.OrdinalIgnoreCase.Compare( entry1.name, entry2.name ); default: throw new NotImplementedException(); diff --git a/ConfigGUI/app.config b/ConfigGUI/app.config index 19fac17..6e2f55a 100644 --- a/ConfigGUI/app.config +++ b/ConfigGUI/app.config @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/ServerCLI/Program.cs b/ServerCLI/Program.cs index 30e7408..4157e60 100644 --- a/ServerCLI/Program.cs +++ b/ServerCLI/Program.cs @@ -20,22 +20,22 @@ * THE SOFTWARE. * */ + using System; +using System.ComponentModel; using System.Diagnostics; using System.IO; +using System.Net; using System.Text; using System.Threading; -using System.Net; -using System.ComponentModel; using fCraft.Events; -using System.Reflection; namespace fCraft.ServerCLI { - static class Program { - static bool useColor = true; + internal static class Program { + private static bool useColor = true; - static void Main( string[] args ) { + private static void Main( string[] args ) { Logger.Logged += OnLogged; Heartbeat.UriChanged += OnHeartbeatUriChanged; @@ -52,36 +52,35 @@ static void Main( string[] args ) { Updater.UpdateCheck(); Console.Title = "800Craft " + Updater.CurrentRelease.VersionString + " - " + ConfigKey.ServerName.GetString(); - if( !ConfigKey.ProcessPriority.IsBlank() ) { + if ( !ConfigKey.ProcessPriority.IsBlank() ) { try { Process.GetCurrentProcess().PriorityClass = ConfigKey.ProcessPriority.GetEnum(); - } catch( Exception ) { + } catch ( Exception ) { Logger.Log( LogType.Warning, "Program.Main: Could not set process priority, using defaults." ); } } - if( Server.StartServer() ) { + if ( Server.StartServer() ) { Console.WriteLine( "** Running 800Craft version {0}. **", Updater.CurrentRelease.VersionString ); Console.WriteLine( "** Server is now ready. Type /Shutdown to exit safely. **" ); - while( !Server.IsShuttingDown ) { + while ( !Server.IsShuttingDown ) { string cmd = Console.ReadLine(); - if( cmd.Equals( "/Clear", StringComparison.OrdinalIgnoreCase ) ) { + if ( cmd.Equals( "/Clear", StringComparison.OrdinalIgnoreCase ) ) { Console.Clear(); } else { try { Player.Console.ParseMessage( cmd, true ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.LogAndReportCrash( "Error while executing a command from console", "ServerCLI", ex, false ); } } } - } else { ReportFailure( ShutdownReason.FailedToStart ); } #if !DEBUG - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.LogAndReportCrash( "Unhandled exception in ServerCLI", "ServerCLI", ex, true ); ReportFailure( ShutdownReason.Crashed ); } finally { @@ -90,47 +89,57 @@ static void Main( string[] args ) { #endif } - - static void ReportFailure( ShutdownReason reason ) { + private static void ReportFailure( ShutdownReason reason ) { Console.Title = String.Format( "800Craft {0} {1}", Updater.CurrentRelease.VersionString, reason ); - if( useColor ) Console.ForegroundColor = ConsoleColor.Red; + if ( useColor ) + Console.ForegroundColor = ConsoleColor.Red; Console.Error.WriteLine( "** {0} **", reason ); - if( useColor ) Console.ResetColor(); + if ( useColor ) + Console.ResetColor(); Server.Shutdown( new ShutdownParams( reason, TimeSpan.Zero, false, false ), true ); - if( !Server.HasArg( ArgKey.ExitOnCrash ) ) { + if ( !Server.HasArg( ArgKey.ExitOnCrash ) ) { Console.ReadLine(); } } - [DebuggerStepThrough] - static void OnLogged( object sender, LogEventArgs e ) { - if( !e.WriteToConsole ) return; - switch( e.MessageType ) { + private static void OnLogged( object sender, LogEventArgs e ) { + if ( !e.WriteToConsole ) + return; + switch ( e.MessageType ) { case LogType.Error: - if(useColor)Console.ForegroundColor = ConsoleColor.Red; + if ( useColor ) + Console.ForegroundColor = ConsoleColor.Red; Console.Error.WriteLine( e.Message ); - if( useColor ) Console.ResetColor(); + if ( useColor ) + Console.ResetColor(); return; case LogType.SeriousError: - if( useColor ) Console.ForegroundColor = ConsoleColor.White; - if( useColor ) Console.BackgroundColor = ConsoleColor.Red; + if ( useColor ) + Console.ForegroundColor = ConsoleColor.White; + if ( useColor ) + Console.BackgroundColor = ConsoleColor.Red; Console.Error.WriteLine( e.Message ); - if( useColor ) Console.ResetColor(); + if ( useColor ) + Console.ResetColor(); return; case LogType.Warning: - if( useColor ) Console.ForegroundColor = ConsoleColor.Yellow; + if ( useColor ) + Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine( e.Message ); - if( useColor ) Console.ResetColor(); + if ( useColor ) + Console.ResetColor(); return; case LogType.Debug: case LogType.Trace: - if( useColor ) Console.ForegroundColor = ConsoleColor.DarkGray; + if ( useColor ) + Console.ForegroundColor = ConsoleColor.DarkGray; Console.WriteLine( e.Message ); - if( useColor ) Console.ResetColor(); + if ( useColor ) + Console.ResetColor(); return; default: @@ -139,26 +148,24 @@ static void OnLogged( object sender, LogEventArgs e ) { } } - - static void OnHeartbeatUriChanged( object sender, UriChangedEventArgs e ) { + private static void OnHeartbeatUriChanged( object sender, UriChangedEventArgs e ) { File.WriteAllText( "externalurl.txt", e.NewUri.ToString(), Encoding.ASCII ); Console.WriteLine( "** URL: {0} **", e.NewUri ); Console.WriteLine( "URL is also saved to file externalurl.txt" ); } - #region Updates + private static readonly AutoResetEvent UpdateDownloadWaiter = new AutoResetEvent( false ); + private static bool updateFailed; - static readonly AutoResetEvent UpdateDownloadWaiter = new AutoResetEvent( false ); - static bool updateFailed; + private static readonly object progressReportLock = new object(); - static readonly object progressReportLock = new object(); - static void OnUpdateDownloadProgress( object sender, DownloadProgressChangedEventArgs e ) { - lock( progressReportLock ) { + private static void OnUpdateDownloadProgress( object sender, DownloadProgressChangedEventArgs e ) { + lock ( progressReportLock ) { Console.CursorLeft = 0; int maxProgress = Console.WindowWidth - 9; - int progress = (int)Math.Round((e.ProgressPercentage / 100f) * (maxProgress - 1)); + int progress = ( int )Math.Round( ( e.ProgressPercentage / 100f ) * ( maxProgress - 1 ) ); Console.Write( "{0,3}% |", e.ProgressPercentage ); Console.Write( new String( '=', progress ) ); Console.Write( '>' ); @@ -167,43 +174,45 @@ static void OnUpdateDownloadProgress( object sender, DownloadProgressChangedEven } } - - static void OnUpdateDownloadCompleted( object sender, AsyncCompletedEventArgs e ) { + private static void OnUpdateDownloadCompleted( object sender, AsyncCompletedEventArgs e ) { Console.WriteLine(); - if( e.Error != null ) { + if ( e.Error != null ) { updateFailed = true; - if( useColor ) Console.ForegroundColor = ConsoleColor.Red; + if ( useColor ) + Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine( "Downloading the updater failed: {0}", e.Error ); - if( useColor ) Console.ResetColor(); + if ( useColor ) + Console.ResetColor(); } else { Console.WriteLine( "Update download finished." ); } UpdateDownloadWaiter.Set(); } - - static void CheckForUpdates() { + private static void CheckForUpdates() { UpdaterMode updaterMode = ConfigKey.UpdaterMode.GetEnum(); - if( updaterMode == UpdaterMode.Disabled ) return; + if ( updaterMode == UpdaterMode.Disabled ) + return; UpdaterResult update = Updater.CheckForUpdates(); - if( update.UpdateAvailable ) { + if ( update.UpdateAvailable ) { Console.WriteLine( "** A new version of 800Craft is available: {0}, released {1:0} day(s) ago. **", update.LatestRelease.VersionString, update.LatestRelease.Age.TotalDays ); - if( updaterMode != UpdaterMode.Notify ) { + if ( updaterMode != UpdaterMode.Notify ) { WebClient client = new WebClient(); client.DownloadProgressChanged += OnUpdateDownloadProgress; client.DownloadFileCompleted += OnUpdateDownloadCompleted; client.DownloadFileAsync( update.DownloadUri, Paths.UpdaterFileName ); UpdateDownloadWaiter.WaitOne(); - if( updateFailed ) return; + if ( updateFailed ) + return; - if( updaterMode == UpdaterMode.Prompt ) { + if ( updaterMode == UpdaterMode.Prompt ) { Console.WriteLine( "Restart the server and update now? y/n" ); var key = Console.ReadKey(); - if( key.KeyChar == 'y' ) { + if ( key.KeyChar == 'y' ) { RestartForUpdate(); return; } else { @@ -217,14 +226,13 @@ static void CheckForUpdates() { } } - - static void RestartForUpdate() { + private static void RestartForUpdate() { string restartArgs = String.Format( "{0} --restart=\"{1}\"", Server.GetArgString(), MonoCompat.PrependMono( "ServerGUI.exe" ) ); MonoCompat.StartDotNetProcess( Paths.UpdaterFileName, restartArgs, true ); } - #endregion + #endregion Updates } } \ No newline at end of file diff --git a/ServerCLI/Properties/AssemblyInfo.cs b/ServerCLI/Properties/AssemblyInfo.cs index a28bc62..ba6c648 100644 --- a/ServerCLI/Properties/AssemblyInfo.cs +++ b/ServerCLI/Properties/AssemblyInfo.cs @@ -3,20 +3,20 @@ using System.Resources; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("800Craft ServerCLI")] -[assembly: AssemblyDescription("Command-line frontend for 800Craft server")] +[assembly: AssemblyTitle( "800Craft ServerCLI" )] +[assembly: AssemblyDescription( "Command-line frontend for 800Craft server" )] [assembly: AssemblyConfiguration( "" )] -[assembly: AssemblyCompany("au70.net")] -[assembly: AssemblyProduct("800Craft ServerCLI")] -[assembly: AssemblyCopyright("")] +[assembly: AssemblyCompany( "au70.net" )] +[assembly: AssemblyProduct( "800Craft ServerCLI" )] +[assembly: AssemblyCopyright( "" )] [assembly: AssemblyTrademark( "" )] [assembly: AssemblyCulture( "" )] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible( false )] @@ -26,15 +26,14 @@ // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -// You can specify all the values or you can default the Build and Revision Numbers +// You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion( "0.6.1.7" )] [assembly: AssemblyFileVersion( "0.6.1.7" )] - [assembly: CLSCompliant( true )] [assembly: NeutralResourcesLanguage( "en-US" )] \ No newline at end of file diff --git a/ServerCLI/app.config b/ServerCLI/app.config index 19fac17..6e2f55a 100644 --- a/ServerCLI/app.config +++ b/ServerCLI/app.config @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/ServerGUI/ConsoleBox.cs b/ServerGUI/ConsoleBox.cs index 29845dc..0b9e2d4 100644 --- a/ServerGUI/ConsoleBox.cs +++ b/ServerGUI/ConsoleBox.cs @@ -1,25 +1,31 @@ -// Copyright 2009-2013 Matvei Stefarov +using System; + +// Copyright 2009-2013 Matvei Stefarov using System.Collections.Generic; using System.Windows.Forms; -using System; namespace fCraft.ServerGUI { - sealed class ConsoleBox : TextBox { - const int WM_KEYDOWN = 0x100; - const int WM_SYSKEYDOWN = 0x104; + + internal sealed class ConsoleBox : TextBox { + private const int WM_KEYDOWN = 0x100; + private const int WM_SYSKEYDOWN = 0x104; + public event Action OnCommand; - readonly List log = new List(); - int logPointer; + + private readonly List log = new List(); + private int logPointer; protected override bool ProcessCmdKey( ref Message msg, Keys keyData ) { - if( !Enabled ) return base.ProcessCmdKey( ref msg, keyData ); - switch( keyData ) { + if ( !Enabled ) + return base.ProcessCmdKey( ref msg, keyData ); + switch ( keyData ) { case Keys.Up: - if( msg.Msg == WM_SYSKEYDOWN || msg.Msg == WM_KEYDOWN ) { - if( log.Count == 0 ) return true; - if( logPointer == -1 ) { + if ( msg.Msg == WM_SYSKEYDOWN || msg.Msg == WM_KEYDOWN ) { + if ( log.Count == 0 ) + return true; + if ( logPointer == -1 ) { logPointer = log.Count - 1; - } else if( logPointer > 0 ) { + } else if ( logPointer > 0 ) { logPointer--; } Text = log[logPointer]; @@ -28,9 +34,10 @@ protected override bool ProcessCmdKey( ref Message msg, Keys keyData ) { return true; case Keys.Down: - if( msg.Msg == WM_SYSKEYDOWN || msg.Msg == WM_KEYDOWN ) { - if( log.Count == 0 || logPointer == -1 ) return true; - if( logPointer < log.Count - 1 ) { + if ( msg.Msg == WM_SYSKEYDOWN || msg.Msg == WM_KEYDOWN ) { + if ( log.Count == 0 || logPointer == -1 ) + return true; + if ( logPointer < log.Count - 1 ) { logPointer++; } Text = log[logPointer]; @@ -39,18 +46,20 @@ protected override bool ProcessCmdKey( ref Message msg, Keys keyData ) { return true; case Keys.Enter: - if( msg.Msg == WM_SYSKEYDOWN || msg.Msg == WM_KEYDOWN ) { - if( Text.Trim().Length > 0 ) { + if ( msg.Msg == WM_SYSKEYDOWN || msg.Msg == WM_KEYDOWN ) { + if ( Text.Trim().Length > 0 ) { log.Add( Text ); - if( log.Count > 100 ) log.RemoveAt( 0 ); + if ( log.Count > 100 ) + log.RemoveAt( 0 ); logPointer = -1; - if( OnCommand != null ) OnCommand(); + if ( OnCommand != null ) + OnCommand(); } } return true; case Keys.Escape: - if( msg.Msg == WM_SYSKEYDOWN || msg.Msg == WM_KEYDOWN ) { + if ( msg.Msg == WM_SYSKEYDOWN || msg.Msg == WM_KEYDOWN ) { logPointer = log.Count; Text = ""; } diff --git a/ServerGUI/MainForm.cs b/ServerGUI/MainForm.cs index 3c2a4b9..bac44a7 100644 --- a/ServerGUI/MainForm.cs +++ b/ServerGUI/MainForm.cs @@ -3,20 +3,22 @@ using System.ComponentModel; using System.Diagnostics; using System.Linq; +using System.Threading; using System.Windows.Forms; using fCraft.Events; using fCraft.GUI; -using System.Threading; namespace fCraft.ServerGUI { public sealed partial class MainForm : Form { - volatile bool shutdownPending, startupComplete, shutdownComplete; - const int MaxLinesInLog = 2000, + private volatile bool shutdownPending, startupComplete, shutdownComplete; + + private const int MaxLinesInLog = 2000, LinesToTrimWhenExceeded = 50; - SkinViewer v; - public MainForm () { + private SkinViewer v; + + public MainForm() { InitializeComponent(); Shown += StartUp; console.OnCommand += console_Enter; @@ -27,9 +29,10 @@ public MainForm () { } #region Startup - Thread startupThread; - void StartUp ( object sender, EventArgs a ) { + private Thread startupThread; + + private void StartUp( object sender, EventArgs a ) { Logger.Logged += OnLogged; Heartbeat.UriChanged += OnHeartbeatUriChanged; Server.PlayerListChanged += OnPlayerListChanged; @@ -40,23 +43,25 @@ void StartUp ( object sender, EventArgs a ) { startupThread.Start(); } - - void StartupThread () { + private void StartupThread() { #if !DEBUG try { #endif Server.InitLibrary( Environment.GetCommandLineArgs() ); - if ( shutdownPending ) return; + if ( shutdownPending ) + return; Server.InitServer(); - if ( shutdownPending ) return; + if ( shutdownPending ) + return; BeginInvoke( ( Action )OnInitSuccess ); // check for updates UpdaterMode updaterMode = ConfigKey.UpdaterMode.GetEnum(); if ( updaterMode != UpdaterMode.Disabled ) { - if ( shutdownPending ) return; + if ( shutdownPending ) + return; if ( Updater.UpdateCheck() ) { if ( updaterMode == UpdaterMode.Notify ) { String updateMsg = String.Format( "An 800Craft update is available! Visit http://github.com/glennmr/800Craft/downloads to download. " + @@ -74,7 +79,6 @@ void StartupThread () { } } - // set process priority if ( !ConfigKey.ProcessPriority.IsBlank() ) { try { @@ -85,7 +89,8 @@ void StartupThread () { } } - if ( shutdownPending ) return; + if ( shutdownPending ) + return; if ( Server.StartServer() ) { startupComplete = true; BeginInvoke( ( Action )OnStartupSuccess ); @@ -100,13 +105,11 @@ void StartupThread () { #endif } - - void OnInitSuccess () { + private void OnInitSuccess() { Text = "800Craft " + Updater.CurrentRelease.VersionString + " - " + ConfigKey.ServerName.GetString(); } - - void OnStartupSuccess () { + private void OnStartupSuccess() { if ( !ConfigKey.HeartbeatEnabled.Enabled() ) { uriDisplay.Text = "Heartbeat disabled. See externalurl.txt"; } @@ -114,17 +117,15 @@ void OnStartupSuccess () { console.Text = ""; } - - void OnStartupFailure () { + private void OnStartupFailure() { Shutdown( ShutdownReason.FailedToStart, Server.HasArg( ArgKey.ExitOnCrash ) ); } - #endregion - + #endregion Startup #region Shutdown - protected override void OnFormClosing ( FormClosingEventArgs e ) { + protected override void OnFormClosing( FormClosingEventArgs e ) { if ( startupThread != null && !shutdownComplete ) { Shutdown( ShutdownReason.ProcessClosing, true ); e.Cancel = true; @@ -133,9 +134,9 @@ protected override void OnFormClosing ( FormClosingEventArgs e ) { } } - - void Shutdown ( ShutdownReason reason, bool quit ) { - if ( shutdownPending ) return; + private void Shutdown( ShutdownReason reason, bool quit ) { + if ( shutdownPending ) + return; shutdownPending = true; console.Enabled = false; console.Text = "Shutting down..."; @@ -147,8 +148,7 @@ void Shutdown ( ShutdownReason reason, bool quit ) { Server.Shutdown( new ShutdownParams( reason, TimeSpan.Zero, quit, false ), false ); } - - void OnServerShutdownEnded ( object sender, ShutdownEventArgs e ) { + private void OnServerShutdownEnded( object sender, ShutdownEventArgs e ) { try { BeginInvoke( ( Action )delegate { shutdownComplete = true; @@ -160,6 +160,7 @@ void OnServerShutdownEnded ( object sender, ShutdownEventArgs e ) { Application.Exit(); } break; + default: Application.Exit(); break; @@ -169,13 +170,14 @@ void OnServerShutdownEnded ( object sender, ShutdownEventArgs e ) { } catch ( InvalidOperationException ) { } } - #endregion - + #endregion Shutdown - public void OnLogged ( object sender, LogEventArgs e ) { - if ( !e.WriteToConsole ) return; + public void OnLogged( object sender, LogEventArgs e ) { + if ( !e.WriteToConsole ) + return; try { - if ( shutdownComplete ) return; + if ( shutdownComplete ) + return; if ( logBox.InvokeRequired ) { BeginInvoke( ( EventHandler )OnLogged, sender, e ); } else { @@ -194,6 +196,7 @@ public void OnLogged ( object sender, LogEventArgs e ) { case LogType.PrivateChat: logBox.SelectionColor = System.Drawing.Color.Teal; break; + case LogType.IRC: if ( ThemeBox.SelectedItem == null ) { logBox.SelectionColor = System.Drawing.Color.LightBlue; @@ -202,15 +205,18 @@ public void OnLogged ( object sender, LogEventArgs e ) { default: logBox.SelectionColor = System.Drawing.Color.LightSkyBlue; break; + case "New 800Craft": logBox.SelectionColor = System.Drawing.Color.Navy; break; } } break; + case LogType.ChangedWorld: logBox.SelectionColor = System.Drawing.Color.Orange; break; + case LogType.Warning: if ( ThemeBox.SelectedItem == null ) { logBox.SelectionColor = System.Drawing.Color.Yellow; @@ -219,19 +225,23 @@ public void OnLogged ( object sender, LogEventArgs e ) { default: logBox.SelectionColor = System.Drawing.Color.MediumOrchid; break; + case "New 800Craft": logBox.SelectionColor = System.Drawing.Color.Yellow; break; } } break; + case LogType.Debug: logBox.SelectionColor = System.Drawing.Color.DarkGray; break; + case LogType.Error: case LogType.SeriousError: logBox.SelectionColor = System.Drawing.Color.Red; break; + case LogType.ConsoleInput: case LogType.ConsoleOutput: if ( ThemeBox.SelectedItem == null ) { @@ -241,12 +251,14 @@ public void OnLogged ( object sender, LogEventArgs e ) { default: logBox.SelectionColor = System.Drawing.Color.Black; break; + case "New 800Craft": logBox.SelectionColor = System.Drawing.Color.White; break; } } break; + default: if ( ThemeBox.SelectedItem == null ) { logBox.SelectionColor = System.Drawing.Color.LightGray; @@ -255,6 +267,7 @@ public void OnLogged ( object sender, LogEventArgs e ) { default: logBox.SelectionColor = System.Drawing.Color.Black; break; + case "New 800Craft": logBox.SelectionColor = System.Drawing.Color.LightGray; break; @@ -268,7 +281,8 @@ public void OnLogged ( object sender, LogEventArgs e ) { logBox.SelectionStart = 0; logBox.SelectionLength = logBox.GetFirstCharIndexFromLine( LinesToTrimWhenExceeded ); userSelectionStart -= logBox.SelectionLength; - if ( userSelectionStart < 0 ) userSelecting = false; + if ( userSelectionStart < 0 ) + userSelecting = false; string textToAdd = "----- cut off, see " + Logger.CurrentLogFileName + " for complete log -----" + Environment.NewLine; logBox.SelectedText = textToAdd; userSelectionStart += textToAdd.Length; @@ -287,10 +301,10 @@ public void OnLogged ( object sender, LogEventArgs e ) { } catch ( InvalidOperationException ) { } } - - public void OnHeartbeatUriChanged ( object sender, UriChangedEventArgs e ) { + public void OnHeartbeatUriChanged( object sender, UriChangedEventArgs e ) { try { - if ( shutdownPending ) return; + if ( shutdownPending ) + return; if ( uriDisplay.InvokeRequired ) { BeginInvoke( ( EventHandler )OnHeartbeatUriChanged, sender, e ); @@ -303,10 +317,10 @@ public void OnHeartbeatUriChanged ( object sender, UriChangedEventArgs e ) { } catch ( InvalidOperationException ) { } } - - public void OnPlayerListChanged ( object sender, EventArgs e ) { + public void OnPlayerListChanged( object sender, EventArgs e ) { try { - if ( shutdownPending ) return; + if ( shutdownPending ) + return; if ( playerList.InvokeRequired ) { BeginInvoke( ( EventHandler )OnPlayerListChanged, null, EventArgs.Empty ); } else { @@ -320,8 +334,7 @@ public void OnPlayerListChanged ( object sender, EventArgs e ) { } catch ( InvalidOperationException ) { } } - - private void console_Enter () { + private void console_Enter() { string[] separator = { Environment.NewLine }; string[] lines = console.Text.Trim().Split( separator, StringSplitOptions.RemoveEmptyEntries ); foreach ( string line in lines ) { @@ -346,8 +359,7 @@ private void console_Enter () { console.Text = ""; } - - private void bPlay_Click ( object sender, EventArgs e ) { + private void bPlay_Click( object sender, EventArgs e ) { try { Process.Start( uriDisplay.Text ); } catch ( Exception ) { @@ -355,18 +367,17 @@ private void bPlay_Click ( object sender, EventArgs e ) { } } - private void logBox_TextChanged ( object sender, EventArgs e ) { - + private void logBox_TextChanged( object sender, EventArgs e ) { } - private void Link_Clicked ( object sender, LinkClickedEventArgs e ) { + + private void Link_Clicked( object sender, LinkClickedEventArgs e ) { System.Diagnostics.Process.Start( e.LinkText ); } - private void MainForm_Load ( object sender, EventArgs e ) { - + private void MainForm_Load( object sender, EventArgs e ) { } - private void comboBox1_SelectedIndexChanged ( object sender, EventArgs e ) { + private void comboBox1_SelectedIndexChanged( object sender, EventArgs e ) { if ( SizeBox.SelectedItem.ToString() == "Normal" ) { logBox.ZoomFactor = 1; } @@ -378,12 +389,12 @@ private void comboBox1_SelectedIndexChanged ( object sender, EventArgs e ) { } } - private void CopyMenuOnClickHandler ( object sender, EventArgs e ) { + private void CopyMenuOnClickHandler( object sender, EventArgs e ) { if ( logBox.SelectedText.Length > 0 ) Clipboard.SetText( logBox.SelectedText.ToString(), TextDataFormat.Text ); } - private void CopyMenuPopupHandler ( object sender, EventArgs e ) { + private void CopyMenuPopupHandler( object sender, EventArgs e ) { ContextMenu menu = sender as ContextMenu; if ( menu != null ) { menu.MenuItems[0].Enabled = ( logBox.SelectedText.Length > 0 ); @@ -391,7 +402,8 @@ private void CopyMenuPopupHandler ( object sender, EventArgs e ) { } private bool _isBlackText = false; - private void ThemeBox_SelectedIndexChanged ( object sender, EventArgs e ) { + + private void ThemeBox_SelectedIndexChanged( object sender, EventArgs e ) { if ( ThemeBox.SelectedItem.ToString().Equals( "New 800Craft" ) ) { SetNewTheme(); } if ( ThemeBox.SelectedItem.ToString().Equals( "Old 800Craft" ) ) { SetOldTheme(); } if ( ThemeBox.SelectedItem.ToString().Equals( "Pink" ) ) { SetPinkTheme(); } @@ -401,8 +413,7 @@ private void ThemeBox_SelectedIndexChanged ( object sender, EventArgs e ) { if ( ThemeBox.SelectedItem.ToString().Equals( "Grey" ) ) { SetGreyTheme(); } } - - public void SetNewTheme () { + public void SetNewTheme() { BackColor = System.Drawing.SystemColors.GradientActiveCaption; playerList.BackColor = System.Drawing.SystemColors.GradientInactiveCaption; if ( logBox.BackColor != System.Drawing.Color.Black ) { @@ -414,7 +425,8 @@ public void SetNewTheme () { _isBlackText = false; } } - public void SetOldTheme () { + + public void SetOldTheme() { BackColor = System.Drawing.SystemColors.GradientActiveCaption; playerList.BackColor = System.Drawing.SystemColors.GradientInactiveCaption; logBox.BackColor = System.Drawing.SystemColors.GradientInactiveCaption; @@ -426,7 +438,8 @@ public void SetOldTheme () { _isBlackText = true; } } - public void SetPinkTheme () { + + public void SetPinkTheme() { BackColor = System.Drawing.Color.Pink; playerList.BackColor = System.Drawing.Color.LightPink; logBox.BackColor = System.Drawing.Color.LightPink; @@ -439,7 +452,7 @@ public void SetPinkTheme () { } } - public void SetYellowTheme () { + public void SetYellowTheme() { BackColor = System.Drawing.Color.LightGoldenrodYellow; playerList.BackColor = System.Drawing.Color.LightYellow; logBox.BackColor = System.Drawing.Color.LightYellow; @@ -452,7 +465,7 @@ public void SetYellowTheme () { } } - public void SetGreenTheme () { + public void SetGreenTheme() { BackColor = System.Drawing.Color.SpringGreen; playerList.BackColor = System.Drawing.Color.LightGreen; logBox.BackColor = System.Drawing.Color.LightGreen; @@ -465,7 +478,7 @@ public void SetGreenTheme () { } } - public void SetPurpleTheme () { + public void SetPurpleTheme() { BackColor = System.Drawing.Color.MediumPurple; playerList.BackColor = System.Drawing.Color.Plum; logBox.BackColor = System.Drawing.Color.Plum; @@ -478,7 +491,7 @@ public void SetPurpleTheme () { } } - public void SetGreyTheme () { + public void SetGreyTheme() { BackColor = System.Drawing.SystemColors.Control; playerList.BackColor = System.Drawing.SystemColors.ControlLight; logBox.BackColor = System.Drawing.SystemColors.ControlLight; @@ -491,8 +504,7 @@ public void SetGreyTheme () { } } - - private void playerList_SelectedIndexChanged ( object sender, EventArgs e ) { + private void playerList_SelectedIndexChanged( object sender, EventArgs e ) { try { string s = ( string )playerList.Items[playerList.SelectedIndex]; s = s.Substring( s.IndexOf( '-' ), @@ -501,14 +513,14 @@ private void playerList_SelectedIndexChanged ( object sender, EventArgs e ) { .Replace( " ", "" ) .Trim(); PlayerInfo player = PlayerDB.FindPlayerInfoExact( s ); - if ( player == null ) return; + if ( player == null ) + return; v = new SkinViewer( player ); v.Show(); - } catch { } //do nothing at all + } catch { } //do nothing at all } - private void contextMenuStrip1_Opening ( object sender, CancelEventArgs e ) { - + private void contextMenuStrip1_Opening( object sender, CancelEventArgs e ) { } } } \ No newline at end of file diff --git a/ServerGUI/Program.cs b/ServerGUI/Program.cs index 9d3aea8..760c430 100644 --- a/ServerGUI/Program.cs +++ b/ServerGUI/Program.cs @@ -20,15 +20,17 @@ * THE SOFTWARE. * */ + using System; -using System.Windows.Forms; using System.Net; +using System.Windows.Forms; namespace fCraft.ServerGUI { - static class Program { + + internal static class Program { [STAThread] - static void Main() { + private static void Main() { ServicePointManager.ServerCertificateValidationCallback = ( a, b, c, d ) => { return true; }; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault( false ); @@ -37,7 +39,7 @@ static void Main() { #else try { Application.Run( new MainForm() ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.LogAndReportCrash( "Unhandled exception in ServerGUI", "ServerGUI", ex, true ); } #endif diff --git a/ServerGUI/Properties/AssemblyInfo.cs b/ServerGUI/Properties/AssemblyInfo.cs index f950c6b..6310005 100644 --- a/ServerGUI/Properties/AssemblyInfo.cs +++ b/ServerGUI/Properties/AssemblyInfo.cs @@ -3,20 +3,20 @@ using System.Resources; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("800Craft ServerGUI")] -[assembly: AssemblyDescription("Graphical frontend for 800Craft server")] +[assembly: AssemblyTitle( "800Craft ServerGUI" )] +[assembly: AssemblyDescription( "Graphical frontend for 800Craft server" )] [assembly: AssemblyConfiguration( "" )] -[assembly: AssemblyCompany("au70.net")] -[assembly: AssemblyProduct("800Craft ServerGUI")] -[assembly: AssemblyCopyright("")] +[assembly: AssemblyCompany( "au70.net" )] +[assembly: AssemblyProduct( "800Craft ServerGUI" )] +[assembly: AssemblyCopyright( "" )] [assembly: AssemblyTrademark( "" )] [assembly: AssemblyCulture( "" )] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible( false )] @@ -26,15 +26,14 @@ // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -// You can specify all the values or you can default the Build and Revision Numbers +// You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion( "0.6.1.7" )] [assembly: AssemblyFileVersion( "0.6.1.7" )] - [assembly: CLSCompliant( false )] [assembly: NeutralResourcesLanguage( "en-US" )] \ No newline at end of file diff --git a/ServerGUI/SkinViewer.cs b/ServerGUI/SkinViewer.cs index 39028f3..884b819 100644 --- a/ServerGUI/SkinViewer.cs +++ b/ServerGUI/SkinViewer.cs @@ -1,17 +1,15 @@ using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Data; using System.Drawing; -using System.Linq; -using System.Text; using System.Windows.Forms; namespace fCraft.ServerGUI { + public partial class SkinViewer : Form { - PlayerInfo player; - Image webSkin; - public SkinViewer ( fCraft.PlayerInfo player_ ) { + private PlayerInfo player; + private Image webSkin; + + public SkinViewer( fCraft.PlayerInfo player_ ) { InitializeComponent(); player = player_; PlayerInfo info = player; @@ -19,13 +17,12 @@ public SkinViewer ( fCraft.PlayerInfo player_ ) { SetPlayerInfoText( info ); } - void SetPlayerInfoText ( PlayerInfo info ) { + private void SetPlayerInfoText( PlayerInfo info ) { textBox1.Text = ""; PlayerLabel.Text = player.Name; SetTextRankColor( Color.GetName( player.Rank.Color ) ); if ( info.LastIP.Equals( System.Net.IPAddress.None ) ) { textBox1.Text += String.Format( "About {0}&S: Never seen before.\r\n", info.ClassyName ); - } else { if ( info != null ) { TimeSpan idle = info.PlayerObject.IdleTime; @@ -132,6 +129,7 @@ void SetPlayerInfoText ( PlayerInfo info ) { textBox1.Text += String.Format( " Account is &CBANNED&S. See &H/BanInfo\r\n" ); } break; + case BanStatus.IPBanExempt: if ( ipBan != null ) { textBox1.Text += String.Format( " IP is &CBANNED&S, but account is exempt. See &H/BanInfo\r\n" ); @@ -139,28 +137,27 @@ void SetPlayerInfoText ( PlayerInfo info ) { textBox1.Text += String.Format( " IP is not banned, and account is exempt. See &H/BanInfo\r\n" ); } break; + case BanStatus.NotBanned: if ( ipBan != null ) { textBox1.Text += String.Format( " IP is &CBANNED&S. See &H/BanInfo\r\n" ); - } break; } - if ( !info.LastIP.Equals( System.Net.IPAddress.None ) ) { // Show alts List altNames = new List(); int bannedAltCount = 0; foreach ( PlayerInfo playerFromSameIP in PlayerDB.FindPlayers( info.LastIP ) ) { - if ( playerFromSameIP == info ) continue; + if ( playerFromSameIP == info ) + continue; altNames.Add( playerFromSameIP ); if ( playerFromSameIP.IsBanned ) { bannedAltCount++; } } - // Stats if ( info.BlocksDrawn > 500000000 ) { textBox1.Text += String.Format( " Built {0} and deleted {1} blocks, drew {2}M blocks, wrote {3} messages.\r\n", @@ -187,7 +184,6 @@ void SetPlayerInfoText ( PlayerInfo info ) { info.MessagesWritten ); } - // More stats if ( info.TimesBannedOthers > 0 || info.TimesKickedOthers > 0 || info.PromoCount > 0 ) { textBox1.Text += String.Format( " Kicked {0}, Promoted {1} and banned {2} players.\r\n", info.TimesKickedOthers, info.PromoCount, info.TimesBannedOthers ); @@ -207,7 +203,6 @@ void SetPlayerInfoText ( PlayerInfo info ) { } } - // Promotion/demotion if ( info.PreviousRank == null ) { if ( info.RankChangedBy == null ) { @@ -255,8 +250,8 @@ void SetPlayerInfoText ( PlayerInfo info ) { textBox1.Text = Color.StripColors( textBox1.Text ); } } - - void GetSetSkin () { + + private void GetSetSkin() { GetSkin(); //get the skin (returns EmptySkin() if null or Exception) Bitmap temp = new Bitmap( 16, 32 ); //finished skin size Rectangle head = new Rectangle( 8, 8, 8, 8 ); @@ -277,69 +272,84 @@ void GetSetSkin () { pictureBox1.Image = MakeGrayscale( pictureBox1.Image as Bitmap ); //make it black and white pictureBox1.Image = ResizeBitmap( pictureBox1.Image as Bitmap, 148, 148 ); //resize to picturebox max size temp = ResizeBitmap( temp, 64, 128 ); //resize the stitched skin and then copy it onto the giant b/w head - CopyRegionIntoImage( temp, - new Rectangle( 0, 0, temp.Width, temp.Height ), - pictureBox1.Image as Bitmap, - new Rectangle( pictureBox1.Image.Width - temp.Width, - pictureBox1.Height - ( temp.Height - 8 ), - temp.Width, + CopyRegionIntoImage( temp, + new Rectangle( 0, 0, temp.Width, temp.Height ), + pictureBox1.Image as Bitmap, + new Rectangle( pictureBox1.Image.Width - temp.Width, + pictureBox1.Height - ( temp.Height - 8 ), + temp.Width, temp.Height ) ); } - void SetTextRankColor ( string c ) { + private void SetTextRankColor( string c ) { switch ( c.ToLower() ) { case "black": PlayerLabel.ForeColor = System.Drawing.Color.Black; break; + case "navy": PlayerLabel.ForeColor = System.Drawing.Color.Navy; break; + case "green": PlayerLabel.ForeColor = System.Drawing.Color.Green; break; + case "teal": PlayerLabel.ForeColor = System.Drawing.Color.Teal; break; + case "maroon": PlayerLabel.ForeColor = System.Drawing.Color.Maroon; break; + case "purple": PlayerLabel.ForeColor = System.Drawing.Color.Purple; break; + case "olive": PlayerLabel.ForeColor = System.Drawing.Color.Olive; break; + case "silver": PlayerLabel.ForeColor = System.Drawing.Color.Silver; break; + case "gray": PlayerLabel.ForeColor = System.Drawing.Color.Gray; break; + case "blue": PlayerLabel.ForeColor = System.Drawing.Color.Blue; break; + case "lime": PlayerLabel.ForeColor = System.Drawing.Color.Lime; break; + case "aqua": PlayerLabel.ForeColor = System.Drawing.Color.Aqua; break; + case "red": PlayerLabel.ForeColor = System.Drawing.Color.Red; break; + case "magenta": PlayerLabel.ForeColor = System.Drawing.Color.Magenta; break; + case "yellow": PlayerLabel.ForeColor = System.Drawing.Color.Yellow; break; + case "white": PlayerLabel.ForeColor = System.Drawing.Color.White; break; } } - private static Bitmap ResizeBitmap ( Bitmap sourceBMP, int width, int height ) { + private static Bitmap ResizeBitmap( Bitmap sourceBMP, int width, int height ) { Bitmap result = new Bitmap( width, height ); using ( Graphics g = Graphics.FromImage( result ) ) { g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; @@ -348,6 +358,7 @@ private static Bitmap ResizeBitmap ( Bitmap sourceBMP, int width, int height ) { } return result; } + private static Image EmptySkin { get { Image image = ( Image )new Bitmap( 64, 32, System.Drawing.Imaging.PixelFormat.Format32bppArgb ); @@ -388,12 +399,13 @@ private static Image EmptySkin { } } - private static void CopyRegionIntoImage ( Bitmap srcBitmap, Rectangle srcRegion, Bitmap destBitmap, Rectangle destRegion ) { + private static void CopyRegionIntoImage( Bitmap srcBitmap, Rectangle srcRegion, Bitmap destBitmap, Rectangle destRegion ) { using ( Graphics grD = Graphics.FromImage( destBitmap ) ) { grD.DrawImage( srcBitmap, destRegion, srcRegion, GraphicsUnit.Pixel ); } } - private void GetSkin () { + + private void GetSkin() { System.Net.WebClient webClient = new System.Net.WebClient(); try { byte[] buffer; @@ -405,7 +417,8 @@ private void GetSkin () { this.webSkin = ( Image )null; } } - public static Bitmap MakeGrayscale ( Bitmap original ) { + + public static Bitmap MakeGrayscale( Bitmap original ) { unsafe { //create an empty bitmap the same size as original Bitmap newBitmap = new Bitmap( original.Width, original.Height ); diff --git a/ServerGUI/UpdateWindow.cs b/ServerGUI/UpdateWindow.cs index a370da3..2af97c0 100644 --- a/ServerGUI/UpdateWindow.cs +++ b/ServerGUI/UpdateWindow.cs @@ -1,54 +1,51 @@ // Copyright 2009-2013 Matvei Stefarov using System; using System.ComponentModel; +using System.IO; using System.Net; using System.Windows.Forms; -using System.Text; -using System.IO; namespace fCraft.ServerGUI { + public sealed partial class UpdateWindow : Form { - readonly string updaterFullPath; - readonly WebClient downloader = new WebClient(); - readonly bool autoUpdate; - bool closeFormWhenDownloaded; + private readonly string updaterFullPath; + private readonly WebClient downloader = new WebClient(); + private readonly bool autoUpdate; + private bool closeFormWhenDownloaded; public UpdateWindow() { InitializeComponent(); updaterFullPath = Path.Combine( Paths.WorkingPath, Paths.UpdaterFileName ); - autoUpdate = (ConfigKey.UpdaterMode.GetEnum() == UpdaterMode.Auto); + autoUpdate = ( ConfigKey.UpdaterMode.GetEnum() == UpdaterMode.Auto ); lVersion.Text = String.Format( lVersion.Text, Updater.CurrentRelease.VersionString, - Updater.WebVersionFullString); + Updater.WebVersionFullString ); tChangeLog.Text = Updater.Changelog; Shown += Download; } - - void Download( object caller, EventArgs args ) { + private void Download( object caller, EventArgs args ) { xShowDetails.Focus(); downloader.DownloadProgressChanged += DownloadProgress; downloader.DownloadFileCompleted += DownloadComplete; - downloader.DownloadFileAsync( new Uri(Updater.UpdaterLocation), updaterFullPath ); + downloader.DownloadFileAsync( new Uri( Updater.UpdaterLocation ), updaterFullPath ); } - - void DownloadProgress( object sender, DownloadProgressChangedEventArgs e ) { - Invoke( (Action)delegate { + private void DownloadProgress( object sender, DownloadProgressChangedEventArgs e ) { + Invoke( ( Action )delegate { progress.Value = e.ProgressPercentage; lProgress.Text = "Downloading (" + e.ProgressPercentage + "%)"; } ); } - - void DownloadComplete( object sender, AsyncCompletedEventArgs e ) { - if( closeFormWhenDownloaded ) { + private void DownloadComplete( object sender, AsyncCompletedEventArgs e ) { + if ( closeFormWhenDownloaded ) { Close(); } else { progress.Value = 100; - if( e.Cancelled || e.Error != null ) { + if ( e.Cancelled || e.Error != null ) { MessageBox.Show( e.Error.ToString(), "Error occured while trying to download " + Paths.UpdaterFileName ); - } else if( autoUpdate ) { + } else if ( autoUpdate ) { bUpdateNow_Click( null, null ); } else { bUpdateNow.Enabled = true; @@ -57,7 +54,6 @@ void DownloadComplete( object sender, AsyncCompletedEventArgs e ) { } } - private void bCancel_Click( object sender, EventArgs e ) { Close(); } @@ -80,7 +76,8 @@ private void bUpdateLater_Click( object sender, EventArgs e ) { } private void UpdateWindow_FormClosing( object sender, FormClosingEventArgs e ) { - if( !downloader.IsBusy ) return; + if ( !downloader.IsBusy ) + return; downloader.CancelAsync(); closeFormWhenDownloaded = true; e.Cancel = true; diff --git a/ServerGUI/app.config b/ServerGUI/app.config index 19fac17..6e2f55a 100644 --- a/ServerGUI/app.config +++ b/ServerGUI/app.config @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/UpdateInstaller/Program.cs b/UpdateInstaller/Program.cs index e4f50de..6065a4b 100644 --- a/UpdateInstaller/Program.cs +++ b/UpdateInstaller/Program.cs @@ -20,73 +20,63 @@ * THE SOFTWARE. * */ + using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; +using System.Linq; using System.Reflection; using System.Threading; -using System.Linq; using System.Xml.Linq; using fCraft.UpdateInstaller.Properties; +namespace fCraft.UpdateInstaller { -namespace fCraft.UpdateInstaller -{ - static class Program - { - const string ConfigFileNameDefault = "config.xml", + internal static class Program { + + private const string ConfigFileNameDefault = "config.xml", BackupFileNameFormat = "800CraftData_{0:yyyyMMdd'_'HH'-'mm'-'ss}_BeforeUpdate.zip"; public const string DataBackupDirectory = "databackups"; - static readonly string[] FilesToBackup = new[]{ + private static readonly string[] FilesToBackup = new[]{ "PlayerDB.txt", "config.xml", "ipbans.txt", "worlds.xml" }; - static readonly string[] LegacyFiles = new[]{ + private static readonly string[] LegacyFiles = new[]{ "fCraftConsole.exe", "fCraftUI.exe", "ConfigTool.exe", "fCraftWinService.exe" }; - - static int Main(string[] args) - { + private static int Main( string[] args ) { string restartTarget = null; string configFileName = ConfigFileNameDefault; // Set path - string defaultPath = Path.GetFullPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); - Directory.SetCurrentDirectory(defaultPath); + string defaultPath = Path.GetFullPath( Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location ) ); + Directory.SetCurrentDirectory( defaultPath ); // Parse command-line arguments List argsList = new List(); - foreach (string arg in args) - { - Console.WriteLine(arg); - if (arg.StartsWith("--path=", StringComparison.OrdinalIgnoreCase)) - { - Directory.SetCurrentDirectory(arg.Substring(arg.IndexOf('=') + 1).TrimQuotes()); - argsList.Add(arg); - } - else if (arg.StartsWith("--config=", StringComparison.OrdinalIgnoreCase)) - { - configFileName = arg.Substring(arg.IndexOf('=') + 1).TrimQuotes(); - argsList.Add(arg); - } - else if (arg.StartsWith("--restart=", StringComparison.OrdinalIgnoreCase)) - { - restartTarget = arg.Substring(arg.IndexOf('=') + 1).TrimQuotes(); - } - else if (arg != "&") - { - argsList.Add(arg); + foreach ( string arg in args ) { + Console.WriteLine( arg ); + if ( arg.StartsWith( "--path=", StringComparison.OrdinalIgnoreCase ) ) { + Directory.SetCurrentDirectory( arg.Substring( arg.IndexOf( '=' ) + 1 ).TrimQuotes() ); + argsList.Add( arg ); + } else if ( arg.StartsWith( "--config=", StringComparison.OrdinalIgnoreCase ) ) { + configFileName = arg.Substring( arg.IndexOf( '=' ) + 1 ).TrimQuotes(); + argsList.Add( arg ); + } else if ( arg.StartsWith( "--restart=", StringComparison.OrdinalIgnoreCase ) ) { + restartTarget = arg.Substring( arg.IndexOf( '=' ) + 1 ).TrimQuotes(); + } else if ( arg != "&" ) { + argsList.Add( arg ); } } @@ -95,218 +85,169 @@ static int Main(string[] args) runAfter = null; bool doBackup = true; - try - { - if (File.Exists(configFileName)) - { - XDocument doc = XDocument.Load(configFileName); - if (doc.Root != null) - { - XElement elRunBefore = doc.Root.Element("RunBeforeUpdate"); - if (elRunBefore != null) runBefore = elRunBefore.Value; - XElement elRunAfter = doc.Root.Element("RunAfterUpdate"); - if (elRunAfter != null) runAfter = elRunAfter.Value; - XElement elDoBackup = doc.Root.Element("BackupBeforeUpdate"); - if (elDoBackup != null && !String.IsNullOrEmpty(elDoBackup.Value)) - { - if (!Boolean.TryParse(elDoBackup.Value, out doBackup)) - { + try { + if ( File.Exists( configFileName ) ) { + XDocument doc = XDocument.Load( configFileName ); + if ( doc.Root != null ) { + XElement elRunBefore = doc.Root.Element( "RunBeforeUpdate" ); + if ( elRunBefore != null ) + runBefore = elRunBefore.Value; + XElement elRunAfter = doc.Root.Element( "RunAfterUpdate" ); + if ( elRunAfter != null ) + runAfter = elRunAfter.Value; + XElement elDoBackup = doc.Root.Element( "BackupBeforeUpdate" ); + if ( elDoBackup != null && !String.IsNullOrEmpty( elDoBackup.Value ) ) { + if ( !Boolean.TryParse( elDoBackup.Value, out doBackup ) ) { doBackup = true; } } } } - } - catch (Exception ex) - { - Console.Error.WriteLine("Error reading fCraft config: {0}", ex); + } catch ( Exception ex ) { + Console.Error.WriteLine( "Error reading fCraft config: {0}", ex ); } // Backup data files (if requested) - if (doBackup) DoBackup(); + if ( doBackup ) + DoBackup(); // Run pre-update script (if any) - if (!String.IsNullOrEmpty(runBefore)) - { - Console.WriteLine("Executing pre-update script..."); - try - { - Process preUpdateProcess = Process.Start(runBefore, ""); - if (preUpdateProcess != null) preUpdateProcess.WaitForExit(); - } - catch (Exception ex) - { - Console.Error.WriteLine("Failed to run pre-update process, aborting update application: {0}", ex); - return (int)ReturnCodes.FailedToRunPreUpdateCommand; + if ( !String.IsNullOrEmpty( runBefore ) ) { + Console.WriteLine( "Executing pre-update script..." ); + try { + Process preUpdateProcess = Process.Start( runBefore, "" ); + if ( preUpdateProcess != null ) + preUpdateProcess.WaitForExit(); + } catch ( Exception ex ) { + Console.Error.WriteLine( "Failed to run pre-update process, aborting update application: {0}", ex ); + return ( int )ReturnCodes.FailedToRunPreUpdateCommand; } } - // Apply the update - using (MemoryStream ms = new MemoryStream(Resources.Payload)) - { - using (ZipStorer zs = ZipStorer.Open(ms, FileAccess.Read)) - { - - var allFiles = zs.ReadCentralDir().Select(entry => entry.FilenameInZip).Union(LegacyFiles); + using ( MemoryStream ms = new MemoryStream( Resources.Payload ) ) { + using ( ZipStorer zs = ZipStorer.Open( ms, FileAccess.Read ) ) { + var allFiles = zs.ReadCentralDir().Select( entry => entry.FilenameInZip ).Union( LegacyFiles ); // ensure that fcraft files are writable bool allPassed; - do - { + do { allPassed = true; - foreach (var fileName in allFiles) - { - try - { - FileInfo fi = new FileInfo(fileName); - if (!fi.Exists) continue; - using (fi.OpenWrite()) { } - - } - catch (Exception ex) - { - if (ex is IOException) - { - Console.WriteLine("Waiting for fCraft-related applications to close..."); - } - else - { - Console.Error.WriteLine("ERROR: could not write to {0}: {1} - {2}", - fileName, ex.GetType().Name, ex.Message); + foreach ( var fileName in allFiles ) { + try { + FileInfo fi = new FileInfo( fileName ); + if ( !fi.Exists ) + continue; + using ( fi.OpenWrite() ) { } + } catch ( Exception ex ) { + if ( ex is IOException ) { + Console.WriteLine( "Waiting for fCraft-related applications to close..." ); + } else { + Console.Error.WriteLine( "ERROR: could not write to {0}: {1} - {2}", + fileName, ex.GetType().Name, ex.Message ); Console.WriteLine(); } allPassed = false; - Thread.Sleep(1000); + Thread.Sleep( 1000 ); break; } } - } while (!allPassed); + } while ( !allPassed ); // delete legacy files - foreach (var legacyFile in LegacyFiles) - { - try - { - File.Delete(legacyFile); - } - catch (Exception ex) - { - Console.Error.WriteLine(" ERROR: {0} {1}", ex.GetType().Name, ex.Message); + foreach ( var legacyFile in LegacyFiles ) { + try { + File.Delete( legacyFile ); + } catch ( Exception ex ) { + Console.Error.WriteLine( " ERROR: {0} {1}", ex.GetType().Name, ex.Message ); } } // extract files - foreach (var entry in zs.ReadCentralDir()) - { - Console.WriteLine("Extracting {0}", entry.FilenameInZip); - try - { - using (FileStream fs = File.Create(entry.FilenameInZip)) - { - zs.ExtractFile(entry, fs); + foreach ( var entry in zs.ReadCentralDir() ) { + Console.WriteLine( "Extracting {0}", entry.FilenameInZip ); + try { + using ( FileStream fs = File.Create( entry.FilenameInZip ) ) { + zs.ExtractFile( entry, fs ); } - } - catch (Exception ex) - { - Console.Error.WriteLine(" ERROR: {0} {1}", ex.GetType().Name, ex.Message); + } catch ( Exception ex ) { + Console.Error.WriteLine( " ERROR: {0} {1}", ex.GetType().Name, ex.Message ); } } } } // Run post-update script - if (!String.IsNullOrEmpty(runAfter)) - { - Console.WriteLine("Executing post-update script..."); - try - { - Process postUpdateProcess = Process.Start(runAfter, ""); - if (postUpdateProcess != null) postUpdateProcess.WaitForExit(); - } - catch (Exception ex) - { - Console.Error.WriteLine("Failed to run post-update process, aborting restart: {0}", ex); - return (int)ReturnCodes.FailedToRunPostUpdateCommand; + if ( !String.IsNullOrEmpty( runAfter ) ) { + Console.WriteLine( "Executing post-update script..." ); + try { + Process postUpdateProcess = Process.Start( runAfter, "" ); + if ( postUpdateProcess != null ) + postUpdateProcess.WaitForExit(); + } catch ( Exception ex ) { + Console.Error.WriteLine( "Failed to run post-update process, aborting restart: {0}", ex ); + return ( int )ReturnCodes.FailedToRunPostUpdateCommand; } } - Console.WriteLine("fCraft update complete."); + Console.WriteLine( "fCraft update complete." ); // Restart fCraft (if requested) - if (restartTarget != null) - { - if (restartTarget == "fCraftConsole.exe") - { + if ( restartTarget != null ) { + if ( restartTarget == "fCraftConsole.exe" ) { restartTarget = "ServerCLI.exe"; - } - else if (restartTarget == "fCraftUI.exe") - { + } else if ( restartTarget == "fCraftUI.exe" ) { restartTarget = "ServerGUI.exe"; } - if (!File.Exists(restartTarget)) - { - Console.Error.WriteLine("Restart target not found, quitting: {0}", restartTarget); - return (int)ReturnCodes.RestartTargetNotFound; + if ( !File.Exists( restartTarget ) ) { + Console.Error.WriteLine( "Restart target not found, quitting: {0}", restartTarget ); + return ( int )ReturnCodes.RestartTargetNotFound; } - string argString = String.Join(" ", argsList.ToArray()); - Console.WriteLine("Starting: {0} {1}", restartTarget, argString); - switch (Environment.OSVersion.Platform) - { + string argString = String.Join( " ", argsList.ToArray() ); + Console.WriteLine( "Starting: {0} {1}", restartTarget, argString ); + switch ( Environment.OSVersion.Platform ) { case PlatformID.MacOSX: case PlatformID.Unix: - Process.Start("mono", "\"" + restartTarget + "\" " + argString + " &"); + Process.Start( "mono", "\"" + restartTarget + "\" " + argString + " &" ); break; + default: - Process.Start(restartTarget, argString); + Process.Start( restartTarget, argString ); break; } } - return (int)ReturnCodes.Ok; + return ( int )ReturnCodes.Ok; } - - static void DoBackup() - { - if (!Directory.Exists(DataBackupDirectory)) - { - Directory.CreateDirectory(DataBackupDirectory); + private static void DoBackup() { + if ( !Directory.Exists( DataBackupDirectory ) ) { + Directory.CreateDirectory( DataBackupDirectory ); } - string backupFileName = String.Format(BackupFileNameFormat, DateTime.Now); // localized - backupFileName = Path.Combine(DataBackupDirectory, backupFileName); - using (FileStream fs = File.Create(backupFileName)) - { - using (ZipStorer backupZip = ZipStorer.Create(fs, "")) - { - foreach (string dataFileName in FilesToBackup) - { - if (File.Exists(dataFileName)) - { - backupZip.AddFile(ZipStorer.Compression.Deflate, dataFileName, dataFileName, ""); + string backupFileName = String.Format( BackupFileNameFormat, DateTime.Now ); // localized + backupFileName = Path.Combine( DataBackupDirectory, backupFileName ); + using ( FileStream fs = File.Create( backupFileName ) ) { + using ( ZipStorer backupZip = ZipStorer.Create( fs, "" ) ) { + foreach ( string dataFileName in FilesToBackup ) { + if ( File.Exists( dataFileName ) ) { + backupZip.AddFile( ZipStorer.Compression.Deflate, dataFileName, dataFileName, "" ); } } } } } - - static string TrimQuotes(this string str) - { - if (str.StartsWith("\"") && str.EndsWith("\"")) - { - return str.Substring(1, str.Length - 2); - } - else - { + private static string TrimQuotes( this string str ) { + if ( str.StartsWith( "\"" ) && str.EndsWith( "\"" ) ) { + return str.Substring( 1, str.Length - 2 ); + } else { return str; } } } - enum ReturnCodes - { + internal enum ReturnCodes { Ok = 0, FailedToRunPreUpdateCommand = 1, FailedToRunPostUpdateCommand = 2, diff --git a/UpdateInstaller/Properties/AssemblyInfo.cs b/UpdateInstaller/Properties/AssemblyInfo.cs index 5e92e80..9728bd0 100644 --- a/UpdateInstaller/Properties/AssemblyInfo.cs +++ b/UpdateInstaller/Properties/AssemblyInfo.cs @@ -1,20 +1,20 @@ using System.Reflection; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("800Craft UpdateInstaller")] -[assembly: AssemblyDescription("800Craft self-extracting updater")] +[assembly: AssemblyTitle( "800Craft UpdateInstaller" )] +[assembly: AssemblyDescription( "800Craft self-extracting updater" )] [assembly: AssemblyConfiguration( "" )] -[assembly: AssemblyCompany("au70.net")] -[assembly: AssemblyProduct("800Craft UpdateInstaller")] -[assembly: AssemblyCopyright("")] +[assembly: AssemblyCompany( "au70.net" )] +[assembly: AssemblyProduct( "800Craft UpdateInstaller" )] +[assembly: AssemblyCopyright( "" )] [assembly: AssemblyTrademark( "" )] [assembly: AssemblyCulture( "" )] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible( false )] @@ -24,11 +24,11 @@ // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -// You can specify all the values or you can default the Build and Revision Numbers +// You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion( "0.6.1.7" )] diff --git a/UpdateInstaller/ZipStorer.cs b/UpdateInstaller/ZipStorer.cs index c191988..6c5f530 100644 --- a/UpdateInstaller/ZipStorer.cs +++ b/UpdateInstaller/ZipStorer.cs @@ -5,14 +5,18 @@ using System.Text; namespace System.IO.Compression { + /// /// Unique class for compression/decompression file. Represents a Zip file. /// public sealed class ZipStorer : IDisposable { + /// Compression method enumeration. public enum Compression : ushort { - /// Uncompressed storage + + /// Uncompressed storage Store = 0, + /// Deflate compression method Deflate = 8 } @@ -21,26 +25,37 @@ public enum Compression : ushort { /// Represents an entry in Zip file directory /// public struct ZipFileEntry { + /// Compression method public Compression Method; + /// Full path and filename as stored in Zip public string FilenameInZip; + /// Original file size public uint FileSize; + /// Compressed file size public uint CompressedSize; + /// Offset of header information inside Zip storage public uint HeaderOffset; + /// Offset of file inside Zip storage public uint FileOffset; + /// Size of header information public uint HeaderSize; + /// 32-bit checksum of entire file public uint Crc32; + /// Last modification time of file public DateTime ModifyTime; + /// User comment for file public string Comment; + /// True if UTF8 encoding for filename and comments, false if default (CP 437) public bool EncodeUTF8; @@ -52,42 +67,56 @@ public override string ToString() { } #region Public fields + /// True if UTF8 encoding for filename and comments, false if default (CP 437) public bool EncodeUTF8; + /// Force deflate algotithm even if it inflates the stored file. Off by default. public bool ForceDeflating; - #endregion + + #endregion Public fields #region Private fields + // List of files to store private readonly List files = new List(); + // Filename of storage file private string fileName; + // Stream object of storage file private Stream zipFileStream; + // General comment private string comment = ""; + // Central dir image private byte[] centralDirImage; + // Existing files in zip private ushort existingFiles; + // File access for Open method private FileAccess access; + // Static CRC32 Table private readonly static UInt32[] CrcTable; + // Default filename encoder private readonly static Encoding DefaultEncoding = Encoding.GetEncoding( 437 ); - #endregion + + #endregion Private fields #region Public methods + // Static constructor. Just invoked once in order to create the CRC32 lookup table. static ZipStorer() { // Generate CRC32 table CrcTable = new UInt32[256]; - for( int i = 0; i < CrcTable.Length; i++ ) { - UInt32 c = (UInt32)i; - for( int j = 0; j < 8; j++ ) { - if( ( c & 1 ) != 0 ) + for ( int i = 0; i < CrcTable.Length; i++ ) { + UInt32 c = ( UInt32 )i; + for ( int j = 0; j < 8; j++ ) { + if ( ( c & 1 ) != 0 ) c = 3988292384 ^ ( c >> 1 ); else c >>= 1; @@ -95,6 +124,7 @@ static ZipStorer() { CrcTable[i] = c; } } + /// /// Method to create a new storage file /// @@ -110,6 +140,7 @@ public static ZipStorer Create( string filename, string fileComment ) { return zip; } + /// /// Method to create a new zip storage in a stream /// @@ -122,7 +153,6 @@ public static ZipStorer Create( Stream stream, string fileComment ) { return zip; } - /// /// Method to open an existing storage file /// @@ -137,6 +167,7 @@ public static ZipStorer Open( string filename, FileAccess fileAccess ) { return zip; } + /// /// Method to open an existing storage from stream /// @@ -144,31 +175,33 @@ public static ZipStorer Open( string filename, FileAccess fileAccess ) { /// File access mode for stream operations /// A valid ZipStorer object public static ZipStorer Open( Stream stream, FileAccess fileFileAccess ) { - if( !stream.CanSeek && fileFileAccess != FileAccess.Read ) + if ( !stream.CanSeek && fileFileAccess != FileAccess.Read ) throw new InvalidOperationException( "Stream cannot seek" ); ZipStorer zip = new ZipStorer { zipFileStream = stream, access = fileFileAccess }; - if( zip.ReadFileInfo() ) + if ( zip.ReadFileInfo() ) return zip; throw new InvalidDataException(); } + /// /// Add full contents of a file into the Zip storage /// /// Compression method /// Full path of file to add to Zip storage /// Filename and path as desired in Zip directory - /// Comment for stored file + /// Comment for stored file public void AddFile( Compression method, string pathname, string filenameInZip, string fileComment ) { - if( access == FileAccess.Read ) + if ( access == FileAccess.Read ) throw new InvalidOperationException( "Writing is not alowed" ); FileStream stream = new FileStream( pathname, FileMode.Open, FileAccess.Read ); AddStream( method, filenameInZip, stream, File.GetLastWriteTime( pathname ), fileComment ); stream.Close(); } + /// /// Add full contents of a stream into the Zip storage /// @@ -178,7 +211,7 @@ public void AddFile( Compression method, string pathname, string filenameInZip, /// Modification time of the data to store /// Comment for stored file public void AddStream( Compression method, string filenameInZip, Stream source, DateTime modTime, string fileComment ) { - if( access == FileAccess.Read ) + if ( access == FileAccess.Read ) throw new InvalidOperationException( "Writing is not alowed" ); /*long offset; @@ -196,7 +229,7 @@ public void AddStream( Compression method, string filenameInZip, Stream source, FilenameInZip = NormalizedFilename( filenameInZip ), Comment = ( fileComment ?? "" ), Crc32 = 0, - HeaderOffset = (uint)zipFileStream.Position, + HeaderOffset = ( uint )zipFileStream.Position, ModifyTime = modTime }; @@ -204,7 +237,7 @@ public void AddStream( Compression method, string filenameInZip, Stream source, // Write local header WriteLocalHeader( ref zfe ); - zfe.FileOffset = (uint)zipFileStream.Position; + zfe.FileOffset = ( uint )zipFileStream.Position; // Write file to zip (store) Store( ref zfe, source ); @@ -214,49 +247,52 @@ public void AddStream( Compression method, string filenameInZip, Stream source, files.Add( zfe ); } + /// /// Updates central directory (if pertinent) and close the Zip storage /// /// This is a required step, unless automatic dispose is used public void Close() { - if( access != FileAccess.Read ) { - uint centralOffset = (uint)zipFileStream.Position; + if ( access != FileAccess.Read ) { + uint centralOffset = ( uint )zipFileStream.Position; uint centralSize = 0; - if( centralDirImage != null ) + if ( centralDirImage != null ) zipFileStream.Write( centralDirImage, 0, centralDirImage.Length ); - for( int i = 0; i < files.Count; i++ ) { + for ( int i = 0; i < files.Count; i++ ) { long pos = zipFileStream.Position; WriteCentralDirRecord( files[i] ); - centralSize += (uint)( zipFileStream.Position - pos ); + centralSize += ( uint )( zipFileStream.Position - pos ); } - if( centralDirImage != null ) - WriteEndRecord( centralSize + (uint)centralDirImage.Length, centralOffset ); + if ( centralDirImage != null ) + WriteEndRecord( centralSize + ( uint )centralDirImage.Length, centralOffset ); else WriteEndRecord( centralSize, centralOffset ); } - if( zipFileStream == null ) return; + if ( zipFileStream == null ) + return; zipFileStream.Flush(); zipFileStream.Dispose(); zipFileStream = null; } + /// - /// Read all the file records in the central directory + /// Read all the file records in the central directory /// /// List of all entries in directory public List ReadCentralDir() { - if( centralDirImage == null ) + if ( centralDirImage == null ) throw new InvalidOperationException( "Central directory currently does not exist" ); List result = new List(); - for( int pointer = 0; pointer < centralDirImage.Length; ) { + for ( int pointer = 0; pointer < centralDirImage.Length; ) { uint signature = BitConverter.ToUInt32( centralDirImage, pointer ); - if( signature != 0x02014b50 ) + if ( signature != 0x02014b50 ) break; bool encodeUTF8 = ( BitConverter.ToUInt16( centralDirImage, pointer + 8 ) & 0x0800 ) != 0; @@ -269,12 +305,12 @@ public List ReadCentralDir() { ushort extraSize = BitConverter.ToUInt16( centralDirImage, pointer + 30 ); ushort commentSize = BitConverter.ToUInt16( centralDirImage, pointer + 32 ); uint headerOffset = BitConverter.ToUInt32( centralDirImage, pointer + 42 ); - uint headerSize = (uint)( 46 + filenameSize + extraSize + commentSize ); + uint headerSize = ( uint )( 46 + filenameSize + extraSize + commentSize ); Encoding encoder = encodeUTF8 ? Encoding.UTF8 : DefaultEncoding; ZipFileEntry zfe = new ZipFileEntry { - Method = (Compression)method, + Method = ( Compression )method, FilenameInZip = encoder.GetString( centralDirImage, pointer + 46, filenameSize ), @@ -286,7 +322,7 @@ public List ReadCentralDir() { Crc32 = crc32, ModifyTime = DosTimeToDateTime( modifyTime ) }; - if( commentSize > 0 ) + if ( commentSize > 0 ) zfe.Comment = encoder.GetString( centralDirImage, pointer + 46 + filenameSize + extraSize, commentSize ); result.Add( zfe ); @@ -295,6 +331,7 @@ public List ReadCentralDir() { return result; } + /// /// Copy the contents of a stored file into a physical file /// @@ -306,15 +343,15 @@ public bool ExtractFile( ZipFileEntry zfe, string filename ) { // Make sure the parent directory exist string path = Path.GetDirectoryName( filename ); - if( !Directory.Exists( path ) ) + if ( !Directory.Exists( path ) ) Directory.CreateDirectory( path ); // Check it is directory. If so, do nothing - if( Directory.Exists( filename ) ) + if ( Directory.Exists( filename ) ) return true; Stream output = new FileStream( filename, FileMode.Create, FileAccess.Write ); bool result = ExtractFile( zfe, output ); - if( result ) + if ( result ) output.Close(); File.SetCreationTime( filename, zfe.ModifyTime ); @@ -322,6 +359,7 @@ public bool ExtractFile( ZipFileEntry zfe, string filename ) { return result; } + /// /// Copy the contents of a stored file into an opened stream /// @@ -330,21 +368,21 @@ public bool ExtractFile( ZipFileEntry zfe, string filename ) { /// True if success, false if not. /// Unique compression methods are Store and Deflate public bool ExtractFile( ZipFileEntry zfe, Stream stream ) { - if( !stream.CanWrite ) + if ( !stream.CanWrite ) throw new InvalidOperationException( "Stream cannot be written" ); // check signature byte[] signature = new byte[4]; zipFileStream.Seek( zfe.HeaderOffset, SeekOrigin.Begin ); zipFileStream.Read( signature, 0, 4 ); - if( BitConverter.ToUInt32( signature, 0 ) != 0x04034b50 ) + if ( BitConverter.ToUInt32( signature, 0 ) != 0x04034b50 ) return false; // Select input stream for inflating or just reading Stream inStream; - if( zfe.Method == Compression.Store ) { + if ( zfe.Method == Compression.Store ) { inStream = zipFileStream; - } else if( zfe.Method == Compression.Deflate ) { + } else if ( zfe.Method == Compression.Deflate ) { inStream = new DeflateStream( zipFileStream, CompressionMode.Decompress, true ); } else { return false; @@ -354,17 +392,18 @@ public bool ExtractFile( ZipFileEntry zfe, Stream stream ) { byte[] buffer = new byte[16384]; zipFileStream.Seek( zfe.FileOffset, SeekOrigin.Begin ); uint bytesPending = zfe.FileSize; - while( bytesPending > 0 ) { - int bytesRead = inStream.Read( buffer, 0, (int)Math.Min( bytesPending, buffer.Length ) ); + while ( bytesPending > 0 ) { + int bytesRead = inStream.Read( buffer, 0, ( int )Math.Min( bytesPending, buffer.Length ) ); stream.Write( buffer, 0, bytesRead ); - bytesPending -= (uint)bytesRead; + bytesPending -= ( uint )bytesRead; } stream.Flush(); - if( zfe.Method == Compression.Deflate ) + if ( zfe.Method == Compression.Deflate ) inStream.Dispose(); return true; } + /// /// Removes one of many files in storage. It creates a new Zip file. /// @@ -373,10 +412,9 @@ public bool ExtractFile( ZipFileEntry zfe, Stream stream ) { /// True if success, false if not /// This method only works for storage of type FileStream public static bool RemoveEntries( ref ZipStorer zip, List zfes ) { - if( !( zip.zipFileStream is FileStream ) ) + if ( !( zip.zipFileStream is FileStream ) ) throw new InvalidOperationException( "RemoveEntries is allowed just over streams of type FileStream" ); - //Get full list of entries List fullList = zip.ReadCentralDir(); @@ -387,9 +425,9 @@ public static bool RemoveEntries( ref ZipStorer zip, List zfes ) { try { ZipStorer tempZip = Create( tempZipName, string.Empty ); - foreach( ZipFileEntry zfe in fullList ) { - if( !zfes.Contains( zfe ) ) { - if( zip.ExtractFile( zfe, tempEntryName ) ) { + foreach ( ZipFileEntry zfe in fullList ) { + if ( !zfes.Contains( zfe ) ) { + if ( zip.ExtractFile( zfe, tempEntryName ) ) { tempZip.AddFile( zfe.Method, tempEntryName, zfe.FilenameInZip, zfe.Comment ); } } @@ -397,7 +435,7 @@ public static bool RemoveEntries( ref ZipStorer zip, List zfes ) { zip.Close(); tempZip.Close(); - if( File.Exists( zip.fileName ) ) { + if ( File.Exists( zip.fileName ) ) { File.Replace( tempZipName, zip.fileName, null, true ); } else { File.Move( tempZipName, zip.fileName ); @@ -407,16 +445,18 @@ public static bool RemoveEntries( ref ZipStorer zip, List zfes ) { } catch { return false; } finally { - if( File.Exists( tempZipName ) ) + if ( File.Exists( tempZipName ) ) File.Delete( tempZipName ); - if( File.Exists( tempEntryName ) ) + if ( File.Exists( tempEntryName ) ) File.Delete( tempEntryName ); } return true; } - #endregion + + #endregion Public methods #region Private methods + // Calculate the file offset by reading the corresponding local header private uint GetFileOffset( uint headerOffset ) { byte[] buffer = new byte[2]; @@ -427,8 +467,9 @@ private uint GetFileOffset( uint headerOffset ) { zipFileStream.Read( buffer, 0, 2 ); ushort extraSize = BitConverter.ToUInt16( buffer, 0 ); - return (uint)( 30 + filenameSize + extraSize + headerOffset ); + return ( uint )( 30 + filenameSize + extraSize + headerOffset ); } + /* Local file header: local file header signature 4 bytes (0x04034b50) version needed to extract 2 bytes @@ -445,22 +486,24 @@ extra field length 2 bytes filename (variable size) extra field (variable size) */ + private void WriteLocalHeader( ref ZipFileEntry zfe ) { long pos = zipFileStream.Position; Encoding encoder = zfe.EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding; byte[] encodedFilename = encoder.GetBytes( zfe.FilenameInZip ); zipFileStream.Write( new byte[] { 80, 75, 3, 4, 20, 0 }, 0, 6 ); // No extra header - zipFileStream.Write( BitConverter.GetBytes( (ushort)( zfe.EncodeUTF8 ? 0x0800 : 0 ) ), 0, 2 ); // filename and comment encoding - zipFileStream.Write( BitConverter.GetBytes( (ushort)zfe.Method ), 0, 2 ); // zipping method + zipFileStream.Write( BitConverter.GetBytes( ( ushort )( zfe.EncodeUTF8 ? 0x0800 : 0 ) ), 0, 2 ); // filename and comment encoding + zipFileStream.Write( BitConverter.GetBytes( ( ushort )zfe.Method ), 0, 2 ); // zipping method zipFileStream.Write( BitConverter.GetBytes( DateTimeToDosTime( zfe.ModifyTime ) ), 0, 4 ); // zipping date and time zipFileStream.Write( new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 12 ); // unused CRC, un/compressed size, updated later - zipFileStream.Write( BitConverter.GetBytes( (ushort)encodedFilename.Length ), 0, 2 ); // filename length - zipFileStream.Write( BitConverter.GetBytes( (ushort)0 ), 0, 2 ); // extra length + zipFileStream.Write( BitConverter.GetBytes( ( ushort )encodedFilename.Length ), 0, 2 ); // filename length + zipFileStream.Write( BitConverter.GetBytes( ( ushort )0 ), 0, 2 ); // extra length zipFileStream.Write( encodedFilename, 0, encodedFilename.Length ); - zfe.HeaderSize = (uint)( zipFileStream.Position - pos ); + zfe.HeaderSize = ( uint )( zipFileStream.Position - pos ); } + /* Central directory's File header: central file header signature 4 bytes (0x02014b50) version made by 2 bytes @@ -484,31 +527,33 @@ relative offset of local header 4 bytes extra field (variable size) file comment (variable size) */ + private void WriteCentralDirRecord( ZipFileEntry zfe ) { Encoding encoder = zfe.EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding; byte[] encodedFilename = encoder.GetBytes( zfe.FilenameInZip ); byte[] encodedComment = encoder.GetBytes( zfe.Comment ); zipFileStream.Write( new byte[] { 80, 75, 1, 2, 23, 0xB, 20, 0 }, 0, 8 ); - zipFileStream.Write( BitConverter.GetBytes( (ushort)( zfe.EncodeUTF8 ? 0x0800 : 0 ) ), 0, 2 ); // filename and comment encoding - zipFileStream.Write( BitConverter.GetBytes( (ushort)zfe.Method ), 0, 2 ); // zipping method + zipFileStream.Write( BitConverter.GetBytes( ( ushort )( zfe.EncodeUTF8 ? 0x0800 : 0 ) ), 0, 2 ); // filename and comment encoding + zipFileStream.Write( BitConverter.GetBytes( ( ushort )zfe.Method ), 0, 2 ); // zipping method zipFileStream.Write( BitConverter.GetBytes( DateTimeToDosTime( zfe.ModifyTime ) ), 0, 4 ); // zipping date and time zipFileStream.Write( BitConverter.GetBytes( zfe.Crc32 ), 0, 4 ); // file CRC zipFileStream.Write( BitConverter.GetBytes( zfe.CompressedSize ), 0, 4 ); // compressed file size zipFileStream.Write( BitConverter.GetBytes( zfe.FileSize ), 0, 4 ); // uncompressed file size - zipFileStream.Write( BitConverter.GetBytes( (ushort)encodedFilename.Length ), 0, 2 ); // Filename in zip - zipFileStream.Write( BitConverter.GetBytes( (ushort)0 ), 0, 2 ); // extra length - zipFileStream.Write( BitConverter.GetBytes( (ushort)encodedComment.Length ), 0, 2 ); - - zipFileStream.Write( BitConverter.GetBytes( (ushort)0 ), 0, 2 ); // disk=0 - zipFileStream.Write( BitConverter.GetBytes( (ushort)0 ), 0, 2 ); // file type: binary - zipFileStream.Write( BitConverter.GetBytes( (ushort)0 ), 0, 2 ); // Internal file attributes - zipFileStream.Write( BitConverter.GetBytes( (ushort)0x8100 ), 0, 2 ); // External file attributes (normal/readable) + zipFileStream.Write( BitConverter.GetBytes( ( ushort )encodedFilename.Length ), 0, 2 ); // Filename in zip + zipFileStream.Write( BitConverter.GetBytes( ( ushort )0 ), 0, 2 ); // extra length + zipFileStream.Write( BitConverter.GetBytes( ( ushort )encodedComment.Length ), 0, 2 ); + + zipFileStream.Write( BitConverter.GetBytes( ( ushort )0 ), 0, 2 ); // disk=0 + zipFileStream.Write( BitConverter.GetBytes( ( ushort )0 ), 0, 2 ); // file type: binary + zipFileStream.Write( BitConverter.GetBytes( ( ushort )0 ), 0, 2 ); // Internal file attributes + zipFileStream.Write( BitConverter.GetBytes( ( ushort )0x8100 ), 0, 2 ); // External file attributes (normal/readable) zipFileStream.Write( BitConverter.GetBytes( zfe.HeaderOffset ), 0, 4 ); // Offset of header zipFileStream.Write( encodedFilename, 0, encodedFilename.Length ); zipFileStream.Write( encodedComment, 0, encodedComment.Length ); } + /* End of central dir record: end of central dir signature 4 bytes (0x06054b50) number of this disk 2 bytes @@ -525,18 +570,20 @@ the starting disk number 4 bytes zipfile comment length 2 bytes zipfile comment (variable size) */ + private void WriteEndRecord( uint size, uint offset ) { Encoding encoder = EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding; byte[] encodedComment = encoder.GetBytes( comment ); zipFileStream.Write( new byte[] { 80, 75, 5, 6, 0, 0, 0, 0 }, 0, 8 ); - zipFileStream.Write( BitConverter.GetBytes( (ushort)files.Count + existingFiles ), 0, 2 ); - zipFileStream.Write( BitConverter.GetBytes( (ushort)files.Count + existingFiles ), 0, 2 ); + zipFileStream.Write( BitConverter.GetBytes( ( ushort )files.Count + existingFiles ), 0, 2 ); + zipFileStream.Write( BitConverter.GetBytes( ( ushort )files.Count + existingFiles ), 0, 2 ); zipFileStream.Write( BitConverter.GetBytes( size ), 0, 4 ); zipFileStream.Write( BitConverter.GetBytes( offset ), 0, 4 ); - zipFileStream.Write( BitConverter.GetBytes( (ushort)encodedComment.Length ), 0, 2 ); + zipFileStream.Write( BitConverter.GetBytes( ( ushort )encodedComment.Length ), 0, 2 ); zipFileStream.Write( encodedComment, 0, encodedComment.Length ); } + // Copies all source file into storage file private void Store( ref ZipFileEntry zfe, Stream source ) { byte[] buffer = new byte[16384]; @@ -547,7 +594,7 @@ private void Store( ref ZipFileEntry zfe, Stream source ) { long posStart = zipFileStream.Position; long sourceStart = source.Position; - if( zfe.Method == Compression.Store ) + if ( zfe.Method == Compression.Store ) outStream = zipFileStream; else outStream = new DeflateStream( zipFileStream, CompressionMode.Compress, true ); @@ -556,28 +603,28 @@ private void Store( ref ZipFileEntry zfe, Stream source ) { do { bytesRead = source.Read( buffer, 0, buffer.Length ); - totalRead += (uint)bytesRead; - if( bytesRead > 0 ) { + totalRead += ( uint )bytesRead; + if ( bytesRead > 0 ) { outStream.Write( buffer, 0, bytesRead ); - for( uint i = 0; i < bytesRead; i++ ) { + for ( uint i = 0; i < bytesRead; i++ ) { zfe.Crc32 = CrcTable[( zfe.Crc32 ^ buffer[i] ) & 0xFF] ^ ( zfe.Crc32 >> 8 ); } } - } while( bytesRead == buffer.Length ); + } while ( bytesRead == buffer.Length ); - if( totalRead > 0 ) + if ( totalRead > 0 ) outStream.Flush(); // fix for "Internal error Flush" under Mono - if( zfe.Method == Compression.Deflate ) + if ( zfe.Method == Compression.Deflate ) outStream.Dispose(); zfe.Crc32 ^= 0xffffffff; zfe.FileSize = totalRead; - zfe.CompressedSize = (uint)( zipFileStream.Position - posStart ); + zfe.CompressedSize = ( uint )( zipFileStream.Position - posStart ); // Verify for real compression - if( zfe.Method == Compression.Deflate && !ForceDeflating && source.CanSeek && zfe.CompressedSize > zfe.FileSize ) { + if ( zfe.Method == Compression.Deflate && !ForceDeflating && source.CanSeek && zfe.CompressedSize > zfe.FileSize ) { // Start operation again with Store algorithm zfe.Method = Compression.Store; zipFileStream.Position = posStart; @@ -586,33 +633,36 @@ private void Store( ref ZipFileEntry zfe, Stream source ) { Store( ref zfe, source ); } } + /* DOS Date and time: - MS-DOS date. The date is a packed value with the following format. Bits Description - 0-4 Day of the month (1–31) - 5-8 Month (1 = January, 2 = February, and so on) - 9-15 Year offset from 1980 (add 1980 to get actual year) - MS-DOS time. The time is a packed value with the following format. Bits Description - 0-4 Second divided by 2 - 5-10 Minute (0–59) - 11-15 Hour (0–23 on a 24-hour clock) + MS-DOS date. The date is a packed value with the following format. Bits Description + 0-4 Day of the month (1–31) + 5-8 Month (1 = January, 2 = February, and so on) + 9-15 Year offset from 1980 (add 1980 to get actual year) + MS-DOS time. The time is a packed value with the following format. Bits Description + 0-4 Second divided by 2 + 5-10 Minute (0–59) + 11-15 Hour (0–23 on a 24-hour clock) */ + private static uint DateTimeToDosTime( DateTime dt ) { - return (uint)( + return ( uint )( ( dt.Second / 2 ) | ( dt.Minute << 5 ) | ( dt.Hour << 11 ) | ( dt.Day << 16 ) | ( dt.Month << 21 ) | ( ( dt.Year - 1980 ) << 25 ) ); } + private static DateTime DosTimeToDateTime( uint dt ) { return new DateTime( - (int)( dt >> 25 ) + 1980, - (int)( dt >> 21 ) & 15, - (int)( dt >> 16 ) & 31, - (int)( dt >> 11 ) & 31, - (int)( dt >> 5 ) & 63, - (int)( dt & 31 ) * 2 ); + ( int )( dt >> 25 ) + 1980, + ( int )( dt >> 21 ) & 15, + ( int )( dt >> 16 ) & 31, + ( int )( dt >> 11 ) & 31, + ( int )( dt >> 5 ) & 63, + ( int )( dt & 31 ) * 2 ); } /* CRC32 algorithm - The 'magic number' for the CRC is 0xdebb20e3. + The 'magic number' for the CRC is 0xdebb20e3. The proper CRC pre and post conditioning is used, meaning that the CRC register is pre-conditioned with all ones (a starting value @@ -623,11 +673,12 @@ field is set to zero in the local header and the correct value is put in the data descriptor and in the central directory. */ + private void UpdateCrcAndSizes( ref ZipFileEntry zfe ) { long lastPos = zipFileStream.Position; // remember position zipFileStream.Position = zfe.HeaderOffset + 8; - zipFileStream.Write( BitConverter.GetBytes( (ushort)zfe.Method ), 0, 2 ); // zipping method + zipFileStream.Write( BitConverter.GetBytes( ( ushort )zfe.Method ), 0, 2 ); // zipping method zipFileStream.Position = zfe.HeaderOffset + 14; zipFileStream.Write( BitConverter.GetBytes( zfe.Crc32 ), 0, 4 ); // Update CRC @@ -636,19 +687,21 @@ private void UpdateCrcAndSizes( ref ZipFileEntry zfe ) { zipFileStream.Position = lastPos; // restore position } + // Replaces backslashes with slashes to store in zip header private static string NormalizedFilename( string filename ) { string normalizedFilename = filename.Replace( '\\', '/' ); int pos = normalizedFilename.IndexOf( ':' ); - if( pos >= 0 ) + if ( pos >= 0 ) normalizedFilename = normalizedFilename.Remove( 0, pos + 1 ); return normalizedFilename.Trim( '/' ); } + // Reads the end-of-central-directory record private bool ReadFileInfo() { - if( zipFileStream.Length < 22 ) + if ( zipFileStream.Length < 22 ) return false; try { @@ -657,7 +710,8 @@ private bool ReadFileInfo() { do { zipFileStream.Seek( -5, SeekOrigin.Current ); UInt32 sig = br.ReadUInt32(); - if( sig != 0x06054b50 ) continue; + if ( sig != 0x06054b50 ) + continue; zipFileStream.Seek( 6, SeekOrigin.Current ); @@ -667,7 +721,7 @@ private bool ReadFileInfo() { UInt16 commentSize = br.ReadUInt16(); // check if comment field is the very last data in file - if( zipFileStream.Position + commentSize != zipFileStream.Length ) + if ( zipFileStream.Position + commentSize != zipFileStream.Length ) return false; // Copy entire central directory to a memory buffer @@ -679,20 +733,23 @@ private bool ReadFileInfo() { // Leave the pointer at the begining of central dir, to append new files zipFileStream.Seek( centralDirOffset, SeekOrigin.Begin ); return true; - } while( zipFileStream.Position > 0 ); + } while ( zipFileStream.Position > 0 ); } catch { } return false; } - #endregion + + #endregion Private methods #region IDisposable Members + /// /// Closes the Zip file stream /// public void Dispose() { Close(); } - #endregion + + #endregion IDisposable Members } } \ No newline at end of file diff --git a/UpdateInstaller/app.config b/UpdateInstaller/app.config index 19fac17..6e2f55a 100644 --- a/UpdateInstaller/app.config +++ b/UpdateInstaller/app.config @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/UpdaterBuilder/Program.cs b/UpdaterBuilder/Program.cs index 93d15e9..31d5318 100644 --- a/UpdaterBuilder/Program.cs +++ b/UpdaterBuilder/Program.cs @@ -1,12 +1,11 @@ using System.IO; using System.IO.Compression; -namespace fCraft.UpdateBuilder -{ - static class Program - { +namespace fCraft.UpdateBuilder { - static readonly string[] FileList = { + internal static class Program { + + private static readonly string[] FileList = { "ConfigGUI.exe", "fCraft.dll", "fCraftGUI.dll", @@ -18,27 +17,21 @@ static class Program "../../README.txt" }; - const string BinariesFileName = "../../UpdateInstaller/Resources/Payload.zip"; - + private const string BinariesFileName = "../../UpdateInstaller/Resources/Payload.zip"; - static void Main() - { - FileInfo binaries = new FileInfo(BinariesFileName); - if (binaries.Exists) - { + private static void Main() { + FileInfo binaries = new FileInfo( BinariesFileName ); + if ( binaries.Exists ) { binaries.Delete(); } - using (ZipStorer zs = ZipStorer.Create(binaries.FullName, "")) - { - foreach (string file in FileList) - { - FileInfo fi = new FileInfo(file); - if (!fi.Exists) - { + using ( ZipStorer zs = ZipStorer.Create( binaries.FullName, "" ) ) { + foreach ( string file in FileList ) { + FileInfo fi = new FileInfo( file ); + if ( !fi.Exists ) { return; // abort if any of the files do not exist } - zs.AddFile(ZipStorer.Compression.Deflate, fi.FullName, fi.Name, ""); + zs.AddFile( ZipStorer.Compression.Deflate, fi.FullName, fi.Name, "" ); } } } diff --git a/UpdaterBuilder/Properties/AssemblyInfo.cs b/UpdaterBuilder/Properties/AssemblyInfo.cs index d8e9f33..80de189 100644 --- a/UpdaterBuilder/Properties/AssemblyInfo.cs +++ b/UpdaterBuilder/Properties/AssemblyInfo.cs @@ -1,20 +1,20 @@ using System.Reflection; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("800Craft UpdateBuilder")] -[assembly: AssemblyDescription("Tool for automating the process of building 800Craft update binaries.")] +[assembly: AssemblyTitle( "800Craft UpdateBuilder" )] +[assembly: AssemblyDescription( "Tool for automating the process of building 800Craft update binaries." )] [assembly: AssemblyConfiguration( "" )] -[assembly: AssemblyCompany("au70.net")] -[assembly: AssemblyProduct("800Craft UpdateBuilder")] -[assembly: AssemblyCopyright("")] +[assembly: AssemblyCompany( "au70.net" )] +[assembly: AssemblyProduct( "800Craft UpdateBuilder" )] +[assembly: AssemblyCopyright( "" )] [assembly: AssemblyTrademark( "" )] [assembly: AssemblyCulture( "" )] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible( false )] @@ -24,12 +24,12 @@ // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -// You can specify all the values or you can default the Build and Revision Numbers +// You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion( "0.6.1.7" )] -[assembly: AssemblyFileVersion( "0.6.1.7" )] +[assembly: AssemblyFileVersion( "0.6.1.7" )] \ No newline at end of file diff --git a/UpdaterBuilder/ZipStorer.cs b/UpdaterBuilder/ZipStorer.cs index d740d29..c913526 100644 --- a/UpdaterBuilder/ZipStorer.cs +++ b/UpdaterBuilder/ZipStorer.cs @@ -5,16 +5,20 @@ using System.Text; namespace System.IO.Compression { + /// /// Unique class for compression/decompression file. Represents a Zip file. /// public sealed class ZipStorer : IDisposable { + /// /// Compression method enumeration /// public enum Compression : ushort { - /// Uncompressed storage + + /// Uncompressed storage Store = 0, + /// Deflate compression method Deflate = 8 } @@ -23,26 +27,37 @@ public enum Compression : ushort { /// Represents an entry in Zip file directory /// public struct ZipFileEntry { + /// Compression method public Compression Method; + /// Full path and filename as stored in Zip public string FilenameInZip; + /// Original file size public uint FileSize; + /// Compressed file size public uint CompressedSize; + /// Offset of header information inside Zip storage public uint HeaderOffset; + /// Offset of file inside Zip storage public uint FileOffset; + /// Size of header information public uint HeaderSize; + /// 32-bit checksum of entire file public uint Crc32; + /// Last modification time of file public DateTime ModifyTime; + /// User comment for file public string Comment; + /// True if UTF8 encoding for filename and comments, false if default (CP 437) public bool EncodeUTF8; @@ -54,42 +69,56 @@ public override string ToString() { } #region Public fields + /// True if UTF8 encoding for filename and comments, false if default (CP 437) public bool EncodeUTF8; + /// Force deflate algotithm even if it inflates the stored file. Off by default. public bool ForceDeflating; - #endregion + + #endregion Public fields #region Private fields + // List of files to store private readonly List files = new List(); + // Filename of storage file private string fileName; + // Stream object of storage file private Stream zipFileStream; + // General comment private string comment = ""; + // Central dir image private byte[] centralDirImage; + // Existing files in zip private ushort existingFiles; + // File access for Open method private FileAccess access; + // Static CRC32 Table private readonly static UInt32[] CrcTable; + // Default filename encoder private readonly static Encoding DefaultEncoding = Encoding.GetEncoding( 437 ); - #endregion + + #endregion Private fields #region Public methods + // Static constructor. Just invoked once in order to create the CRC32 lookup table. static ZipStorer() { // Generate CRC32 table CrcTable = new UInt32[256]; - for( int i = 0; i < CrcTable.Length; i++ ) { - UInt32 c = (UInt32)i; - for( int j = 0; j < 8; j++ ) { - if( ( c & 1 ) != 0 ) + for ( int i = 0; i < CrcTable.Length; i++ ) { + UInt32 c = ( UInt32 )i; + for ( int j = 0; j < 8; j++ ) { + if ( ( c & 1 ) != 0 ) c = 3988292384 ^ ( c >> 1 ); else c >>= 1; @@ -97,6 +126,7 @@ static ZipStorer() { CrcTable[i] = c; } } + /// /// Method to create a new storage file /// @@ -112,6 +142,7 @@ public static ZipStorer Create( string filename, string fileComment ) { return zip; } + /// /// Method to create a new zip storage in a stream /// @@ -124,7 +155,6 @@ public static ZipStorer Create( Stream stream, string fileComment ) { return zip; } - /// /// Method to open an existing storage file /// @@ -139,6 +169,7 @@ public static ZipStorer Open( string filename, FileAccess fileAccess ) { return zip; } + /// /// Method to open an existing storage from stream /// @@ -146,31 +177,33 @@ public static ZipStorer Open( string filename, FileAccess fileAccess ) { /// File access mode for stream operations /// A valid ZipStorer object public static ZipStorer Open( Stream stream, FileAccess fileFileAccess ) { - if( !stream.CanSeek && fileFileAccess != FileAccess.Read ) + if ( !stream.CanSeek && fileFileAccess != FileAccess.Read ) throw new InvalidOperationException( "Stream cannot seek" ); ZipStorer zip = new ZipStorer { zipFileStream = stream, access = fileFileAccess }; - if( zip.ReadFileInfo() ) + if ( zip.ReadFileInfo() ) return zip; throw new InvalidDataException(); } + /// /// Add full contents of a file into the Zip storage /// /// Compression method /// Full path of file to add to Zip storage /// Filename and path as desired in Zip directory - /// Comment for stored file + /// Comment for stored file public void AddFile( Compression method, string pathname, string filenameInZip, string fileComment ) { - if( access == FileAccess.Read ) + if ( access == FileAccess.Read ) throw new InvalidOperationException( "Writing is not alowed" ); FileStream stream = new FileStream( pathname, FileMode.Open, FileAccess.Read ); AddStream( method, filenameInZip, stream, File.GetLastWriteTime( pathname ), fileComment ); stream.Close(); } + /// /// Add full contents of a stream into the Zip storage /// @@ -180,7 +213,7 @@ public void AddFile( Compression method, string pathname, string filenameInZip, /// Modification time of the data to store /// Comment for stored file public void AddStream( Compression method, string filenameInZip, Stream source, DateTime modTime, string fileComment ) { - if( access == FileAccess.Read ) + if ( access == FileAccess.Read ) throw new InvalidOperationException( "Writing is not alowed" ); /*long offset; @@ -198,7 +231,7 @@ public void AddStream( Compression method, string filenameInZip, Stream source, FilenameInZip = NormalizedFilename( filenameInZip ), Comment = ( fileComment ?? "" ), Crc32 = 0, - HeaderOffset = (uint)zipFileStream.Position, + HeaderOffset = ( uint )zipFileStream.Position, ModifyTime = modTime }; @@ -206,7 +239,7 @@ public void AddStream( Compression method, string filenameInZip, Stream source, // Write local header WriteLocalHeader( ref zfe ); - zfe.FileOffset = (uint)zipFileStream.Position; + zfe.FileOffset = ( uint )zipFileStream.Position; // Write file to zip (store) Store( ref zfe, source ); @@ -216,49 +249,52 @@ public void AddStream( Compression method, string filenameInZip, Stream source, files.Add( zfe ); } + /// /// Updates central directory (if pertinent) and close the Zip storage /// /// This is a required step, unless automatic dispose is used public void Close() { - if( access != FileAccess.Read ) { - uint centralOffset = (uint)zipFileStream.Position; + if ( access != FileAccess.Read ) { + uint centralOffset = ( uint )zipFileStream.Position; uint centralSize = 0; - if( centralDirImage != null ) + if ( centralDirImage != null ) zipFileStream.Write( centralDirImage, 0, centralDirImage.Length ); - for( int i = 0; i < files.Count; i++ ) { + for ( int i = 0; i < files.Count; i++ ) { long pos = zipFileStream.Position; WriteCentralDirRecord( files[i] ); - centralSize += (uint)( zipFileStream.Position - pos ); + centralSize += ( uint )( zipFileStream.Position - pos ); } - if( centralDirImage != null ) - WriteEndRecord( centralSize + (uint)centralDirImage.Length, centralOffset ); + if ( centralDirImage != null ) + WriteEndRecord( centralSize + ( uint )centralDirImage.Length, centralOffset ); else WriteEndRecord( centralSize, centralOffset ); } - if( zipFileStream == null ) return; + if ( zipFileStream == null ) + return; zipFileStream.Flush(); zipFileStream.Dispose(); zipFileStream = null; } + /// - /// Read all the file records in the central directory + /// Read all the file records in the central directory /// /// List of all entries in directory public List ReadCentralDir() { - if( centralDirImage == null ) + if ( centralDirImage == null ) throw new InvalidOperationException( "Central directory currently does not exist" ); List result = new List(); - for( int pointer = 0; pointer < centralDirImage.Length; ) { + for ( int pointer = 0; pointer < centralDirImage.Length; ) { uint signature = BitConverter.ToUInt32( centralDirImage, pointer ); - if( signature != 0x02014b50 ) + if ( signature != 0x02014b50 ) break; bool encodeUTF8 = ( BitConverter.ToUInt16( centralDirImage, pointer + 8 ) & 0x0800 ) != 0; @@ -271,12 +307,12 @@ public List ReadCentralDir() { ushort extraSize = BitConverter.ToUInt16( centralDirImage, pointer + 30 ); ushort commentSize = BitConverter.ToUInt16( centralDirImage, pointer + 32 ); uint headerOffset = BitConverter.ToUInt32( centralDirImage, pointer + 42 ); - uint headerSize = (uint)( 46 + filenameSize + extraSize + commentSize ); + uint headerSize = ( uint )( 46 + filenameSize + extraSize + commentSize ); Encoding encoder = encodeUTF8 ? Encoding.UTF8 : DefaultEncoding; ZipFileEntry zfe = new ZipFileEntry { - Method = (Compression)method, + Method = ( Compression )method, FilenameInZip = encoder.GetString( centralDirImage, pointer + 46, filenameSize ), @@ -288,7 +324,7 @@ public List ReadCentralDir() { Crc32 = crc32, ModifyTime = DosTimeToDateTime( modifyTime ) }; - if( commentSize > 0 ) + if ( commentSize > 0 ) zfe.Comment = encoder.GetString( centralDirImage, pointer + 46 + filenameSize + extraSize, commentSize ); result.Add( zfe ); @@ -297,6 +333,7 @@ public List ReadCentralDir() { return result; } + /// /// Copy the contents of a stored file into a physical file /// @@ -308,15 +345,15 @@ public bool ExtractFile( ZipFileEntry zfe, string filename ) { // Make sure the parent directory exist string path = Path.GetDirectoryName( filename ); - if( !Directory.Exists( path ) ) + if ( !Directory.Exists( path ) ) Directory.CreateDirectory( path ); // Check it is directory. If so, do nothing - if( Directory.Exists( filename ) ) + if ( Directory.Exists( filename ) ) return true; Stream output = new FileStream( filename, FileMode.Create, FileAccess.Write ); bool result = ExtractFile( zfe, output ); - if( result ) + if ( result ) output.Close(); File.SetCreationTime( filename, zfe.ModifyTime ); @@ -324,6 +361,7 @@ public bool ExtractFile( ZipFileEntry zfe, string filename ) { return result; } + /// /// Copy the contents of a stored file into an opened stream /// @@ -332,21 +370,21 @@ public bool ExtractFile( ZipFileEntry zfe, string filename ) { /// True if success, false if not. /// Unique compression methods are Store and Deflate public bool ExtractFile( ZipFileEntry zfe, Stream stream ) { - if( !stream.CanWrite ) + if ( !stream.CanWrite ) throw new InvalidOperationException( "Stream cannot be written" ); // check signature byte[] signature = new byte[4]; zipFileStream.Seek( zfe.HeaderOffset, SeekOrigin.Begin ); zipFileStream.Read( signature, 0, 4 ); - if( BitConverter.ToUInt32( signature, 0 ) != 0x04034b50 ) + if ( BitConverter.ToUInt32( signature, 0 ) != 0x04034b50 ) return false; // Select input stream for inflating or just reading Stream inStream; - if( zfe.Method == Compression.Store ) { + if ( zfe.Method == Compression.Store ) { inStream = zipFileStream; - } else if( zfe.Method == Compression.Deflate ) { + } else if ( zfe.Method == Compression.Deflate ) { inStream = new DeflateStream( zipFileStream, CompressionMode.Decompress, true ); } else { return false; @@ -356,17 +394,18 @@ public bool ExtractFile( ZipFileEntry zfe, Stream stream ) { byte[] buffer = new byte[16384]; zipFileStream.Seek( zfe.FileOffset, SeekOrigin.Begin ); uint bytesPending = zfe.FileSize; - while( bytesPending > 0 ) { - int bytesRead = inStream.Read( buffer, 0, (int)Math.Min( bytesPending, buffer.Length ) ); + while ( bytesPending > 0 ) { + int bytesRead = inStream.Read( buffer, 0, ( int )Math.Min( bytesPending, buffer.Length ) ); stream.Write( buffer, 0, bytesRead ); - bytesPending -= (uint)bytesRead; + bytesPending -= ( uint )bytesRead; } stream.Flush(); - if( zfe.Method == Compression.Deflate ) + if ( zfe.Method == Compression.Deflate ) inStream.Dispose(); return true; } + /// /// Removes one of many files in storage. It creates a new Zip file. /// @@ -375,10 +414,9 @@ public bool ExtractFile( ZipFileEntry zfe, Stream stream ) { /// True if success, false if not /// This method only works for storage of type FileStream public static bool RemoveEntries( ref ZipStorer zip, List zfes ) { - if( !( zip.zipFileStream is FileStream ) ) + if ( !( zip.zipFileStream is FileStream ) ) throw new InvalidOperationException( "RemoveEntries is allowed just over streams of type FileStream" ); - //Get full list of entries List fullList = zip.ReadCentralDir(); @@ -389,9 +427,9 @@ public static bool RemoveEntries( ref ZipStorer zip, List zfes ) { try { ZipStorer tempZip = Create( tempZipName, string.Empty ); - foreach( ZipFileEntry zfe in fullList ) { - if( !zfes.Contains( zfe ) ) { - if( zip.ExtractFile( zfe, tempEntryName ) ) { + foreach ( ZipFileEntry zfe in fullList ) { + if ( !zfes.Contains( zfe ) ) { + if ( zip.ExtractFile( zfe, tempEntryName ) ) { tempZip.AddFile( zfe.Method, tempEntryName, zfe.FilenameInZip, zfe.Comment ); } } @@ -399,7 +437,7 @@ public static bool RemoveEntries( ref ZipStorer zip, List zfes ) { zip.Close(); tempZip.Close(); - if( File.Exists( zip.fileName ) ) { + if ( File.Exists( zip.fileName ) ) { File.Replace( tempZipName, zip.fileName, null, true ); } else { File.Move( tempZipName, zip.fileName ); @@ -409,16 +447,18 @@ public static bool RemoveEntries( ref ZipStorer zip, List zfes ) { } catch { return false; } finally { - if( File.Exists( tempZipName ) ) + if ( File.Exists( tempZipName ) ) File.Delete( tempZipName ); - if( File.Exists( tempEntryName ) ) + if ( File.Exists( tempEntryName ) ) File.Delete( tempEntryName ); } return true; } - #endregion + + #endregion Public methods #region Private methods + // Calculate the file offset by reading the corresponding local header private uint GetFileOffset( uint headerOffset ) { byte[] buffer = new byte[2]; @@ -429,8 +469,9 @@ private uint GetFileOffset( uint headerOffset ) { zipFileStream.Read( buffer, 0, 2 ); ushort extraSize = BitConverter.ToUInt16( buffer, 0 ); - return (uint)( 30 + filenameSize + extraSize + headerOffset ); + return ( uint )( 30 + filenameSize + extraSize + headerOffset ); } + /* Local file header: local file header signature 4 bytes (0x04034b50) version needed to extract 2 bytes @@ -447,22 +488,24 @@ extra field length 2 bytes filename (variable size) extra field (variable size) */ + private void WriteLocalHeader( ref ZipFileEntry zfe ) { long pos = zipFileStream.Position; Encoding encoder = zfe.EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding; byte[] encodedFilename = encoder.GetBytes( zfe.FilenameInZip ); zipFileStream.Write( new byte[] { 80, 75, 3, 4, 20, 0 }, 0, 6 ); // No extra header - zipFileStream.Write( BitConverter.GetBytes( (ushort)( zfe.EncodeUTF8 ? 0x0800 : 0 ) ), 0, 2 ); // filename and comment encoding - zipFileStream.Write( BitConverter.GetBytes( (ushort)zfe.Method ), 0, 2 ); // zipping method + zipFileStream.Write( BitConverter.GetBytes( ( ushort )( zfe.EncodeUTF8 ? 0x0800 : 0 ) ), 0, 2 ); // filename and comment encoding + zipFileStream.Write( BitConverter.GetBytes( ( ushort )zfe.Method ), 0, 2 ); // zipping method zipFileStream.Write( BitConverter.GetBytes( DateTimeToDosTime( zfe.ModifyTime ) ), 0, 4 ); // zipping date and time zipFileStream.Write( new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 12 ); // unused CRC, un/compressed size, updated later - zipFileStream.Write( BitConverter.GetBytes( (ushort)encodedFilename.Length ), 0, 2 ); // filename length - zipFileStream.Write( BitConverter.GetBytes( (ushort)0 ), 0, 2 ); // extra length + zipFileStream.Write( BitConverter.GetBytes( ( ushort )encodedFilename.Length ), 0, 2 ); // filename length + zipFileStream.Write( BitConverter.GetBytes( ( ushort )0 ), 0, 2 ); // extra length zipFileStream.Write( encodedFilename, 0, encodedFilename.Length ); - zfe.HeaderSize = (uint)( zipFileStream.Position - pos ); + zfe.HeaderSize = ( uint )( zipFileStream.Position - pos ); } + /* Central directory's File header: central file header signature 4 bytes (0x02014b50) version made by 2 bytes @@ -486,31 +529,33 @@ relative offset of local header 4 bytes extra field (variable size) file comment (variable size) */ + private void WriteCentralDirRecord( ZipFileEntry zfe ) { Encoding encoder = zfe.EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding; byte[] encodedFilename = encoder.GetBytes( zfe.FilenameInZip ); byte[] encodedComment = encoder.GetBytes( zfe.Comment ); zipFileStream.Write( new byte[] { 80, 75, 1, 2, 23, 0xB, 20, 0 }, 0, 8 ); - zipFileStream.Write( BitConverter.GetBytes( (ushort)( zfe.EncodeUTF8 ? 0x0800 : 0 ) ), 0, 2 ); // filename and comment encoding - zipFileStream.Write( BitConverter.GetBytes( (ushort)zfe.Method ), 0, 2 ); // zipping method + zipFileStream.Write( BitConverter.GetBytes( ( ushort )( zfe.EncodeUTF8 ? 0x0800 : 0 ) ), 0, 2 ); // filename and comment encoding + zipFileStream.Write( BitConverter.GetBytes( ( ushort )zfe.Method ), 0, 2 ); // zipping method zipFileStream.Write( BitConverter.GetBytes( DateTimeToDosTime( zfe.ModifyTime ) ), 0, 4 ); // zipping date and time zipFileStream.Write( BitConverter.GetBytes( zfe.Crc32 ), 0, 4 ); // file CRC zipFileStream.Write( BitConverter.GetBytes( zfe.CompressedSize ), 0, 4 ); // compressed file size zipFileStream.Write( BitConverter.GetBytes( zfe.FileSize ), 0, 4 ); // uncompressed file size - zipFileStream.Write( BitConverter.GetBytes( (ushort)encodedFilename.Length ), 0, 2 ); // Filename in zip - zipFileStream.Write( BitConverter.GetBytes( (ushort)0 ), 0, 2 ); // extra length - zipFileStream.Write( BitConverter.GetBytes( (ushort)encodedComment.Length ), 0, 2 ); - - zipFileStream.Write( BitConverter.GetBytes( (ushort)0 ), 0, 2 ); // disk=0 - zipFileStream.Write( BitConverter.GetBytes( (ushort)0 ), 0, 2 ); // file type: binary - zipFileStream.Write( BitConverter.GetBytes( (ushort)0 ), 0, 2 ); // Internal file attributes - zipFileStream.Write( BitConverter.GetBytes( (ushort)0x8100 ), 0, 2 ); // External file attributes (normal/readable) + zipFileStream.Write( BitConverter.GetBytes( ( ushort )encodedFilename.Length ), 0, 2 ); // Filename in zip + zipFileStream.Write( BitConverter.GetBytes( ( ushort )0 ), 0, 2 ); // extra length + zipFileStream.Write( BitConverter.GetBytes( ( ushort )encodedComment.Length ), 0, 2 ); + + zipFileStream.Write( BitConverter.GetBytes( ( ushort )0 ), 0, 2 ); // disk=0 + zipFileStream.Write( BitConverter.GetBytes( ( ushort )0 ), 0, 2 ); // file type: binary + zipFileStream.Write( BitConverter.GetBytes( ( ushort )0 ), 0, 2 ); // Internal file attributes + zipFileStream.Write( BitConverter.GetBytes( ( ushort )0x8100 ), 0, 2 ); // External file attributes (normal/readable) zipFileStream.Write( BitConverter.GetBytes( zfe.HeaderOffset ), 0, 4 ); // Offset of header zipFileStream.Write( encodedFilename, 0, encodedFilename.Length ); zipFileStream.Write( encodedComment, 0, encodedComment.Length ); } + /* End of central dir record: end of central dir signature 4 bytes (0x06054b50) number of this disk 2 bytes @@ -527,18 +572,20 @@ the starting disk number 4 bytes zipfile comment length 2 bytes zipfile comment (variable size) */ + private void WriteEndRecord( uint size, uint offset ) { Encoding encoder = EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding; byte[] encodedComment = encoder.GetBytes( comment ); zipFileStream.Write( new byte[] { 80, 75, 5, 6, 0, 0, 0, 0 }, 0, 8 ); - zipFileStream.Write( BitConverter.GetBytes( (ushort)files.Count + existingFiles ), 0, 2 ); - zipFileStream.Write( BitConverter.GetBytes( (ushort)files.Count + existingFiles ), 0, 2 ); + zipFileStream.Write( BitConverter.GetBytes( ( ushort )files.Count + existingFiles ), 0, 2 ); + zipFileStream.Write( BitConverter.GetBytes( ( ushort )files.Count + existingFiles ), 0, 2 ); zipFileStream.Write( BitConverter.GetBytes( size ), 0, 4 ); zipFileStream.Write( BitConverter.GetBytes( offset ), 0, 4 ); - zipFileStream.Write( BitConverter.GetBytes( (ushort)encodedComment.Length ), 0, 2 ); + zipFileStream.Write( BitConverter.GetBytes( ( ushort )encodedComment.Length ), 0, 2 ); zipFileStream.Write( encodedComment, 0, encodedComment.Length ); } + // Copies all source file into storage file private void Store( ref ZipFileEntry zfe, Stream source ) { byte[] buffer = new byte[16384]; @@ -549,7 +596,7 @@ private void Store( ref ZipFileEntry zfe, Stream source ) { long posStart = zipFileStream.Position; long sourceStart = source.Position; - if( zfe.Method == Compression.Store ) + if ( zfe.Method == Compression.Store ) outStream = zipFileStream; else outStream = new DeflateStream( zipFileStream, CompressionMode.Compress, true ); @@ -558,28 +605,28 @@ private void Store( ref ZipFileEntry zfe, Stream source ) { do { bytesRead = source.Read( buffer, 0, buffer.Length ); - totalRead += (uint)bytesRead; - if( bytesRead > 0 ) { + totalRead += ( uint )bytesRead; + if ( bytesRead > 0 ) { outStream.Write( buffer, 0, bytesRead ); - for( uint i = 0; i < bytesRead; i++ ) { + for ( uint i = 0; i < bytesRead; i++ ) { zfe.Crc32 = CrcTable[( zfe.Crc32 ^ buffer[i] ) & 0xFF] ^ ( zfe.Crc32 >> 8 ); } } - } while( bytesRead == buffer.Length ); + } while ( bytesRead == buffer.Length ); - if( totalRead > 0 ) + if ( totalRead > 0 ) outStream.Flush(); // fix for "Internal error Flush" under Mono - if( zfe.Method == Compression.Deflate ) + if ( zfe.Method == Compression.Deflate ) outStream.Dispose(); zfe.Crc32 ^= 0xffffffff; zfe.FileSize = totalRead; - zfe.CompressedSize = (uint)( zipFileStream.Position - posStart ); + zfe.CompressedSize = ( uint )( zipFileStream.Position - posStart ); // Verify for real compression - if( zfe.Method == Compression.Deflate && !ForceDeflating && source.CanSeek && zfe.CompressedSize > zfe.FileSize ) { + if ( zfe.Method == Compression.Deflate && !ForceDeflating && source.CanSeek && zfe.CompressedSize > zfe.FileSize ) { // Start operation again with Store algorithm zfe.Method = Compression.Store; zipFileStream.Position = posStart; @@ -588,33 +635,36 @@ private void Store( ref ZipFileEntry zfe, Stream source ) { Store( ref zfe, source ); } } + /* DOS Date and time: - MS-DOS date. The date is a packed value with the following format. Bits Description - 0-4 Day of the month (1–31) - 5-8 Month (1 = January, 2 = February, and so on) - 9-15 Year offset from 1980 (add 1980 to get actual year) - MS-DOS time. The time is a packed value with the following format. Bits Description - 0-4 Second divided by 2 - 5-10 Minute (0–59) - 11-15 Hour (0–23 on a 24-hour clock) + MS-DOS date. The date is a packed value with the following format. Bits Description + 0-4 Day of the month (1–31) + 5-8 Month (1 = January, 2 = February, and so on) + 9-15 Year offset from 1980 (add 1980 to get actual year) + MS-DOS time. The time is a packed value with the following format. Bits Description + 0-4 Second divided by 2 + 5-10 Minute (0–59) + 11-15 Hour (0–23 on a 24-hour clock) */ + private static uint DateTimeToDosTime( DateTime dt ) { - return (uint)( + return ( uint )( ( dt.Second / 2 ) | ( dt.Minute << 5 ) | ( dt.Hour << 11 ) | ( dt.Day << 16 ) | ( dt.Month << 21 ) | ( ( dt.Year - 1980 ) << 25 ) ); } + private static DateTime DosTimeToDateTime( uint dt ) { return new DateTime( - (int)( dt >> 25 ) + 1980, - (int)( dt >> 21 ) & 15, - (int)( dt >> 16 ) & 31, - (int)( dt >> 11 ) & 31, - (int)( dt >> 5 ) & 63, - (int)( dt & 31 ) * 2 ); + ( int )( dt >> 25 ) + 1980, + ( int )( dt >> 21 ) & 15, + ( int )( dt >> 16 ) & 31, + ( int )( dt >> 11 ) & 31, + ( int )( dt >> 5 ) & 63, + ( int )( dt & 31 ) * 2 ); } /* CRC32 algorithm - The 'magic number' for the CRC is 0xdebb20e3. + The 'magic number' for the CRC is 0xdebb20e3. The proper CRC pre and post conditioning is used, meaning that the CRC register is pre-conditioned with all ones (a starting value @@ -625,11 +675,12 @@ field is set to zero in the local header and the correct value is put in the data descriptor and in the central directory. */ + private void UpdateCrcAndSizes( ref ZipFileEntry zfe ) { long lastPos = zipFileStream.Position; // remember position zipFileStream.Position = zfe.HeaderOffset + 8; - zipFileStream.Write( BitConverter.GetBytes( (ushort)zfe.Method ), 0, 2 ); // zipping method + zipFileStream.Write( BitConverter.GetBytes( ( ushort )zfe.Method ), 0, 2 ); // zipping method zipFileStream.Position = zfe.HeaderOffset + 14; zipFileStream.Write( BitConverter.GetBytes( zfe.Crc32 ), 0, 4 ); // Update CRC @@ -638,19 +689,21 @@ private void UpdateCrcAndSizes( ref ZipFileEntry zfe ) { zipFileStream.Position = lastPos; // restore position } + // Replaces backslashes with slashes to store in zip header private static string NormalizedFilename( string filename ) { string normalizedFilename = filename.Replace( '\\', '/' ); int pos = normalizedFilename.IndexOf( ':' ); - if( pos >= 0 ) + if ( pos >= 0 ) normalizedFilename = normalizedFilename.Remove( 0, pos + 1 ); return normalizedFilename.Trim( '/' ); } + // Reads the end-of-central-directory record private bool ReadFileInfo() { - if( zipFileStream.Length < 22 ) + if ( zipFileStream.Length < 22 ) return false; try { @@ -659,7 +712,8 @@ private bool ReadFileInfo() { do { zipFileStream.Seek( -5, SeekOrigin.Current ); UInt32 sig = br.ReadUInt32(); - if( sig != 0x06054b50 ) continue; + if ( sig != 0x06054b50 ) + continue; zipFileStream.Seek( 6, SeekOrigin.Current ); @@ -669,7 +723,7 @@ private bool ReadFileInfo() { UInt16 commentSize = br.ReadUInt16(); // check if comment field is the very last data in file - if( zipFileStream.Position + commentSize != zipFileStream.Length ) + if ( zipFileStream.Position + commentSize != zipFileStream.Length ) return false; // Copy entire central directory to a memory buffer @@ -681,20 +735,23 @@ private bool ReadFileInfo() { // Leave the pointer at the begining of central dir, to append new files zipFileStream.Seek( centralDirOffset, SeekOrigin.Begin ); return true; - } while( zipFileStream.Position > 0 ); + } while ( zipFileStream.Position > 0 ); } catch { } return false; } - #endregion + + #endregion Private methods #region IDisposable Members + /// /// Closes the Zip file stream /// public void Dispose() { Close(); } - #endregion + + #endregion IDisposable Members } } \ No newline at end of file diff --git a/UpdaterBuilder/app.config b/UpdaterBuilder/app.config index 19fac17..6e2f55a 100644 --- a/UpdaterBuilder/app.config +++ b/UpdaterBuilder/app.config @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/fCraft/AutoRank/AutoRankManager.cs b/fCraft/AutoRank/AutoRankManager.cs index 8c824c3..702e220 100644 --- a/fCraft/AutoRank/AutoRankManager.cs +++ b/fCraft/AutoRank/AutoRankManager.cs @@ -7,8 +7,8 @@ using JetBrains.Annotations; namespace fCraft.AutoRank { - public static class AutoRankManager { + public static class AutoRankManager { internal static readonly TimeSpan TickInterval = TimeSpan.FromSeconds( 60 ); public static readonly List Criteria = new List(); @@ -20,27 +20,27 @@ public static bool HasCriteria { get { return Criteria.Count > 0; } } - /// Adds a new criterion to the list. Throws an ArgumentException on duplicates. public static void Add( [NotNull] Criterion criterion ) { - if( criterion == null ) throw new ArgumentNullException( "criterion" ); - if( Criteria.Contains( criterion ) ) throw new ArgumentException( "This criterion has already been added." ); + if ( criterion == null ) + throw new ArgumentNullException( "criterion" ); + if ( Criteria.Contains( criterion ) ) + throw new ArgumentException( "This criterion has already been added." ); Criteria.Add( criterion ); } - /// Checks whether a given player is due for a promotion or demotion. /// PlayerInfo to check. /// Null if no rank change is needed, or a rank to promote/demote to. [CanBeNull] public static Rank Check( [NotNull] PlayerInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); + if ( info == null ) + throw new ArgumentNullException( "info" ); // ReSharper disable LoopCanBeConvertedToQuery - for( int i = 0; i < Criteria.Count; i++ ) { - if( Criteria[i].FromRank == info.Rank && + for ( int i = 0; i < Criteria.Count; i++ ) { + if ( Criteria[i].FromRank == info.Rank && !info.IsBanned && Criteria[i].Condition.Eval( info ) ) { - return Criteria[i].ToRank; } } @@ -48,34 +48,34 @@ public static Rank Check( [NotNull] PlayerInfo info ) { return null; } - internal static void TaskCallback( SchedulerTask schedulerTask ) { - if( !ConfigKey.AutoRankEnabled.Enabled() ) return; + if ( !ConfigKey.AutoRankEnabled.Enabled() ) + return; PlayerInfo[] onlinePlayers = Server.Players.Select( p => p.Info ).ToArray(); MaintenanceCommands.DoAutoRankAll( Player.AutoRank, onlinePlayers, false, "~AutoRank" ); } - public static bool Init() { Criteria.Clear(); - if( File.Exists( Paths.AutoRankFileName ) ) { + if ( File.Exists( Paths.AutoRankFileName ) ) { try { XDocument doc = XDocument.Load( Paths.AutoRankFileName ); - if( doc.Root == null ) return false; - foreach( XElement el in doc.Root.Elements( "Criterion" ) ) { + if ( doc.Root == null ) + return false; + foreach ( XElement el in doc.Root.Elements( "Criterion" ) ) { try { Add( new Criterion( el ) ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.Log( LogType.Error, "AutoRank.Init: Could not parse an AutoRank criterion: {0}", ex ); } } - if( Criteria.Count == 0 ) { + if ( Criteria.Count == 0 ) { Logger.Log( LogType.Warning, "AutoRank.Init: No criteria loaded." ); } return true; - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.Log( LogType.Error, "AutoRank.Init: Could not parse the AutoRank file: {0}", ex ); return false; @@ -87,7 +87,6 @@ public static bool Init() { } } - #region Enums /// Operators used to compare PlayerInfo fields. @@ -112,9 +111,9 @@ public enum ComparisonOp { Lte } - /// Enumeration of quantifiable PlayerInfo fields (or field combinations) that may be used with AutoRank conditions. public enum ConditionField { + /// Time since first login (first time the player connected), in seconds. /// For players who have been entered into PlayerDB but have never logged in, this is a huge value. TimeSinceFirstLogin, @@ -166,5 +165,5 @@ public enum ConditionField { TimeSinceLastKick } - #endregion + #endregion Enums } \ No newline at end of file diff --git a/fCraft/AutoRank/Conditions.cs b/fCraft/AutoRank/Conditions.cs index cde6516..9c3f182 100644 --- a/fCraft/AutoRank/Conditions.cs +++ b/fCraft/AutoRank/Conditions.cs @@ -9,10 +9,11 @@ namespace fCraft.AutoRank { /// Base class for all AutoRank conditions. public abstract class Condition { + public abstract bool Eval( PlayerInfo info ); public static Condition Parse( XElement el ) { - switch( el.Name.ToString() ) { + switch ( el.Name.ToString() ) { case "AND": return new ConditionAND( el ); case "OR": @@ -35,11 +36,13 @@ public static Condition Parse( XElement el ) { public abstract XElement Serialize(); } - /// Class for checking ranges of countable PlayerInfo fields (see ConditionField enum). public sealed class ConditionIntRange : Condition { + public ConditionField Field { get; set; } + public ComparisonOp Comparison { get; set; } + public int Value { get; set; } public ConditionIntRange() { @@ -49,16 +52,16 @@ public ConditionIntRange() { public ConditionIntRange( [NotNull] XElement el ) : this() { // ReSharper disable PossibleNullReferenceException - if( el == null ) throw new ArgumentNullException( "el" ); - Field = (ConditionField)Enum.Parse( typeof( ConditionField ), el.Attribute( "field" ).Value, true ); + if ( el == null ) + throw new ArgumentNullException( "el" ); + Field = ( ConditionField )Enum.Parse( typeof( ConditionField ), el.Attribute( "field" ).Value, true ); Value = Int32.Parse( el.Attribute( "val" ).Value ); - if( el.Attribute( "op" ) != null ) { - Comparison = (ComparisonOp)Enum.Parse( typeof( ComparisonOp ), el.Attribute( "op" ).Value, true ); + if ( el.Attribute( "op" ) != null ) { + Comparison = ( ComparisonOp )Enum.Parse( typeof( ComparisonOp ), el.Attribute( "op" ).Value, true ); } // ReSharper restore PossibleNullReferenceException } - public ConditionIntRange( ConditionField field, ComparisonOp comparison, int value ) { Field = field; Comparison = comparison; @@ -66,65 +69,79 @@ public ConditionIntRange( ConditionField field, ComparisonOp comparison, int val } public override bool Eval( [NotNull] PlayerInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); + if ( info == null ) + throw new ArgumentNullException( "info" ); long givenValue; - switch( Field ) { + switch ( Field ) { case ConditionField.TimeSinceFirstLogin: - givenValue = (int)info.TimeSinceFirstLogin.TotalSeconds; + givenValue = ( int )info.TimeSinceFirstLogin.TotalSeconds; break; + case ConditionField.TimeSinceLastLogin: - givenValue = (int)info.TimeSinceLastLogin.TotalSeconds; + givenValue = ( int )info.TimeSinceLastLogin.TotalSeconds; break; + case ConditionField.LastSeen: - givenValue = (int)info.TimeSinceLastSeen.TotalSeconds; + givenValue = ( int )info.TimeSinceLastSeen.TotalSeconds; break; + case ConditionField.BlocksBuilt: givenValue = info.BlocksBuilt; break; + case ConditionField.BlocksDeleted: givenValue = info.BlocksDeleted; break; + case ConditionField.BlocksChanged: givenValue = info.BlocksBuilt + info.BlocksDeleted; break; + case ConditionField.BlocksDrawn: givenValue = info.BlocksDrawn; break; + case ConditionField.TimesVisited: givenValue = info.TimesVisited; break; + case ConditionField.MessagesWritten: givenValue = info.MessagesWritten; break; + case ConditionField.TimesKicked: givenValue = info.TimesKicked; break; + case ConditionField.TotalTime: - givenValue = (int)info.TotalTime.TotalSeconds; + givenValue = ( int )info.TotalTime.TotalSeconds; break; + case ConditionField.TimeSinceRankChange: - givenValue = (int)info.TimeSinceRankChange.TotalSeconds; + givenValue = ( int )info.TimeSinceRankChange.TotalSeconds; break; + case ConditionField.TimeSinceLastKick: - givenValue = (int)info.TimeSinceLastKick.TotalSeconds; + givenValue = ( int )info.TimeSinceLastKick.TotalSeconds; break; + default: throw new ArgumentOutOfRangeException(); } - switch( Comparison ) { + switch ( Comparison ) { case ComparisonOp.Lt: - return (givenValue < Value); + return ( givenValue < Value ); case ComparisonOp.Lte: - return (givenValue <= Value); + return ( givenValue <= Value ); case ComparisonOp.Gte: - return (givenValue >= Value); + return ( givenValue >= Value ); case ComparisonOp.Gt: - return (givenValue > Value); + return ( givenValue > Value ); case ComparisonOp.Eq: - return (givenValue == Value); + return ( givenValue == Value ); case ComparisonOp.Neq: - return (givenValue != Value); + return ( givenValue != Value ); default: throw new ArgumentOutOfRangeException(); } @@ -146,9 +163,9 @@ public override string ToString() { } } - /// Checks what caused player's last rank change (see RankChangeType enum). public sealed class ConditionRankChangeType : Condition { + public RankChangeType Type { get; set; } public ConditionRankChangeType( RankChangeType type ) { @@ -156,15 +173,17 @@ public ConditionRankChangeType( RankChangeType type ) { } public ConditionRankChangeType( [NotNull] XElement el ) { - if( el == null ) throw new ArgumentNullException( "el" ); + if ( el == null ) + throw new ArgumentNullException( "el" ); // ReSharper disable PossibleNullReferenceException - Type = (RankChangeType)Enum.Parse( typeof( RankChangeType ), el.Attribute( "val" ).Value, true ); + Type = ( RankChangeType )Enum.Parse( typeof( RankChangeType ), el.Attribute( "val" ).Value, true ); // ReSharper restore PossibleNullReferenceException } public override bool Eval( [NotNull] PlayerInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); - return (info.RankChangeType == Type); + if ( info == null ) + throw new ArgumentNullException( "info" ); + return ( info.RankChangeType == Type ); } public override XElement Serialize() { @@ -174,15 +193,17 @@ public override XElement Serialize() { } } - /// Checks what rank the player held previously. public sealed class ConditionPreviousRank : Condition { + public Rank Rank { get; set; } + public ComparisonOp Comparison { get; set; } public ConditionPreviousRank( [NotNull] Rank rank, ComparisonOp comparison ) { - if( rank == null ) throw new ArgumentNullException( "rank" ); - if( !Enum.IsDefined( typeof( ComparisonOp ), comparison ) ) { + if ( rank == null ) + throw new ArgumentNullException( "rank" ); + if ( !Enum.IsDefined( typeof( ComparisonOp ), comparison ) ) { throw new ArgumentOutOfRangeException( "comparison", "Unknown comparison type" ); } Rank = rank; @@ -191,28 +212,30 @@ public ConditionPreviousRank( [NotNull] Rank rank, ComparisonOp comparison ) { public ConditionPreviousRank( [NotNull] XElement el ) { // ReSharper disable PossibleNullReferenceException - if( el == null ) throw new ArgumentNullException( "el" ); + if ( el == null ) + throw new ArgumentNullException( "el" ); Rank = Rank.Parse( el.Attribute( "val" ).Value ); - Comparison = (ComparisonOp)Enum.Parse( typeof( ComparisonOp ), el.Attribute( "op" ).Value, true ); + Comparison = ( ComparisonOp )Enum.Parse( typeof( ComparisonOp ), el.Attribute( "op" ).Value, true ); // ReSharper restore PossibleNullReferenceException } public override bool Eval( [NotNull] PlayerInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); + if ( info == null ) + throw new ArgumentNullException( "info" ); Rank prevRank = info.PreviousRank ?? info.Rank; - switch( Comparison ) { + switch ( Comparison ) { case ComparisonOp.Lt: - return (prevRank < Rank); + return ( prevRank < Rank ); case ComparisonOp.Lte: - return (prevRank <= Rank); + return ( prevRank <= Rank ); case ComparisonOp.Gte: - return (prevRank >= Rank); + return ( prevRank >= Rank ); case ComparisonOp.Gt: - return (prevRank > Rank); + return ( prevRank > Rank ); case ComparisonOp.Eq: - return (prevRank == Rank); + return ( prevRank == Rank ); case ComparisonOp.Neq: - return (prevRank != Rank); + return ( prevRank != Rank ); default: throw new ArgumentOutOfRangeException(); } @@ -226,11 +249,11 @@ public override XElement Serialize() { } } - #region Condition Sets /// Base class for condition sets/combinations. public class ConditionSet : Condition { + protected ConditionSet() { Conditions = new List(); } @@ -238,14 +261,16 @@ protected ConditionSet() { public List Conditions { get; private set; } protected ConditionSet( [NotNull] IEnumerable conditions ) { - if( conditions == null ) throw new ArgumentNullException( "conditions" ); + if ( conditions == null ) + throw new ArgumentNullException( "conditions" ); Conditions = conditions.ToList(); } protected ConditionSet( [NotNull] XContainer el ) : this() { - if( el == null ) throw new ArgumentNullException( "el" ); - foreach( XElement cel in el.Elements() ) { + if ( el == null ) + throw new ArgumentNullException( "el" ); + foreach ( XElement cel in el.Elements() ) { Add( Parse( cel ) ); } } @@ -255,7 +280,8 @@ public override bool Eval( PlayerInfo info ) { } public void Add( [NotNull] Condition condition ) { - if( condition == null ) throw new ArgumentNullException( "condition" ); + if ( condition == null ) + throw new ArgumentNullException( "condition" ); Conditions.Add( condition ); } @@ -264,92 +290,119 @@ public override XElement Serialize() { } } - /// Logical AND - true if ALL conditions are true. public sealed class ConditionAND : ConditionSet { - public ConditionAND() { } - public ConditionAND( IEnumerable conditions ) : base( conditions ) { } - public ConditionAND( XContainer el ) : base( el ) { } + + public ConditionAND() { + } + + public ConditionAND( IEnumerable conditions ) + : base( conditions ) { + } + + public ConditionAND( XContainer el ) + : base( el ) { + } public override bool Eval( PlayerInfo info ) { return Conditions == null || Conditions.All( t => t.Eval( info ) ); } - public override XElement Serialize() { XElement el = new XElement( "AND" ); - foreach( Condition cond in Conditions ) { + foreach ( Condition cond in Conditions ) { el.Add( cond.Serialize() ); } return el; } } - /// Logical AND - true if NOT ALL of the conditions are true. public sealed class ConditionNAND : ConditionSet { - public ConditionNAND() { } - public ConditionNAND( IEnumerable conditions ) : base( conditions ) { } - public ConditionNAND( XContainer el ) : base( el ) { } + + public ConditionNAND() { + } + + public ConditionNAND( IEnumerable conditions ) + : base( conditions ) { + } + + public ConditionNAND( XContainer el ) + : base( el ) { + } public override bool Eval( [NotNull] PlayerInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); + if ( info == null ) + throw new ArgumentNullException( "info" ); return Conditions == null || Conditions.Any( t => !t.Eval( info ) ); } - public override XElement Serialize() { XElement el = new XElement( "NAND" ); - foreach( Condition cond in Conditions ) { + foreach ( Condition cond in Conditions ) { el.Add( cond.Serialize() ); } return el; } } - /// Logical AND - true if ANY of the conditions are true. public sealed class ConditionOR : ConditionSet { - public ConditionOR() { } - public ConditionOR( IEnumerable conditions ) : base( conditions ) { } - public ConditionOR( XContainer el ) : base( el ) { } + + public ConditionOR() { + } + + public ConditionOR( IEnumerable conditions ) + : base( conditions ) { + } + + public ConditionOR( XContainer el ) + : base( el ) { + } public override bool Eval( [NotNull] PlayerInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); + if ( info == null ) + throw new ArgumentNullException( "info" ); return Conditions == null || Conditions.Any( t => t.Eval( info ) ); } - public override XElement Serialize() { XElement el = new XElement( "OR" ); - foreach( Condition cond in Conditions ) { + foreach ( Condition cond in Conditions ) { el.Add( cond.Serialize() ); } return el; } } - /// Logical AND - true if NONE of the conditions are true. public sealed class ConditionNOR : ConditionSet { - public ConditionNOR() { } - public ConditionNOR( IEnumerable conditions ) : base( conditions ) { } - public ConditionNOR( XContainer el ) : base( el ) { } + + public ConditionNOR() { + } + + public ConditionNOR( IEnumerable conditions ) + : base( conditions ) { + } + + public ConditionNOR( XContainer el ) + : base( el ) { + } public override bool Eval( [NotNull] PlayerInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); + if ( info == null ) + throw new ArgumentNullException( "info" ); return Conditions == null || Conditions.All( t => !t.Eval( info ) ); } - public override XElement Serialize() { XElement el = new XElement( "NOR" ); - foreach( Condition cond in Conditions ) { + foreach ( Condition cond in Conditions ) { el.Add( cond.Serialize() ); } return el; } } - #endregion + #endregion Condition Sets } \ No newline at end of file diff --git a/fCraft/AutoRank/Criterion.cs b/fCraft/AutoRank/Criterion.cs index 25dd646..9b2417c 100644 --- a/fCraft/AutoRank/Criterion.cs +++ b/fCraft/AutoRank/Criterion.cs @@ -5,43 +5,55 @@ using JetBrains.Annotations; namespace fCraft.AutoRank { + public sealed class Criterion : ICloneable { + public Rank FromRank { get; set; } + public Rank ToRank { get; set; } + public ConditionSet Condition { get; set; } - public Criterion() { } + public Criterion() { + } public Criterion( [NotNull] Criterion other ) { - if( other == null ) throw new ArgumentNullException( "other" ); + if ( other == null ) + throw new ArgumentNullException( "other" ); FromRank = other.FromRank; ToRank = other.ToRank; Condition = other.Condition; } public Criterion( [NotNull] Rank fromRank, [NotNull] Rank toRank, [NotNull] ConditionSet condition ) { - if( fromRank == null ) throw new ArgumentNullException( "fromRank" ); - if( toRank == null ) throw new ArgumentNullException( "toRank" ); - if( condition == null ) throw new ArgumentNullException( "condition" ); + if ( fromRank == null ) + throw new ArgumentNullException( "fromRank" ); + if ( toRank == null ) + throw new ArgumentNullException( "toRank" ); + if ( condition == null ) + throw new ArgumentNullException( "condition" ); FromRank = fromRank; ToRank = toRank; Condition = condition; } public Criterion( [NotNull] XElement el ) { - if( el == null ) throw new ArgumentNullException( "el" ); + if ( el == null ) + throw new ArgumentNullException( "el" ); // ReSharper disable PossibleNullReferenceException FromRank = Rank.Parse( el.Attribute( "fromRank" ).Value ); // ReSharper restore PossibleNullReferenceException - if( FromRank == null ) throw new FormatException( "Could not parse \"fromRank\"" ); + if ( FromRank == null ) + throw new FormatException( "Could not parse \"fromRank\"" ); // ReSharper disable PossibleNullReferenceException ToRank = Rank.Parse( el.Attribute( "toRank" ).Value ); // ReSharper restore PossibleNullReferenceException - if( ToRank == null ) throw new FormatException( "Could not parse \"toRank\"" ); + if ( ToRank == null ) + throw new FormatException( "Could not parse \"toRank\"" ); - Condition = (ConditionSet)AutoRank.Condition.Parse( el.Elements().First() ); + Condition = ( ConditionSet )AutoRank.Condition.Parse( el.Elements().First() ); } public object Clone() { @@ -50,7 +62,7 @@ public object Clone() { public override string ToString() { return String.Format( "Criteria( {0} from {1} to {2} )", - (FromRank < ToRank ? "promote" : "demote"), + ( FromRank < ToRank ? "promote" : "demote" ), FromRank.Name, ToRank.Name ); } @@ -59,10 +71,10 @@ public XElement Serialize() { XElement el = new XElement( "Criterion" ); el.Add( new XAttribute( "fromRank", FromRank.FullName ) ); el.Add( new XAttribute( "toRank", ToRank.FullName ) ); - if( Condition != null ) { + if ( Condition != null ) { el.Add( Condition.Serialize() ); } return el; } } -} +} \ No newline at end of file diff --git a/fCraft/Commands/BuildingCommands.cs b/fCraft/Commands/BuildingCommands.cs index e5eeeb2..3b41f71 100644 --- a/fCraft/Commands/BuildingCommands.cs +++ b/fCraft/Commands/BuildingCommands.cs @@ -1,25 +1,28 @@ // Copyright 2009-2013 Matvei Stefarov using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; using System.Linq; +using fCraft.Doors; using fCraft.Drawing; using fCraft.MapConversion; using JetBrains.Annotations; -using System.Collections.Generic; -using System.IO; -using System.Drawing; -using fCraft.Doors; + namespace fCraft { + /// Commands for placing specific blocks (solid, water, grass), /// and switching block placement modes (paint, bind). - static class BuildingCommands { + internal static class BuildingCommands { #region Init + public static int MaxUndoCount = 2000000; - const string GeneralDrawingHelp = " Use &H/Cancel&S to cancel selection mode. " + + private const string GeneralDrawingHelp = " Use &H/Cancel&S to cancel selection mode. " + "Use &H/Undo&S to stop and undo the last command."; - internal static void Init () { + internal static void Init() { CommandManager.RegisterCommand( CdBind ); CommandManager.RegisterCommand( CdGrass ); CommandManager.RegisterCommand( CdLava ); @@ -109,7 +112,8 @@ internal static void Init () { CommandManager.RegisterCommand( CdSetFont ); CommandManager.RegisterCommand( CdDrawImage ); } - #endregion + + #endregion Init #region 800Craft @@ -140,7 +144,7 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ - static readonly CommandDescriptor CdDoor = new CommandDescriptor { + private static readonly CommandDescriptor CdDoor = new CommandDescriptor { Name = "Door", Category = CommandCategory.Building, Permissions = new[] { Permission.Build }, @@ -160,12 +164,12 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY Handler = Door }; - static void Door ( Player player, Command cmd ) { + private static void Door( Player player, Command cmd ) { string option = cmd.Next(); if ( option == null ) { int MaxNumberOfDoorsPerPlayer = 5; if ( DoorHandler.GetPlayerOwnedDoorsNumber( player.World, player ) >= MaxNumberOfDoorsPerPlayer ) { - player.Message( "You cannot place any more doors, a player can have a maximum of {0} doors per world", + player.Message( "You cannot place any more doors, a player can have a maximum of {0} doors per world", MaxNumberOfDoorsPerPlayer ); return; } @@ -245,8 +249,9 @@ static void Door ( Player player, Command cmd ) { } } - static void DoorTestCallback ( Player player, Vector3I[] marks, object tag ) { - Vector3I Pos = marks[0]; Door door = fCraft.Doors.DoorHandler.GetDoor( Pos, player ); + private static void DoorTestCallback( Player player, Vector3I[] marks, object tag ) { + Vector3I Pos = marks[0]; + Door door = fCraft.Doors.DoorHandler.GetDoor( Pos, player ); if ( door == null ) { player.Message( "DoorTest: There is no door at this position" ); } else { @@ -254,7 +259,7 @@ static void DoorTestCallback ( Player player, Vector3I[] marks, object tag ) { } } - static void DoorAdd ( Player player, Vector3I[] marks, object tag ) { + private static void DoorAdd( Player player, Vector3I[] marks, object tag ) { int sx = Math.Min( marks[0].X, marks[1].X ); int ex = Math.Max( marks[0].X, marks[1].X ); int sy = Math.Min( marks[0].Y, marks[1].Y ); @@ -274,6 +279,7 @@ static void DoorAdd ( Player player, Vector3I[] marks, object tag ) { player.Message( "Cannot add a door to world {0}&S: You are barred from building here.", player.World.ClassyName ); return; + case SecurityCheckResult.RankTooLow: player.Message( "Cannot add a door to world {0}&S: You are not allowed to build here.", player.World.ClassyName ); @@ -300,7 +306,7 @@ static void DoorAdd ( Player player, Vector3I[] marks, object tag ) { player.ClassyName ); door.Range = new DoorRange( sx, ex, sy, ey, sz, ez ); foreach ( Vector3I v in DoorHandler.GetInstance().GetAffectedBlocks( door ) ) { - if ( DoorHandler.GetInstance().GetDoor( player.World, v) != null ) { + if ( DoorHandler.GetInstance().GetDoor( player.World, v ) != null ) { player.Message( "You can not build a door inside a door, U MAD BRO?" ); player.World.Map.DoorID--; return; @@ -311,7 +317,7 @@ static void DoorAdd ( Player player, Vector3I[] marks, object tag ) { player.Message( "Door created on world {0}&S with name {1}", player.World.ClassyName, door.Name ); } - static readonly CommandDescriptor CdDrawImage = new CommandDescriptor { + private static readonly CommandDescriptor CdDrawImage = new CommandDescriptor { Name = "DrawImage", Aliases = new[] { "Drawimg", "Imgdraw", "ImgPrint" }, Category = CommandCategory.Building, @@ -322,7 +328,8 @@ static void DoorAdd ( Player player, Vector3I[] marks, object tag ) { "If your url is from imgur.com, you can type '++' followed by the image code. Example: ++kbFRo.png", Handler = DrawImageHandler }; - static void DrawImageHandler ( Player player, Command cmd ) { + + private static void DrawImageHandler( Player player, Command cmd ) { string Url = cmd.Next(); if ( string.IsNullOrEmpty( Url ) ) { CdDrawImage.PrintUsage( player ); @@ -333,10 +340,12 @@ static void DrawImageHandler ( Player player, Command cmd ) { } } - static void DrawImgCallback ( Player player, Vector3I[] marks, object tag ) { + private static void DrawImgCallback( Player player, Vector3I[] marks, object tag ) { string Url = ( string )tag; - if ( Url.StartsWith( "++" ) ) Url = Url.Replace( "++", "i.imgur.com/" ); - if ( !Url.StartsWith( "http://", StringComparison.OrdinalIgnoreCase ) ) Url = "http://" + Url; + if ( Url.StartsWith( "++" ) ) + Url = Url.Replace( "++", "i.imgur.com/" ); + if ( !Url.StartsWith( "http://", StringComparison.OrdinalIgnoreCase ) ) + Url = "http://" + Url; player.MessageNow( "&HDrawImg: Downloading image from {0}", Url ); @@ -357,7 +366,7 @@ static void DrawImgCallback ( Player player, Vector3I[] marks, object tag ) { Op = null; //get lost } - static CommandDescriptor CdSetFont = new CommandDescriptor() { + private static CommandDescriptor CdSetFont = new CommandDescriptor() { Name = "SetFont", Aliases = new[] { "FontSet", "Font", "Sf" }, Category = CommandCategory.Building, @@ -368,7 +377,7 @@ static void DrawImgCallback ( Player player, Vector3I[] marks, object tag ) { Usage = "/SetFont < Font | Size | Reset > " }; - static void SetFontHandler ( Player player, Command cmd ) { + private static void SetFontHandler( Player player, Command cmd ) { string Param = cmd.Next(); if ( Param == null ) { CdSetFont.PrintUsage( player ); @@ -396,7 +405,8 @@ static void SetFontHandler ( Player player, Command cmd ) { } for ( int i = 0; i < sectionFiles.Length; i++ ) { string sectionFullName = Path.GetFileNameWithoutExtension( sectionFiles[i] ); - if ( sectionFullName == null ) continue; + if ( sectionFullName == null ) + continue; if ( sectionFullName.StartsWith( sectionName, StringComparison.OrdinalIgnoreCase ) ) { if ( sectionFullName.Equals( sectionName, StringComparison.OrdinalIgnoreCase ) ) { fontFileName = sectionFiles[i]; @@ -448,7 +458,7 @@ static void SetFontHandler ( Player player, Command cmd ) { } } - static readonly CommandDescriptor CdDraw2D = new CommandDescriptor { + private static readonly CommandDescriptor CdDraw2D = new CommandDescriptor { Name = "Draw2D", Aliases = new[] { "D2d" }, Category = CommandCategory.Building, @@ -463,7 +473,7 @@ static void SetFontHandler ( Player player, Command cmd ) { Handler = Draw2DHandler, }; - static void Draw2DHandler ( Player player, Command cmd ) { + private static void Draw2DHandler( Player player, Command cmd ) { string Shape = cmd.Next(); if ( Shape == null ) { CdDraw2D.PrintUsage( player ); @@ -474,6 +484,7 @@ static void Draw2DHandler ( Player player, Command cmd ) { case "star": case "spiral": break; + default: CdDraw2D.PrintUsage( player ); return; @@ -497,14 +508,14 @@ static void Draw2DHandler ( Player player, Command cmd ) { player.SelectionStart( 2, Draw2DCallback, tag, Permission.DrawAdvanced ); } - struct Draw2DData { + private struct Draw2DData { public int Radius; public int Points; public string Shape; public bool Fill; } - static void Draw2DCallback ( Player player, Vector3I[] marks, object tag ) { + private static void Draw2DCallback( Player player, Vector3I[] marks, object tag ) { Block block = new Block(); Draw2DData data = ( Draw2DData )tag; int radius = data.Radius; @@ -523,12 +534,15 @@ static void Draw2DCallback ( Player player, Vector3I[] marks, object tag ) { case "polygon": lib.DrawRegularPolygon( Points, 18, fill ); break; + case "star": lib.DrawStar( Points, radius, fill ); break; + case "spiral": lib.DrawSpiral(); break; + default: player.Message( "&WUnknown shape" ); CdDraw2D.PrintUsage( player ); @@ -550,7 +564,8 @@ static void Draw2DCallback ( Player player, Vector3I[] marks, object tag ) { player.Message( e.Message ); } } - static readonly CommandDescriptor CdWrite = new CommandDescriptor { + + private static readonly CommandDescriptor CdWrite = new CommandDescriptor { Name = "Write", Aliases = new[] { "Text", "Wt" }, Category = CommandCategory.Building, @@ -562,7 +577,7 @@ static void Draw2DCallback ( Player player, Vector3I[] marks, object tag ) { Handler = WriteHandler, }; - static void WriteHandler ( Player player, Command cmd ) { + private static void WriteHandler( Player player, Command cmd ) { string sentence = cmd.NextAll(); if ( sentence.Length < 1 ) { CdWrite.PrintUsage( player ); @@ -573,7 +588,7 @@ static void WriteHandler ( Player player, Command cmd ) { } } - static void WriteCallback ( Player player, Vector3I[] marks, object tag ) { + private static void WriteCallback( Player player, Vector3I[] marks, object tag ) { Block block = new Block(); string sentence = ( string )tag; //block bugfix kinda @@ -602,7 +617,7 @@ static void WriteCallback ( Player player, Vector3I[] marks, object tag ) { } } - static string[] GetFontSectionList () { + private static string[] GetFontSectionList() { if ( Directory.Exists( Paths.FontsPath ) ) { string[] sections = Directory.GetFiles( Paths.FontsPath, "*.ttf", SearchOption.TopDirectoryOnly ) .Select( name => Path.GetFileNameWithoutExtension( name ) ) @@ -615,7 +630,7 @@ static string[] GetFontSectionList () { return null; } - static readonly CommandDescriptor CdTree = new CommandDescriptor { + private static readonly CommandDescriptor CdTree = new CommandDescriptor { Name = "Tree", Category = CommandCategory.Building, Permissions = new[] { Permission.DrawAdvanced }, @@ -624,7 +639,7 @@ static string[] GetFontSectionList () { Handler = TreeHandler }; - static void TreeHandler ( Player player, Command cmd ) { + private static void TreeHandler( Player player, Command cmd ) { string shapeName = cmd.Next(); int height; Forester.TreeShape shape; @@ -667,7 +682,7 @@ static void TreeHandler ( Player player, Command cmd ) { player.MessageNow( "Tree: Place a block or type /Mark to use your location." ); } - static void TreeCallback ( Player player, Vector3I[] marks, object tag ) { + private static void TreeCallback( Player player, Vector3I[] marks, object tag ) { ForesterArgs args = ( ForesterArgs )tag; int blocksPlaced = 0, blocksDenied = 0; UndoState undoState = player.DrawBegin( null ); @@ -680,8 +695,7 @@ static void TreeCallback ( Player player, Vector3I[] marks, object tag ) { DrawingFinished( player, "/Tree: Planted", blocksPlaced, blocksDenied ); } - - static readonly CommandDescriptor CdCylinder = new CommandDescriptor { + private static readonly CommandDescriptor CdCylinder = new CommandDescriptor { Name = "Cylinder", Category = CommandCategory.Building, Permissions = new[] { Permission.Build }, @@ -694,10 +708,11 @@ static void TreeCallback ( Player player, Vector3I[] marks, object tag ) { Handler = CylinderHandler }; - static void CylinderHandler ( Player player, Command cmd ) { + private static void CylinderHandler( Player player, Command cmd ) { DrawOperationBegin( player, cmd, new CylinderDrawOperation( player ) ); } - static readonly CommandDescriptor CdPlace = new CommandDescriptor { + + private static readonly CommandDescriptor CdPlace = new CommandDescriptor { Name = "Place", Category = CommandCategory.Building, Permissions = new[] { Permission.Build }, @@ -709,7 +724,7 @@ static void CylinderHandler ( Player player, Command cmd ) { Handler = Place }; - static void Place ( Player player, Command cmd ) { + private static void Place( Player player, Command cmd ) { if ( player.LastUsedBlockType != Block.Undefined ) { Vector3I Pos = new Vector3I( player.Position.X / 32, player.Position.Y / 32, ( player.Position.Z / 32 ) - 2 ); @@ -722,10 +737,11 @@ static void Place ( Player player, Command cmd ) { BlockUpdate blockUpdate = new BlockUpdate( null, Pos, player.LastUsedBlockType ); player.World.Map.QueueUpdate( blockUpdate ); player.Message( "Block placed below your feet" ); - } else player.Message( "&WError: No last used blocktype was found" ); + } else + player.Message( "&WError: No last used blocktype was found" ); } - static readonly CommandDescriptor CdCenter = new CommandDescriptor { + private static readonly CommandDescriptor CdCenter = new CommandDescriptor { Name = "Center", Aliases = new[] { "Centre" }, Category = CommandCategory.Building, @@ -738,13 +754,12 @@ static void Place ( Player player, Command cmd ) { Handler = CenterHandler }; - static void CenterHandler ( Player player, Command cmd ) { + private static void CenterHandler( Player player, Command cmd ) { player.SelectionStart( 2, CenterCallback, null, CdCenter.Permissions ); player.MessageNow( "Center: Place a block or type /Mark to use your location." ); } - - static void CenterCallback ( Player player, Vector3I[] marks, object tag ) { + private static void CenterCallback( Player player, Vector3I[] marks, object tag ) { if ( player.LastUsedBlockType != Block.Undefined ) { int sx = Math.Min( marks[0].X, marks[1].X ), ex = Math.Max( marks[0].X, marks[1].X ), sy = Math.Min( marks[0].Y, marks[1].Y ), ey = Math.Max( marks[0].Y, marks[1].Y ), @@ -759,7 +774,8 @@ static void CenterCallback ( Player player, Vector3I[] marks, object tag ) { UndoState undoState = player.DrawBegin( null ); World playerWorld = player.World; - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); Map map = player.WorldMap; DrawOneBlock( player, player.World.Map, player.LastUsedBlockType, cPos, BlockChangeContext.Drawn, @@ -770,8 +786,7 @@ static void CenterCallback ( Player player, Vector3I[] marks, object tag ) { } } - - static readonly CommandDescriptor CdFly = new CommandDescriptor { + private static readonly CommandDescriptor CdFly = new CommandDescriptor { Name = "Fly", Category = CommandCategory.Building | CommandCategory.Fun, IsConsoleSafe = false, @@ -782,7 +797,7 @@ static void CenterCallback ( Player player, Vector3I[] marks, object tag ) { Handler = Fly }; - static void Fly ( Player player, Command cmd ) { + private static void Fly( Player player, Command cmd ) { if ( player.IsFlying ) { fCraft.Utils.FlyHandler.GetInstance().StopFlying( player ); player.Message( "You are no longer flying." ); @@ -798,7 +813,8 @@ static void Fly ( Player player, Command cmd ) { } #region banx - static readonly CommandDescriptor CdBanx = new CommandDescriptor { + + private static readonly CommandDescriptor CdBanx = new CommandDescriptor { Name = "Banx", Category = CommandCategory.Moderation, IsConsoleSafe = false, @@ -809,7 +825,7 @@ static void Fly ( Player player, Command cmd ) { Handler = BanXHandler }; - static void BanXHandler ( Player player, Command cmd ) { + private static void BanXHandler( Player player, Command cmd ) { string ban = cmd.Next(); if ( ban == null ) { @@ -827,14 +843,15 @@ static void BanXHandler ( Player player, Command cmd ) { } } PlayerInfo target = PlayerDB.FindPlayerInfoOrPrintMatches( player, ban ); - if ( target == null ) return; + if ( target == null ) + return; if ( !Player.IsValidName( ban ) ) { CdBanx.PrintUsage( player ); return; } else { string reason = cmd.NextAll(); - if ( reason.Length < 1 || string.IsNullOrEmpty(reason) ) + if ( reason.Length < 1 || string.IsNullOrEmpty( reason ) ) reason = "Reason Undefined: BanX"; try { Player targetPlayer = target.PlayerObject; @@ -863,8 +880,8 @@ static void BanXHandler ( Player player, Command cmd ) { } } - static void UndoPlayerHandler2 (Player player, PlayerInfo[] target) { - BlockDBUndoArgs args = new BlockDBUndoArgs() { Player = player, World = player.World, CountLimit = 50000, Not = false, Targets = target }; + private static void UndoPlayerHandler2( Player player, PlayerInfo[] target ) { + BlockDBUndoArgs args = new BlockDBUndoArgs() { Player = player, World = player.World, CountLimit = 50000, Not = false, Targets = target }; bool allPlayers = ( args.Targets.Length == 0 ); string cmdName = ( args.Not ? "UndoPlayerNot" : "UndoPlayer" ); @@ -894,7 +911,6 @@ static void UndoPlayerHandler2 (Player player, PlayerInfo[] target) { "Undo last {0} changes made by {1}&S?", changes.Length, targetList ); } - } else { // time-limited lookup if ( args.Targets.Length == 0 ) { @@ -919,10 +935,10 @@ static void UndoPlayerHandler2 (Player player, PlayerInfo[] target) { args.Entries = changes; } } - #endregion + #endregion banx - static readonly CommandDescriptor CdWalls = new CommandDescriptor { + private static readonly CommandDescriptor CdWalls = new CommandDescriptor { Name = "Walls", IsConsoleSafe = false, RepeatableSelection = true, @@ -933,14 +949,15 @@ static void UndoPlayerHandler2 (Player player, PlayerInfo[] target) { Handler = WallsHandler }; - static void WallsHandler ( Player player, Command cmd ) { + private static void WallsHandler( Player player, Command cmd ) { DrawOperationBegin( player, cmd, new WallsDrawOperation( player ) ); } - #endregion + + #endregion 800Craft #region DrawOperations & Brushes - static readonly CommandDescriptor CdCuboid = new CommandDescriptor { + private static readonly CommandDescriptor CdCuboid = new CommandDescriptor { Name = "Cuboid", Aliases = new[] { "blb", "c", "z" }, Category = CommandCategory.Building, @@ -950,13 +967,11 @@ static void WallsHandler ( Player player, Command cmd ) { Handler = CuboidHandler }; - static void CuboidHandler ( Player player, Command cmd ) { + private static void CuboidHandler( Player player, Command cmd ) { DrawOperationBegin( player, cmd, new CuboidDrawOperation( player ) ); } - - - static readonly CommandDescriptor CdCuboidWireframe = new CommandDescriptor { + private static readonly CommandDescriptor CdCuboidWireframe = new CommandDescriptor { Name = "CuboidW", Aliases = new[] { "cubw", "cw", "bfb" }, Category = CommandCategory.Building, @@ -966,13 +981,11 @@ static void CuboidHandler ( Player player, Command cmd ) { Handler = CuboidWireframeHandler }; - static void CuboidWireframeHandler ( Player player, Command cmd ) { + private static void CuboidWireframeHandler( Player player, Command cmd ) { DrawOperationBegin( player, cmd, new CuboidWireframeDrawOperation( player ) ); } - - - static readonly CommandDescriptor CdCuboidHollow = new CommandDescriptor { + private static readonly CommandDescriptor CdCuboidHollow = new CommandDescriptor { Name = "CuboidH", Aliases = new[] { "cubh", "ch", "h", "bhb" }, Category = CommandCategory.Building, @@ -983,13 +996,11 @@ static void CuboidWireframeHandler ( Player player, Command cmd ) { Handler = CuboidHollowHandler }; - static void CuboidHollowHandler ( Player player, Command cmd ) { + private static void CuboidHollowHandler( Player player, Command cmd ) { DrawOperationBegin( player, cmd, new CuboidHollowDrawOperation( player ) ); } - - - static readonly CommandDescriptor CdEllipsoid = new CommandDescriptor { + private static readonly CommandDescriptor CdEllipsoid = new CommandDescriptor { Name = "Ellipsoid", Aliases = new[] { "e" }, Category = CommandCategory.Building, @@ -999,13 +1010,11 @@ static void CuboidHollowHandler ( Player player, Command cmd ) { Handler = EllipsoidHandler }; - static void EllipsoidHandler ( Player player, Command cmd ) { + private static void EllipsoidHandler( Player player, Command cmd ) { DrawOperationBegin( player, cmd, new EllipsoidDrawOperation( player ) ); } - - - static readonly CommandDescriptor CdEllipsoidHollow = new CommandDescriptor { + private static readonly CommandDescriptor CdEllipsoidHollow = new CommandDescriptor { Name = "EllipsoidH", Aliases = new[] { "eh" }, Category = CommandCategory.Building, @@ -1015,13 +1024,11 @@ static void EllipsoidHandler ( Player player, Command cmd ) { Handler = EllipsoidHollowHandler }; - static void EllipsoidHollowHandler ( Player player, Command cmd ) { + private static void EllipsoidHollowHandler( Player player, Command cmd ) { DrawOperationBegin( player, cmd, new EllipsoidHollowDrawOperation( player ) ); } - - - static readonly CommandDescriptor CdSphere = new CommandDescriptor { + private static readonly CommandDescriptor CdSphere = new CommandDescriptor { Name = "Sphere", Aliases = new[] { "sp", "spheroid" }, Category = CommandCategory.Building, @@ -1033,13 +1040,11 @@ static void EllipsoidHollowHandler ( Player player, Command cmd ) { Handler = SphereHandler }; - static void SphereHandler ( Player player, Command cmd ) { + private static void SphereHandler( Player player, Command cmd ) { DrawOperationBegin( player, cmd, new SphereDrawOperation( player ) ); } - - - static readonly CommandDescriptor CdSphereHollow = new CommandDescriptor { + private static readonly CommandDescriptor CdSphereHollow = new CommandDescriptor { Name = "SphereH", Aliases = new[] { "sph", "hsphere" }, Category = CommandCategory.Building, @@ -1051,13 +1056,11 @@ static void SphereHandler ( Player player, Command cmd ) { Handler = SphereHollowHandler }; - static void SphereHollowHandler ( Player player, Command cmd ) { + private static void SphereHollowHandler( Player player, Command cmd ) { DrawOperationBegin( player, cmd, new SphereHollowDrawOperation( player ) ); } - - - static readonly CommandDescriptor CdLine = new CommandDescriptor { + private static readonly CommandDescriptor CdLine = new CommandDescriptor { Name = "Line", Aliases = new[] { "ln" }, Category = CommandCategory.Building, @@ -1068,13 +1071,11 @@ static void SphereHollowHandler ( Player player, Command cmd ) { Handler = LineHandler }; - static void LineHandler ( Player player, Command cmd ) { + private static void LineHandler( Player player, Command cmd ) { DrawOperationBegin( player, cmd, new LineDrawOperation( player ) ); } - - - static readonly CommandDescriptor CdTriangleWireframe = new CommandDescriptor { + private static readonly CommandDescriptor CdTriangleWireframe = new CommandDescriptor { Name = "TriangleW", Aliases = new[] { "tw" }, Category = CommandCategory.Building, @@ -1084,13 +1085,11 @@ static void LineHandler ( Player player, Command cmd ) { Handler = TriangleWireframeHandler }; - static void TriangleWireframeHandler ( Player player, Command cmd ) { + private static void TriangleWireframeHandler( Player player, Command cmd ) { DrawOperationBegin( player, cmd, new TriangleWireframeDrawOperation( player ) ); } - - - static readonly CommandDescriptor CdTriangle = new CommandDescriptor { + private static readonly CommandDescriptor CdTriangle = new CommandDescriptor { Name = "Triangle", Aliases = new[] { "t" }, Category = CommandCategory.Building, @@ -1100,13 +1099,11 @@ static void TriangleWireframeHandler ( Player player, Command cmd ) { Handler = TriangleHandler }; - static void TriangleHandler ( Player player, Command cmd ) { + private static void TriangleHandler( Player player, Command cmd ) { DrawOperationBegin( player, cmd, new TriangleDrawOperation( player ) ); } - - - static readonly CommandDescriptor CdTorus = new CommandDescriptor { + private static readonly CommandDescriptor CdTorus = new CommandDescriptor { Name = "Torus", Aliases = new[] { "donut", "bagel" }, Category = CommandCategory.Building, @@ -1118,29 +1115,28 @@ static void TriangleHandler ( Player player, Command cmd ) { Handler = TorusHandler }; - static void TorusHandler ( Player player, Command cmd ) { + private static void TorusHandler( Player player, Command cmd ) { DrawOperationBegin( player, cmd, new TorusDrawOperation( player ) ); } - - - public static void DrawOperationBegin ( Player player, Command cmd, DrawOperation op ) { + public static void DrawOperationBegin( Player player, Command cmd, DrawOperation op ) { // try to create instance of player's currently selected brush // all command parameters are passed to the brush IBrushInstance brush = player.Brush.MakeInstance( player, cmd, op ); // MakeInstance returns null if there were problems with syntax, abort - if ( brush == null ) return; + if ( brush == null ) + return; op.Brush = brush; player.SelectionStart( op.ExpectedMarks, DrawOperationCallback, op, Permission.Draw ); player.Message( "{0}: Click {1} blocks or use &H/Mark&S to make a selection.", op.Description, op.ExpectedMarks ); } - - static void DrawOperationCallback ( Player player, Vector3I[] marks, object tag ) { + private static void DrawOperationCallback( Player player, Vector3I[] marks, object tag ) { DrawOperation op = ( DrawOperation )tag; - if ( !op.Prepare( marks ) ) return; + if ( !op.Prepare( marks ) ) + return; if ( !player.CanDraw( op.BlocksTotalEstimate ) ) { player.MessageNow( "You are only allowed to run draw commands that affect up to {0} blocks. This one would affect {1} blocks.", player.Info.Rank.DrawLimit, @@ -1153,11 +1149,11 @@ static void DrawOperationCallback ( Player player, Vector3I[] marks, object tag op.Begin(); } - #endregion + #endregion DrawOperations & Brushes #region Fill - static readonly CommandDescriptor CdFill2D = new CommandDescriptor { + private static readonly CommandDescriptor CdFill2D = new CommandDescriptor { Name = "Fill2D", Aliases = new[] { "f2d" }, Category = CommandCategory.Building, @@ -1170,17 +1166,17 @@ static void DrawOperationCallback ( Player player, Vector3I[] marks, object tag Handler = Fill2DHandler }; - static void Fill2DHandler ( Player player, Command cmd ) { + private static void Fill2DHandler( Player player, Command cmd ) { Fill2DDrawOperation op = new Fill2DDrawOperation( player ); op.ReadParams( cmd ); player.SelectionStart( 1, Fill2DCallback, op, Permission.Draw ); player.Message( "{0}: Click a block to start filling.", op.Description ); } - - static void Fill2DCallback ( Player player, Vector3I[] marks, object tag ) { + private static void Fill2DCallback( Player player, Vector3I[] marks, object tag ) { DrawOperation op = ( DrawOperation )tag; - if ( !op.Prepare( marks ) ) return; + if ( !op.Prepare( marks ) ) + return; if ( player.WorldMap.GetBlock( marks[0] ) == Block.Air ) { player.Confirm( Fill2DConfirmCallback, op, "{0}: Replace air?", op.Description ); } else { @@ -1188,19 +1184,18 @@ static void Fill2DCallback ( Player player, Vector3I[] marks, object tag ) { } } - - static void Fill2DConfirmCallback ( Player player, object tag, bool fromConsole ) { + private static void Fill2DConfirmCallback( Player player, object tag, bool fromConsole ) { Fill2DDrawOperation op = ( Fill2DDrawOperation )tag; player.Message( "{0}: Filling in a {1}x{1} area...", op.Description, player.Info.Rank.FillLimit ); op.Begin(); } - #endregion + #endregion Fill #region Block Commands - static readonly CommandDescriptor CdSolid = new CommandDescriptor { + private static readonly CommandDescriptor CdSolid = new CommandDescriptor { Name = "Solid", Aliases = new[] { "s" }, Category = CommandCategory.Building, @@ -1209,7 +1204,7 @@ static void Fill2DConfirmCallback ( Player player, object tag, bool fromConsole Handler = SolidHandler }; - static void SolidHandler ( Player player, Command cmd ) { + private static void SolidHandler( Player player, Command cmd ) { if ( player.GetBind( Block.Stone ) == Block.Admincrete ) { player.ResetBind( Block.Stone ); player.Message( "Solid: OFF" ); @@ -1219,9 +1214,7 @@ static void SolidHandler ( Player player, Command cmd ) { } } - - - static readonly CommandDescriptor CdPaint = new CommandDescriptor { + private static readonly CommandDescriptor CdPaint = new CommandDescriptor { Name = "Paint", Aliases = new[] { "p" }, Category = CommandCategory.Building, @@ -1230,7 +1223,7 @@ static void SolidHandler ( Player player, Command cmd ) { Handler = PaintHandler }; - static void PaintHandler ( Player player, Command cmd ) { + private static void PaintHandler( Player player, Command cmd ) { player.IsPainting = !player.IsPainting; if ( player.IsPainting ) { player.Message( "Paint mode: ON" ); @@ -1239,9 +1232,7 @@ static void PaintHandler ( Player player, Command cmd ) { } } - - - static readonly CommandDescriptor CdGrass = new CommandDescriptor { + private static readonly CommandDescriptor CdGrass = new CommandDescriptor { Name = "Grass", Aliases = new[] { "g" }, Category = CommandCategory.Building, @@ -1250,7 +1241,7 @@ static void PaintHandler ( Player player, Command cmd ) { Handler = GrassHandler }; - static void GrassHandler ( Player player, Command cmd ) { + private static void GrassHandler( Player player, Command cmd ) { if ( player.GetBind( Block.Dirt ) == Block.Grass ) { player.ResetBind( Block.Dirt ); player.Message( "Grass: OFF" ); @@ -1260,9 +1251,7 @@ static void GrassHandler ( Player player, Command cmd ) { } } - - - static readonly CommandDescriptor CdWater = new CommandDescriptor { + private static readonly CommandDescriptor CdWater = new CommandDescriptor { Name = "Water", Aliases = new[] { "w" }, Category = CommandCategory.Building, @@ -1271,7 +1260,7 @@ static void GrassHandler ( Player player, Command cmd ) { Handler = WaterHandler }; - static void WaterHandler ( Player player, Command cmd ) { + private static void WaterHandler( Player player, Command cmd ) { if ( player.GetBind( Block.Aqua ) == Block.Water || player.GetBind( Block.Cyan ) == Block.Water || player.GetBind( Block.Blue ) == Block.Water ) { @@ -1285,9 +1274,7 @@ static void WaterHandler ( Player player, Command cmd ) { } } - - - static readonly CommandDescriptor CdLava = new CommandDescriptor { + private static readonly CommandDescriptor CdLava = new CommandDescriptor { Name = "Lava", Aliases = new[] { "l" }, Category = CommandCategory.Building, @@ -1296,7 +1283,7 @@ static void WaterHandler ( Player player, Command cmd ) { Handler = LavaHandler }; - static void LavaHandler ( Player player, Command cmd ) { + private static void LavaHandler( Player player, Command cmd ) { if ( player.GetBind( Block.Red ) == Block.Lava ) { player.ResetBind( Block.Red ); player.Message( "Lava: OFF" ); @@ -1306,9 +1293,7 @@ static void LavaHandler ( Player player, Command cmd ) { } } - - - static readonly CommandDescriptor CdBind = new CommandDescriptor { + private static readonly CommandDescriptor CdBind = new CommandDescriptor { Name = "Bind", Category = CommandCategory.Building, Permissions = new[] { Permission.Build }, @@ -1319,7 +1304,7 @@ static void LavaHandler ( Player player, Command cmd ) { Handler = BindHandler }; - static void BindHandler ( Player player, Command cmd ) { + private static void BindHandler( Player player, Command cmd ) { string originalBlockName = cmd.Next(); if ( originalBlockName == null ) { player.Message( "All bindings have been reset." ); @@ -1360,12 +1345,15 @@ static void BindHandler ( Player player, Command cmd ) { case Block.Grass: permission = Permission.PlaceGrass; break; + case Block.Admincrete: permission = Permission.PlaceAdmincrete; break; + case Block.Water: permission = Permission.PlaceWater; break; + case Block.Lava: permission = Permission.PlaceLava; break; @@ -1379,17 +1367,20 @@ static void BindHandler ( Player player, Command cmd ) { } } - #endregion + #endregion Block Commands #region Drawing Helpers - static void DrawOneBlock ( [NotNull] Player player, [NotNull] Map map, Block drawBlock, Vector3I coord, - BlockChangeContext context, ref int blocks, ref int blocksDenied, UndoState undoState ) { - if ( player == null ) throw new ArgumentNullException( "player" ); + private static void DrawOneBlock( [NotNull] Player player, [NotNull] Map map, Block drawBlock, Vector3I coord, + BlockChangeContext context, ref int blocks, ref int blocksDenied, UndoState undoState ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); - if ( !map.InBounds( coord ) ) return; + if ( !map.InBounds( coord ) ) + return; Block block = map.GetBlock( coord ); - if ( block == drawBlock ) return; + if ( block == drawBlock ) + return; if ( player.CanPlace( map, coord, drawBlock, context ) != CanPlaceResult.Allowed ) { blocksDenied++; @@ -1408,9 +1399,9 @@ static void DrawOneBlock ( [NotNull] Player player, [NotNull] Map map, Block dra blocks++; } - - static void DrawingFinished ( [NotNull] Player player, string verb, int blocks, int blocksDenied ) { - if ( player == null ) throw new ArgumentNullException( "player" ); + private static void DrawingFinished( [NotNull] Player player, string verb, int blocks, int blocksDenied ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); if ( blocks == 0 ) { if ( blocksDenied > 0 ) { player.MessageNow( "No blocks could be {0} due to permission issues.", verb.ToLower() ); @@ -1431,14 +1422,15 @@ static void DrawingFinished ( [NotNull] Player player, string verb, int blocks, } } - #endregion + #endregion Drawing Helpers #region Replace - static void ReplaceHandlerInternal ( IBrush factory, Player player, Command cmd ) { + private static void ReplaceHandlerInternal( IBrush factory, Player player, Command cmd ) { CuboidDrawOperation op = new CuboidDrawOperation( player ); IBrushInstance brush = factory.MakeInstance( player, cmd, op ); - if ( brush == null ) return; + if ( brush == null ) + return; op.Brush = brush; player.SelectionStart( 2, DrawOperationCallback, op, Permission.Draw ); @@ -1446,8 +1438,7 @@ static void ReplaceHandlerInternal ( IBrush factory, Player player, Command cmd op.Brush.InstanceDescription ); } - - static readonly CommandDescriptor CdReplace = new CommandDescriptor { + private static readonly CommandDescriptor CdReplace = new CommandDescriptor { Name = "Replace", Aliases = new[] { "r" }, Category = CommandCategory.Building, @@ -1458,15 +1449,14 @@ static void ReplaceHandlerInternal ( IBrush factory, Player player, Command cmd Handler = ReplaceHandler }; - static void ReplaceHandler ( Player player, Command cmd ) { + private static void ReplaceHandler( Player player, Command cmd ) { var replaceBrush = ReplaceBrushFactory.Instance.MakeBrush( player, cmd ); - if ( replaceBrush == null ) return; + if ( replaceBrush == null ) + return; ReplaceHandlerInternal( replaceBrush, player, cmd ); } - - - static readonly CommandDescriptor CdReplaceNot = new CommandDescriptor { + private static readonly CommandDescriptor CdReplaceNot = new CommandDescriptor { Name = "ReplaceNot", Aliases = new[] { "rn" }, Category = CommandCategory.Building, @@ -1477,15 +1467,14 @@ static void ReplaceHandler ( Player player, Command cmd ) { Handler = ReplaceNotHandler }; - static void ReplaceNotHandler ( Player player, Command cmd ) { + private static void ReplaceNotHandler( Player player, Command cmd ) { var replaceBrush = ReplaceNotBrushFactory.Instance.MakeBrush( player, cmd ); - if ( replaceBrush == null ) return; + if ( replaceBrush == null ) + return; ReplaceHandlerInternal( replaceBrush, player, cmd ); } - - - static readonly CommandDescriptor CdReplaceBrush = new CommandDescriptor { + private static readonly CommandDescriptor CdReplaceBrush = new CommandDescriptor { Name = "ReplaceBrush", Aliases = new[] { "rb" }, Category = CommandCategory.Building, @@ -1497,16 +1486,18 @@ static void ReplaceNotHandler ( Player player, Command cmd ) { Handler = ReplaceBrushHandler }; - static void ReplaceBrushHandler ( Player player, Command cmd ) { + private static void ReplaceBrushHandler( Player player, Command cmd ) { var replaceBrush = ReplaceBrushBrushFactory.Instance.MakeBrush( player, cmd ); - if ( replaceBrush == null ) return; + if ( replaceBrush == null ) + return; ReplaceHandlerInternal( replaceBrush, player, cmd ); } - #endregion + + #endregion Replace #region Undo / Redo - static readonly CommandDescriptor CdUndo = new CommandDescriptor { + private static readonly CommandDescriptor CdUndo = new CommandDescriptor { Name = "Undo", Category = CommandCategory.Building, Permissions = new[] { Permission.Draw }, @@ -1515,9 +1506,10 @@ static void ReplaceBrushHandler ( Player player, Command cmd ) { Handler = UndoHandler }; - static void UndoHandler ( Player player, Command cmd ) { + private static void UndoHandler( Player player, Command cmd ) { World playerWorld = player.World; - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); if ( cmd.HasNext ) { player.Message( "Undo command takes no parameters. Did you mean to do &H/UndoPlayer&S or &H/UndoArea&S?" ); return; @@ -1564,8 +1556,7 @@ static void UndoHandler ( Player player, Command cmd ) { op.Begin(); } - - static readonly CommandDescriptor CdRedo = new CommandDescriptor { + private static readonly CommandDescriptor CdRedo = new CommandDescriptor { Name = "Redo", Category = CommandCategory.Building, Permissions = new[] { Permission.Draw }, @@ -1574,14 +1565,15 @@ static void UndoHandler ( Player player, Command cmd ) { Handler = RedoHandler }; - static void RedoHandler ( Player player, Command cmd ) { + private static void RedoHandler( Player player, Command cmd ) { if ( cmd.HasNext ) { CdRedo.PrintUsage( player ); return; } World playerWorld = player.World; - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); UndoState redoState = player.RedoPop(); if ( redoState == null ) { @@ -1613,11 +1605,11 @@ static void RedoHandler ( Player player, Command cmd ) { op.Begin(); } - #endregion + #endregion Undo / Redo #region Copy and Paste - static readonly CommandDescriptor CdCopySlot = new CommandDescriptor { + private static readonly CommandDescriptor CdCopySlot = new CommandDescriptor { Name = "CopySlot", Category = CommandCategory.Building, Permissions = new[] { Permission.CopyAndPaste }, @@ -1626,7 +1618,7 @@ static void RedoHandler ( Player player, Command cmd ) { Handler = CopySlotHandler }; - static void CopySlotHandler ( Player player, Command cmd ) { + private static void CopySlotHandler( Player player, Command cmd ) { int slotNumber; if ( cmd.NextInt( out slotNumber ) ) { if ( cmd.HasNext ) { @@ -1660,9 +1652,7 @@ static void CopySlotHandler ( Player player, Command cmd ) { } } - - - static readonly CommandDescriptor CdCopy = new CommandDescriptor { + private static readonly CommandDescriptor CdCopy = new CommandDescriptor { Name = "Copy", Category = CommandCategory.Building, Permissions = new[] { Permission.CopyAndPaste }, @@ -1672,7 +1662,7 @@ static void CopySlotHandler ( Player player, Command cmd ) { Handler = CopyHandler }; - static void CopyHandler ( Player player, Command cmd ) { + private static void CopyHandler( Player player, Command cmd ) { if ( cmd.HasNext ) { CdCopy.PrintUsage( player ); return; @@ -1681,8 +1671,7 @@ static void CopyHandler ( Player player, Command cmd ) { player.MessageNow( "Copy: Place a block or type /Mark to use your location." ); } - - static void CopyCallback ( Player player, Vector3I[] marks, object tag ) { + private static void CopyCallback( Player player, Vector3I[] marks, object tag ) { int sx = Math.Min( marks[0].X, marks[1].X ); int ex = Math.Max( marks[0].X, marks[1].X ); int sy = Math.Min( marks[0].Y, marks[1].Y ); @@ -1703,7 +1692,8 @@ static void CopyCallback ( Player player, Vector3I[] marks, object tag ) { Map map = player.WorldMap; World playerWorld = player.World; - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); for ( int x = sx; x <= ex; x++ ) { for ( int y = sy; y <= ey; y++ ) { @@ -1730,9 +1720,7 @@ static void CopyCallback ( Player player, Vector3I[] marks, object tag ) { bounds.MinVertex, bounds.MaxVertex ); } - - - static readonly CommandDescriptor CdCut = new CommandDescriptor { + private static readonly CommandDescriptor CdCut = new CommandDescriptor { Name = "Cut", Category = CommandCategory.Building, Permissions = new[] { Permission.CopyAndPaste }, @@ -1744,11 +1732,12 @@ static void CopyCallback ( Player player, Vector3I[] marks, object tag ) { Handler = CutHandler }; - static void CutHandler ( Player player, Command cmd ) { + private static void CutHandler( Player player, Command cmd ) { Block fillBlock = Block.Air; if ( cmd.HasNext ) { fillBlock = cmd.NextBlock( player ); - if ( fillBlock == Block.Undefined ) return; + if ( fillBlock == Block.Undefined ) + return; if ( cmd.HasNext ) { CdCut.PrintUsage( player ); return; @@ -1768,8 +1757,7 @@ static void CutHandler ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdMirror = new CommandDescriptor { + private static readonly CommandDescriptor CdMirror = new CommandDescriptor { Name = "Mirror", Aliases = new[] { "flip" }, Category = CommandCategory.Building, @@ -1781,7 +1769,7 @@ static void CutHandler ( Player player, Command cmd ) { Handler = MirrorHandler }; - static void MirrorHandler ( Player player, Command cmd ) { + private static void MirrorHandler( Player player, Command cmd ) { CopyState originalInfo = player.GetCopyInformation(); if ( originalInfo == null ) { player.MessageNow( "Nothing to flip! Copy something first." ); @@ -1795,9 +1783,12 @@ static void MirrorHandler ( Player player, Command cmd ) { string axis; while ( ( axis = cmd.Next() ) != null ) { foreach ( char c in axis.ToLower() ) { - if ( c == 'x' ) flipX = true; - if ( c == 'y' ) flipY = true; - if ( c == 'z' ) flipH = true; + if ( c == 'x' ) + flipX = true; + if ( c == 'y' ) + flipY = true; + if ( c == 'z' ) + flipH = true; } } @@ -1885,9 +1876,7 @@ static void MirrorHandler ( Player player, Command cmd ) { player.SetCopyInformation( info ); } - - - static readonly CommandDescriptor CdRotate = new CommandDescriptor { + private static readonly CommandDescriptor CdRotate = new CommandDescriptor { Name = "Rotate", Aliases = new[] { "spin" }, Category = CommandCategory.Building, @@ -1897,7 +1886,7 @@ static void MirrorHandler ( Player player, Command cmd ) { Handler = RotateHandler }; - static void RotateHandler ( Player player, Command cmd ) { + private static void RotateHandler( Player player, Command cmd ) { CopyState originalInfo = player.GetCopyInformation(); if ( originalInfo == null ) { player.MessageNow( "Nothing to rotate! Copy something first." ); @@ -1917,13 +1906,16 @@ static void RotateHandler ( Player player, Command cmd ) { case "x": axis = Axis.X; break; + case "y": axis = Axis.Y; break; + case "z": case "h": axis = Axis.Z; break; + default: CdRotate.PrintUsage( player ); return; @@ -1936,13 +1928,10 @@ static void RotateHandler ( Player player, Command cmd ) { if ( degrees == 180 ) { newBuffer = new Block[oldBuffer.GetLength( 0 ), oldBuffer.GetLength( 1 ), oldBuffer.GetLength( 2 )]; - } else if ( axis == Axis.X ) { newBuffer = new Block[oldBuffer.GetLength( 0 ), oldBuffer.GetLength( 2 ), oldBuffer.GetLength( 1 )]; - } else if ( axis == Axis.Y ) { newBuffer = new Block[oldBuffer.GetLength( 2 ), oldBuffer.GetLength( 1 ), oldBuffer.GetLength( 0 )]; - } else { // axis == Axis.Z newBuffer = new Block[oldBuffer.GetLength( 1 ), oldBuffer.GetLength( 0 ), oldBuffer.GetLength( 2 )]; } @@ -1963,10 +1952,12 @@ static void RotateHandler ( Player player, Command cmd ) { a = 1; b = 2; break; + case Axis.Y: a = 0; b = 2; break; + default: a = 0; b = 1; @@ -1980,10 +1971,12 @@ static void RotateHandler ( Player player, Command cmd ) { matrix[a, b] = -1; matrix[b, a] = 1; break; + case 180: matrix[a, a] = -1; matrix[b, b] = -1; break; + case -90: case 270: matrix[a, a] = 0; @@ -2016,9 +2009,7 @@ static void RotateHandler ( Player player, Command cmd ) { player.SetCopyInformation( info ); } - - - static readonly CommandDescriptor CdPasteX = new CommandDescriptor { + private static readonly CommandDescriptor CdPasteX = new CommandDescriptor { Name = "PasteX", Aliases = new[] { "px" }, Category = CommandCategory.Building, @@ -2031,17 +2022,16 @@ static void RotateHandler ( Player player, Command cmd ) { Handler = PasteXHandler }; - static void PasteXHandler ( Player player, Command cmd ) { + private static void PasteXHandler( Player player, Command cmd ) { PasteDrawOperation op = new PasteDrawOperation( player, false ); - if ( !op.ReadParams( cmd ) ) return; + if ( !op.ReadParams( cmd ) ) + return; player.SelectionStart( 2, DrawOperationCallback, op, Permission.Draw, Permission.CopyAndPaste ); player.MessageNow( "{0}: Click 2 blocks or use &H/Mark&S to make a selection.", op.Description ); } - - - static readonly CommandDescriptor CdPasteNotX = new CommandDescriptor { + private static readonly CommandDescriptor CdPasteNotX = new CommandDescriptor { Name = "PasteNotX", Aliases = new[] { "pnx", "pxn" }, Category = CommandCategory.Building, @@ -2054,17 +2044,16 @@ static void PasteXHandler ( Player player, Command cmd ) { Handler = PasteNotXHandler }; - static void PasteNotXHandler ( Player player, Command cmd ) { + private static void PasteNotXHandler( Player player, Command cmd ) { PasteDrawOperation op = new PasteDrawOperation( player, true ); - if ( !op.ReadParams( cmd ) ) return; + if ( !op.ReadParams( cmd ) ) + return; player.SelectionStart( 2, DrawOperationCallback, op, Permission.Draw, Permission.CopyAndPaste ); player.MessageNow( "{0}: Click 2 blocks or use &H/Mark&S to make a selection.", op.Description ); } - - - static readonly CommandDescriptor CdPaste = new CommandDescriptor { + private static readonly CommandDescriptor CdPaste = new CommandDescriptor { Name = "Paste", Category = CommandCategory.Building, Permissions = new[] { Permission.CopyAndPaste }, @@ -2076,17 +2065,16 @@ static void PasteNotXHandler ( Player player, Command cmd ) { Handler = PasteHandler }; - static void PasteHandler ( Player player, Command cmd ) { + private static void PasteHandler( Player player, Command cmd ) { QuickPasteDrawOperation op = new QuickPasteDrawOperation( player, false ); - if ( !op.ReadParams( cmd ) ) return; + if ( !op.ReadParams( cmd ) ) + return; player.SelectionStart( 1, DrawOperationCallback, op, Permission.Draw, Permission.CopyAndPaste ); player.MessageNow( "{0}: Click a block or use &H/Mark&S to begin pasting.", op.Description ); } - - - static readonly CommandDescriptor CdPasteNot = new CommandDescriptor { + private static readonly CommandDescriptor CdPasteNot = new CommandDescriptor { Name = "PasteNot", Aliases = new[] { "pn" }, Category = CommandCategory.Building, @@ -2099,22 +2087,22 @@ static void PasteHandler ( Player player, Command cmd ) { Handler = PasteNotHandler }; - static void PasteNotHandler ( Player player, Command cmd ) { + private static void PasteNotHandler( Player player, Command cmd ) { QuickPasteDrawOperation op = new QuickPasteDrawOperation( player, true ); - if ( !op.ReadParams( cmd ) ) return; + if ( !op.ReadParams( cmd ) ) + return; player.SelectionStart( 1, DrawOperationCallback, op, Permission.Draw, Permission.CopyAndPaste ); player.MessageNow( "{0}: Click a block or use &H/Mark&S to begin pasting.", op.Description ); } - #endregion + #endregion Copy and Paste #region Restore - const BlockChangeContext RestoreContext = BlockChangeContext.Drawn | BlockChangeContext.Restored; - + private const BlockChangeContext RestoreContext = BlockChangeContext.Drawn | BlockChangeContext.Restored; - static readonly CommandDescriptor CdRestore = new CommandDescriptor { + private static readonly CommandDescriptor CdRestore = new CommandDescriptor { Name = "Restore", Category = CommandCategory.World, Permissions = new[] { @@ -2130,7 +2118,7 @@ static void PasteNotHandler ( Player player, Command cmd ) { Handler = RestoreHandler }; - static void RestoreHandler ( Player player, Command cmd ) { + private static void RestoreHandler( Player player, Command cmd ) { string fileName = cmd.Next(); if ( fileName == null ) { CdRestore.PrintUsage( player ); @@ -2142,7 +2130,8 @@ static void RestoreHandler ( Player player, Command cmd ) { } string fullFileName = WorldManager.FindMapFile( player, fileName ); - if ( fullFileName == null ) return; + if ( fullFileName == null ) + return; Map map; if ( !MapUtility.TryLoad( fullFileName, out map ) ) { @@ -2164,8 +2153,7 @@ static void RestoreHandler ( Player player, Command cmd ) { player.MessageNow( "Restore: Select the area to restore. To mark a corner, place/click a block or type &H/Mark" ); } - - static void RestoreCallback ( Player player, Vector3I[] marks, object tag ) { + private static void RestoreCallback( Player player, Vector3I[] marks, object tag ) { BoundingBox selection = new BoundingBox( marks[0], marks[1] ); Map map = ( Map )tag; @@ -2182,7 +2170,8 @@ static void RestoreCallback ( Player player, Vector3I[] marks, object tag ) { UndoState undoState = player.DrawBegin( null ); World playerWorld = player.World; - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); Map playerMap = player.WorldMap; for ( int x = selection.XMin; x <= selection.XMax; x++ ) { for ( int y = selection.YMin; y <= selection.YMax; y++ ) { @@ -2205,11 +2194,11 @@ static void RestoreCallback ( Player player, Vector3I[] marks, object tag ) { DrawingFinished( player, "Restored", blocksDrawn, blocksSkipped ); } - #endregion + #endregion Restore #region Mark, Cancel - static readonly CommandDescriptor CdMark = new CommandDescriptor { + private static readonly CommandDescriptor CdMark = new CommandDescriptor { Name = "Mark", Aliases = new[] { "m" }, Category = CommandCategory.Building, @@ -2219,7 +2208,7 @@ static void RestoreCallback ( Player player, Vector3I[] marks, object tag ) { Handler = MarkHandler }; - static void MarkHandler ( Player player, Command cmd ) { + private static void MarkHandler( Player player, Command cmd ) { Map map = player.WorldMap; int x, y, z; Vector3I coords; @@ -2243,9 +2232,7 @@ static void MarkHandler ( Player player, Command cmd ) { } } - - - static readonly CommandDescriptor CdCancel = new CommandDescriptor { + private static readonly CommandDescriptor CdCancel = new CommandDescriptor { Name = "Cancel", Category = CommandCategory.Building, NotRepeatable = true, @@ -2254,7 +2241,7 @@ static void MarkHandler ( Player player, Command cmd ) { Handler = CancelHandler }; - static void CancelHandler ( Player player, Command cmd ) { + private static void CancelHandler( Player player, Command cmd ) { if ( cmd.HasNext ) { CdCancel.PrintUsage( player ); return; @@ -2267,11 +2254,11 @@ static void CancelHandler ( Player player, Command cmd ) { } } - #endregion + #endregion Mark, Cancel #region UndoPlayer and UndoArea - sealed class BlockDBUndoArgs { + private sealed class BlockDBUndoArgs { public Player Player; public PlayerInfo[] Targets; public World World; @@ -2282,13 +2269,13 @@ sealed class BlockDBUndoArgs { public bool Not; } - // parses and checks command parameters (for both UndoPlayer and UndoArea) [CanBeNull] - static BlockDBUndoArgs ParseBlockDBUndoParams ( Player player, Command cmd, string cmdName, bool not ) { + private static BlockDBUndoArgs ParseBlockDBUndoParams( Player player, Command cmd, string cmdName, bool not ) { // check if command's being called by a worldless player (e.g. console) World playerWorld = player.World; - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); // ensure that BlockDB is enabled if ( !BlockDB.IsEnabledGlobally ) { @@ -2303,45 +2290,44 @@ static BlockDBUndoArgs ParseBlockDBUndoParams ( Player player, Command cmd, stri // parse first and consequent parameters (player names) HashSet targets = new HashSet(); bool allPlayers = false; - string name = cmd.Next(); - if ( name == null ) { + string name = cmd.Next(); + if ( name == null ) { + return null; + } else if ( name == "*" ) { + // all players + if ( not ) { + player.Message( "{0}: \"*\" not allowed (cannot undo \"everyone except everyone\")", cmdName ); + return null; + } + if ( allPlayers ) { + player.Message( "{0}: \"*\" was listed twice.", cmdName ); + return null; + } + allPlayers = true; + } else { + // individual player + PlayerInfo target = PlayerDB.FindPlayerInfoOrPrintMatches( player, name ); + if ( target == null ) { + return null; + } + if ( targets.Contains( target ) ) { + player.Message( "{0}: Player {1}&S was listed twice.", + target.ClassyName, cmdName ); + return null; + } + // make sure player has the permission + if ( !not && + player.Info != target && !player.Can( Permission.UndoAll ) && + !player.Can( Permission.UndoOthersActions, target.Rank ) ) { + player.Message( "&W{0}: You may only undo actions of players ranked {1}&S or lower.", + cmdName, + player.Info.Rank.GetLimit( Permission.UndoOthersActions ).ClassyName ); + player.Message( "Player {0}&S is ranked {1}", + target.ClassyName, target.Rank.ClassyName ); return null; - } else if ( name == "*" ) { - // all players - if ( not ) { - player.Message( "{0}: \"*\" not allowed (cannot undo \"everyone except everyone\")", cmdName ); - return null; - } - if ( allPlayers ) { - player.Message( "{0}: \"*\" was listed twice.", cmdName ); - return null; - } - allPlayers = true; - - } else { - // individual player - PlayerInfo target = PlayerDB.FindPlayerInfoOrPrintMatches( player, name ); - if ( target == null ) { - return null; - } - if ( targets.Contains( target ) ) { - player.Message( "{0}: Player {1}&S was listed twice.", - target.ClassyName, cmdName ); - return null; - } - // make sure player has the permission - if ( !not && - player.Info != target && !player.Can( Permission.UndoAll ) && - !player.Can( Permission.UndoOthersActions, target.Rank ) ) { - player.Message( "&W{0}: You may only undo actions of players ranked {1}&S or lower.", - cmdName, - player.Info.Rank.GetLimit( Permission.UndoOthersActions ).ClassyName ); - player.Message( "Player {0}&S is ranked {1}", - target.ClassyName, target.Rank.ClassyName ); - return null; - } - targets.Add( target ); } + targets.Add( target ); + } // parse the 2nd parameter - either numeric or time limit string range = cmd.Next(); @@ -2349,7 +2335,7 @@ static BlockDBUndoArgs ParseBlockDBUndoParams ( Player player, Command cmd, stri CdUndoPlayer.PrintUsage( player ); return null; } - + if ( targets.Count == 0 && !allPlayers ) { player.Message( "{0}: Specify at least one player name, or \"*\" to undo everyone.", cmdName ); return null; @@ -2388,14 +2374,14 @@ static BlockDBUndoArgs ParseBlockDBUndoParams ( Player player, Command cmd, stri }; } - // called after player types "/ok" to the confirmation prompt. - static void BlockDBUndoConfirmCallback ( Player player, object tag, bool fromConsole ) { + private static void BlockDBUndoConfirmCallback( Player player, object tag, bool fromConsole ) { BlockDBUndoArgs args = ( BlockDBUndoArgs )tag; string cmdName = ( args.Area == null ? "UndoArea" : "UndoPlayer" ); - if ( args.Not ) cmdName += "Not"; + if ( args.Not ) + cmdName += "Not"; - // Produce + // Produce Vector3I[] coords; if ( args.Area != null ) { coords = new[] { args.Area.MinVertex, args.Area.MaxVertex }; @@ -2456,10 +2442,9 @@ static void BlockDBUndoConfirmCallback ( Player player, object tag, bool fromCon op.Begin(); } - #region UndoArea - static readonly CommandDescriptor CdUndoArea = new CommandDescriptor { + private static readonly CommandDescriptor CdUndoArea = new CommandDescriptor { Name = "UndoArea", Aliases = new[] { "ua" }, Category = CommandCategory.Moderation, @@ -2472,10 +2457,11 @@ static void BlockDBUndoConfirmCallback ( Player player, object tag, bool fromCon Handler = UndoAreaHandler }; - static void UndoAreaHandler ( Player player, Command cmd ) { - if ( !cmd.HasNext ){ CdUndoArea.PrintUsage( player ); return; } + private static void UndoAreaHandler( Player player, Command cmd ) { + if ( !cmd.HasNext ) { CdUndoArea.PrintUsage( player ); return; } BlockDBUndoArgs args = ParseBlockDBUndoParams( player, cmd, "UndoArea", false ); - if ( args == null ) return; + if ( args == null ) + return; Permission permission; if ( args.Targets.Length == 0 ) { @@ -2487,8 +2473,7 @@ static void UndoAreaHandler ( Player player, Command cmd ) { player.MessageNow( "UndoArea: Click or &H/Mark&S 2 blocks." ); } - - static readonly CommandDescriptor CdUndoAreaNot = new CommandDescriptor { + private static readonly CommandDescriptor CdUndoAreaNot = new CommandDescriptor { Name = "UndoAreaNot", Aliases = new[] { "uan", "una" }, Category = CommandCategory.Moderation, @@ -2500,27 +2485,26 @@ static void UndoAreaHandler ( Player player, Command cmd ) { Handler = UndoAreaNotHandler }; - static void UndoAreaNotHandler ( Player player, Command cmd ) { + private static void UndoAreaNotHandler( Player player, Command cmd ) { if ( !cmd.HasNext ) { CdUndoAreaNot.PrintUsage( player ); return; } BlockDBUndoArgs args = ParseBlockDBUndoParams( player, cmd, "UndoAreaNot", true ); - if ( args == null ) return; + if ( args == null ) + return; player.SelectionStart( 2, UndoAreaSelectionCallback, args, CdUndoAreaNot.Permissions ); player.MessageNow( "UndoAreaNot: Click or &H/Mark&S 2 blocks." ); } - // Queues UndoAreaLookup to run in the background - static void UndoAreaSelectionCallback ( Player player, Vector3I[] marks, object tag ) { + private static void UndoAreaSelectionCallback( Player player, Vector3I[] marks, object tag ) { BlockDBUndoArgs args = ( BlockDBUndoArgs )tag; args.Area = new BoundingBox( marks[0], marks[1] ); Scheduler.NewBackgroundTask( UndoAreaLookup ) .RunOnce( args, TimeSpan.Zero ); } - // Looks up the changes in BlockDB and prints a confirmation prompt. Runs on a background thread. - static void UndoAreaLookup ( SchedulerTask task ) { + private static void UndoAreaLookup( SchedulerTask task ) { BlockDBUndoArgs args = ( BlockDBUndoArgs )task.UserState; bool allPlayers = ( args.Targets.Length == 0 ); string cmdName = ( args.Not ? "UndoAreaNot" : "UndoArea" ); @@ -2551,7 +2535,6 @@ static void UndoAreaLookup ( SchedulerTask task ) { "Undo last {0} changes made here by {1}&S?", changes.Length, targetList ); } - } else { // time-limited lookup if ( args.Targets.Length == 0 ) { @@ -2577,12 +2560,11 @@ static void UndoAreaLookup ( SchedulerTask task ) { } } - #endregion - + #endregion UndoArea #region UndoPlayer - static readonly CommandDescriptor CdUndoPlayer = new CommandDescriptor { + private static readonly CommandDescriptor CdUndoPlayer = new CommandDescriptor { Name = "UndoPlayer", Aliases = new[] { "up", "undox" }, Category = CommandCategory.Moderation, @@ -2593,16 +2575,16 @@ static void UndoAreaLookup ( SchedulerTask task ) { Handler = UndoPlayerHandler }; - static void UndoPlayerHandler ( Player player, Command cmd ) { + private static void UndoPlayerHandler( Player player, Command cmd ) { if ( !cmd.HasNext ) { CdUndoPlayer.PrintUsage( player ); return; } BlockDBUndoArgs args = ParseBlockDBUndoParams( player, cmd, "UndoPlayer", false ); - if ( args == null ) return; + if ( args == null ) + return; Scheduler.NewBackgroundTask( UndoPlayerLookup ) .RunOnce( args, TimeSpan.Zero ); } - - static readonly CommandDescriptor CdUndoPlayerNot = new CommandDescriptor { + private static readonly CommandDescriptor CdUndoPlayerNot = new CommandDescriptor { Name = "UndoPlayerNot", Aliases = new[] { "upn", "unp" }, Category = CommandCategory.Moderation, @@ -2613,17 +2595,17 @@ static void UndoPlayerHandler ( Player player, Command cmd ) { Handler = UndoPlayerNotHandler }; - static void UndoPlayerNotHandler ( Player player, Command cmd ) { + private static void UndoPlayerNotHandler( Player player, Command cmd ) { if ( !cmd.HasNext ) { CdUndoPlayerNot.PrintUsage( player ); return; } BlockDBUndoArgs args = ParseBlockDBUndoParams( player, cmd, "UndoPlayerNot", true ); - if ( args == null ) return; + if ( args == null ) + return; Scheduler.NewBackgroundTask( UndoPlayerLookup ) .RunOnce( args, TimeSpan.Zero ); } - // Looks up the changes in BlockDB and prints a confirmation prompt. Runs on a background thread. - static void UndoPlayerLookup ( SchedulerTask task ) { + private static void UndoPlayerLookup( SchedulerTask task ) { BlockDBUndoArgs args = ( BlockDBUndoArgs )task.UserState; bool allPlayers = ( args.Targets.Length == 0 ); string cmdName = ( args.Not ? "UndoPlayerNot" : "UndoPlayer" ); @@ -2654,7 +2636,6 @@ static void UndoPlayerLookup ( SchedulerTask task ) { "Undo last {0} changes made by {1}&S?", changes.Length, targetList ); } - } else { // time-limited lookup if ( args.Targets.Length == 0 ) { @@ -2680,20 +2661,20 @@ static void UndoPlayerLookup ( SchedulerTask task ) { } } - #endregion + #endregion UndoPlayer - #endregion + #endregion UndoPlayer and UndoArea #region Static - static readonly CommandDescriptor CdStatic = new CommandDescriptor { + private static readonly CommandDescriptor CdStatic = new CommandDescriptor { Name = "Static", Category = CommandCategory.Building, Help = "&HToggles repetition of last selection on or off.", Handler = StaticHandler }; - static void StaticHandler ( Player player, Command cmd ) { + private static void StaticHandler( Player player, Command cmd ) { if ( cmd.HasNext ) { CdStatic.PrintUsage( player ); return; @@ -2708,6 +2689,6 @@ static void StaticHandler ( Player player, Command cmd ) { } } - #endregion + #endregion Static } } \ No newline at end of file diff --git a/fCraft/Commands/ChatCommands.cs b/fCraft/Commands/ChatCommands.cs index 971d7b2..d4a016d 100644 --- a/fCraft/Commands/ChatCommands.cs +++ b/fCraft/Commands/ChatCommands.cs @@ -4,9 +4,10 @@ using System.Linq; namespace fCraft { - static class ChatCommands { - public static void Init () { + internal static class ChatCommands { + + public static void Init() { CommandManager.RegisterCommand( CdSay ); CommandManager.RegisterCommand( CdStaff ); @@ -37,6 +38,7 @@ public static void Init () { Player.Moved += new EventHandler( Player_IsBack ); } + #region 800Craft /* ---- @@ -65,7 +67,8 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ - static readonly CommandDescriptor CdQuit = new CommandDescriptor { + + private static readonly CommandDescriptor CdQuit = new CommandDescriptor { Name = "Quitmsg", Aliases = new[] { "quit", "quitmessage" }, Category = CommandCategory.Chat, @@ -76,7 +79,7 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY Handler = QuitHandler }; - static void QuitHandler ( Player player, Command cmd ) { + private static void QuitHandler( Player player, Command cmd ) { string Msg = cmd.NextAll(); if ( Msg.Length < 1 ) { @@ -88,7 +91,7 @@ static void QuitHandler ( Player player, Command cmd ) { } } - static readonly CommandDescriptor CdRageQuit = new CommandDescriptor { + private static readonly CommandDescriptor CdRageQuit = new CommandDescriptor { Name = "Ragequit", Aliases = new[] { "rq" }, Category = CommandCategory.Chat | CommandCategory.Fun, @@ -99,7 +102,7 @@ static void QuitHandler ( Player player, Command cmd ) { Handler = RageHandler }; - static void RageHandler ( Player player, Command cmd ) { + private static void RageHandler( Player player, Command cmd ) { string reason = cmd.NextAll(); if ( reason.Length < 1 ) { Server.Players.Message( "{0} &4Ragequit from the server", player.ClassyName ); @@ -114,7 +117,7 @@ static void RageHandler ( Player player, Command cmd ) { } } - static readonly CommandDescriptor CdBroMode = new CommandDescriptor { + private static readonly CommandDescriptor CdBroMode = new CommandDescriptor { Name = "Bromode", Aliases = new string[] { "bm" }, Category = CommandCategory.Chat | CommandCategory.Fun, @@ -125,7 +128,7 @@ static void RageHandler ( Player player, Command cmd ) { Handler = BroMode }; - static void BroMode ( Player player, Command command ) { + private static void BroMode( Player player, Command command ) { if ( !fCraft.Utils.BroMode.Active ) { foreach ( Player p in Server.Players ) { fCraft.Utils.BroMode.GetInstance().RegisterPlayer( p ); @@ -145,7 +148,7 @@ static void BroMode ( Player player, Command command ) { } } - public static void Player_IsBack ( object sender, Events.PlayerMovedEventArgs e ) { + public static void Player_IsBack( object sender, Events.PlayerMovedEventArgs e ) { if ( e.Player.IsAway ) { // We need to have block positions, so we divide by 32 Vector3I oldPos = new Vector3I( e.OldPosition.X / 32, e.OldPosition.Y / 32, e.OldPosition.Z / 32 ); @@ -159,7 +162,7 @@ public static void Player_IsBack ( object sender, Events.PlayerMovedEventArgs e } } - static readonly CommandDescriptor CdVote = new CommandDescriptor { + private static readonly CommandDescriptor CdVote = new CommandDescriptor { Name = "Vote", Category = CommandCategory.Chat | CommandCategory.Fun, Permissions = new[] { Permission.Chat }, @@ -170,11 +173,11 @@ public static void Player_IsBack ( object sender, Events.PlayerMovedEventArgs e Handler = VoteHandler }; - public static void VoteHandler ( Player player, Command cmd ) { + public static void VoteHandler( Player player, Command cmd ) { fCraft.VoteHandler.VoteParams( player, cmd ); } - static readonly CommandDescriptor CdCustomChat = new CommandDescriptor { + private static readonly CommandDescriptor CdCustomChat = new CommandDescriptor { Name = ConfigKey.CustomChatName.GetString(), Category = CommandCategory.Chat, Aliases = new[] { ConfigKey.CustomAliasName.GetString() }, @@ -186,13 +189,14 @@ public static void VoteHandler ( Player player, Command cmd ) { Handler = CustomChatHandler }; - static void CustomChatHandler ( Player player, Command cmd ) { + private static void CustomChatHandler( Player player, Command cmd ) { if ( player.Info.IsMuted ) { player.MessageMuted(); return; } - if ( player.DetectChatSpam() ) return; + if ( player.DetectChatSpam() ) + return; string message = cmd.NextAll().Trim(); if ( message.Length > 0 ) { @@ -203,7 +207,7 @@ static void CustomChatHandler ( Player player, Command cmd ) { } } - static readonly CommandDescriptor cdAway = new CommandDescriptor { + private static readonly CommandDescriptor cdAway = new CommandDescriptor { Name = "Away", Category = CommandCategory.Chat, Aliases = new[] { "afk" }, @@ -214,7 +218,7 @@ static void CustomChatHandler ( Player player, Command cmd ) { Handler = Away }; - internal static void Away ( Player player, Command cmd ) { + internal static void Away( Player player, Command cmd ) { string msg = cmd.NextAll().Trim(); if ( player.Info.IsMuted ) { player.MessageMuted(); @@ -231,8 +235,7 @@ internal static void Away ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdHigh5 = new CommandDescriptor { + private static readonly CommandDescriptor CdHigh5 = new CommandDescriptor { Name = "High5", Aliases = new string[] { "H5" }, Category = CommandCategory.Chat | CommandCategory.Fun, @@ -244,7 +247,7 @@ internal static void Away ( Player player, Command cmd ) { Handler = High5Handler, }; - internal static void High5Handler ( Player player, Command cmd ) { + internal static void High5Handler( Player player, Command cmd ) { string targetName = cmd.Next(); if ( targetName == null ) { CdHigh5.PrintUsage( player ); @@ -262,7 +265,7 @@ internal static void High5Handler ( Player player, Command cmd ) { target.Message( "{0}&S high fived you.", player.ClassyName ); } - static readonly CommandDescriptor CdPoke = new CommandDescriptor { + private static readonly CommandDescriptor CdPoke = new CommandDescriptor { Name = "Poke", Category = CommandCategory.Chat | CommandCategory.Fun, IsConsoleSafe = true, @@ -272,7 +275,7 @@ internal static void High5Handler ( Player player, Command cmd ) { Handler = PokeHandler }; - internal static void PokeHandler ( Player player, Command cmd ) { + internal static void PokeHandler( Player player, Command cmd ) { string targetName = cmd.Next(); if ( targetName == null ) { CdPoke.PrintUsage( player ); @@ -299,7 +302,7 @@ internal static void PokeHandler ( Player player, Command cmd ) { } } - static readonly CommandDescriptor cdReview = new CommandDescriptor { + private static readonly CommandDescriptor cdReview = new CommandDescriptor { Name = "Review", Category = CommandCategory.Chat, IsConsoleSafe = true, @@ -309,7 +312,7 @@ internal static void PokeHandler ( Player player, Command cmd ) { Handler = Review }; - internal static void Review ( Player player, Command cmd ) { + internal static void Review( Player player, Command cmd ) { if ( player.Info.IsMuted ) { player.MessageMuted(); return; @@ -329,7 +332,7 @@ internal static void Review ( Player player, Command cmd ) { player.Message( "&WThere are no players online who can review you. A member of staff needs to be online." ); } - static readonly CommandDescriptor CdAdminChat = new CommandDescriptor { + private static readonly CommandDescriptor CdAdminChat = new CommandDescriptor { Name = "Adminchat", Aliases = new[] { "ac" }, Category = CommandCategory.Chat | CommandCategory.Moderation, @@ -341,7 +344,7 @@ internal static void Review ( Player player, Command cmd ) { Handler = AdminChat }; - internal static void AdminChat ( Player player, Command cmd ) { + internal static void AdminChat( Player player, Command cmd ) { if ( player.Info.IsMuted ) { player.MessageMuted(); return; @@ -359,11 +362,12 @@ internal static void AdminChat ( Player player, Command cmd ) { Chat.SendAdmin( player, message ); } } - #endregion + + #endregion 800Craft #region Say - static readonly CommandDescriptor CdSay = new CommandDescriptor { + private static readonly CommandDescriptor CdSay = new CommandDescriptor { Name = "Say", Category = CommandCategory.Chat, IsConsoleSafe = true, @@ -376,13 +380,14 @@ internal static void AdminChat ( Player player, Command cmd ) { Handler = SayHandler }; - static void SayHandler ( Player player, Command cmd ) { + private static void SayHandler( Player player, Command cmd ) { if ( player.Info.IsMuted ) { player.MessageMuted(); return; } - if ( player.DetectChatSpam() ) return; + if ( player.DetectChatSpam() ) + return; if ( player.Can( Permission.Say ) ) { string msg = cmd.NextAll().Trim(); @@ -396,12 +401,11 @@ static void SayHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Say #region Staff - static readonly CommandDescriptor CdStaff = new CommandDescriptor { + private static readonly CommandDescriptor CdStaff = new CommandDescriptor { Name = "Staff", Aliases = new[] { "st" }, Category = CommandCategory.Chat | CommandCategory.Moderation, @@ -414,13 +418,14 @@ static void SayHandler ( Player player, Command cmd ) { Handler = StaffHandler }; - static void StaffHandler ( Player player, Command cmd ) { + private static void StaffHandler( Player player, Command cmd ) { if ( player.Info.IsMuted ) { player.MessageMuted(); return; } - if ( player.DetectChatSpam() ) return; + if ( player.DetectChatSpam() ) + return; string message = cmd.NextAll().Trim(); if ( message.Length > 0 ) { @@ -428,12 +433,11 @@ static void StaffHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Staff #region Ignore / Unignore - static readonly CommandDescriptor CdIgnore = new CommandDescriptor { + private static readonly CommandDescriptor CdIgnore = new CommandDescriptor { Name = "Ignore", Category = CommandCategory.Chat, IsConsoleSafe = true, @@ -443,7 +447,7 @@ static void StaffHandler ( Player player, Command cmd ) { Handler = IgnoreHandler }; - static void IgnoreHandler ( Player player, Command cmd ) { + private static void IgnoreHandler( Player player, Command cmd ) { string name = cmd.Next(); if ( name != null ) { if ( cmd.HasNext ) { @@ -451,14 +455,14 @@ static void IgnoreHandler ( Player player, Command cmd ) { return; } PlayerInfo targetInfo = PlayerDB.FindPlayerInfoOrPrintMatches( player, name ); - if ( targetInfo == null ) return; + if ( targetInfo == null ) + return; if ( player.Ignore( targetInfo ) ) { player.MessageNow( "You are now ignoring {0}", targetInfo.ClassyName ); } else { player.MessageNow( "You are already ignoring {0}", targetInfo.ClassyName ); } - } else { PlayerInfo[] ignoreList = player.IgnoreList; if ( ignoreList.Length > 0 ) { @@ -470,8 +474,7 @@ static void IgnoreHandler ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdUnignore = new CommandDescriptor { + private static readonly CommandDescriptor CdUnignore = new CommandDescriptor { Name = "Unignore", Category = CommandCategory.Chat, IsConsoleSafe = true, @@ -480,7 +483,7 @@ static void IgnoreHandler ( Player player, Command cmd ) { Handler = UnignoreHandler }; - static void UnignoreHandler ( Player player, Command cmd ) { + private static void UnignoreHandler( Player player, Command cmd ) { string name = cmd.Next(); if ( name != null ) { if ( cmd.HasNext ) { @@ -488,7 +491,8 @@ static void UnignoreHandler ( Player player, Command cmd ) { return; } PlayerInfo targetInfo = PlayerDB.FindPlayerInfoOrPrintMatches( player, name ); - if ( targetInfo == null ) return; + if ( targetInfo == null ) + return; if ( player.Unignore( targetInfo ) ) { player.MessageNow( "You are no longer ignoring {0}", targetInfo.ClassyName ); @@ -506,12 +510,11 @@ static void UnignoreHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Ignore / Unignore #region Me - static readonly CommandDescriptor CdMe = new CommandDescriptor { + private static readonly CommandDescriptor CdMe = new CommandDescriptor { Name = "Me", Category = CommandCategory.Chat, Permissions = new[] { Permission.Chat }, @@ -523,13 +526,14 @@ static void UnignoreHandler ( Player player, Command cmd ) { Handler = MeHandler }; - static void MeHandler ( Player player, Command cmd ) { + private static void MeHandler( Player player, Command cmd ) { if ( player.Info.IsMuted ) { player.MessageMuted(); return; } - if ( player.DetectChatSpam() ) return; + if ( player.DetectChatSpam() ) + return; string msg = cmd.NextAll().Trim(); if ( msg.Length > 0 ) { @@ -539,12 +543,11 @@ static void MeHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Me #region Roll - static readonly CommandDescriptor CdRoll = new CommandDescriptor { + private static readonly CommandDescriptor CdRoll = new CommandDescriptor { Name = "Roll", Category = CommandCategory.Chat, Permissions = new[] { Permission.Chat }, @@ -557,13 +560,14 @@ static void MeHandler ( Player player, Command cmd ) { Handler = RollHandler }; - static void RollHandler ( Player player, Command cmd ) { + private static void RollHandler( Player player, Command cmd ) { if ( player.Info.IsMuted ) { player.MessageMuted(); return; } - if ( player.DetectChatSpam() ) return; + if ( player.DetectChatSpam() ) + return; Random rand = new Random(); int n1; @@ -588,12 +592,11 @@ static void RollHandler ( Player player, Command cmd ) { Color.Silver, num, min, max ); } - #endregion - + #endregion Roll #region Deafen - static readonly CommandDescriptor CdDeafen = new CommandDescriptor { + private static readonly CommandDescriptor CdDeafen = new CommandDescriptor { Name = "Deafen", Aliases = new[] { "deaf" }, Category = CommandCategory.Chat, @@ -602,7 +605,7 @@ static void RollHandler ( Player player, Command cmd ) { Handler = DeafenHandler }; - static void DeafenHandler ( Player player, Command cmd ) { + private static void DeafenHandler( Player player, Command cmd ) { if ( cmd.HasNext ) { CdDeafen.PrintUsage( player ); return; @@ -620,13 +623,13 @@ static void DeafenHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Deafen #region Clear - const int LinesToClear = 30; - static readonly CommandDescriptor CdClear = new CommandDescriptor { + private const int LinesToClear = 30; + + private static readonly CommandDescriptor CdClear = new CommandDescriptor { Name = "Clear", UsableByFrozenPlayers = true, Category = CommandCategory.Chat, @@ -634,7 +637,7 @@ static void DeafenHandler ( Player player, Command cmd ) { Handler = ClearHandler }; - static void ClearHandler ( Player player, Command cmd ) { + private static void ClearHandler( Player player, Command cmd ) { if ( cmd.HasNext ) { CdClear.PrintUsage( player ); return; @@ -644,12 +647,11 @@ static void ClearHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Clear #region Timer - static readonly CommandDescriptor CdTimer = new CommandDescriptor { + private static readonly CommandDescriptor CdTimer = new CommandDescriptor { Name = "Timer", Permissions = new[] { Permission.Say }, IsConsoleSafe = true, @@ -665,7 +667,7 @@ static void ClearHandler ( Player player, Command cmd ) { Handler = TimerHandler }; - static void TimerHandler ( Player player, Command cmd ) { + private static void TimerHandler( Player player, Command cmd ) { string param = cmd.Next(); // List timers @@ -707,7 +709,8 @@ static void TimerHandler ( Player player, Command cmd ) { player.MessageMuted(); return; } - if ( player.DetectChatSpam() ) return; + if ( player.DetectChatSpam() ) + return; TimeSpan duration; if ( !param.TryParseMiniTimespan( out duration ) ) { CdTimer.PrintUsage( player ); @@ -738,6 +741,6 @@ static void TimerHandler ( Player player, Command cmd ) { ChatTimer.Start( duration, message, player.Name ); } - #endregion + #endregion Timer } } \ No newline at end of file diff --git a/fCraft/Commands/Command Handlers/BroModeHandler.cs b/fCraft/Commands/Command Handlers/BroModeHandler.cs index 9e7a9ac..cae4641 100644 --- a/fCraft/Commands/Command Handlers/BroModeHandler.cs +++ b/fCraft/Commands/Command Handlers/BroModeHandler.cs @@ -29,30 +29,24 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -namespace fCraft.Utils -{ - class BroMode - { +namespace fCraft.Utils { + + internal class BroMode { private static BroMode instance; private static List broNames; private static Dictionary registeredBroNames; private static int namesRegistered = 0; public static bool Active = false; - private BroMode() - { + private BroMode() { // Empty, singleton // single // single like glennmr? } - public static BroMode GetInstance() - { - if (instance == null) - { + public static BroMode GetInstance() { + if ( instance == null ) { instance = new BroMode(); broNames = new List() { @@ -171,131 +165,100 @@ public static BroMode GetInstance() "Magnetbro" }; registeredBroNames = new Dictionary(); - Player.Disconnected += new EventHandler(Player_Disconnected); - Player.Connected += new EventHandler(Player_Connected); + Player.Disconnected += new EventHandler( Player_Disconnected ); + Player.Connected += new EventHandler( Player_Connected ); } return instance; } - static void Player_Connected(object sender, Events.PlayerConnectedEventArgs e) - { - if (Active) - { - BroMode.GetInstance().RegisterPlayer(e.Player); + private static void Player_Connected( object sender, Events.PlayerConnectedEventArgs e ) { + if ( Active ) { + BroMode.GetInstance().RegisterPlayer( e.Player ); } } - static void Player_Disconnected(object sender, Events.PlayerDisconnectedEventArgs e) - { - if (Active) - { - BroMode.GetInstance().UnregisterPlayer(e.Player); + private static void Player_Disconnected( object sender, Events.PlayerDisconnectedEventArgs e ) { + if ( Active ) { + BroMode.GetInstance().UnregisterPlayer( e.Player ); } } - public void RegisterPlayer(Player player) - { - if (!player.Info.IsWarned) - { - if (!player.Info.IsMuted) - { - if (!player.Info.IsFrozen) - { - try - { - if (namesRegistered < broNames.Count) - { + public void RegisterPlayer( Player player ) { + if ( !player.Info.IsWarned ) { + if ( !player.Info.IsMuted ) { + if ( !player.Info.IsFrozen ) { + try { + if ( namesRegistered < broNames.Count ) { Random randomizer = new Random(); - int index = randomizer.Next(0, broNames.Count); + int index = randomizer.Next( 0, broNames.Count ); int attempts = 0; Player output = null; bool found = false; - if (player.Info.DisplayedName == null) - { + if ( player.Info.DisplayedName == null ) { player.Info.changedName = false; //fix for rank problems during - } - - else + } else player.Info.oldname = player.Info.DisplayedName; player.Info.changedName = true; //if name is changed, true - while (!found) - { - registeredBroNames.TryGetValue(index, out output); + while ( !found ) { + registeredBroNames.TryGetValue( index, out output ); - if (output == null) - { + if ( output == null ) { found = true; break; } attempts++; - index = randomizer.Next(0, broNames.Count); + index = randomizer.Next( 0, broNames.Count ); output = null; - if (attempts > 2000) - { + if ( attempts > 2000 ) { // Not good :D break; } } - if (found) - { - player.Message("Giving you name: " + broNames[index]); - player.Info.DisplayedName = Color.ReplacePercentCodes(player.Info.Rank.Color + player.Info.Rank.Prefix + broNames[index]); + if ( found ) { + player.Message( "Giving you name: " + broNames[index] ); + player.Info.DisplayedName = Color.ReplacePercentCodes( player.Info.Rank.Color + player.Info.Rank.Prefix + broNames[index] ); namesRegistered++; registeredBroNames[index] = player; + } else { + player.Message( "Could not find a name for you." ); } - else - { - player.Message("Could not find a name for you."); - } + } else { + player.Message( "All bro names have been assigned." ); } - else - { - player.Message("All bro names have been assigned."); - } - } - catch (Exception ex) - { - Logger.Log(LogType.Error, "BroMode.RegisterPlayer: " + ex); + } catch ( Exception ex ) { + Logger.Log( LogType.Error, "BroMode.RegisterPlayer: " + ex ); } } } } } - public void UnregisterPlayer(Player p) - { - try - { - for (int i = 0; i < broNames.Count; i++) - { - if (registeredBroNames.ContainsKey(i) && registeredBroNames[i].Name.Equals(p.Name)) - { - Logger.Log(LogType.SystemActivity, "Unregistering bro name '" + broNames[i] + "' for player '" + p.Name + "'"); - registeredBroNames.Remove(i); + public void UnregisterPlayer( Player p ) { + try { + for ( int i = 0; i < broNames.Count; i++ ) { + if ( registeredBroNames.ContainsKey( i ) && registeredBroNames[i].Name.Equals( p.Name ) ) { + Logger.Log( LogType.SystemActivity, "Unregistering bro name '" + broNames[i] + "' for player '" + p.Name + "'" ); + registeredBroNames.Remove( i ); namesRegistered--; - if (!p.Info.changedName) - { + if ( !p.Info.changedName ) { p.Info.DisplayedName = null; } - if (p.Info.changedName) - { + if ( p.Info.changedName ) { p.Info.DisplayedName = p.Info.oldname; p.Info.oldname = null; //clears oldname if its ever removed in setinfo p.Info.changedName = false; } } } - } - catch (Exception ex) - { - Logger.Log(LogType.Error, "BroMode.UnregisterPlayer: " + ex); + } catch ( Exception ex ) { + Logger.Log( LogType.Error, "BroMode.UnregisterPlayer: " + ex ); } } } diff --git a/fCraft/Commands/Command Handlers/FeedData.cs b/fCraft/Commands/Command Handlers/FeedData.cs index 1a1218b..8f5cdfa 100644 --- a/fCraft/Commands/Command Handlers/FeedData.cs +++ b/fCraft/Commands/Command Handlers/FeedData.cs @@ -1,27 +1,26 @@ using System; -using System.Collections.Generic; -using System.Linq; -using JetBrains.Annotations; -using fCraft; using System.Collections.Concurrent; +using System.Collections.Generic; using System.Drawing; -using fCraft.Events; +using System.Linq; using fCraft.Drawing; +using fCraft.Events; +using JetBrains.Annotations; namespace fCraft { public static class FeedSettings { - public static Bitmap ImageCache = null; - public static void PlayerJoiningWorld ( object sender, PlayerJoinedWorldEventArgs e ) { + public static void PlayerJoiningWorld( object sender, PlayerJoinedWorldEventArgs e ) { foreach ( FeedData data in e.NewWorld.Feeds.Values.Where( f => !f.started ) ) { if ( data.world.Name == e.NewWorld.Name ) { data.Start(); } } } - public static void PlayerPlacingBlock ( object sender, PlayerPlacingBlockEventArgs e ) { + + public static void PlayerPlacingBlock( object sender, PlayerPlacingBlockEventArgs e ) { foreach ( FeedData feed in e.Player.World.Feeds.Values ) { for ( int x = feed.StartPos.X; x <= feed.FinishPos.X; x++ ) { for ( int y = feed.StartPos.Y; y <= feed.FinishPos.Y; y++ ) { @@ -42,7 +41,7 @@ public sealed class FeedData { public Vector3I FinishPos; //the end position, start -> end public Vector3I EndPos; //the moving position - + public Vector3I Pos; //the position of the blockupdate public List last = new List(); public List originalMap = new List(); @@ -61,7 +60,7 @@ public sealed class FeedData { public SchedulerTask task; public Player player; - public FeedData ( Block _textType, Vector3I _pos, Bitmap Image, World world, Direction direction_, Player player_ ) { + public FeedData( Block _textType, Vector3I _pos, Bitmap Image, World world, Direction direction_, Player player_ ) { direction = direction_; Blocks = new ConcurrentDictionary(); Init( Image, world ); @@ -78,35 +77,37 @@ public FeedData ( Block _textType, Vector3I _pos, Bitmap Image, World world, Dir Operation.AnnounceCompletion = false; Operation.Brush = brush; Operation.Context = BlockChangeContext.Drawn; - + if ( !Operation.Prepare( new Vector3I[] { StartPos, FinishPos } ) ) { throw new Exception( "Unable to cubw frame." ); } Operation.Begin(); AddFeedToList( this, world ); - + Start(); } - public void Start () { + public void Start() { started = true; task = Scheduler.NewTask( StartFeed ); task.RunForever( TimeSpan.FromMilliseconds( 600 ) ); } public static int feedCounter; - static readonly object FeedListLock = new object(); + private static readonly object FeedListLock = new object(); - static void AddFeedToList ( [NotNull] FeedData data, [NotNull] World world ) { - if ( data == null ) throw new ArgumentNullException( "Feed" ); + private static void AddFeedToList( [NotNull] FeedData data, [NotNull] World world ) { + if ( data == null ) + throw new ArgumentNullException( "Feed" ); lock ( FeedListLock ) { world.Feeds.Add( data.Id, data ); } } - public static void RemoveFeedFromList ( [NotNull] FeedData data, [NotNull] World world ) { - if ( data == null ) throw new ArgumentNullException( "feed" ); + public static void RemoveFeedFromList( [NotNull] FeedData data, [NotNull] World world ) { + if ( data == null ) + throw new ArgumentNullException( "feed" ); lock ( FeedListLock ) { world.Feeds.Remove( data.Id ); } @@ -121,7 +122,7 @@ public FeedData[] FeedList { } [CanBeNull] - public static FeedData FindFeedById ( int id, World world ) { + public static FeedData FindFeedById( int id, World world ) { lock ( FeedListLock ) { FeedData result; if ( world.Feeds.TryGetValue( id, out result ) ) { @@ -131,8 +132,10 @@ public static FeedData FindFeedById ( int id, World world ) { } } } - static Permission[] per = new Permission[] { Permission.Promote, Permission.Demote, Permission.ReadStaffChat }; - public static void AddMessages () { + + private static Permission[] per = new Permission[] { Permission.Promote, Permission.Demote, Permission.ReadStaffChat }; + + public static void AddMessages() { if ( Messages != null ) { Messages.Clear(); } @@ -148,7 +151,8 @@ public static void AddMessages () { Messages.Add( "This scrolling feed is cool!" ); Messages.Add( "This server has had " + PlayerDB.PlayerInfoList.Count() + " unique visitors" ); } - public void Init ( Bitmap Image, World _world ) { + + public void Init( Bitmap Image, World _world ) { world = _world; List> pixels = new List>(); //open up PNG file @@ -192,9 +196,11 @@ public void Init ( Bitmap Image, World _world ) { } public bool done = true; //check to see if one cycle is complete - private void StartFeed ( SchedulerTask task ) { + + private void StartFeed( SchedulerTask task ) { if ( !started ) { task.Stop(); return; } - if ( !done ) return; + if ( !done ) + return; try { done = false; RemoveText(); @@ -204,6 +210,7 @@ private void StartFeed ( SchedulerTask task ) { case Direction.two: EndPos.X = FinishPos.X; break; + case Direction.three: case Direction.four: EndPos.Y = FinishPos.Y; @@ -216,12 +223,15 @@ private void StartFeed ( SchedulerTask task ) { case Direction.one: EndPos.X -= 7; break; + case Direction.two: EndPos.X += 7; break; + case Direction.three: EndPos.Y -= 7; break; + case Direction.four: EndPos.Y += 7; break; @@ -233,7 +243,8 @@ private void StartFeed ( SchedulerTask task ) { } public bool ChangeMessage = false; //a check if the previous sentence is complete - public void RemoveText () { + + public void RemoveText() { if ( Blocks.Values.Count < 1 ) { ChangeMessage = true; } foreach ( Vector3I block in Blocks.Values ) { if ( world.Map == null ) { @@ -249,7 +260,7 @@ public void RemoveText () { } //makes the block updates - public void Render ( string text ) { + public void Render( string text ) { List current = new List(); for ( int p = 0; p < text.Length; p++ ) { char c = text[p]; @@ -285,7 +296,7 @@ public void Render ( string text ) { done = true; } - public void Render ( string text, Block t ) { + public void Render( string text, Block t ) { byte temp = textType; textType = ( byte )t; Render( text ); @@ -293,7 +304,7 @@ public void Render ( string text, Block t ) { } //gets the next sentence - public void PickNewMessage () { + public void PickNewMessage() { if ( FeedData.Messages.Count() > 0 ) { FeedData.AddMessages(); if ( MessageCount == FeedData.Messages.Count() - 1 ) { @@ -307,7 +318,7 @@ public void PickNewMessage () { } //processess one blockupdate - public void sendWorldBlock ( int index, byte type ) { + public void sendWorldBlock( int index, byte type ) { if ( world.Map == null ) { started = false; return; @@ -329,6 +340,7 @@ public void sendWorldBlock ( int index, byte type ) { } } break; + case Direction.two: x = ( short )( EndPos.X - ( index / 8 ) ); y = ( short )StartPos.Y; @@ -343,6 +355,7 @@ public void sendWorldBlock ( int index, byte type ) { } } break; + case Direction.three: x = ( short )StartPos.X; y = ( short )( EndPos.Y + ( index / 8 ) ); @@ -357,6 +370,7 @@ public void sendWorldBlock ( int index, byte type ) { } } break; + case Direction.four: x = ( short )StartPos.X; y = ( short )( EndPos.Y - ( index / 8 ) ); @@ -371,6 +385,7 @@ public void sendWorldBlock ( int index, byte type ) { } } break; + default: break; } diff --git a/fCraft/Commands/Command Handlers/FlyHandler.cs b/fCraft/Commands/Command Handlers/FlyHandler.cs index c21be19..c018426 100644 --- a/fCraft/Commands/Command Handlers/FlyHandler.cs +++ b/fCraft/Commands/Command Handlers/FlyHandler.cs @@ -28,22 +28,18 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) <2011 - 2013> Glenn Mariën (http://project-vanilla.com) and Jon Baker (http://au70.net) using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Collections; using System.Collections.Concurrent; -using System.Threading; namespace fCraft.Utils { - class FlyHandler { + + internal class FlyHandler { private static FlyHandler instance; - private FlyHandler () { + private FlyHandler() { // Empty, singleton } - public static FlyHandler GetInstance () { + public static FlyHandler GetInstance() { if ( instance == null ) { instance = new FlyHandler(); Player.PlacingBlock += new EventHandler( Player_Clicked ); @@ -51,7 +47,8 @@ public static FlyHandler GetInstance () { return instance; } - private static void Player_Clicked ( object sender, Events.PlayerPlacingBlockEventArgs e ) //placing air + + private static void Player_Clicked( object sender, Events.PlayerPlacingBlockEventArgs e ) //placing air { if ( e.Player.IsFlying ) { if ( e.Context == BlockChangeContext.Manual )//ignore all other things { @@ -61,12 +58,12 @@ private static void Player_Clicked ( object sender, Events.PlayerPlacingBlockEve } } - public void StartFlying ( Player player ) { + public void StartFlying( Player player ) { player.IsFlying = true; player.FlyCache = new ConcurrentDictionary(); } - public void StopFlying ( Player player ) { + public void StopFlying( Player player ) { try { player.IsFlying = false; @@ -80,7 +77,7 @@ public void StopFlying ( Player player ) { } } - public static bool CanRemoveBlock ( Player player, Vector3I block, Vector3I newPos ) { + public static bool CanRemoveBlock( Player player, Vector3I block, Vector3I newPos ) { int x = block.X - newPos.X; int y = block.Y - newPos.Y; int z = block.Z - newPos.Z; diff --git a/fCraft/Commands/Command Handlers/GunHandler.cs b/fCraft/Commands/Command Handlers/GunHandler.cs index 4185fa9..5087c57 100644 --- a/fCraft/Commands/Command Handlers/GunHandler.cs +++ b/fCraft/Commands/Command Handlers/GunHandler.cs @@ -29,85 +29,74 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY using System; using System.Collections.Concurrent; -using System.Linq; -using System.Text; -using fCraft.Events; using System.Threading; +using fCraft.Events; -namespace fCraft -{ - public class GunGlassTimer - { +namespace fCraft { + + public class GunGlassTimer { private Timer _timer; private bool _started; private Player _player; private const int Tick = 125; private object _objectLock = new object(); - public GunGlassTimer(Player player) - { + + public GunGlassTimer( Player player ) { _player = player; _started = false; - _timer = new Timer(callback, null, Timeout.Infinite, Timeout.Infinite); + _timer = new Timer( callback, null, Timeout.Infinite, Timeout.Infinite ); } - public void Start() - { - lock (_objectLock) - { - if (!_started) - { + + public void Start() { + lock ( _objectLock ) { + if ( !_started ) { _started = true; - _timer.Change(0, Timeout.Infinite); + _timer.Change( 0, Timeout.Infinite ); } } } - public void Stop() - { - lock (_objectLock) - { + + public void Stop() { + lock ( _objectLock ) { _started = false; - _timer.Change(Timeout.Infinite, Timeout.Infinite); + _timer.Change( Timeout.Infinite, Timeout.Infinite ); } } - private void callback(object state) - { - try - { - if (_player.IsOnline && _player != null) - { - if (_player.GunMode){ - GunClass.gunMove(_player); - }else{ + + private void callback( object state ) { + try { + if ( _player.IsOnline && _player != null ) { + if ( _player.GunMode ) { + GunClass.gunMove( _player ); + } else { Stop(); } - }else{ + } else { Stop(); } + } catch ( Exception e ) { + Logger.Log( LogType.Error, "GunGlassTimer: " + e ); } - catch (Exception e) - { - Logger.Log(LogType.Error, "GunGlassTimer: " + e); - } - - lock (_objectLock) - { - if (_started) - _timer.Change(Tick, Timeout.Infinite); + + lock ( _objectLock ) { + if ( _started ) + _timer.Change( Tick, Timeout.Infinite ); } } } - class GunClass - { - public static void Init() - { + + internal class GunClass { + + public static void Init() { Player.Clicking += ClickedGlass;// Player.JoinedWorld += changedWorld;// Player.Moving += movePortal;// Player.Disconnected += playerDisconnected;// Player.PlacingBlock += playerPlaced; - CommandManager.RegisterCommand(CdGun); + CommandManager.RegisterCommand( CdGun ); } - static readonly CommandDescriptor CdGun = new CommandDescriptor - { + + private static readonly CommandDescriptor CdGun = new CommandDescriptor { Name = "Gun", Category = CommandCategory.Moderation, IsConsoleSafe = false, @@ -117,410 +106,312 @@ public static void Init() Handler = GunHandler }; - public static void GunHandler(Player player, Command cmd) - { - if (player.GunMode) - { + public static void GunHandler( Player player, Command cmd ) { + if ( player.GunMode ) { player.GunMode = false; - try - { - foreach (Vector3I block in player.GunCache.Values) - { - player.Send(PacketWriter.MakeSetBlock(block.X, block.Y, block.Z, player.WorldMap.GetBlock(block))); + try { + foreach ( Vector3I block in player.GunCache.Values ) { + player.Send( PacketWriter.MakeSetBlock( block.X, block.Y, block.Z, player.WorldMap.GetBlock( block ) ) ); Vector3I removed; - player.GunCache.TryRemove(block.ToString(), out removed); + player.GunCache.TryRemove( block.ToString(), out removed ); } - if (player.bluePortal.Count > 0) - { + if ( player.bluePortal.Count > 0 ) { int i = 0; - foreach (Vector3I block in player.bluePortal) - { - if (player.WorldMap != null && player.World.IsLoaded) - { - player.WorldMap.QueueUpdate(new BlockUpdate(null, block, player.blueOld[i])); + foreach ( Vector3I block in player.bluePortal ) { + if ( player.WorldMap != null && player.World.IsLoaded ) { + player.WorldMap.QueueUpdate( new BlockUpdate( null, block, player.blueOld[i] ) ); i++; } } player.blueOld.Clear(); player.bluePortal.Clear(); } - if (player.orangePortal.Count > 0) - { + if ( player.orangePortal.Count > 0 ) { int i = 0; - foreach (Vector3I block in player.orangePortal) - { - if (player.WorldMap != null && player.World.IsLoaded) - { - player.WorldMap.QueueUpdate(new BlockUpdate(null, block, player.orangeOld[i])); + foreach ( Vector3I block in player.orangePortal ) { + if ( player.WorldMap != null && player.World.IsLoaded ) { + player.WorldMap.QueueUpdate( new BlockUpdate( null, block, player.orangeOld[i] ) ); i++; } } player.orangeOld.Clear(); player.orangePortal.Clear(); } - player.Message("&SGunMode deactivated"); - } - catch (Exception ex) - { - Logger.Log(LogType.SeriousError, "" + ex); + player.Message( "&SGunMode deactivated" ); + } catch ( Exception ex ) { + Logger.Log( LogType.SeriousError, "" + ex ); } - } - else - { - if (!player.World.gunPhysics) - { - player.Message("&WGun physics are disabled on this world"); + } else { + if ( !player.World.gunPhysics ) { + player.Message( "&WGun physics are disabled on this world" ); return; } player.GunMode = true; - GunGlassTimer timer = new GunGlassTimer(player); + GunGlassTimer timer = new GunGlassTimer( player ); timer.Start(); - player.Message("&SGunMode activated. Fire at will!"); + player.Message( "&SGunMode activated. Fire at will!" ); } } - public static void gunMove(Player player) - { + public static void gunMove( Player player ) { World world = player.World; - if (null==world) - return; - try - { - lock (world.SyncRoot) - { - if (null==world.Map) - return; - if(player.IsOnline) - { + if ( null == world ) + return; + try { + lock ( world.SyncRoot ) { + if ( null == world.Map ) + return; + if ( player.IsOnline ) { Position p = player.Position; - double ksi = 2.0 * Math.PI * (-player.Position.L) / 256.0; - double phi = 2.0 * Math.PI * (player.Position.R - 64) / 256.0; - double sphi = Math.Sin(phi); - double cphi = Math.Cos(phi); - double sksi = Math.Sin(ksi); - double cksi = Math.Cos(ksi); + double ksi = 2.0 * Math.PI * ( -player.Position.L ) / 256.0; + double phi = 2.0 * Math.PI * ( player.Position.R - 64 ) / 256.0; + double sphi = Math.Sin( phi ); + double cphi = Math.Cos( phi ); + double sksi = Math.Sin( ksi ); + double cksi = Math.Cos( ksi ); - if (player.IsOnline) - { - if (player.GunCache.Values.Count > 0) - { - foreach (Vector3I block in player.GunCache.Values) - { - if(player.IsOnline) - { - player.Send(PacketWriter.MakeSetBlock(block.X, block.Y, block.Z, world.Map.GetBlock(block))); + if ( player.IsOnline ) { + if ( player.GunCache.Values.Count > 0 ) { + foreach ( Vector3I block in player.GunCache.Values ) { + if ( player.IsOnline ) { + player.Send( PacketWriter.MakeSetBlock( block.X, block.Y, block.Z, world.Map.GetBlock( block ) ) ); Vector3I removed; - player.GunCache.TryRemove(block.ToString(), out removed); + player.GunCache.TryRemove( block.ToString(), out removed ); } } } } - for (int y = -1; y < 2; ++y) - { - for (int z = -1; z < 2; ++z) - { - if (player.IsOnline) - { + for ( int y = -1; y < 2; ++y ) { + for ( int z = -1; z < 2; ++z ) { + if ( player.IsOnline ) { //4 is the distance betwen the player and the glass wall - Vector3I glassBlockPos = new Vector3I((int)(cphi * cksi * 4 - sphi * (0.5 + y) - cphi * sksi * (0.5 + z)), - (int)(sphi * cksi * 4 + cphi * (0.5 + y) - sphi * sksi * (0.5 + z)), - (int)(sksi * 4 + cksi * (0.5 + z))); + Vector3I glassBlockPos = new Vector3I( ( int )( cphi * cksi * 4 - sphi * ( 0.5 + y ) - cphi * sksi * ( 0.5 + z ) ), + ( int )( sphi * cksi * 4 + cphi * ( 0.5 + y ) - sphi * sksi * ( 0.5 + z ) ), + ( int )( sksi * 4 + cksi * ( 0.5 + z ) ) ); glassBlockPos += p.ToBlockCoords(); - if (world.Map.GetBlock(glassBlockPos) == Block.Air) - { - player.Send(PacketWriter.MakeSetBlock(glassBlockPos, Block.Glass)); - player.GunCache.TryAdd(glassBlockPos.ToString(), glassBlockPos); + if ( world.Map.GetBlock( glassBlockPos ) == Block.Air ) { + player.Send( PacketWriter.MakeSetBlock( glassBlockPos, Block.Glass ) ); + player.GunCache.TryAdd( glassBlockPos.ToString(), glassBlockPos ); } } } } } } - } - catch (Exception ex) - { - Logger.Log(LogType.SeriousError, "GunGlass: " + ex); + } catch ( Exception ex ) { + Logger.Log( LogType.SeriousError, "GunGlass: " + ex ); } } - - - public static void playerPlaced(object sender, PlayerPlacingBlockEventArgs e) - { - try - { - foreach (Player p in e.Player.World.Players) - { - if (e.OldBlock == Block.Water || e.OldBlock == Block.Lava) - { - if (p.orangePortal.Contains(e.Coords) || p.bluePortal.Contains(e.Coords)) - { + public static void playerPlaced( object sender, PlayerPlacingBlockEventArgs e ) { + try { + foreach ( Player p in e.Player.World.Players ) { + if ( e.OldBlock == Block.Water || e.OldBlock == Block.Lava ) { + if ( p.orangePortal.Contains( e.Coords ) || p.bluePortal.Contains( e.Coords ) ) { e.Result = CanPlaceResult.Revert; } } } - } - catch (Exception ex) - { - Logger.Log(LogType.SeriousError, "PlacingInPortal: " + ex); + } catch ( Exception ex ) { + Logger.Log( LogType.SeriousError, "PlacingInPortal: " + ex ); } } - private static TntBulletBehavior _tntBulletBehavior=new TntBulletBehavior(); + private static TntBulletBehavior _tntBulletBehavior = new TntBulletBehavior(); private static BulletBehavior _bulletBehavior = new BulletBehavior(); - public static void ClickedGlass(object sender, PlayerClickingEventArgs e) - { - if (e.Player.GunMode && !e.Player.Info.IsHidden && !e.Player.Info.IsFrozen) - { + public static void ClickedGlass( object sender, PlayerClickingEventArgs e ) { + if ( e.Player.GunMode && !e.Player.Info.IsHidden && !e.Player.Info.IsFrozen ) { World world = e.Player.World; Map map = e.Player.World.Map; - if (e.Player.GunCache.Values.Contains(e.Coords)) - { - if (world.gunPhysics) - { - e.Player.Send(PacketWriter.MakeSetBlock(e.Coords.X, e.Coords.Y, e.Coords.Z, Block.Glass)); - if (e.Block == Block.TNT && world.tntPhysics) - { - if (e.Player.CanFireTNT()) - { - double ksi = 2.0 * Math.PI * (-e.Player.Position.L) / 256.0; - double r = Math.Cos(ksi); - double phi = 2.0 * Math.PI * (e.Player.Position.R - 64) / 256.0; - Vector3F dir = new Vector3F((float)(r * Math.Cos(phi)), (float)(r * Math.Sin(phi)), (float)(Math.Sin(ksi))); - world.AddPhysicsTask(new Particle(world, e.Coords, dir, e.Player, Block.TNT, _tntBulletBehavior), 0); + if ( e.Player.GunCache.Values.Contains( e.Coords ) ) { + if ( world.gunPhysics ) { + e.Player.Send( PacketWriter.MakeSetBlock( e.Coords.X, e.Coords.Y, e.Coords.Z, Block.Glass ) ); + if ( e.Block == Block.TNT && world.tntPhysics ) { + if ( e.Player.CanFireTNT() ) { + double ksi = 2.0 * Math.PI * ( -e.Player.Position.L ) / 256.0; + double r = Math.Cos( ksi ); + double phi = 2.0 * Math.PI * ( e.Player.Position.R - 64 ) / 256.0; + Vector3F dir = new Vector3F( ( float )( r * Math.Cos( phi ) ), ( float )( r * Math.Sin( phi ) ), ( float )( Math.Sin( ksi ) ) ); + world.AddPhysicsTask( new Particle( world, e.Coords, dir, e.Player, Block.TNT, _tntBulletBehavior ), 0 ); } - } - else - { + } else { Block block = e.Block; - if (block == Block.Blue) block = Block.Water; - if (block == Block.Orange) block = Block.Lava; - double ksi = 2.0 * Math.PI * (-e.Player.Position.L) / 256.0; - double r = Math.Cos(ksi); - double phi = 2.0 * Math.PI * (e.Player.Position.R - 64) / 256.0; - Vector3F dir = new Vector3F((float)(r * Math.Cos(phi)), (float)(r * Math.Sin(phi)), (float)(Math.Sin(ksi))); - world.AddPhysicsTask(new Particle(world, e.Coords, dir, e.Player, block, _bulletBehavior), 0); + if ( block == Block.Blue ) + block = Block.Water; + if ( block == Block.Orange ) + block = Block.Lava; + double ksi = 2.0 * Math.PI * ( -e.Player.Position.L ) / 256.0; + double r = Math.Cos( ksi ); + double phi = 2.0 * Math.PI * ( e.Player.Position.R - 64 ) / 256.0; + Vector3F dir = new Vector3F( ( float )( r * Math.Cos( phi ) ), ( float )( r * Math.Sin( phi ) ), ( float )( Math.Sin( ksi ) ) ); + world.AddPhysicsTask( new Particle( world, e.Coords, dir, e.Player, block, _bulletBehavior ), 0 ); } } } } } - - public static void movePortal(object sender, PlayerMovingEventArgs e) - { - try - { - if (e.Player.LastUsedPortal != null && (DateTime.Now - e.Player.LastUsedPortal).TotalSeconds < 4) - { + public static void movePortal( object sender, PlayerMovingEventArgs e ) { + try { + if ( e.Player.LastUsedPortal != null && ( DateTime.Now - e.Player.LastUsedPortal ).TotalSeconds < 4 ) { return; } - Vector3I newPos = new Vector3I(e.NewPosition.X / 32, e.NewPosition.Y / 32, (e.NewPosition.Z / 32)); - foreach (Player p in e.Player.World.Players) - { - foreach (Vector3I block in p.bluePortal) - { - if (newPos == block) - { - if (p.World.Map.GetBlock(block) == Block.Water) - { - if (p.orangePortal.Count > 0) - { - e.Player.TeleportTo(new Position - { - X = (short)(((p.orangePortal[0].X) + 0.5) * 32), - Y = (short)(((p.orangePortal[0].Y) + 0.5) * 32), - Z = (short)(((p.orangePortal[0].Z) + 1.59375) * 32), - R = (byte)(p.blueOut - 128), + Vector3I newPos = new Vector3I( e.NewPosition.X / 32, e.NewPosition.Y / 32, ( e.NewPosition.Z / 32 ) ); + foreach ( Player p in e.Player.World.Players ) { + foreach ( Vector3I block in p.bluePortal ) { + if ( newPos == block ) { + if ( p.World.Map.GetBlock( block ) == Block.Water ) { + if ( p.orangePortal.Count > 0 ) { + e.Player.TeleportTo( new Position { + X = ( short )( ( ( p.orangePortal[0].X ) + 0.5 ) * 32 ), + Y = ( short )( ( ( p.orangePortal[0].Y ) + 0.5 ) * 32 ), + Z = ( short )( ( ( p.orangePortal[0].Z ) + 1.59375 ) * 32 ), + R = ( byte )( p.blueOut - 128 ), L = e.Player.Position.L - }); + } ); } e.Player.LastUsedPortal = DateTime.Now; } } } - foreach (Vector3I block in p.orangePortal) - { - if (newPos == block) - { - if (p.World.Map.GetBlock(block) == Block.Lava) - { - if (p.bluePortal.Count > 0) - { - e.Player.TeleportTo(new Position - { - X = (short)(((p.bluePortal[0].X + 0.5)) * 32), - Y = (short)(((p.bluePortal[0].Y + 0.5)) * 32), - Z = (short)(((p.bluePortal[0].Z) + 1.59375) * 32), //fixed point 1.59375 lol. - R = (byte)(p.orangeOut - 128), + foreach ( Vector3I block in p.orangePortal ) { + if ( newPos == block ) { + if ( p.World.Map.GetBlock( block ) == Block.Lava ) { + if ( p.bluePortal.Count > 0 ) { + e.Player.TeleportTo( new Position { + X = ( short )( ( ( p.bluePortal[0].X + 0.5 ) ) * 32 ), + Y = ( short )( ( ( p.bluePortal[0].Y + 0.5 ) ) * 32 ), + Z = ( short )( ( ( p.bluePortal[0].Z ) + 1.59375 ) * 32 ), //fixed point 1.59375 lol. + R = ( byte )( p.orangeOut - 128 ), L = e.Player.Position.L - }); + } ); } e.Player.LastUsedPortal = DateTime.Now; } } } } - } - catch (Exception ex) - { - Logger.Log(LogType.SeriousError, "MovePortal: " + ex); + } catch ( Exception ex ) { + Logger.Log( LogType.SeriousError, "MovePortal: " + ex ); } } - public static void changedWorld(object sender, PlayerJoinedWorldEventArgs e) - { - try - { - if (e.OldWorld != null) - { - if (e.OldWorld.Name == e.NewWorld.Name) - { + public static void changedWorld( object sender, PlayerJoinedWorldEventArgs e ) { + try { + if ( e.OldWorld != null ) { + if ( e.OldWorld.Name == e.NewWorld.Name ) { e.Player.orangeOld.Clear(); e.Player.orangePortal.Clear(); e.Player.blueOld.Clear(); e.Player.bluePortal.Clear(); } - if (e.OldWorld.IsLoaded) - { + if ( e.OldWorld.IsLoaded ) { Map map = e.OldWorld.Map; - if (e.Player.orangePortal.Count > 0) - { + if ( e.Player.orangePortal.Count > 0 ) { int i = 0; - foreach (Vector3I block in e.Player.orangePortal) - { - map.QueueUpdate(new BlockUpdate(null, block, e.Player.orangeOld[i])); + foreach ( Vector3I block in e.Player.orangePortal ) { + map.QueueUpdate( new BlockUpdate( null, block, e.Player.orangeOld[i] ) ); i++; } e.Player.orangeOld.Clear(); e.Player.orangePortal.Clear(); } - if (e.Player.bluePortal.Count > 0) - { + if ( e.Player.bluePortal.Count > 0 ) { int i = 0; - foreach (Vector3I block in e.Player.bluePortal) - { - map.QueueUpdate(new BlockUpdate(null, block, e.Player.blueOld[i])); + foreach ( Vector3I block in e.Player.bluePortal ) { + map.QueueUpdate( new BlockUpdate( null, block, e.Player.blueOld[i] ) ); i++; } e.Player.blueOld.Clear(); e.Player.bluePortal.Clear(); } - } - else - { - if (e.Player.bluePortal.Count > 0) - { - e.OldWorld.Map.Blocks[e.OldWorld.Map.Index(e.Player.bluePortal[0])] = (byte)e.Player.blueOld[0]; - e.OldWorld.Map.Blocks[e.OldWorld.Map.Index(e.Player.bluePortal[1])] = (byte)e.Player.blueOld[1]; + } else { + if ( e.Player.bluePortal.Count > 0 ) { + e.OldWorld.Map.Blocks[e.OldWorld.Map.Index( e.Player.bluePortal[0] )] = ( byte )e.Player.blueOld[0]; + e.OldWorld.Map.Blocks[e.OldWorld.Map.Index( e.Player.bluePortal[1] )] = ( byte )e.Player.blueOld[1]; e.Player.blueOld.Clear(); e.Player.bluePortal.Clear(); } - if (e.Player.orangePortal.Count > 0) - { - e.OldWorld.Map.Blocks[e.OldWorld.Map.Index(e.Player.orangePortal[0])] = (byte)e.Player.orangeOld[0]; - e.OldWorld.Map.Blocks[e.OldWorld.Map.Index(e.Player.orangePortal[1])] = (byte)e.Player.orangeOld[1]; + if ( e.Player.orangePortal.Count > 0 ) { + e.OldWorld.Map.Blocks[e.OldWorld.Map.Index( e.Player.orangePortal[0] )] = ( byte )e.Player.orangeOld[0]; + e.OldWorld.Map.Blocks[e.OldWorld.Map.Index( e.Player.orangePortal[1] )] = ( byte )e.Player.orangeOld[1]; e.Player.orangeOld.Clear(); e.Player.orangePortal.Clear(); } } } - } - catch (Exception ex) - { - Logger.Log(LogType.SeriousError, "GunPortalChangeWorld: " + ex); + } catch ( Exception ex ) { + Logger.Log( LogType.SeriousError, "GunPortalChangeWorld: " + ex ); } } - public static void playerDisconnected(object sender, PlayerDisconnectedEventArgs e) - { - try - { - if (e.Player.World != null) - { - if (e.Player.World.IsLoaded) - { + public static void playerDisconnected( object sender, PlayerDisconnectedEventArgs e ) { + try { + if ( e.Player.World != null ) { + if ( e.Player.World.IsLoaded ) { Map map = e.Player.World.Map; - if (e.Player.orangePortal.Count > 0) - { + if ( e.Player.orangePortal.Count > 0 ) { int i = 0; - foreach (Vector3I block in e.Player.orangePortal) - { - map.QueueUpdate(new BlockUpdate(null, block, e.Player.orangeOld[i])); + foreach ( Vector3I block in e.Player.orangePortal ) { + map.QueueUpdate( new BlockUpdate( null, block, e.Player.orangeOld[i] ) ); i++; } e.Player.orangeOld.Clear(); e.Player.orangePortal.Clear(); } - if (e.Player.bluePortal.Count > 0) - { + if ( e.Player.bluePortal.Count > 0 ) { int i = 0; - foreach (Vector3I block in e.Player.bluePortal) - { - map.QueueUpdate(new BlockUpdate(null, block, e.Player.blueOld[i])); + foreach ( Vector3I block in e.Player.bluePortal ) { + map.QueueUpdate( new BlockUpdate( null, block, e.Player.blueOld[i] ) ); i++; } e.Player.blueOld.Clear(); e.Player.bluePortal.Clear(); } - } - else - { - if (e.Player.bluePortal.Count > 0) - { - e.Player.World.Map.Blocks[e.Player.World.Map.Index(e.Player.bluePortal[0])] = (byte)e.Player.blueOld[0]; - e.Player.World.Map.Blocks[e.Player.World.Map.Index(e.Player.bluePortal[1])] = (byte)e.Player.blueOld[1]; + } else { + if ( e.Player.bluePortal.Count > 0 ) { + e.Player.World.Map.Blocks[e.Player.World.Map.Index( e.Player.bluePortal[0] )] = ( byte )e.Player.blueOld[0]; + e.Player.World.Map.Blocks[e.Player.World.Map.Index( e.Player.bluePortal[1] )] = ( byte )e.Player.blueOld[1]; } - if (e.Player.orangePortal.Count > 0) - { - e.Player.WorldMap.Blocks[e.Player.WorldMap.Index(e.Player.orangePortal[0])] = (byte)e.Player.orangeOld[0]; - e.Player.WorldMap.Blocks[e.Player.WorldMap.Index(e.Player.orangePortal[1])] = (byte)e.Player.orangeOld[1]; + if ( e.Player.orangePortal.Count > 0 ) { + e.Player.WorldMap.Blocks[e.Player.WorldMap.Index( e.Player.orangePortal[0] )] = ( byte )e.Player.orangeOld[0]; + e.Player.WorldMap.Blocks[e.Player.WorldMap.Index( e.Player.orangePortal[1] )] = ( byte )e.Player.orangeOld[1]; } } } - } - catch (Exception ex) - { - Logger.Log(LogType.SeriousError, "GunPortalDisconnected: " + ex); + } catch ( Exception ex ) { + Logger.Log( LogType.SeriousError, "GunPortalDisconnected: " + ex ); } } - public static void removal(ConcurrentDictionary bullets, Map map) - { - foreach (Vector3I bp in bullets.Values) - { - map.QueueUpdate(new BlockUpdate(null, - (short)bp.X, - (short)bp.Y, - (short)bp.Z, - Block.Air)); + + public static void removal( ConcurrentDictionary bullets, Map map ) { + foreach ( Vector3I bp in bullets.Values ) { + map.QueueUpdate( new BlockUpdate( null, + ( short )bp.X, + ( short )bp.Y, + ( short )bp.Z, + Block.Air ) ); Vector3I removed; - bullets.TryRemove(bp.ToString(), out removed); + bullets.TryRemove( bp.ToString(), out removed ); } } - - public static bool CanPlacePortal(short x, short y, short z, Map map) - { + public static bool CanPlacePortal( short x, short y, short z, Map map ) { int Count = 0; - for (short Z = z; Z < z + 2; Z++) - { - Block check = map.GetBlock(x, y, Z); - if (check != Block.Air && check != Block.Water && check != Block.Lava) - { + for ( short Z = z; Z < z + 2; Z++ ) { + Block check = map.GetBlock( x, y, Z ); + if ( check != Block.Air && check != Block.Water && check != Block.Lava ) { Count++; } } - if (Count == 2) - { + if ( Count == 2 ) { return true; - } - else - { + } else { return false; } } diff --git a/fCraft/Commands/Command Handlers/LifeHandler.cs b/fCraft/Commands/Command Handlers/LifeHandler.cs index cd23064..7077654 100644 --- a/fCraft/Commands/Command Handlers/LifeHandler.cs +++ b/fCraft/Commands/Command Handlers/LifeHandler.cs @@ -31,546 +31,477 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY using System.Linq; using System.Text; -namespace fCraft -{ - public class LifeHandler - { - private class LifeCommand - { - public string[] Names; - public string Help; - public Action F; - } - - private class Param - { - public string Name; - public string Help; - public Action SetValue; - } - private static Dictionary _commands=new Dictionary(); - private static StringBuilder _allCommands = new StringBuilder(); - private static Dictionary _params = new Dictionary(); - private static StringBuilder _allParams = new StringBuilder(); - - //static preparation - static LifeHandler() - { - CreateParams(); - CreateCommands(); - _commands["help"].Help += _allCommands.ToString(); - } - - private static void CreateParams() - { - AddParam(new Param() - { - Name = "Delay", - Help = "&hDelay in msec before the next life state is drawn. Must be >=20.", - SetValue = SetDelay - }); - AddParam(new Param() - { - Name = "IntrDelay", - Help = "&hIf >0 the intermediate state of the life is drawn and shown for this anount of timein msec. If 0 the intermediate state is not shown.", - SetValue = SetHalfDelay - }); - AddParam(new Param() - { - Name = "Normal", - Help = "&hBlock type representing the living cell.", - SetValue = SetNormal - }); - AddParam(new Param() - { - Name = "Empty", - Help = "&hBlock type representing the empty cell.", - SetValue = SetEmpty - }); - AddParam(new Param() - { - Name = "Dead", - Help = "&hBlock type representing the dying cell (only relevant for intermediate state).", - SetValue = SetDead - }); - AddParam(new Param() - { - Name = "Newborn", - Help = "&hBlock type representing the newborn cell (only relevant for intermediate state).", - SetValue = SetNewborn - }); - AddParam(new Param() - { - Name = "Torus", - Help = "&hBoolean parameter telling if the life area must be understood as a torus (i.e. the top side is connected to the bottom and the left side with the right one.", - SetValue = SetTorus - }); - AddParam(new Param() - { - Name = "AutoReset", - Help = "&hThis parameter tells if the life must be auto reset after the detection of a short-periodical state. Possible values are None (no), ToInitial (i), ToRandom (r).", - SetValue = SetAutoReset - }); - } - - private static void AddParam(Param p) - { - if (_params.Count > 0) - _allParams.Append(", "); - _allParams.Append(p.Name); - - _params.Add(p.Name.ToLower(), p); - } - - private static void CreateCommands() - { - //assuming each command has at least one name and no names repeating. Will throw on start if it is not the case. - AddCommand(new LifeCommand() - { - Names = new string[] { "help", "h" }, - Help = "&hPrints help on commands. Usage: /life help . For the list of parameters type '/life help set'. Commands are: ", - F = OnHelp - }); - AddCommand(new LifeCommand() - { - Names = new string[] { "create", "new" }, - Help = "&hCreates a new life. Usage: /life create . Then mark two blocks to define a *flat* rectangle. The life is created stopped and with default settings. After that you can set params by 'set' command and start it by 'start' command.", - F = OnCreate - }); - AddCommand(new LifeCommand() - { - Names = new string[] { "delete", "del", "remove" }, - Help = "&hDeletes a life. Usage: /life delete . If this life exists it will be stopped and removed from the map book keeping.", - F = OnDelete - }); - AddCommand(new LifeCommand() - { - Names = new string[] { "start", "run" }, - Help = "&hStarts a stopped life. Usage: /life start . If this life exists and is stopped it will be started. Otherwise nothing happens.", - F = OnStart - }); - AddCommand(new LifeCommand() - { - Names = new string[] { "stop", "pause" }, - Help = "&hStops a life. Usage: /life stop . If this life exists and is started it will be stopped. Otherwise nothing happens.", - F = OnStop - }); - AddCommand(new LifeCommand() - { - Names = new string[] { "set" }, - Help = "&hSets a life parameter. Usage: /life set =[| =]. Sets parameter 'param' value for the life 'name'. Parameters are: " - + _allParams.ToString(), - F = OnSet - }); - AddCommand(new LifeCommand() - { - Names = new string[] { "list", "ls" }, - Help = "&hPrints all lifes in players world. Usage: /life list [started|stopped]", - F = OnList - }); - AddCommand(new LifeCommand() - { - Names = new string[] { "print", "cat" }, - Help = "&hPrints this life settings. Usage: /life print ", - F = OnPrint - }); - } - - private static void AddCommand(LifeCommand c) - { - if (_commands.Count > 0) - _allCommands.Append(", "); - _allCommands.Append(c.Names[0]); - foreach (string name in c.Names) - _commands.Add(name.ToLower(), c); - } - - //processing - private string _name; - private World _world; - private Life2DZone _life; - - public static void ProcessCommand(Player p, Command cmd) - { - string command = cmd.Next(); - if (String.IsNullOrWhiteSpace(command)) - { - p.Message("&WLife command is missing or empty"); - return; - } - LifeCommand c; - if (!_commands.TryGetValue(command.ToLower(), out c)) - { - p.Message("&WUnknown life command "+command+". &hType '/life help' for the list of commands."); - return; - } - c.F(p, cmd); - } - - private static string AliasesStr(LifeCommand cmd) - { - if (cmd.Names.Length < 2) - return ""; - StringBuilder sb = new StringBuilder("&hAliases: "); - for (int i=1; i 1) - sb.Append(", "); - sb.Append(cmd.Names[i]); - } - return sb.Append(".").ToString(); - } - - private static void OnHelp(Player p, Command cmd) - { - string cOrP = cmd.Next(); - if (String.IsNullOrWhiteSpace(cOrP)) - { - p.Message("&hLife commands are: "+_allCommands.ToString()+ - ".\nType '/life help for detailed command or param info. Type '/life help set' for the list of parameters."); - return; - } - LifeCommand c; - Param param; - string help; - if (!_commands.TryGetValue(cOrP.ToLower(), out c)) - { - if (!_params.TryGetValue(cOrP.ToLower(), out param)) - { - p.Message("&WUnknown life command/parameter " + cOrP + ". &hType '/life help' for the list of commands."); - return; - } - help = param.Help; - } - else - help = AliasesStr(c)+c.Help; - - p.Message(help); - } - - private bool CheckAndGetLifeZone(Player p, Command cmd) - { - _life = null; - _world = null; - _name = cmd.Next(); - if (String.IsNullOrWhiteSpace(_name)) - { - p.Message("&WLife name is missing or empty"); - return false; - } - - _world = p.World; - if (null == _world) - { - p.Message("&WYou are in limbo state. Prepare for eternal torment."); - return false; - } - - lock (_world.SyncRoot) - { - if (null == _world.Map) - return false; - _life = _world.GetLife(_name); - return true; - } - } - - private static LifeHandler GetCheckedLifeHandler(Player p, Command cmd) - { - LifeHandler handler = new LifeHandler(); - if (!handler.CheckAndGetLifeZone(p, cmd)) - return null; - if (null == handler._life) - { - p.Message("&WLife " + handler._name + " does not exist."); - return null; - } - return handler; - } - - private static void OnCreate(Player p, Command cmd) - { - LifeHandler handler=new LifeHandler(); - if (!handler.CheckAndGetLifeZone(p, cmd)) - return; - if (!handler.CheckWorldPermissions(p)) - return; - if (null!=handler._life) - { - p.Message("&WLife with such name exists already, choose another"); - return; - } - - p.SelectionStart(2, handler.LifeCreateCallback, null, Permission.DrawAdvanced); - p.MessageNow("Select life zone: place/remove a block or type /Mark to use your location."); - } - - private void LifeCreateCallback(Player player, Vector3I[] marks, object state) - { - try - { - lock (_world.SyncRoot) - { - if (!CheckWorldPermissions(player)) - return; - if (null == _world.Map) - return; - if (null != _world.GetLife(_name)) //check it again, since smone could create it in between +namespace fCraft { + + public class LifeHandler { + + private class LifeCommand { + public string[] Names; + public string Help; + public Action F; + } + + private class Param { + public string Name; + public string Help; + public Action SetValue; + } + + private static Dictionary _commands = new Dictionary(); + private static StringBuilder _allCommands = new StringBuilder(); + private static Dictionary _params = new Dictionary(); + private static StringBuilder _allParams = new StringBuilder(); + + //static preparation + static LifeHandler() { + CreateParams(); + CreateCommands(); + _commands["help"].Help += _allCommands.ToString(); + } + + private static void CreateParams() { + AddParam( new Param() { + Name = "Delay", + Help = "&hDelay in msec before the next life state is drawn. Must be >=20.", + SetValue = SetDelay + } ); + AddParam( new Param() { + Name = "IntrDelay", + Help = "&hIf >0 the intermediate state of the life is drawn and shown for this anount of timein msec. If 0 the intermediate state is not shown.", + SetValue = SetHalfDelay + } ); + AddParam( new Param() { + Name = "Normal", + Help = "&hBlock type representing the living cell.", + SetValue = SetNormal + } ); + AddParam( new Param() { + Name = "Empty", + Help = "&hBlock type representing the empty cell.", + SetValue = SetEmpty + } ); + AddParam( new Param() { + Name = "Dead", + Help = "&hBlock type representing the dying cell (only relevant for intermediate state).", + SetValue = SetDead + } ); + AddParam( new Param() { + Name = "Newborn", + Help = "&hBlock type representing the newborn cell (only relevant for intermediate state).", + SetValue = SetNewborn + } ); + AddParam( new Param() { + Name = "Torus", + Help = "&hBoolean parameter telling if the life area must be understood as a torus (i.e. the top side is connected to the bottom and the left side with the right one.", + SetValue = SetTorus + } ); + AddParam( new Param() { + Name = "AutoReset", + Help = "&hThis parameter tells if the life must be auto reset after the detection of a short-periodical state. Possible values are None (no), ToInitial (i), ToRandom (r).", + SetValue = SetAutoReset + } ); + } + + private static void AddParam( Param p ) { + if ( _params.Count > 0 ) + _allParams.Append( ", " ); + _allParams.Append( p.Name ); + + _params.Add( p.Name.ToLower(), p ); + } + + private static void CreateCommands() { + //assuming each command has at least one name and no names repeating. Will throw on start if it is not the case. + AddCommand( new LifeCommand() { + Names = new string[] { "help", "h" }, + Help = "&hPrints help on commands. Usage: /life help . For the list of parameters type '/life help set'. Commands are: ", + F = OnHelp + } ); + AddCommand( new LifeCommand() { + Names = new string[] { "create", "new" }, + Help = "&hCreates a new life. Usage: /life create . Then mark two blocks to define a *flat* rectangle. The life is created stopped and with default settings. After that you can set params by 'set' command and start it by 'start' command.", + F = OnCreate + } ); + AddCommand( new LifeCommand() { + Names = new string[] { "delete", "del", "remove" }, + Help = "&hDeletes a life. Usage: /life delete . If this life exists it will be stopped and removed from the map book keeping.", + F = OnDelete + } ); + AddCommand( new LifeCommand() { + Names = new string[] { "start", "run" }, + Help = "&hStarts a stopped life. Usage: /life start . If this life exists and is stopped it will be started. Otherwise nothing happens.", + F = OnStart + } ); + AddCommand( new LifeCommand() { + Names = new string[] { "stop", "pause" }, + Help = "&hStops a life. Usage: /life stop . If this life exists and is started it will be stopped. Otherwise nothing happens.", + F = OnStop + } ); + AddCommand( new LifeCommand() { + Names = new string[] { "set" }, + Help = "&hSets a life parameter. Usage: /life set =[| =]. Sets parameter 'param' value for the life 'name'. Parameters are: " + + _allParams.ToString(), + F = OnSet + } ); + AddCommand( new LifeCommand() { + Names = new string[] { "list", "ls" }, + Help = "&hPrints all lifes in players world. Usage: /life list [started|stopped]", + F = OnList + } ); + AddCommand( new LifeCommand() { + Names = new string[] { "print", "cat" }, + Help = "&hPrints this life settings. Usage: /life print ", + F = OnPrint + } ); + } + + private static void AddCommand( LifeCommand c ) { + if ( _commands.Count > 0 ) + _allCommands.Append( ", " ); + _allCommands.Append( c.Names[0] ); + foreach ( string name in c.Names ) + _commands.Add( name.ToLower(), c ); + } + + //processing + private string _name; + + private World _world; + private Life2DZone _life; + + public static void ProcessCommand( Player p, Command cmd ) { + string command = cmd.Next(); + if ( String.IsNullOrWhiteSpace( command ) ) { + p.Message( "&WLife command is missing or empty" ); + return; + } + LifeCommand c; + if ( !_commands.TryGetValue( command.ToLower(), out c ) ) { + p.Message( "&WUnknown life command " + command + ". &hType '/life help' for the list of commands." ); + return; + } + c.F( p, cmd ); + } + + private static string AliasesStr( LifeCommand cmd ) { + if ( cmd.Names.Length < 2 ) + return ""; + StringBuilder sb = new StringBuilder( "&hAliases: " ); + for ( int i = 1; i < cmd.Names.Length; ++i ) { + if ( i > 1 ) + sb.Append( ", " ); + sb.Append( cmd.Names[i] ); + } + return sb.Append( "." ).ToString(); + } + + private static void OnHelp( Player p, Command cmd ) { + string cOrP = cmd.Next(); + if ( String.IsNullOrWhiteSpace( cOrP ) ) { + p.Message( "&hLife commands are: " + _allCommands.ToString() + + ".\nType '/life help for detailed command or param info. Type '/life help set' for the list of parameters." ); + return; + } + LifeCommand c; + Param param; + string help; + if ( !_commands.TryGetValue( cOrP.ToLower(), out c ) ) { + if ( !_params.TryGetValue( cOrP.ToLower(), out param ) ) { + p.Message( "&WUnknown life command/parameter " + cOrP + ". &hType '/life help' for the list of commands." ); + return; + } + help = param.Help; + } else + help = AliasesStr( c ) + c.Help; + + p.Message( help ); + } + + private bool CheckAndGetLifeZone( Player p, Command cmd ) { + _life = null; + _world = null; + _name = cmd.Next(); + if ( String.IsNullOrWhiteSpace( _name ) ) { + p.Message( "&WLife name is missing or empty" ); + return false; + } + + _world = p.World; + if ( null == _world ) { + p.Message( "&WYou are in limbo state. Prepare for eternal torment." ); + return false; + } + + lock ( _world.SyncRoot ) { + if ( null == _world.Map ) + return false; + _life = _world.GetLife( _name ); + return true; + } + } + + private static LifeHandler GetCheckedLifeHandler( Player p, Command cmd ) { + LifeHandler handler = new LifeHandler(); + if ( !handler.CheckAndGetLifeZone( p, cmd ) ) + return null; + if ( null == handler._life ) { + p.Message( "&WLife " + handler._name + " does not exist." ); + return null; + } + return handler; + } + + private static void OnCreate( Player p, Command cmd ) { + LifeHandler handler = new LifeHandler(); + if ( !handler.CheckAndGetLifeZone( p, cmd ) ) + return; + if ( !handler.CheckWorldPermissions( p ) ) + return; + if ( null != handler._life ) { + p.Message( "&WLife with such name exists already, choose another" ); + return; + } + + p.SelectionStart( 2, handler.LifeCreateCallback, null, Permission.DrawAdvanced ); + p.MessageNow( "Select life zone: place/remove a block or type /Mark to use your location." ); + } + + private void LifeCreateCallback( Player player, Vector3I[] marks, object state ) { + try { + lock ( _world.SyncRoot ) { + if ( !CheckWorldPermissions( player ) ) + return; + if ( null == _world.Map ) + return; + if ( null != _world.GetLife( _name ) ) //check it again, since smone could create it in between { - player.Message("&WLife with such name exists already, choose another"); - return; - } - Life2DZone life = new Life2DZone(_name, _world.Map, marks, player, (player.Info.Rank.NextRankUp ?? player.Info.Rank).Name); - if (_world.TryAddLife(life)) - player.Message("&yLife was created. Named " + _name); - else - player.Message("&WCoulnd't create life for some reason unknown."); //really unknown: we are under a lock so nobody could create a life with the same name in between - } - } - catch (Exception e) - { - player.Message("&WCreate life error: " + e.Message); - } - } - - private static void OnStart(Player p, Command cmd) - { - LifeHandler handler = GetCheckedLifeHandler(p, cmd); - if (null == handler) - return; - if (!handler.CheckChangePermissions(p)) - return; - handler._life.Start(); - p.Message("&yLife " + handler._life.Name + " is started"); - } - - private static void OnStop(Player p, Command cmd) - { - LifeHandler handler = GetCheckedLifeHandler(p, cmd); - if (null == handler) - return; - if (!handler.CheckChangePermissions(p)) - return; - handler._life.Stop(); - p.Message("&yLife " + handler._life.Name + " is stopped"); - } - - private static void OnDelete(Player p, Command cmd) - { - LifeHandler handler = GetCheckedLifeHandler(p, cmd); - if (null == handler) - return; - if (!handler.CheckChangePermissions(p)) - return; - handler._life.Stop(); - handler._world.DeleteLife(handler._name); - p.Message("&yLife " + handler._life.Name + " is deleted"); - } - private static void OnList(Player p, Command cmd) - { - World w = p.World; - if (null == w) - { - p.Message("&WYou are in limbo state. Prepare for eternal torment."); - return; - } - string param = cmd.Next(); - Func f = l => true; - if (!string.IsNullOrWhiteSpace(param)) - { - if (param == "started") - f = l => !l.Stopped; - else if (param == "stopped") - f = l => l.Stopped; - else - p.Message("&WUnrecognised parameter " + param + ". Ignored.\n"); - } - int i = 0; - foreach (Life2DZone life in w.GetLifes().Where(life => f(life))) - { - if (i++>0) - p.Message(", "); - p.Message((life.Stopped?"&8":"&2")+life.Name); - } - } - private static void OnPrint(Player p, Command cmd) - { - LifeHandler handler = GetCheckedLifeHandler(p, cmd); - if (null == handler) - return; - Life2DZone l = handler._life; - p.Message("&y"+l.Name+": "+(l.Stopped ? "stopped" : "started") + ", delay "+l.Delay+ - ", intermediate delay "+l.HalfStepDelay+", is"+(l.Torus?"":" not")+" on torus, "+ - "auto reset strategy is "+Enum.GetName(typeof(AutoResetMethod), l.AutoReset)+ - ", owner is "+l.CreatorName+ - ", changable by "+l.MinRankToChange+ - ", block types: "+ l.Normal+" is normal, "+l.Empty+" is empty, "+l.Dead+" is dead, "+l.Newborn+" is newborn"); - } - - private static void OnSet(Player p, Command cmd) - { - LifeHandler handler = GetCheckedLifeHandler(p, cmd); - if (null == handler) - return; - if (!handler.CheckChangePermissions(p)) - return; - - string paramStr = cmd.Next(); - if (string.IsNullOrWhiteSpace(paramStr)) - { - p.Message("&WEmpty parameter name. &hAccepted names are " + _allParams.ToString()); - return; - } - Param param; - if(!_params.TryGetValue(paramStr, out param)) - { - p.Message("&WUknown parameter name" + paramStr + ". &hAccepted names are " + _allParams.ToString()); - return; - } - string val=cmd.Next(); - if (string.IsNullOrWhiteSpace(val)) - { - p.Message("&WEmpty value."); - return; - } - param.SetValue(p, handler._life, val); - } - - private static void SetDelay(Player p, Life2DZone life, string val) - { - int delay; - if (!int.TryParse(val, out delay) || delay <=20) - { - p.Message("&WExpected integer value >=20 as delay"); - return; - } - life.Delay = delay; - p.Message("&yStep delay set to "+val); - } - private static void SetHalfDelay(Player p, Life2DZone life, string val) - { - int delay; - if (!int.TryParse(val, out delay) || delay < 0) - { - p.Message("&WExpected non-negative integer value as intermediate delay"); - return; - } - life.HalfStepDelay = delay; - p.Message("&yIntermediate step delay set to " + val); - } - - private static void SetNormal(Player p, Life2DZone life, string val) - { - Block b = Map.GetBlockByName(val); - if (b==Block.Undefined) - { - p.Message("&WUnrecognized block name "+val); - return; - } - life.Normal = b; - p.Message("&yNormal block set to " + val); - } - private static void SetEmpty(Player p, Life2DZone life, string val) - { - Block b = Map.GetBlockByName(val); - if (b == Block.Undefined) - { - p.Message("&WUnrecognized block name " + val); - return; - } - life.Empty = b; - p.Message("&yEmpty block set to " + val); - } - private static void SetDead(Player p, Life2DZone life, string val) - { - Block b = Map.GetBlockByName(val); - if (b == Block.Undefined) - { - p.Message("&WUnrecognized block name " + val); - return; - } - life.Dead = b; - p.Message("&yDead block set to " + val); - } - private static void SetNewborn(Player p, Life2DZone life, string val) - { - Block b = Map.GetBlockByName(val); - if (b == Block.Undefined) - { - p.Message("&WUnrecognized block name " + val); - return; - } - life.Newborn = b; - p.Message("&yNewborn block set to " + val); - } - private static void SetTorus(Player p, Life2DZone life, string val) - { - bool torus; - if (!bool.TryParse(val, out torus)) - { - p.Message("&WExpected 'true' or 'false' as torus parameter value"); - return; - } - life.Torus = torus; - p.Message("&yTorus param set to " + val); - } - private static void SetAutoReset(Player p, Life2DZone life, string val) - { - AutoResetMethod method; - val = val.ToLower(); - if (val == "no" || val == "none") - method = AutoResetMethod.None; - else if (val == "toinitial" || val == "i") - method = AutoResetMethod.ToInitial; - else if (val=="torandom" || val=="r" || val=="rnd") - method = AutoResetMethod.ToRandom; - else - { - p.Message("&WUnrecognized auto reset method "+val+".\n&h Type '/life help AutoReset' to see all the possible values."); - return; - } - life.AutoReset = method; - p.Message("&yAutoReset param set to " + Enum.GetName(typeof(AutoResetMethod), method)); - } - - private bool CheckWorldPermissions(Player p) - { - if (!p.Info.Rank.AllowSecurityCircumvention) - { - SecurityCheckResult buildCheck = _world.BuildSecurity.CheckDetailed(p.Info); - switch (buildCheck) - { - case SecurityCheckResult.BlackListed: - p.Message("Cannot add life to world {0}&S: You are barred from building here.", - p.ClassyName); - return false; - case SecurityCheckResult.RankTooLow: - p.Message("Cannot add life to world {0}&S: You are not allowed to build here.", - p.ClassyName); - return false; - } - } - return true; - } - - private bool CheckChangePermissions(Player p) - { - if (string.IsNullOrWhiteSpace(_life.CreatorName) || p.Name==_life.CreatorName) - return true; - if (string.IsNullOrWhiteSpace(_life.MinRankToChange)) - return true; - Rank r; - if (!RankManager.RanksByName.TryGetValue(_life.MinRankToChange, out r)) - { - string prevRank = _life.MinRankToChange; - r = RankManager.LowestRank.NextRankUp ?? RankManager.LowestRank; - _life.MinRankToChange = r.Name; - p.Message("&WRank "+prevRank+" couldn't be found. Updated to "+r.Name); - } - if (p.Info.Rank>=r) - return true; - p.Message("&WYour rank is too low to change this life."); - return false; - } - } -} + player.Message( "&WLife with such name exists already, choose another" ); + return; + } + Life2DZone life = new Life2DZone( _name, _world.Map, marks, player, ( player.Info.Rank.NextRankUp ?? player.Info.Rank ).Name ); + if ( _world.TryAddLife( life ) ) + player.Message( "&yLife was created. Named " + _name ); + else + player.Message( "&WCoulnd't create life for some reason unknown." ); //really unknown: we are under a lock so nobody could create a life with the same name in between + } + } catch ( Exception e ) { + player.Message( "&WCreate life error: " + e.Message ); + } + } + + private static void OnStart( Player p, Command cmd ) { + LifeHandler handler = GetCheckedLifeHandler( p, cmd ); + if ( null == handler ) + return; + if ( !handler.CheckChangePermissions( p ) ) + return; + handler._life.Start(); + p.Message( "&yLife " + handler._life.Name + " is started" ); + } + + private static void OnStop( Player p, Command cmd ) { + LifeHandler handler = GetCheckedLifeHandler( p, cmd ); + if ( null == handler ) + return; + if ( !handler.CheckChangePermissions( p ) ) + return; + handler._life.Stop(); + p.Message( "&yLife " + handler._life.Name + " is stopped" ); + } + + private static void OnDelete( Player p, Command cmd ) { + LifeHandler handler = GetCheckedLifeHandler( p, cmd ); + if ( null == handler ) + return; + if ( !handler.CheckChangePermissions( p ) ) + return; + handler._life.Stop(); + handler._world.DeleteLife( handler._name ); + p.Message( "&yLife " + handler._life.Name + " is deleted" ); + } + + private static void OnList( Player p, Command cmd ) { + World w = p.World; + if ( null == w ) { + p.Message( "&WYou are in limbo state. Prepare for eternal torment." ); + return; + } + string param = cmd.Next(); + Func f = l => true; + if ( !string.IsNullOrWhiteSpace( param ) ) { + if ( param == "started" ) + f = l => !l.Stopped; + else if ( param == "stopped" ) + f = l => l.Stopped; + else + p.Message( "&WUnrecognised parameter " + param + ". Ignored.\n" ); + } + int i = 0; + foreach ( Life2DZone life in w.GetLifes().Where( life => f( life ) ) ) { + if ( i++ > 0 ) + p.Message( ", " ); + p.Message( ( life.Stopped ? "&8" : "&2" ) + life.Name ); + } + } + + private static void OnPrint( Player p, Command cmd ) { + LifeHandler handler = GetCheckedLifeHandler( p, cmd ); + if ( null == handler ) + return; + Life2DZone l = handler._life; + p.Message( "&y" + l.Name + ": " + ( l.Stopped ? "stopped" : "started" ) + ", delay " + l.Delay + + ", intermediate delay " + l.HalfStepDelay + ", is" + ( l.Torus ? "" : " not" ) + " on torus, " + + "auto reset strategy is " + Enum.GetName( typeof( AutoResetMethod ), l.AutoReset ) + + ", owner is " + l.CreatorName + + ", changable by " + l.MinRankToChange + + ", block types: " + l.Normal + " is normal, " + l.Empty + " is empty, " + l.Dead + " is dead, " + l.Newborn + " is newborn" ); + } + + private static void OnSet( Player p, Command cmd ) { + LifeHandler handler = GetCheckedLifeHandler( p, cmd ); + if ( null == handler ) + return; + if ( !handler.CheckChangePermissions( p ) ) + return; + + string paramStr = cmd.Next(); + if ( string.IsNullOrWhiteSpace( paramStr ) ) { + p.Message( "&WEmpty parameter name. &hAccepted names are " + _allParams.ToString() ); + return; + } + Param param; + if ( !_params.TryGetValue( paramStr, out param ) ) { + p.Message( "&WUknown parameter name" + paramStr + ". &hAccepted names are " + _allParams.ToString() ); + return; + } + string val = cmd.Next(); + if ( string.IsNullOrWhiteSpace( val ) ) { + p.Message( "&WEmpty value." ); + return; + } + param.SetValue( p, handler._life, val ); + } + + private static void SetDelay( Player p, Life2DZone life, string val ) { + int delay; + if ( !int.TryParse( val, out delay ) || delay <= 20 ) { + p.Message( "&WExpected integer value >=20 as delay" ); + return; + } + life.Delay = delay; + p.Message( "&yStep delay set to " + val ); + } + + private static void SetHalfDelay( Player p, Life2DZone life, string val ) { + int delay; + if ( !int.TryParse( val, out delay ) || delay < 0 ) { + p.Message( "&WExpected non-negative integer value as intermediate delay" ); + return; + } + life.HalfStepDelay = delay; + p.Message( "&yIntermediate step delay set to " + val ); + } + + private static void SetNormal( Player p, Life2DZone life, string val ) { + Block b = Map.GetBlockByName( val ); + if ( b == Block.Undefined ) { + p.Message( "&WUnrecognized block name " + val ); + return; + } + life.Normal = b; + p.Message( "&yNormal block set to " + val ); + } + + private static void SetEmpty( Player p, Life2DZone life, string val ) { + Block b = Map.GetBlockByName( val ); + if ( b == Block.Undefined ) { + p.Message( "&WUnrecognized block name " + val ); + return; + } + life.Empty = b; + p.Message( "&yEmpty block set to " + val ); + } + + private static void SetDead( Player p, Life2DZone life, string val ) { + Block b = Map.GetBlockByName( val ); + if ( b == Block.Undefined ) { + p.Message( "&WUnrecognized block name " + val ); + return; + } + life.Dead = b; + p.Message( "&yDead block set to " + val ); + } + + private static void SetNewborn( Player p, Life2DZone life, string val ) { + Block b = Map.GetBlockByName( val ); + if ( b == Block.Undefined ) { + p.Message( "&WUnrecognized block name " + val ); + return; + } + life.Newborn = b; + p.Message( "&yNewborn block set to " + val ); + } + + private static void SetTorus( Player p, Life2DZone life, string val ) { + bool torus; + if ( !bool.TryParse( val, out torus ) ) { + p.Message( "&WExpected 'true' or 'false' as torus parameter value" ); + return; + } + life.Torus = torus; + p.Message( "&yTorus param set to " + val ); + } + + private static void SetAutoReset( Player p, Life2DZone life, string val ) { + AutoResetMethod method; + val = val.ToLower(); + if ( val == "no" || val == "none" ) + method = AutoResetMethod.None; + else if ( val == "toinitial" || val == "i" ) + method = AutoResetMethod.ToInitial; + else if ( val == "torandom" || val == "r" || val == "rnd" ) + method = AutoResetMethod.ToRandom; + else { + p.Message( "&WUnrecognized auto reset method " + val + ".\n&h Type '/life help AutoReset' to see all the possible values." ); + return; + } + life.AutoReset = method; + p.Message( "&yAutoReset param set to " + Enum.GetName( typeof( AutoResetMethod ), method ) ); + } + + private bool CheckWorldPermissions( Player p ) { + if ( !p.Info.Rank.AllowSecurityCircumvention ) { + SecurityCheckResult buildCheck = _world.BuildSecurity.CheckDetailed( p.Info ); + switch ( buildCheck ) { + case SecurityCheckResult.BlackListed: + p.Message( "Cannot add life to world {0}&S: You are barred from building here.", + p.ClassyName ); + return false; + case SecurityCheckResult.RankTooLow: + p.Message( "Cannot add life to world {0}&S: You are not allowed to build here.", + p.ClassyName ); + return false; + } + } + return true; + } + + private bool CheckChangePermissions( Player p ) { + if ( string.IsNullOrWhiteSpace( _life.CreatorName ) || p.Name == _life.CreatorName ) + return true; + if ( string.IsNullOrWhiteSpace( _life.MinRankToChange ) ) + return true; + Rank r; + if ( !RankManager.RanksByName.TryGetValue( _life.MinRankToChange, out r ) ) { + string prevRank = _life.MinRankToChange; + r = RankManager.LowestRank.NextRankUp ?? RankManager.LowestRank; + _life.MinRankToChange = r.Name; + p.Message( "&WRank " + prevRank + " couldn't be found. Updated to " + r.Name ); + } + if ( p.Info.Rank >= r ) + return true; + p.Message( "&WYour rank is too low to change this life." ); + return false; + } + } +} \ No newline at end of file diff --git a/fCraft/Commands/Command Handlers/Math Handlers/EqualityDrawOperation.cs b/fCraft/Commands/Command Handlers/Math Handlers/EqualityDrawOperation.cs index e83d15d..a20e4cf 100644 --- a/fCraft/Commands/Command Handlers/Math Handlers/EqualityDrawOperation.cs +++ b/fCraft/Commands/Command Handlers/Math Handlers/EqualityDrawOperation.cs @@ -28,144 +28,125 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) <2011 - 2013> Lao Tszy (lao_tszy@yahoo.co.uk) using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft; using fCraft.Drawing; -namespace fCraft -{ - //draws volume, defined by an inequality - public class EqualityDrawOperation : DrawOperation - { - private Expression _expression; - private Scaler _scaler; - private int _count; - public EqualityDrawOperation(Player player, Command cmd) - : base(player) - { - string strFunc = cmd.Next(); - if (string.IsNullOrWhiteSpace(strFunc)) - { - player.Message("empty equality expression"); +namespace fCraft { + + //draws volume, defined by an inequality + public class EqualityDrawOperation : DrawOperation { + private Expression _expression; + private Scaler _scaler; + private int _count; + + public EqualityDrawOperation( Player player, Command cmd ) + : base( player ) { + string strFunc = cmd.Next(); + if ( string.IsNullOrWhiteSpace( strFunc ) ) { + player.Message( "empty equality expression" ); return; } - if (strFunc.Length < 3) - { - player.Message("expression is too short (should be like f(x,y,z)=g(x,y,z))"); + if ( strFunc.Length < 3 ) { + player.Message( "expression is too short (should be like f(x,y,z)=g(x,y,z))" ); return; } - strFunc = strFunc.ToLower(); - - _expression = SimpleParser.ParseAsEquality(strFunc, new string[] { "x", "y", "z" }); - - player.Message("Expression parsed as " + _expression.Print()); - string scalingStr = cmd.Next(); - _scaler = new Scaler(scalingStr); - } - - public override int DrawBatch(int maxBlocksToDraw) - { - //ignoring maxBlocksToDraw - - //do it 3 times, iterating axis in different order, to get to the closed surface as close as possible - InternalDraw(ref Coords.X, ref Coords.Y, ref Coords.Z, - Bounds.XMin, Bounds.XMax, Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, - ref Coords.X, ref Coords.Y, ref Coords.Z, - Bounds.XMin, Bounds.XMax, Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, - maxBlocksToDraw); - InternalDraw(ref Coords.X, ref Coords.Z, ref Coords.Y, - Bounds.XMin, Bounds.XMax, Bounds.ZMin, Bounds.ZMax, Bounds.YMin, Bounds.YMax, - ref Coords.X, ref Coords.Y, ref Coords.Z, - Bounds.XMin, Bounds.XMax, Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, - maxBlocksToDraw); - InternalDraw(ref Coords.Y, ref Coords.Z, ref Coords.X, - Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, Bounds.XMin, Bounds.XMax, - ref Coords.X, ref Coords.Y, ref Coords.Z, - Bounds.XMin, Bounds.XMax, Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, - maxBlocksToDraw); - - IsDone = true; - return _count; - } - - //this method exists to box coords nicely as ref params, note that the set of {arg1, arg2, arg3} must be the same with - //{ xArg, yArg, zArg } - private int InternalDraw(ref int arg1, ref int arg2, ref int arg3, - int min1, int max1, int min2, int max2, int min3, int max3, - ref int argX, ref int argY, ref int argZ, - int minX, int maxX, int minY, int maxY, int minZ, int maxZ, - int maxBlocksToDraw) - { - _count = 0; - int exCount = 0; - - for (arg1 = min1; arg1 <= max1 && MathCommands.MaxCalculationExceptions >= exCount; ++arg1) - { - for (arg2 = min2; arg2 <= max2 && MathCommands.MaxCalculationExceptions >= exCount; ++arg2) - { - double prevDiff = 0; - double prevComp = 0; - for (int arg3Iterator = min3; arg3Iterator <= max3; ++arg3Iterator) - { - try - { - arg3 = arg3Iterator; - Tuple res= - _expression.EvaluateAsEquality(_scaler.ToFuncParam(argX, minX, maxX), - _scaler.ToFuncParam(argY, minY, maxY), - _scaler.ToFuncParam(argZ, minZ, maxZ)); - //decision: we cant only take points with 0 as comparison result as it will happen almost never. - //We are reacting on the changes of the comparison result sign - arg3 = int.MaxValue; - if (res.Item1 == 0) //exactly equal, wow, such a surprise - arg3 = arg3Iterator; - else if (res.Item1 * prevComp < 0) //i.e. different signs, but not the prev==0 - arg3 = res.Item2 < prevDiff ? arg3Iterator : arg3Iterator - 1; //then choose the closest to 0 difference - - if (DrawOneBlock()) - ++_count; - //if (TimeToEndBatch) - // return _count; - - prevComp = res.Item1; + strFunc = strFunc.ToLower(); + + _expression = SimpleParser.ParseAsEquality( strFunc, new string[] { "x", "y", "z" } ); + + player.Message( "Expression parsed as " + _expression.Print() ); + string scalingStr = cmd.Next(); + _scaler = new Scaler( scalingStr ); + } + + public override int DrawBatch( int maxBlocksToDraw ) { + //ignoring maxBlocksToDraw + + //do it 3 times, iterating axis in different order, to get to the closed surface as close as possible + InternalDraw( ref Coords.X, ref Coords.Y, ref Coords.Z, + Bounds.XMin, Bounds.XMax, Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, + ref Coords.X, ref Coords.Y, ref Coords.Z, + Bounds.XMin, Bounds.XMax, Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, + maxBlocksToDraw ); + InternalDraw( ref Coords.X, ref Coords.Z, ref Coords.Y, + Bounds.XMin, Bounds.XMax, Bounds.ZMin, Bounds.ZMax, Bounds.YMin, Bounds.YMax, + ref Coords.X, ref Coords.Y, ref Coords.Z, + Bounds.XMin, Bounds.XMax, Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, + maxBlocksToDraw ); + InternalDraw( ref Coords.Y, ref Coords.Z, ref Coords.X, + Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, Bounds.XMin, Bounds.XMax, + ref Coords.X, ref Coords.Y, ref Coords.Z, + Bounds.XMin, Bounds.XMax, Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, + maxBlocksToDraw ); + + IsDone = true; + return _count; + } + + //this method exists to box coords nicely as ref params, note that the set of {arg1, arg2, arg3} must be the same with + //{ xArg, yArg, zArg } + private int InternalDraw( ref int arg1, ref int arg2, ref int arg3, + int min1, int max1, int min2, int max2, int min3, int max3, + ref int argX, ref int argY, ref int argZ, + int minX, int maxX, int minY, int maxY, int minZ, int maxZ, + int maxBlocksToDraw ) { + _count = 0; + int exCount = 0; + + for ( arg1 = min1; arg1 <= max1 && MathCommands.MaxCalculationExceptions >= exCount; ++arg1 ) { + for ( arg2 = min2; arg2 <= max2 && MathCommands.MaxCalculationExceptions >= exCount; ++arg2 ) { + double prevDiff = 0; + double prevComp = 0; + for ( int arg3Iterator = min3; arg3Iterator <= max3; ++arg3Iterator ) { + try { + arg3 = arg3Iterator; + Tuple res = + _expression.EvaluateAsEquality( _scaler.ToFuncParam( argX, minX, maxX ), + _scaler.ToFuncParam( argY, minY, maxY ), + _scaler.ToFuncParam( argZ, minZ, maxZ ) ); + //decision: we cant only take points with 0 as comparison result as it will happen almost never. + //We are reacting on the changes of the comparison result sign + arg3 = int.MaxValue; + if ( res.Item1 == 0 ) //exactly equal, wow, such a surprise + arg3 = arg3Iterator; + else if ( res.Item1 * prevComp < 0 ) //i.e. different signs, but not the prev==0 + arg3 = res.Item2 < prevDiff ? arg3Iterator : arg3Iterator - 1; //then choose the closest to 0 difference + + if ( DrawOneBlock() ) + ++_count; + //if (TimeToEndBatch) + // return _count; + + prevComp = res.Item1; prevDiff = res.Item2; - } - catch (Exception) - { - //the exception here is kinda of normal, for functions (especially interesting ones) - //may have eg punctured points; we just have to keep an eye on the number, since producing 10000 - //exceptions in the multiclient application is not the best idea - if (++exCount > MathCommands.MaxCalculationExceptions) - { - Player.Message("Surface drawing is interrupted: too many (>" + MathCommands.MaxCalculationExceptions + - ") calculation exceptions."); - break; - } - } - } - } - } - return _count; - } - - public override bool Prepare(Vector3I[] marks) - { - if (!base.Prepare(marks)) - { - return false; - } - BlocksTotalEstimate = Bounds.Volume; - return true; - } - public override string Name - { - get - { - return "Equality"; - } - } - } -} + } catch ( Exception ) { + //the exception here is kinda of normal, for functions (especially interesting ones) + //may have eg punctured points; we just have to keep an eye on the number, since producing 10000 + //exceptions in the multiclient application is not the best idea + if ( ++exCount > MathCommands.MaxCalculationExceptions ) { + Player.Message( "Surface drawing is interrupted: too many (>" + MathCommands.MaxCalculationExceptions + + ") calculation exceptions." ); + break; + } + } + } + } + } + return _count; + } + + public override bool Prepare( Vector3I[] marks ) { + if ( !base.Prepare( marks ) ) { + return false; + } + BlocksTotalEstimate = Bounds.Volume; + return true; + } + + public override string Name { + get { + return "Equality"; + } + } + } +} \ No newline at end of file diff --git a/fCraft/Commands/Command Handlers/Math Handlers/Expression.cs b/fCraft/Commands/Command Handlers/Math Handlers/Expression.cs index 7a72a4e..500ce62 100644 --- a/fCraft/Commands/Command Handlers/Math Handlers/Expression.cs +++ b/fCraft/Commands/Command Handlers/Math Handlers/Expression.cs @@ -24,513 +24,488 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + //Copyright (C) <2011 - 2013> Lao Tszy (lao_tszy@yahoo.co.uk) using System; using System.Collections.Generic; using System.Linq; -using System.Text; -namespace fCraft -{ +namespace fCraft { //reverse polish notation expression - public class Expression : IExpressionElement - { + public class Expression : IExpressionElement { private List _expression = new List(); private Dictionary _vars = new Dictionary(); //vars by name private Variable[] _varsArray; //vars by ordes of appearence in constructor + public IDictionary Vars { get { return _vars; } } public String AssignedFunctionName { get; internal set; } - public Expression(IEnumerable vars) - { - if (null != vars) - { + public Expression( IEnumerable vars ) { + if ( null != vars ) { _varsArray = new Variable[vars.Count()]; int i = 0; - foreach (var v in vars) - { + foreach ( var v in vars ) { _varsArray[i] = new Variable() { Name = v }; - _vars.Add(v, _varsArray[i]); + _vars.Add( v, _varsArray[i] ); ++i; } } } - public Expression Append(IExpressionElement element) - { - _expression.Add(element); + public Expression Append( IExpressionElement element ) { + _expression.Add( element ); return this; } //var value can be set by name - public void Var(string name, double val) - { + public void Var( string name, double val ) { _vars[name].Value = val; } + //here var values must be given in the same order as in the ctr - public double Evaluate(params double[] param) - { + public double Evaluate( params double[] param ) { Stack stack = new Stack(); - EvaluateInternal(param, stack); + EvaluateInternal( param, stack ); return stack.Pop(); } - private void EvaluateInternal(double[] param, Stack stack) - { - if (null != param) - { - if (param.Length != _varsArray.Length) - throw new ArgumentException("wrong number of params"); - for (int i = 0; i < param.Length; ++i) + private void EvaluateInternal( double[] param, Stack stack ) { + if ( null != param ) { + if ( param.Length != _varsArray.Length ) + throw new ArgumentException( "wrong number of params" ); + for ( int i = 0; i < param.Length; ++i ) _varsArray[i].Value = param[i]; } - foreach (IExpressionElement e in _expression) - e.Evaluate(stack); + foreach ( IExpressionElement e in _expression ) + e.Evaluate( stack ); } - public string Print() - { + + public string Print() { Stack stack = new Stack(); - foreach (IExpressionElement e in _expression) - e.Print(stack); + foreach ( IExpressionElement e in _expression ) + e.Print( stack ); return stack.Pop(); } - public void MakeEquality() - { - if (!(_expression.Last() is Equal)) - throw new ArgumentException("expression is not an equality"); + public void MakeEquality() { + if ( !( _expression.Last() is Equal ) ) + throw new ArgumentException( "expression is not an equality" ); _expression[_expression.Count - 1] = new EqualityEqual(); } - public bool IsEquality() - { + + public bool IsEquality() { return _expression.Last() is EqualityEqual; } - public bool IsInEquality() - { + + public bool IsInEquality() { IExpressionElement e = _expression.Last(); - return (e is Less) || (e is Greater); + return ( e is Less ) || ( e is Greater ); } - public Tuple EvaluateAsEquality(params double[] param) - { + + public Tuple EvaluateAsEquality( params double[] param ) { Stack stack = new Stack(); - EvaluateInternal(param, stack); + EvaluateInternal( param, stack ); double compRes = stack.Pop(); - return new Tuple(compRes, stack.Pop()); + return new Tuple( compRes, stack.Pop() ); } - public void Evaluate(Stack stack) - { - foreach (IExpressionElement e in _expression) - e.Evaluate(stack); + public void Evaluate( Stack stack ) { + foreach ( IExpressionElement e in _expression ) + e.Evaluate( stack ); } - public void Print(Stack stack) - { - stack.Push(AssignedFunctionName); + public void Print( Stack stack ) { + stack.Push( AssignedFunctionName ); } } //elements, like all consts, operators, and functions - public interface IExpressionElement - { - void Evaluate(Stack stack); - void Print(Stack stack); + public interface IExpressionElement { + + void Evaluate( Stack stack ); + + void Print( Stack stack ); } //all the classes except Variable are stateless and those - //instances can be reused careless. - public class Variable : IExpressionElement - { + //instances can be reused careless. + public class Variable : IExpressionElement { + public string Name { get; set; } + public double Value { get; set; } - public void Evaluate(Stack stack) - { - stack.Push(Value); + + public void Evaluate( Stack stack ) { + stack.Push( Value ); } - public void Print(Stack stack) - { - stack.Push(Name); + + public void Print( Stack stack ) { + stack.Push( Name ); } } - public class E : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.E); + public class E : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.E ); } - public void Print(Stack stack) - { - stack.Push("e"); + + public void Print( Stack stack ) { + stack.Push( "e" ); } } - public class Pi : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.PI); + public class Pi : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.PI ); } - public void Print(Stack stack) - { - stack.Push("pi"); + + public void Print( Stack stack ) { + stack.Push( "pi" ); } } - public class Sum : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(stack.Pop() + stack.Pop()); + public class Sum : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( stack.Pop() + stack.Pop() ); } - public void Print(Stack stack) - { + + public void Print( Stack stack ) { string second = stack.Pop(); - stack.Push("(" + stack.Pop() + "+" + second + ")"); + stack.Push( "(" + stack.Pop() + "+" + second + ")" ); } } - public class Mul : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(stack.Pop() * stack.Pop()); + public class Mul : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( stack.Pop() * stack.Pop() ); } - public void Print(Stack stack) - { + + public void Print( Stack stack ) { string second = stack.Pop(); - stack.Push(stack.Pop() + "*" + second); + stack.Push( stack.Pop() + "*" + second ); } } - public class Sub : IExpressionElement - { - public void Evaluate(Stack stack) - { + public class Sub : IExpressionElement { + + public void Evaluate( Stack stack ) { double sub = stack.Pop(); - stack.Push(stack.Pop() - sub); + stack.Push( stack.Pop() - sub ); } - public void Print(Stack stack) - { + + public void Print( Stack stack ) { string second = stack.Pop(); - stack.Push("(" + stack.Pop() + "-" + second + ")"); + stack.Push( "(" + stack.Pop() + "-" + second + ")" ); } } - public class Div : IExpressionElement - { - public void Evaluate(Stack stack) - { + public class Div : IExpressionElement { + + public void Evaluate( Stack stack ) { double denom = stack.Pop(); - stack.Push(stack.Pop() / denom); + stack.Push( stack.Pop() / denom ); } - public void Print(Stack stack) - { + + public void Print( Stack stack ) { string second = stack.Pop(); - stack.Push(stack.Pop() + "/" + second); + stack.Push( stack.Pop() + "/" + second ); } } - public class Mod : IExpressionElement - { - public void Evaluate(Stack stack) - { + public class Mod : IExpressionElement { + + public void Evaluate( Stack stack ) { double b = stack.Pop(); - stack.Push(stack.Pop() % b); + stack.Push( stack.Pop() % b ); } - public void Print(Stack stack) - { + + public void Print( Stack stack ) { string second = stack.Pop(); - stack.Push("(" + stack.Pop() + "%" + second + ")"); + stack.Push( "(" + stack.Pop() + "%" + second + ")" ); } } - public class Pow : IExpressionElement - { - public void Evaluate(Stack stack) - { + public class Pow : IExpressionElement { + + public void Evaluate( Stack stack ) { double pow = stack.Pop(); - stack.Push(Math.Pow(stack.Pop(), pow)); + stack.Push( Math.Pow( stack.Pop(), pow ) ); } - public void Print(Stack stack) - { + + public void Print( Stack stack ) { string second = stack.Pop(); - stack.Push(stack.Pop() + "^" + second); + stack.Push( stack.Pop() + "^" + second ); } } - public class Negate : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(-stack.Pop()); + public class Negate : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( -stack.Pop() ); } - public void Print(Stack stack) - { - stack.Push("-(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "-(" + stack.Pop() + ")" ); } } - public class Sqrt : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.Sqrt(stack.Pop())); + public class Sqrt : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.Sqrt( stack.Pop() ) ); } - public void Print(Stack stack) - { - stack.Push("sqrt(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "sqrt(" + stack.Pop() + ")" ); } } - public class Abs : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.Abs(stack.Pop())); + public class Abs : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.Abs( stack.Pop() ) ); } - public void Print(Stack stack) - { - stack.Push("abs(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "abs(" + stack.Pop() + ")" ); } } - public class Sign : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.Sign(stack.Pop())); + public class Sign : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.Sign( stack.Pop() ) ); } - public void Print(Stack stack) - { - stack.Push("sign(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "sign(" + stack.Pop() + ")" ); } } - public class Sq : IExpressionElement - { - public void Evaluate(Stack stack) - { + public class Sq : IExpressionElement { + + public void Evaluate( Stack stack ) { double d = stack.Pop(); - stack.Push(d * d); + stack.Push( d * d ); } - public void Print(Stack stack) - { - stack.Push("sq(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "sq(" + stack.Pop() + ")" ); } } - public class Exp : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.Exp(stack.Pop())); + public class Exp : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.Exp( stack.Pop() ) ); } - public void Print(Stack stack) - { - stack.Push("exp(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "exp(" + stack.Pop() + ")" ); } } - public class Lg : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.Log10(stack.Pop())); + public class Lg : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.Log10( stack.Pop() ) ); } - public void Print(Stack stack) - { - stack.Push("lg(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "lg(" + stack.Pop() + ")" ); } } - public class Ln : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.Log(stack.Pop())); + public class Ln : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.Log( stack.Pop() ) ); } - public void Print(Stack stack) - { - stack.Push("ln(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "ln(" + stack.Pop() + ")" ); } } - public class Log : IExpressionElement - { - public void Evaluate(Stack stack) - { + + public class Log : IExpressionElement { + + public void Evaluate( Stack stack ) { double b = stack.Pop(); - stack.Push(Math.Log(stack.Pop(), b)); + stack.Push( Math.Log( stack.Pop(), b ) ); } - public void Print(Stack stack) - { + + public void Print( Stack stack ) { string second = stack.Pop(); - stack.Push("log(" + stack.Pop() + ", " + second + ")"); + stack.Push( "log(" + stack.Pop() + ", " + second + ")" ); } } - public class Sin : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.Sin(stack.Pop())); + + public class Sin : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.Sin( stack.Pop() ) ); } - public void Print(Stack stack) - { - stack.Push("sin(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "sin(" + stack.Pop() + ")" ); } } - public class Cos : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.Cos(stack.Pop())); + + public class Cos : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.Cos( stack.Pop() ) ); } - public void Print(Stack stack) - { - stack.Push("cos(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "cos(" + stack.Pop() + ")" ); } } - public class Tan : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.Tan(stack.Pop())); + + public class Tan : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.Tan( stack.Pop() ) ); } - public void Print(Stack stack) - { - stack.Push("tan(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "tan(" + stack.Pop() + ")" ); } } - public class Sinh : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.Sinh(stack.Pop())); + + public class Sinh : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.Sinh( stack.Pop() ) ); } - public void Print(Stack stack) - { - stack.Push("sinh(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "sinh(" + stack.Pop() + ")" ); } } - public class Cosh : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.Cosh(stack.Pop())); + + public class Cosh : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.Cosh( stack.Pop() ) ); } - public void Print(Stack stack) - { - stack.Push("cosh(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "cosh(" + stack.Pop() + ")" ); } } - public class Tanh : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(Math.Tanh(stack.Pop())); + + public class Tanh : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( Math.Tanh( stack.Pop() ) ); } - public void Print(Stack stack) - { - stack.Push("tanh(" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "tanh(" + stack.Pop() + ")" ); } } + //comparison ops - public class Greater : IExpressionElement - { - public void Evaluate(Stack stack) - { + public class Greater : IExpressionElement { + + public void Evaluate( Stack stack ) { double b = stack.Pop(); - stack.Push(stack.Pop() > b ? 1.0 : 0); + stack.Push( stack.Pop() > b ? 1.0 : 0 ); } - public void Print(Stack stack) - { + + public void Print( Stack stack ) { string second = stack.Pop(); - stack.Push("(" + stack.Pop() + ">" + second + ")"); + stack.Push( "(" + stack.Pop() + ">" + second + ")" ); } } - public class Less : IExpressionElement - { - public void Evaluate(Stack stack) - { + + public class Less : IExpressionElement { + + public void Evaluate( Stack stack ) { double b = stack.Pop(); - stack.Push(stack.Pop() < b ? 1.0 : 0); + stack.Push( stack.Pop() < b ? 1.0 : 0 ); } - public void Print(Stack stack) - { + + public void Print( Stack stack ) { string second = stack.Pop(); - stack.Push("(" + stack.Pop() + "<" + second + ")"); + stack.Push( "(" + stack.Pop() + "<" + second + ")" ); } } - //simple equality for use in-exp - public class Equal : IExpressionElement - { - public void Evaluate(Stack stack) - { + + //simple equality for use in-exp + public class Equal : IExpressionElement { + + public void Evaluate( Stack stack ) { double b = stack.Pop(); - stack.Push(stack.Pop() == b ? 1.0 : 0); + stack.Push( stack.Pop() == b ? 1.0 : 0 ); } - public void Print(Stack stack) - { + + public void Print( Stack stack ) { string second = stack.Pop(); - stack.Push("(" + stack.Pop() + "=" + second + ")"); + stack.Push( "(" + stack.Pop() + "=" + second + ")" ); } } - //special equality operation needed for equations, where we need to know whether the equality happened in between of two evaluation points - //and also choose between those points - public class EqualityEqual : IExpressionElement - { - public void Evaluate(Stack stack) - { + + //special equality operation needed for equations, where we need to know whether the equality happened in between of two evaluation points + //and also choose between those points + public class EqualityEqual : IExpressionElement { + + public void Evaluate( Stack stack ) { double b = stack.Pop(); double a = stack.Pop(); - stack.Push(Math.Abs(a - b)); - stack.Push(Math.Sign(a - b)); + stack.Push( Math.Abs( a - b ) ); + stack.Push( Math.Sign( a - b ) ); } - public void Print(Stack stack) - { + + public void Print( Stack stack ) { string second = stack.Pop(); - stack.Push(stack.Pop() + "=" + second); + stack.Push( stack.Pop() + "=" + second ); } } + //logical ops - public class And : IExpressionElement - { - public void Evaluate(Stack stack) - { + public class And : IExpressionElement { + + public void Evaluate( Stack stack ) { double b = stack.Pop(); - stack.Push(stack.Pop() != 0 && b != 0 ? 1.0 : 0); + stack.Push( stack.Pop() != 0 && b != 0 ? 1.0 : 0 ); } - public void Print(Stack stack) - { + + public void Print( Stack stack ) { string second = stack.Pop(); - stack.Push("(" + stack.Pop() + "&" + second + ")"); + stack.Push( "(" + stack.Pop() + "&" + second + ")" ); } } - public class Or : IExpressionElement - { - public void Evaluate(Stack stack) - { + + public class Or : IExpressionElement { + + public void Evaluate( Stack stack ) { double b = stack.Pop(); - stack.Push(stack.Pop() != 0 || b != 0 ? 1.0 : 0); + stack.Push( stack.Pop() != 0 || b != 0 ? 1.0 : 0 ); } - public void Print(Stack stack) - { + + public void Print( Stack stack ) { string second = stack.Pop(); - stack.Push("(" + stack.Pop() + "|" + second + ")"); + stack.Push( "(" + stack.Pop() + "|" + second + ")" ); } } - public class Not : IExpressionElement - { - public void Evaluate(Stack stack) - { - stack.Push(stack.Pop() == 0 ? 1.0 : 0); + + public class Not : IExpressionElement { + + public void Evaluate( Stack stack ) { + stack.Push( stack.Pop() == 0 ? 1.0 : 0 ); } - public void Print(Stack stack) - { - stack.Push("(!" + stack.Pop() + ")"); + + public void Print( Stack stack ) { + stack.Push( "(!" + stack.Pop() + ")" ); } } -} +} \ No newline at end of file diff --git a/fCraft/Commands/Command Handlers/Math Handlers/FuncDrawOperation.cs b/fCraft/Commands/Command Handlers/Math Handlers/FuncDrawOperation.cs index 96d8c80..381cea1 100644 --- a/fCraft/Commands/Command Handlers/Math Handlers/FuncDrawOperation.cs +++ b/fCraft/Commands/Command Handlers/Math Handlers/FuncDrawOperation.cs @@ -28,173 +28,155 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) <2011 - 2013> Lao Tszy (lao_tszy@yahoo.co.uk) using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft; using fCraft.Drawing; -namespace fCraft -{ - //draws all func variants: any axis as value axis, points, surface, filled - public abstract class FuncDrawOperation : DrawOperation - { - public enum ValueAxis - { - Z, - Y, - X, - } - private Expression _expression; - private Scaler _scaler; - private ValueAxis _vaxis; - protected int _count; - - protected FuncDrawOperation(Player player, Command cmd) - : base(player) - { - string strFunc = cmd.Next(); - if (string.IsNullOrWhiteSpace(strFunc)) - { - player.Message("&WEmpty function expression"); +namespace fCraft { + + //draws all func variants: any axis as value axis, points, surface, filled + public abstract class FuncDrawOperation : DrawOperation { + + public enum ValueAxis { + Z, + Y, + X, + } + + private Expression _expression; + private Scaler _scaler; + private ValueAxis _vaxis; + protected int _count; + + protected FuncDrawOperation( Player player, Command cmd ) + : base( player ) { + string strFunc = cmd.Next(); + if ( string.IsNullOrWhiteSpace( strFunc ) ) { + player.Message( "&WEmpty function expression" ); return; } - if (strFunc.Length < 3) - { - player.Message("&WExpression is too short (should be like z=f(x,y))"); + if ( strFunc.Length < 3 ) { + player.Message( "&WExpression is too short (should be like z=f(x,y))" ); return; } - - strFunc = strFunc.ToLower(); - _vaxis = GetAxis(SimpleParser.PreparseAssignment(ref strFunc)); + strFunc = strFunc.ToLower(); + + _vaxis = GetAxis( SimpleParser.PreparseAssignment( ref strFunc ) ); + + _expression = SimpleParser.Parse( strFunc, GetVarArray( _vaxis ) ); - _expression = SimpleParser.Parse(strFunc, GetVarArray(_vaxis)); - - player.Message("Expression parsed as "+_expression.Print()); - string scalingStr=cmd.Next(); - _scaler = new Scaler(scalingStr); + player.Message( "Expression parsed as " + _expression.Print() ); + string scalingStr = cmd.Next(); + _scaler = new Scaler( scalingStr ); } - private static string[] GetVarArray(ValueAxis axis) - { - switch (axis) - { - case ValueAxis.Z: - return new string[] {"x", "y"}; - case ValueAxis.Y: - return new string[] { "x", "z" }; - case ValueAxis.X: - return new string[] { "y", "z" }; - } - throw new ArgumentException("Unknown value axis direction "+axis+". This software is not released for use in spaces with dimension higher than three."); - } - - private static ValueAxis GetAxis(string varName) - { - if (varName.Length == 1) - switch (varName[0]) - { - case 'x': - return ValueAxis.X; - case 'y': - return ValueAxis.Y; - case 'z': - return ValueAxis.Z; - } - throw new ArgumentException("value axis " + varName + " is not valid, must be one of 'x', 'y', or 'z'"); - } - - public override int DrawBatch(int maxBlocksToDraw) - { - //ignoring maxBlocksToDraw - switch (_vaxis) - { - case ValueAxis.Z: - InternalDraw(ref Coords.X, ref Coords.Y, ref Coords.Z, - Bounds.XMin, Bounds.XMax, Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, - maxBlocksToDraw); - break; - case ValueAxis.Y: - InternalDraw(ref Coords.X, ref Coords.Z, ref Coords.Y, - Bounds.XMin, Bounds.XMax, Bounds.ZMin, Bounds.ZMax, Bounds.YMin, Bounds.YMax, - maxBlocksToDraw); - break; - case ValueAxis.X: - InternalDraw(ref Coords.Y, ref Coords.Z, ref Coords.X, - Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, Bounds.XMin, Bounds.XMax, - maxBlocksToDraw); - break; - default: - throw new ArgumentException("Unknown value axis direction " + _vaxis + - ". This software is not released for use in spaces with dimension higher than three."); - } - + private static string[] GetVarArray( ValueAxis axis ) { + switch ( axis ) { + case ValueAxis.Z: + return new string[] { "x", "y" }; + case ValueAxis.Y: + return new string[] { "x", "z" }; + case ValueAxis.X: + return new string[] { "y", "z" }; + } + throw new ArgumentException( "Unknown value axis direction " + axis + ". This software is not released for use in spaces with dimension higher than three." ); + } + + private static ValueAxis GetAxis( string varName ) { + if ( varName.Length == 1 ) + switch ( varName[0] ) { + case 'x': + return ValueAxis.X; + case 'y': + return ValueAxis.Y; + case 'z': + return ValueAxis.Z; + } + throw new ArgumentException( "value axis " + varName + " is not valid, must be one of 'x', 'y', or 'z'" ); + } + + public override int DrawBatch( int maxBlocksToDraw ) { + //ignoring maxBlocksToDraw + switch ( _vaxis ) { + case ValueAxis.Z: + InternalDraw( ref Coords.X, ref Coords.Y, ref Coords.Z, + Bounds.XMin, Bounds.XMax, Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, + maxBlocksToDraw ); + break; + + case ValueAxis.Y: + InternalDraw( ref Coords.X, ref Coords.Z, ref Coords.Y, + Bounds.XMin, Bounds.XMax, Bounds.ZMin, Bounds.ZMax, Bounds.YMin, Bounds.YMax, + maxBlocksToDraw ); + break; + + case ValueAxis.X: + InternalDraw( ref Coords.Y, ref Coords.Z, ref Coords.X, + Bounds.YMin, Bounds.YMax, Bounds.ZMin, Bounds.ZMax, Bounds.XMin, Bounds.XMax, + maxBlocksToDraw ); + break; + + default: + throw new ArgumentException( "Unknown value axis direction " + _vaxis + + ". This software is not released for use in spaces with dimension higher than three." ); + } + IsDone = true; return _count; } - //this method exists to box coords nicely as ref params - private int InternalDraw(ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, int minV, int maxV, int maxBlocksToDraw) - { - _count = 0; - int exCount = 0; - DrawFasePrepare(min1, max1, min2, max2); - - for (arg1 = min1; arg1 <= max1 && MathCommands.MaxCalculationExceptions >= exCount; ++arg1) - { - for (arg2 = min2; arg2 <= max2; ++arg2) - { - try - { - int fval = - _scaler.FromFuncResult( - _expression.Evaluate(_scaler.ToFuncParam(arg1, min1, max1), - _scaler.ToFuncParam(arg2, min2, max2)), - minV, maxV); - DrawFase1(fval, ref arg1, ref arg2, ref val, min1, max1, min2, max2, minV, maxV, maxBlocksToDraw); - //if (TimeToEndBatch) - // return _count; - } - catch (Exception) - { - //the exception here is kinda of normal, for functions (especially interesting ones) - //may have eg punctured points; we just have to keep an eye on the number, since producing 10000 - //exceptions in the multiclient application is not the best idea - if (++exCount > MathCommands.MaxCalculationExceptions) - { - Player.Message("Function drawing is interrupted: too many (>"+MathCommands.MaxCalculationExceptions+") calculation exceptions."); - break; - } - } - } - } - //the real drawing for the surface variant - DrawFase2(ref arg1, ref arg2, ref val, min1, max1, min2, max2, minV, maxV, maxBlocksToDraw); - return _count; - } - - protected abstract void DrawFasePrepare(int min1, int max1, int min2, int max2); - protected abstract void DrawFase1(int fval, ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, - int minV, int maxV, int maxBlocksToDraw); - protected abstract void DrawFase2(ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, - int minV, int maxV, int maxBlocksToDraw); - - public override bool Prepare(Vector3I[] marks) - { - if (!base.Prepare(marks)) - { + //this method exists to box coords nicely as ref params + private int InternalDraw( ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, int minV, int maxV, int maxBlocksToDraw ) { + _count = 0; + int exCount = 0; + DrawFasePrepare( min1, max1, min2, max2 ); + + for ( arg1 = min1; arg1 <= max1 && MathCommands.MaxCalculationExceptions >= exCount; ++arg1 ) { + for ( arg2 = min2; arg2 <= max2; ++arg2 ) { + try { + int fval = + _scaler.FromFuncResult( + _expression.Evaluate( _scaler.ToFuncParam( arg1, min1, max1 ), + _scaler.ToFuncParam( arg2, min2, max2 ) ), + minV, maxV ); + DrawFase1( fval, ref arg1, ref arg2, ref val, min1, max1, min2, max2, minV, maxV, maxBlocksToDraw ); + //if (TimeToEndBatch) + // return _count; + } catch ( Exception ) { + //the exception here is kinda of normal, for functions (especially interesting ones) + //may have eg punctured points; we just have to keep an eye on the number, since producing 10000 + //exceptions in the multiclient application is not the best idea + if ( ++exCount > MathCommands.MaxCalculationExceptions ) { + Player.Message( "Function drawing is interrupted: too many (>" + MathCommands.MaxCalculationExceptions + ") calculation exceptions." ); + break; + } + } + } + } + //the real drawing for the surface variant + DrawFase2( ref arg1, ref arg2, ref val, min1, max1, min2, max2, minV, maxV, maxBlocksToDraw ); + return _count; + } + + protected abstract void DrawFasePrepare( int min1, int max1, int min2, int max2 ); + + protected abstract void DrawFase1( int fval, ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, + int minV, int maxV, int maxBlocksToDraw ); + + protected abstract void DrawFase2( ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, + int minV, int maxV, int maxBlocksToDraw ); + + public override bool Prepare( Vector3I[] marks ) { + if ( !base.Prepare( marks ) ) { return false; } BlocksTotalEstimate = Bounds.Volume; return true; } - public override string Name - { - get - { - return "Func"; + + public override string Name { + get { + return "Func"; } } } -} +} \ No newline at end of file diff --git a/fCraft/Commands/Command Handlers/Math Handlers/FuncDrawOperationPSF.cs b/fCraft/Commands/Command Handlers/Math Handlers/FuncDrawOperationPSF.cs index 754c230..fc1dcea 100644 --- a/fCraft/Commands/Command Handlers/Math Handlers/FuncDrawOperationPSF.cs +++ b/fCraft/Commands/Command Handlers/Math Handlers/FuncDrawOperationPSF.cs @@ -28,154 +28,124 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) <2011 - 2013> Lao Tszy (lao_tszy@yahoo.co.uk) using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft; - -namespace fCraft -{ - public class FuncDrawOperationPoints : FuncDrawOperation - { - public FuncDrawOperationPoints(Player player, Command cmd) - : base(player, cmd) - { - - } - - protected override void DrawFasePrepare(int min1, int max1, int min2, int max2) - { - - } - protected override void DrawFase1(int fval, ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, - int minV, int maxV, int maxBlocksToDraw) - { - if (fval <= maxV && fval >= minV) - { - val = fval; - if (DrawOneBlock()) - ++_count; - } - } - protected override void DrawFase2(ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, - int minV, int maxV, int maxBlocksToDraw) - { - - } - public override string Name - { - get - { - return base.Name + "Points"; - } - } - } - - - - public class FuncDrawOperationFill : FuncDrawOperation - { - public FuncDrawOperationFill(Player player, Command cmd) - : base(player, cmd) - { - - } - - protected override void DrawFasePrepare(int min1, int max1, int min2, int max2) - { - - } - protected override void DrawFase1(int fval, ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, - int minV, int maxV, int maxBlocksToDraw) - { - for (val = minV; val <= fval && val <= maxV; ++val) - { - if (DrawOneBlock()) - { - ++_count; - //if (TimeToEndBatch) - // return; - } - } - } - protected override void DrawFase2(ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, - int minV, int maxV, int maxBlocksToDraw) - { - - } - public override string Name - { - get - { - return base.Name + "Fill"; - } - } - } - - - public class FuncDrawOperationSurface : FuncDrawOperation - { - private int[][] _surface; - public FuncDrawOperationSurface(Player player, Command cmd) - : base(player, cmd) - { - - } - - protected override void DrawFasePrepare(int min1, int max1, int min2, int max2) - { - _surface = new int[max1 - min1 + 1][]; - for (int i = 0; i < _surface.Length; ++i) - { - _surface[i] = new int[max2 - min2 + 1]; - for (int j = 1; j < _surface[i].Length; ++j) - _surface[i][j] = int.MaxValue; - } - } - protected override void DrawFase1(int fval, ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, - int minV, int maxV, int maxBlocksToDraw) - { - _surface[arg1 - min1][arg2 - min2] = fval; - } - protected override void DrawFase2(ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, - int minV, int maxV, int maxBlocksToDraw) - { - int count = 0; - for (arg1 = min1; arg1 <= max1; ++arg1) - { - for (arg2 = min2; arg2 <= max2; ++arg2) - { - int a1 = arg1 - min1, a2 = arg2 - min2; - if (_surface[a1][a2] == int.MaxValue) - continue; - //find min value around - int minVal = _surface[a1][a2]; - if (a1 - 1 >= 0) - minVal = Math.Min(minVal, _surface[a1 - 1][a2] + 1); - if (a1 + 1 < _surface.Length) - minVal = Math.Min(minVal, _surface[a1 + 1][a2] + 1); - if (a2 - 1 >= 0) - minVal = Math.Min(minVal, _surface[a1][a2 - 1] + 1); - if (a2 + 1 < _surface[a1].Length) - minVal = Math.Min(minVal, _surface[a1][a2 + 1] + 1); - minVal = Math.Max(minVal, minV); - - for (val = minVal; val <= _surface[a1][a2] && val <= maxV; ++val) - if (DrawOneBlock()) - { - ++count; - //if (TimeToEndBatch) - // return; - } - } - } - } - public override string Name - { - get - { - return base.Name + "Surface"; - } - } - } -} + +namespace fCraft { + + public class FuncDrawOperationPoints : FuncDrawOperation { + + public FuncDrawOperationPoints( Player player, Command cmd ) + : base( player, cmd ) { + } + + protected override void DrawFasePrepare( int min1, int max1, int min2, int max2 ) { + } + + protected override void DrawFase1( int fval, ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, + int minV, int maxV, int maxBlocksToDraw ) { + if ( fval <= maxV && fval >= minV ) { + val = fval; + if ( DrawOneBlock() ) + ++_count; + } + } + + protected override void DrawFase2( ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, + int minV, int maxV, int maxBlocksToDraw ) { + } + + public override string Name { + get { + return base.Name + "Points"; + } + } + } + + public class FuncDrawOperationFill : FuncDrawOperation { + + public FuncDrawOperationFill( Player player, Command cmd ) + : base( player, cmd ) { + } + + protected override void DrawFasePrepare( int min1, int max1, int min2, int max2 ) { + } + + protected override void DrawFase1( int fval, ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, + int minV, int maxV, int maxBlocksToDraw ) { + for ( val = minV; val <= fval && val <= maxV; ++val ) { + if ( DrawOneBlock() ) { + ++_count; + //if (TimeToEndBatch) + // return; + } + } + } + + protected override void DrawFase2( ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, + int minV, int maxV, int maxBlocksToDraw ) { + } + + public override string Name { + get { + return base.Name + "Fill"; + } + } + } + + public class FuncDrawOperationSurface : FuncDrawOperation { + private int[][] _surface; + + public FuncDrawOperationSurface( Player player, Command cmd ) + : base( player, cmd ) { + } + + protected override void DrawFasePrepare( int min1, int max1, int min2, int max2 ) { + _surface = new int[max1 - min1 + 1][]; + for ( int i = 0; i < _surface.Length; ++i ) { + _surface[i] = new int[max2 - min2 + 1]; + for ( int j = 1; j < _surface[i].Length; ++j ) + _surface[i][j] = int.MaxValue; + } + } + + protected override void DrawFase1( int fval, ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, + int minV, int maxV, int maxBlocksToDraw ) { + _surface[arg1 - min1][arg2 - min2] = fval; + } + + protected override void DrawFase2( ref int arg1, ref int arg2, ref int val, int min1, int max1, int min2, int max2, + int minV, int maxV, int maxBlocksToDraw ) { + int count = 0; + for ( arg1 = min1; arg1 <= max1; ++arg1 ) { + for ( arg2 = min2; arg2 <= max2; ++arg2 ) { + int a1 = arg1 - min1, a2 = arg2 - min2; + if ( _surface[a1][a2] == int.MaxValue ) + continue; + //find min value around + int minVal = _surface[a1][a2]; + if ( a1 - 1 >= 0 ) + minVal = Math.Min( minVal, _surface[a1 - 1][a2] + 1 ); + if ( a1 + 1 < _surface.Length ) + minVal = Math.Min( minVal, _surface[a1 + 1][a2] + 1 ); + if ( a2 - 1 >= 0 ) + minVal = Math.Min( minVal, _surface[a1][a2 - 1] + 1 ); + if ( a2 + 1 < _surface[a1].Length ) + minVal = Math.Min( minVal, _surface[a1][a2 + 1] + 1 ); + minVal = Math.Max( minVal, minV ); + + for ( val = minVal; val <= _surface[a1][a2] && val <= maxV; ++val ) + if ( DrawOneBlock() ) { + ++count; + //if (TimeToEndBatch) + // return; + } + } + } + } + + public override string Name { + get { + return base.Name + "Surface"; + } + } + } +} \ No newline at end of file diff --git a/fCraft/Commands/Command Handlers/Math Handlers/InequalityDrawOperation.cs b/fCraft/Commands/Command Handlers/Math Handlers/InequalityDrawOperation.cs index 02f2251..d2bc957 100644 --- a/fCraft/Commands/Command Handlers/Math Handlers/InequalityDrawOperation.cs +++ b/fCraft/Commands/Command Handlers/Math Handlers/InequalityDrawOperation.cs @@ -28,100 +28,83 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) <2011 - 2013> Lao Tszy (lao_tszy@yahoo.co.uk) using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft; using fCraft.Drawing; -namespace fCraft -{ - //draws volume, defined by an inequality - public class InequalityDrawOperation : DrawOperation - { - private Expression _expression; - private Scaler _scaler; - private int _count; +namespace fCraft { - public InequalityDrawOperation(Player player, Command cmd) - : base(player) - { - string strFunc = cmd.Next(); - if (string.IsNullOrWhiteSpace(strFunc)) - throw new ArgumentException("empty inequality expression"); - if (strFunc.Length < 3) - throw new ArgumentException("expression is too short (should be like f(x,y,z)>g(x,y,z))"); - - strFunc = strFunc.ToLower(); + //draws volume, defined by an inequality + public class InequalityDrawOperation : DrawOperation { + private Expression _expression; + private Scaler _scaler; + private int _count; - _expression = SimpleParser.Parse(strFunc, new string[] { "x", "y", "z" }); - if (!_expression.IsInEquality()) - throw new ArgumentException("the expression given is not an inequality (should be like f(x,y,z)>g(x,y,z))"); + public InequalityDrawOperation( Player player, Command cmd ) + : base( player ) { + string strFunc = cmd.Next(); + if ( string.IsNullOrWhiteSpace( strFunc ) ) + throw new ArgumentException( "empty inequality expression" ); + if ( strFunc.Length < 3 ) + throw new ArgumentException( "expression is too short (should be like f(x,y,z)>g(x,y,z))" ); - player.Message("Expression parsed as " + _expression.Print()); - string scalingStr = cmd.Next(); - _scaler = new Scaler(scalingStr); - } + strFunc = strFunc.ToLower(); - public override int DrawBatch(int maxBlocksToDraw) - { - //ignoring maxBlocksToDraw - _count = 0; - int exCount = 0; + _expression = SimpleParser.Parse( strFunc, new string[] { "x", "y", "z" } ); + if ( !_expression.IsInEquality() ) + throw new ArgumentException( "the expression given is not an inequality (should be like f(x,y,z)>g(x,y,z))" ); - for (Coords.X = Bounds.XMin; Coords.X <= Bounds.XMax && MathCommands.MaxCalculationExceptions >= exCount; ++Coords.X) - { - for (Coords.Y = Bounds.YMin; Coords.Y <= Bounds.YMax && MathCommands.MaxCalculationExceptions >= exCount; ++Coords.Y) - { - for (Coords.Z = Bounds.ZMin; Coords.Z <= Bounds.ZMax; ++Coords.Z) - { - try - { - if (_expression.Evaluate(_scaler.ToFuncParam(Coords.X, Bounds.XMin, Bounds.XMax), - _scaler.ToFuncParam(Coords.Y, Bounds.YMin, Bounds.YMax), - _scaler.ToFuncParam(Coords.Z, Bounds.ZMin, Bounds.ZMax))>0) //1.0 means true - { - if (DrawOneBlock()) - ++_count; - } - //if (TimeToEndBatch) - // return _count; - } - catch (Exception) - { - //the exception here is kinda of normal, for functions (especially interesting ones) - //may have eg punctured points; we just have to keep an eye on the number, since producing 10000 - //exceptions in the multiclient application is not the best idea - if (++exCount > MathCommands.MaxCalculationExceptions) + player.Message( "Expression parsed as " + _expression.Print() ); + string scalingStr = cmd.Next(); + _scaler = new Scaler( scalingStr ); + } + + public override int DrawBatch( int maxBlocksToDraw ) { + //ignoring maxBlocksToDraw + _count = 0; + int exCount = 0; + + for ( Coords.X = Bounds.XMin; Coords.X <= Bounds.XMax && MathCommands.MaxCalculationExceptions >= exCount; ++Coords.X ) { + for ( Coords.Y = Bounds.YMin; Coords.Y <= Bounds.YMax && MathCommands.MaxCalculationExceptions >= exCount; ++Coords.Y ) { + for ( Coords.Z = Bounds.ZMin; Coords.Z <= Bounds.ZMax; ++Coords.Z ) { + try { + if ( _expression.Evaluate( _scaler.ToFuncParam( Coords.X, Bounds.XMin, Bounds.XMax ), + _scaler.ToFuncParam( Coords.Y, Bounds.YMin, Bounds.YMax ), + _scaler.ToFuncParam( Coords.Z, Bounds.ZMin, Bounds.ZMax ) ) > 0 ) //1.0 means true { - Player.Message("Drawing is interrupted: too many (>" + MathCommands.MaxCalculationExceptions + - ") calculation exceptions."); - break; - } - } - } - } - } + if ( DrawOneBlock() ) + ++_count; + } + //if (TimeToEndBatch) + // return _count; + } catch ( Exception ) { + //the exception here is kinda of normal, for functions (especially interesting ones) + //may have eg punctured points; we just have to keep an eye on the number, since producing 10000 + //exceptions in the multiclient application is not the best idea + if ( ++exCount > MathCommands.MaxCalculationExceptions ) { + Player.Message( "Drawing is interrupted: too many (>" + MathCommands.MaxCalculationExceptions + + ") calculation exceptions." ); + break; + } + } + } + } + } + + IsDone = true; + return _count; + } - IsDone = true; - return _count; - } + public override bool Prepare( Vector3I[] marks ) { + if ( !base.Prepare( marks ) ) { + return false; + } + BlocksTotalEstimate = Bounds.Volume; + return true; + } - public override bool Prepare(Vector3I[] marks) - { - if (!base.Prepare(marks)) - { - return false; - } - BlocksTotalEstimate = Bounds.Volume; - return true; - } - public override string Name - { - get - { - return "Inequality"; - } - } - } -} + public override string Name { + get { + return "Inequality"; + } + } + } +} \ No newline at end of file diff --git a/fCraft/Commands/Command Handlers/Math Handlers/ManifoldDrawOperation.cs b/fCraft/Commands/Command Handlers/Math Handlers/ManifoldDrawOperation.cs index a780fe3..ee17004 100644 --- a/fCraft/Commands/Command Handlers/Math Handlers/ManifoldDrawOperation.cs +++ b/fCraft/Commands/Command Handlers/Math Handlers/ManifoldDrawOperation.cs @@ -27,110 +27,95 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) <2011 - 2013> Lao Tszy (lao_tszy@yahoo.co.uk) -using System; -using System.Collections.Generic; using System.Data; -using System.Linq; -using System.Text; -using fCraft; using fCraft.Drawing; -namespace fCraft -{ - public class ManifoldDrawOperation : DrawOperation - { - private Scaler _scaler; - private Expression[] _expressions; - private double[][] _paramIterations; - private const double MaxIterationSteps = 1000000; - - public ManifoldDrawOperation(Player p, Command cmd) : base (p) - { - _expressions = PrepareParametrizedManifold.GetPlayerParametrizationCoordsStorage(p); - if (null == _expressions[0]) - throw new InvalidExpressionException("x is undefined"); - if (null == _expressions[1]) - throw new InvalidExpressionException("y is undefined"); - if (null == _expressions[2]) - throw new InvalidExpressionException("z is undefined"); - - _paramIterations = PrepareParametrizedManifold.GetPlayerParametrizationParamsStorage(p); - if (null==_paramIterations[0] && null==_paramIterations[1] && null==_paramIterations[2]) - throw new InvalidExpressionException("all parametrization variables are undefined"); - - if (GetNumOfSteps(0) * GetNumOfSteps(1) * GetNumOfSteps(2) > MaxIterationSteps) - throw new InvalidExpressionException("too many iteration steps (over " + MaxIterationSteps + ")"); - - _scaler=new Scaler(cmd.Next()); - - p.Message("Going to draw the following parametrization:\nx=" + _expressions[0].Print()+ - "\ny=" + _expressions[1].Print() + "\nz=" + _expressions[2].Print()); - } - - public override string Name - { - get { return "ParametrizedManifold"; } - } - - public override int DrawBatch(int maxBlocksToDraw) - { - int count = 0; - double fromT, toT, stepT; - double fromU, toU, stepU; - double fromV, toV, stepV; - - GetIterationBounds(0, out fromT, out toT, out stepT); - GetIterationBounds(1, out fromU, out toU, out stepU); - GetIterationBounds(2, out fromV, out toV, out stepV); - - for (double t=fromT; t<=toT; t+=stepT) - { - for (double u=fromU; u<=toU; u+=stepU) - { - for (double v = fromV; v <= toV; v += stepV) - { - Coords.X = _scaler.FromFuncResult(_expressions[0].Evaluate(t, u, v), Bounds.XMin, Bounds.XMax); - Coords.Y = _scaler.FromFuncResult(_expressions[1].Evaluate(t, u, v), Bounds.YMin, Bounds.YMax); - Coords.Z = _scaler.FromFuncResult(_expressions[2].Evaluate(t, u, v), Bounds.ZMin, Bounds.ZMax); - if (DrawOneBlock()) - ++count; - //if (TimeToEndBatch) - // return count; - } - } - } - IsDone = true; - return count; - } - - private double GetNumOfSteps(int idx) - { - if (null == _paramIterations[idx]) - return 1; - return (_paramIterations[idx][1] - _paramIterations[idx][0])/_paramIterations[idx][2] + 1; - } - private void GetIterationBounds(int idx, out double from, out double to, out double step) - { - if (null==_paramIterations[idx]) - { - from = 0; - to = 0; - step = 1; - return; - } - from = _paramIterations[idx][0]; - to = _paramIterations[idx][1]; - step = _paramIterations[idx][2]; - } - - public override bool Prepare(Vector3I[] marks) - { - if (!base.Prepare(marks)) - { - return false; - } - BlocksTotalEstimate = Bounds.Volume; - return true; - } - } -} +namespace fCraft { + + public class ManifoldDrawOperation : DrawOperation { + private Scaler _scaler; + private Expression[] _expressions; + private double[][] _paramIterations; + private const double MaxIterationSteps = 1000000; + + public ManifoldDrawOperation( Player p, Command cmd ) + : base( p ) { + _expressions = PrepareParametrizedManifold.GetPlayerParametrizationCoordsStorage( p ); + if ( null == _expressions[0] ) + throw new InvalidExpressionException( "x is undefined" ); + if ( null == _expressions[1] ) + throw new InvalidExpressionException( "y is undefined" ); + if ( null == _expressions[2] ) + throw new InvalidExpressionException( "z is undefined" ); + + _paramIterations = PrepareParametrizedManifold.GetPlayerParametrizationParamsStorage( p ); + if ( null == _paramIterations[0] && null == _paramIterations[1] && null == _paramIterations[2] ) + throw new InvalidExpressionException( "all parametrization variables are undefined" ); + + if ( GetNumOfSteps( 0 ) * GetNumOfSteps( 1 ) * GetNumOfSteps( 2 ) > MaxIterationSteps ) + throw new InvalidExpressionException( "too many iteration steps (over " + MaxIterationSteps + ")" ); + + _scaler = new Scaler( cmd.Next() ); + + p.Message( "Going to draw the following parametrization:\nx=" + _expressions[0].Print() + + "\ny=" + _expressions[1].Print() + "\nz=" + _expressions[2].Print() ); + } + + public override string Name { + get { return "ParametrizedManifold"; } + } + + public override int DrawBatch( int maxBlocksToDraw ) { + int count = 0; + double fromT, toT, stepT; + double fromU, toU, stepU; + double fromV, toV, stepV; + + GetIterationBounds( 0, out fromT, out toT, out stepT ); + GetIterationBounds( 1, out fromU, out toU, out stepU ); + GetIterationBounds( 2, out fromV, out toV, out stepV ); + + for ( double t = fromT; t <= toT; t += stepT ) { + for ( double u = fromU; u <= toU; u += stepU ) { + for ( double v = fromV; v <= toV; v += stepV ) { + Coords.X = _scaler.FromFuncResult( _expressions[0].Evaluate( t, u, v ), Bounds.XMin, Bounds.XMax ); + Coords.Y = _scaler.FromFuncResult( _expressions[1].Evaluate( t, u, v ), Bounds.YMin, Bounds.YMax ); + Coords.Z = _scaler.FromFuncResult( _expressions[2].Evaluate( t, u, v ), Bounds.ZMin, Bounds.ZMax ); + if ( DrawOneBlock() ) + ++count; + //if (TimeToEndBatch) + // return count; + } + } + } + IsDone = true; + return count; + } + + private double GetNumOfSteps( int idx ) { + if ( null == _paramIterations[idx] ) + return 1; + return ( _paramIterations[idx][1] - _paramIterations[idx][0] ) / _paramIterations[idx][2] + 1; + } + + private void GetIterationBounds( int idx, out double from, out double to, out double step ) { + if ( null == _paramIterations[idx] ) { + from = 0; + to = 0; + step = 1; + return; + } + from = _paramIterations[idx][0]; + to = _paramIterations[idx][1]; + step = _paramIterations[idx][2]; + } + + public override bool Prepare( Vector3I[] marks ) { + if ( !base.Prepare( marks ) ) { + return false; + } + BlocksTotalEstimate = Bounds.Volume; + return true; + } + } +} \ No newline at end of file diff --git a/fCraft/Commands/Command Handlers/Math Handlers/PrepareParametrizedManifold.cs b/fCraft/Commands/Command Handlers/Math Handlers/PrepareParametrizedManifold.cs index ee62d3c..0c530ba 100644 --- a/fCraft/Commands/Command Handlers/Math Handlers/PrepareParametrizedManifold.cs +++ b/fCraft/Commands/Command Handlers/Math Handlers/PrepareParametrizedManifold.cs @@ -28,151 +28,129 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) <2011 - 2013> Lao Tszy (lao_tszy@yahoo.co.uk) using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft; - -namespace fCraft -{ - public static class PrepareParametrizedManifold - { - public static void SetParametrization(Player p, Command cmd) - { - string strFunc = cmd.Next(); - if (string.IsNullOrWhiteSpace(strFunc)) - { - p.Message("Error: empty parametrization expression"); - return; - } - if (strFunc.Length < 3) - { - p.Message("Error: expression is too short (should be like x=f(t,u,v))"); - return; - } - - strFunc = strFunc.ToLower(); - - try - { - string coordVar = SimpleParser.PreparseAssignment(ref strFunc); - CheckCoordVar(coordVar); - - Expression expression = SimpleParser.Parse(strFunc, new string[] { "t", "u", "v" }); - - p.Message("Expression parsed as " + coordVar + "=" + expression.Print()); - - GetPlayerParametrizationCoordsStorage(p)[VarNameToIdx(coordVar[0])] = expression; - } - catch (Exception e) - { - p.Message("Error: "+e.Message); - } - } - - public static void SetParamIteration(Player p, Command cmd) - { - string strParam = cmd.Next(); - if (string.IsNullOrWhiteSpace(strParam)) - { - p.Message("Error: missing param variable name"); - return; - } - - strParam = strParam.ToLower(); - - try - { - CheckParamVar(strParam); - - double from = ReadDoubleParam(cmd, "lower bound"); - double to = ReadDoubleParam(cmd, "upper bound"); - double step = ReadDoubleParam(cmd, "step"); - - if (step == 0 || - (to - from)/step < 0) - throw new ArgumentException("wrong iteration bounds/step combination"); - - p.Message("Iteration for " + strParam + " from " + from + " to " + to + " with step " + step + ". " + - ((to - from)/step + 1) + " steps."); - - GetPlayerParametrizationParamsStorage(p)[VarNameToIdx(strParam[0])] = new double[] {from, to, step}; - } - catch (Exception e) - { - p.Message("Error: " + e.Message); - } - } - - public static void ClearParametrization(Player p, Command cmd) - { - p.PublicAuxStateObjects.Remove(CoordsStorageName); - p.PublicAuxStateObjects.Remove(ParamsStorageName); - p.Message("Prepared parametrization data cleared"); - } - - private static double ReadDoubleParam(Command cmd, string msgParamParamName) - { - string s = cmd.Next(); - if (string.IsNullOrWhiteSpace(s)) - throw new ArgumentException("missing param variable " + msgParamParamName); - double d; - if (!double.TryParse(s, out d)) - throw new ArgumentException("cannot parse param variable " + msgParamParamName); - return d; - } - - public static Expression[] GetPlayerParametrizationCoordsStorage(Player p) - { - Object o; - if (!p.PublicAuxStateObjects.TryGetValue(CoordsStorageName, out o)) - { - o = new Expression[3]; - p.PublicAuxStateObjects.Add(CoordsStorageName, o); - } - return (Expression[]) o; - } - - public static double[][] GetPlayerParametrizationParamsStorage(Player p) - { - Object o; - if (!p.PublicAuxStateObjects.TryGetValue(ParamsStorageName, out o)) - { - o = new double[3][]; - p.PublicAuxStateObjects.Add(ParamsStorageName, o); - } - return (double[][])o; - } - - private static string CoordsStorageName { get { return typeof (PrepareParametrizedManifold).Name + "Coords"; } } - private static string ParamsStorageName { get { return typeof(PrepareParametrizedManifold).Name + "Params"; } } - - private static void CheckCoordVar(string s) - { - if (string.IsNullOrWhiteSpace(s) || (s != "x" && s != "y" && s != "z")) - throw new ArgumentException("expected assignment of x, y, or z (e.g. x=2*t)"); - } - private static void CheckParamVar(string s) - { - if (string.IsNullOrWhiteSpace(s) || (s != "t" && s != "u" && s != "v")) - throw new ArgumentException("expected parametrization variable name is t, u, or v"); - } - public static int VarNameToIdx(char varName) - { - switch (varName) - { - case 'x': - case 't': - return 0; - case 'y': - case 'u': - return 1; - case 'z': - case 'v': - return 2; - default: - throw new ArgumentException("unknown variable "+varName); - } - } - } -} + +namespace fCraft { + + public static class PrepareParametrizedManifold { + + public static void SetParametrization( Player p, Command cmd ) { + string strFunc = cmd.Next(); + if ( string.IsNullOrWhiteSpace( strFunc ) ) { + p.Message( "Error: empty parametrization expression" ); + return; + } + if ( strFunc.Length < 3 ) { + p.Message( "Error: expression is too short (should be like x=f(t,u,v))" ); + return; + } + + strFunc = strFunc.ToLower(); + + try { + string coordVar = SimpleParser.PreparseAssignment( ref strFunc ); + CheckCoordVar( coordVar ); + + Expression expression = SimpleParser.Parse( strFunc, new string[] { "t", "u", "v" } ); + + p.Message( "Expression parsed as " + coordVar + "=" + expression.Print() ); + + GetPlayerParametrizationCoordsStorage( p )[VarNameToIdx( coordVar[0] )] = expression; + } catch ( Exception e ) { + p.Message( "Error: " + e.Message ); + } + } + + public static void SetParamIteration( Player p, Command cmd ) { + string strParam = cmd.Next(); + if ( string.IsNullOrWhiteSpace( strParam ) ) { + p.Message( "Error: missing param variable name" ); + return; + } + + strParam = strParam.ToLower(); + + try { + CheckParamVar( strParam ); + + double from = ReadDoubleParam( cmd, "lower bound" ); + double to = ReadDoubleParam( cmd, "upper bound" ); + double step = ReadDoubleParam( cmd, "step" ); + + if ( step == 0 || + ( to - from ) / step < 0 ) + throw new ArgumentException( "wrong iteration bounds/step combination" ); + + p.Message( "Iteration for " + strParam + " from " + from + " to " + to + " with step " + step + ". " + + ( ( to - from ) / step + 1 ) + " steps." ); + + GetPlayerParametrizationParamsStorage( p )[VarNameToIdx( strParam[0] )] = new double[] { from, to, step }; + } catch ( Exception e ) { + p.Message( "Error: " + e.Message ); + } + } + + public static void ClearParametrization( Player p, Command cmd ) { + p.PublicAuxStateObjects.Remove( CoordsStorageName ); + p.PublicAuxStateObjects.Remove( ParamsStorageName ); + p.Message( "Prepared parametrization data cleared" ); + } + + private static double ReadDoubleParam( Command cmd, string msgParamParamName ) { + string s = cmd.Next(); + if ( string.IsNullOrWhiteSpace( s ) ) + throw new ArgumentException( "missing param variable " + msgParamParamName ); + double d; + if ( !double.TryParse( s, out d ) ) + throw new ArgumentException( "cannot parse param variable " + msgParamParamName ); + return d; + } + + public static Expression[] GetPlayerParametrizationCoordsStorage( Player p ) { + Object o; + if ( !p.PublicAuxStateObjects.TryGetValue( CoordsStorageName, out o ) ) { + o = new Expression[3]; + p.PublicAuxStateObjects.Add( CoordsStorageName, o ); + } + return ( Expression[] )o; + } + + public static double[][] GetPlayerParametrizationParamsStorage( Player p ) { + Object o; + if ( !p.PublicAuxStateObjects.TryGetValue( ParamsStorageName, out o ) ) { + o = new double[3][]; + p.PublicAuxStateObjects.Add( ParamsStorageName, o ); + } + return ( double[][] )o; + } + + private static string CoordsStorageName { get { return typeof( PrepareParametrizedManifold ).Name + "Coords"; } } + + private static string ParamsStorageName { get { return typeof( PrepareParametrizedManifold ).Name + "Params"; } } + + private static void CheckCoordVar( string s ) { + if ( string.IsNullOrWhiteSpace( s ) || ( s != "x" && s != "y" && s != "z" ) ) + throw new ArgumentException( "expected assignment of x, y, or z (e.g. x=2*t)" ); + } + + private static void CheckParamVar( string s ) { + if ( string.IsNullOrWhiteSpace( s ) || ( s != "t" && s != "u" && s != "v" ) ) + throw new ArgumentException( "expected parametrization variable name is t, u, or v" ); + } + + public static int VarNameToIdx( char varName ) { + switch ( varName ) { + case 'x': + case 't': + return 0; + case 'y': + case 'u': + return 1; + case 'z': + case 'v': + return 2; + default: + throw new ArgumentException( "unknown variable " + varName ); + } + } + } +} \ No newline at end of file diff --git a/fCraft/Commands/Command Handlers/Math Handlers/Scaler.cs b/fCraft/Commands/Command Handlers/Math Handlers/Scaler.cs index d8cda21..bc7dc3d 100644 --- a/fCraft/Commands/Command Handlers/Math Handlers/Scaler.cs +++ b/fCraft/Commands/Command Handlers/Math Handlers/Scaler.cs @@ -28,68 +28,58 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) <2011 - 2013> Lao Tszy (lao_tszy@yahoo.co.uk) using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft; -using fCraft.Drawing; -namespace fCraft -{ - //scales coords according to the defined possibilities - public class Scaler - { - //scalings: - //ZeroToMaxBound means that every dimension of the selected area is measured from 0 to its size in cubes minus 1 - //Normalized means that every dimension is measured from 0 to 1 - private enum Scaling - { - ZeroToMaxBound, - Normalized, - DoubleNormalized, - } - private Scaling _scaling; - - public Scaler(string scaling) - { - if (string.IsNullOrWhiteSpace(scaling)) - _scaling = Scaling.ZeroToMaxBound; - else if (scaling.ToLower() == "u") - _scaling = Scaling.Normalized; - else if (scaling.ToLower() == "uu") - _scaling = Scaling.DoubleNormalized; - else - throw new ArgumentException("unrecognized scaling "+scaling); - } +namespace fCraft { - public double ToFuncParam(double coord, double min, double max) - { - switch (_scaling) - { - case Scaling.ZeroToMaxBound: - return coord - min; - case Scaling.Normalized: - return (coord - min) / Math.Max(1, max - min); - case Scaling.DoubleNormalized: - return max == min ? 0 : 2.0*(coord - min)/Math.Max(1, max - min) - 1; - default: - throw new Exception("unknown scaling"); - } - } + //scales coords according to the defined possibilities + public class Scaler { - public int FromFuncResult(double result, double min, double max) - { - switch (_scaling) - { - case Scaling.ZeroToMaxBound: - return (int)(result + min); - case Scaling.Normalized: - return (int)(result * Math.Max(1, max - min) + min); - case Scaling.DoubleNormalized: - return (int) ((result + 1)*Math.Max(1, max - min)/2.0 + min); - default: - throw new Exception("unknown scaling"); - } - } - } -} + //scalings: + //ZeroToMaxBound means that every dimension of the selected area is measured from 0 to its size in cubes minus 1 + //Normalized means that every dimension is measured from 0 to 1 + private enum Scaling { + ZeroToMaxBound, + Normalized, + DoubleNormalized, + } + + private Scaling _scaling; + + public Scaler( string scaling ) { + if ( string.IsNullOrWhiteSpace( scaling ) ) + _scaling = Scaling.ZeroToMaxBound; + else if ( scaling.ToLower() == "u" ) + _scaling = Scaling.Normalized; + else if ( scaling.ToLower() == "uu" ) + _scaling = Scaling.DoubleNormalized; + else + throw new ArgumentException( "unrecognized scaling " + scaling ); + } + + public double ToFuncParam( double coord, double min, double max ) { + switch ( _scaling ) { + case Scaling.ZeroToMaxBound: + return coord - min; + case Scaling.Normalized: + return ( coord - min ) / Math.Max( 1, max - min ); + case Scaling.DoubleNormalized: + return max == min ? 0 : 2.0 * ( coord - min ) / Math.Max( 1, max - min ) - 1; + default: + throw new Exception( "unknown scaling" ); + } + } + + public int FromFuncResult( double result, double min, double max ) { + switch ( _scaling ) { + case Scaling.ZeroToMaxBound: + return ( int )( result + min ); + case Scaling.Normalized: + return ( int )( result * Math.Max( 1, max - min ) + min ); + case Scaling.DoubleNormalized: + return ( int )( ( result + 1 ) * Math.Max( 1, max - min ) / 2.0 + min ); + default: + throw new Exception( "unknown scaling" ); + } + } + } +} \ No newline at end of file diff --git a/fCraft/Commands/Command Handlers/Math Handlers/SimpleParser.cs b/fCraft/Commands/Command Handlers/Math Handlers/SimpleParser.cs index 70a9e2d..63c8f80 100644 --- a/fCraft/Commands/Command Handlers/Math Handlers/SimpleParser.cs +++ b/fCraft/Commands/Command Handlers/Math Handlers/SimpleParser.cs @@ -29,37 +29,35 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY using System; using System.Collections.Generic; -using System.Linq; using System.Text; -namespace fCraft -{ - //Shunting yard (Dijkstra) parser - public static class SimpleParser - { - private enum SpecialOperandKind - { - NotSpecial=0, - LeftParenthesis, - RightParenthesis, - Comma - } - private struct FuncData - { - public IExpressionElement Func; - public bool IsFunctionOrUnary; - public int Precedence; - public SpecialOperandKind SpecialKind; - } - static private Dictionary _functions; - static private Dictionary _operators; //binary ops - static private Dictionary _soperators; //special ops - static private Dictionary _uoperators; //unary ops - static private Dictionary _consts; - - static SimpleParser() - { - _functions=new Dictionary +namespace fCraft { + + //Shunting yard (Dijkstra) parser + public static class SimpleParser { + + private enum SpecialOperandKind { + NotSpecial = 0, + LeftParenthesis, + RightParenthesis, + Comma + } + + private struct FuncData { + public IExpressionElement Func; + public bool IsFunctionOrUnary; + public int Precedence; + public SpecialOperandKind SpecialKind; + } + + static private Dictionary _functions; + static private Dictionary _operators; //binary ops + static private Dictionary _soperators; //special ops + static private Dictionary _uoperators; //unary ops + static private Dictionary _consts; + + static SimpleParser() { + _functions = new Dictionary { {"sqrt", new FuncData() {Func = new Sqrt(), IsFunctionOrUnary = true}}, {"abs", new FuncData() {Func = new Abs(), IsFunctionOrUnary = true}}, @@ -77,16 +75,16 @@ static SimpleParser() {"tanh", new FuncData() {Func = new Tanh(), IsFunctionOrUnary = true}} }; - //special operators - _soperators=new Dictionary + //special operators + _soperators = new Dictionary { {'(', new FuncData() {SpecialKind = SpecialOperandKind.LeftParenthesis}}, {')', new FuncData() {SpecialKind = SpecialOperandKind.RightParenthesis}}, {',', new FuncData() {SpecialKind = SpecialOperandKind.Comma}} }; - //'normal' ops - _operators = new Dictionary + //'normal' ops + _operators = new Dictionary { {'+', new FuncData() {Func = new Sum(), Precedence = 2}}, {'*', new FuncData() {Func = new Mul(), Precedence = 3}}, @@ -101,212 +99,195 @@ static SimpleParser() {'&', new FuncData() {Func = new And(), Precedence = 0}}, {'|', new FuncData() {Func = new And(), Precedence = 0}}, }; -//etc + //etc - //unary ops - //negate, since it must be distinct from binary minus - _uoperators = new Dictionary + //unary ops + //negate, since it must be distinct from binary minus + _uoperators = new Dictionary { {'-', new FuncData() {Func = new Negate(), IsFunctionOrUnary = true}}, {'!', new FuncData() {Func = new Not(), IsFunctionOrUnary = true}} }; - //constants: e, pi - _consts=new Dictionary {{"e", new E()}, {"pi", new Pi()}}; - } + //constants: e, pi + _consts = new Dictionary { { "e", new E() }, { "pi", new Pi() } }; + } - public static Expression Parse(string expression, IEnumerable vars) - { - expression.ToLower(); - int pos = 0; - Stack tmpStack=new Stack(); - Expression e=new Expression(vars); - bool noBOperatorExpected = true; - bool lParenthExpected = false; + public static Expression Parse( string expression, IEnumerable vars ) { + expression.ToLower(); + int pos = 0; + Stack tmpStack = new Stack(); + Expression e = new Expression( vars ); + bool noBOperatorExpected = true; + bool lParenthExpected = false; - while (pos push to stack - FuncData fd; - if (_functions.TryGetValue(term, out fd)) + e.Append( el ); + noBOperatorExpected = false; + continue; + } + Variable v; + if ( e.Vars.TryGetValue( term, out v ) ) //variable { - tmpStack.Push(fd); - lParenthExpected = true; //dont need to set/reset noBOperatorExpected - continue; - } - if (term.Length == 1) //operators + e.Append( v ); + noBOperatorExpected = false; + continue; + } + + //if function -> push to stack + FuncData fd; + if ( _functions.TryGetValue( term, out fd ) ) { + tmpStack.Push( fd ); + lParenthExpected = true; //dont need to set/reset noBOperatorExpected + continue; + } + if ( term.Length == 1 ) //operators { - char termch = term[0]; - if (_soperators.TryGetValue(termch, out fd)) - { - switch (fd.SpecialKind) - { - case SpecialOperandKind.LeftParenthesis: - tmpStack.Push(fd); - noBOperatorExpected = true; - break; - case SpecialOperandKind.RightParenthesis: - noBOperatorExpected = false; - ProcessRightParenth(e, tmpStack, pos); - break; - case SpecialOperandKind.Comma: - noBOperatorExpected = true; - ProcessComma(e, tmpStack, pos); - break; - } - continue; - } - if (noBOperatorExpected) - { - if (_uoperators.TryGetValue(termch, out fd)) - { - tmpStack.Push(fd); - //noBOperatorExpected = true; - is already - continue; - } - } - else - { - if(_operators.TryGetValue(termch, out fd)) - { - ProcessOperator(fd, e, tmpStack); - noBOperatorExpected = true; - continue; - } - } - } - - //unrecongnizable - throw new ArgumentException("unrecognizable term " + term + " at before " + pos); - } - - //we will be tolerant to closing parenthesis, i.e. the left parenthesis left will be ignored - foreach (var f in tmpStack) - if (f.SpecialKind!=SpecialOperandKind.LeftParenthesis) - e.Append(f.Func); - else - throw new ArgumentException("unmatching parenthesis"); - - return e; - } - - public static Expression ParseAsEquality(string expression, IEnumerable vars) - { - Expression e = Parse(expression, vars); - e.MakeEquality(); - return e; - } - - //the input must be in the form of a=... - public static string PreparseAssignment(ref string assignmentFunction) - { - int pos = 0; - string varName=ReadTerm(assignmentFunction, ref pos); - string ass = ReadTerm(assignmentFunction, ref pos); - if (ass.Length>1 || ass[0]!='=') - throw new ArgumentException("the expression is not an assignment (i.e. not like z=...)"); - assignmentFunction = assignmentFunction.Substring(pos); - return varName; - } - - private static void ProcessComma(Expression e, Stack tmpStack, int pos) - { - if (tmpStack.Count==0) - throw new ArgumentException("comma without left parenthesis at " + pos); - while (tmpStack.Peek().SpecialKind!=SpecialOperandKind.LeftParenthesis) - { - e.Append(tmpStack.Pop().Func); - if (tmpStack.Count == 0) - throw new ArgumentException("comma without left parenthesis at " + pos); - } - } - - private static void ProcessRightParenth(Expression e, Stack tmpStack, int pos) - { - if (tmpStack.Count == 0) - throw new ArgumentException("unmatching right parenthesis at " + pos); - while (tmpStack.Peek().SpecialKind != SpecialOperandKind.LeftParenthesis) - { - e.Append(tmpStack.Pop().Func); - if (tmpStack.Count == 0) - throw new ArgumentException("unmatching right parenthesis at " + pos); - } - tmpStack.Pop(); //remove left parenthesis - while (tmpStack.Count > 0 && tmpStack.Peek().IsFunctionOrUnary) //append function/unary minus or both - e.Append(tmpStack.Pop().Func); - } - - private static void ProcessOperator(FuncData op, Expression e, Stack tmpStack) - { - while (tmpStack.Count>0) //while operators with higher or equal precedence - { - FuncData fd = tmpStack.Peek(); - if (fd.SpecialKind == SpecialOperandKind.NotSpecial && !fd.IsFunctionOrUnary && fd.Precedence >= op.Precedence) - e.Append(tmpStack.Pop().Func); - else - break; - } - tmpStack.Push(op); - } - - private static string ReadTerm(string s, ref int pos) - { - ReadSpaces(s, ref pos); - - char ch = s[pos]; - if (_operators.ContainsKey(ch) || _soperators.ContainsKey(ch) || _uoperators.ContainsKey(ch) || /*tmp*/ch=='=') - { - string ret=new string(s[pos], 1); - ++pos; - ReadSpaces(s, ref pos); - return ret; - } - StringBuilder term = new StringBuilder(); - while (pos vars ) { + Expression e = Parse( expression, vars ); + e.MakeEquality(); + return e; + } + + //the input must be in the form of a=... + public static string PreparseAssignment( ref string assignmentFunction ) { + int pos = 0; + string varName = ReadTerm( assignmentFunction, ref pos ); + string ass = ReadTerm( assignmentFunction, ref pos ); + if ( ass.Length > 1 || ass[0] != '=' ) + throw new ArgumentException( "the expression is not an assignment (i.e. not like z=...)" ); + assignmentFunction = assignmentFunction.Substring( pos ); + return varName; + } + + private static void ProcessComma( Expression e, Stack tmpStack, int pos ) { + if ( tmpStack.Count == 0 ) + throw new ArgumentException( "comma without left parenthesis at " + pos ); + while ( tmpStack.Peek().SpecialKind != SpecialOperandKind.LeftParenthesis ) { + e.Append( tmpStack.Pop().Func ); + if ( tmpStack.Count == 0 ) + throw new ArgumentException( "comma without left parenthesis at " + pos ); + } + } + + private static void ProcessRightParenth( Expression e, Stack tmpStack, int pos ) { + if ( tmpStack.Count == 0 ) + throw new ArgumentException( "unmatching right parenthesis at " + pos ); + while ( tmpStack.Peek().SpecialKind != SpecialOperandKind.LeftParenthesis ) { + e.Append( tmpStack.Pop().Func ); + if ( tmpStack.Count == 0 ) + throw new ArgumentException( "unmatching right parenthesis at " + pos ); + } + tmpStack.Pop(); //remove left parenthesis + while ( tmpStack.Count > 0 && tmpStack.Peek().IsFunctionOrUnary ) //append function/unary minus or both + e.Append( tmpStack.Pop().Func ); + } + + private static void ProcessOperator( FuncData op, Expression e, Stack tmpStack ) { + while ( tmpStack.Count > 0 ) //while operators with higher or equal precedence { - if (Char.IsLetterOrDigit(s[pos]) || s[pos]=='.') //no support for exp number form! - term.Append(s[pos]); - else - break; - ++pos; - } - - ReadSpaces(s, ref pos); - - return term.ToString(); - } - private static void ReadSpaces(string s, ref int pos) - { - while (pos < s.Length && (s[pos] == ' ' || s[pos] == '\t')) ++pos; - } - } + FuncData fd = tmpStack.Peek(); + if ( fd.SpecialKind == SpecialOperandKind.NotSpecial && !fd.IsFunctionOrUnary && fd.Precedence >= op.Precedence ) + e.Append( tmpStack.Pop().Func ); + else + break; + } + tmpStack.Push( op ); + } + + private static string ReadTerm( string s, ref int pos ) { + ReadSpaces( s, ref pos ); + + char ch = s[pos]; + if ( _operators.ContainsKey( ch ) || _soperators.ContainsKey( ch ) || _uoperators.ContainsKey( ch ) || /*tmp*/ch == '=' ) { + string ret = new string( s[pos], 1 ); + ++pos; + ReadSpaces( s, ref pos ); + return ret; + } + StringBuilder term = new StringBuilder(); + while ( pos < s.Length ) { + if ( Char.IsLetterOrDigit( s[pos] ) || s[pos] == '.' ) //no support for exp number form! + term.Append( s[pos] ); + else + break; + ++pos; + } + + ReadSpaces( s, ref pos ); + + return term.ToString(); + } + + private static void ReadSpaces( string s, ref int pos ) { + while ( pos < s.Length && ( s[pos] == ' ' || s[pos] == '\t' ) ) + ++pos; + } + } } \ No newline at end of file diff --git a/fCraft/Commands/Command Handlers/RealmHandler.cs b/fCraft/Commands/Command Handlers/RealmHandler.cs index 882a593..4c6c507 100644 --- a/fCraft/Commands/Command Handlers/RealmHandler.cs +++ b/fCraft/Commands/Command Handlers/RealmHandler.cs @@ -26,20 +26,15 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ----*/ using System; -using System.Collections.Generic; using System.IO; using System.Linq; using fCraft.MapConversion; -using JetBrains.Annotations; -using fCraft.Drawing; -using System.Collections; -using System.Text; -using System.Threading; namespace fCraft { - class RealmHandler { - public static void RealmLoad ( Player player, Command cmd, string fileName, string worldName, string buildRankName, string accessRankName ) { + internal class RealmHandler { + + public static void RealmLoad( Player player, Command cmd, string fileName, string worldName, string buildRankName, string accessRankName ) { if ( worldName == null && player.World == null ) { player.Message( "When using /realm from console, you must specify the realm name." ); return; @@ -52,7 +47,8 @@ public static void RealmLoad ( Player player, Command cmd, string fileName, stri } string fullFileName = WorldManager.FindMapFile( player, fileName ); - if ( fullFileName == null ) return; + if ( fullFileName == null ) + return; // Loading map into current realm if ( worldName == null ) { @@ -186,7 +182,6 @@ public static void RealmLoad ( Player player, Command cmd, string fileName, stri World newWorld; try { newWorld = WorldManager.AddWorld( player, worldName, map, false ); - } catch ( WorldOpException ex ) { player.Message( "RealmLoad: {0}", ex.Message ); return; @@ -216,7 +211,6 @@ public static void RealmLoad ( Player player, Command cmd, string fileName, stri player.MessageNow( "Access permission is {0}+&S, and build permission is {1}+", newWorld.AccessSecurity.MinRank.ClassyName, newWorld.BuildSecurity.MinRank.ClassyName ); - } } } @@ -224,8 +218,7 @@ public static void RealmLoad ( Player player, Command cmd, string fileName, stri Server.RequestGC(); } - - public static void RealmCreate ( Player player, Command cmd, string themeName, string templateName ) { + public static void RealmCreate( Player player, Command cmd, string themeName, string templateName ) { MapGenTemplate template; MapGenTheme theme; @@ -256,7 +249,7 @@ public static void RealmCreate ( Player player, Command cmd, string themeName, s return; } - string fileName = player.Name.Replace(".", "-"); + string fileName = player.Name.Replace( ".", "-" ); string fullFileName = null; if ( fileName == null ) { @@ -319,7 +312,6 @@ public static void RealmCreate ( Player player, Command cmd, string themeName, s } if ( !Enum.IsDefined( typeof( MapGenTheme ), theme ) || !Enum.IsDefined( typeof( MapGenTemplate ), template ) ) { - return; } @@ -345,7 +337,6 @@ public static void RealmCreate ( Player player, Command cmd, string themeName, s MapGenerator generator = new MapGenerator( args ); map = generator.Generate(); } - } catch ( Exception ex ) { Logger.Log( LogType.Error, "MapGenerator: Generation failed: {0}", ex ); @@ -365,10 +356,7 @@ public static void RealmCreate ( Player player, Command cmd, string themeName, s } } - - - - internal static void RealmAccess ( Player player, Command cmd, string worldName, string name ) { + internal static void RealmAccess( Player player, Command cmd, string worldName, string name ) { // Print information about the current realm if ( worldName == null ) { if ( player.World == null ) { @@ -381,7 +369,8 @@ internal static void RealmAccess ( Player player, Command cmd, string worldName, // Find a realm by name World realm = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( realm == null ) return; + if ( realm == null ) + return; if ( name == null ) { player.Message( realm.AccessSecurity.GetDescription( realm, "realm", "accessed" ) ); @@ -394,14 +383,14 @@ internal static void RealmAccess ( Player player, Command cmd, string worldName, bool changesWereMade = false; do { - if ( name.Length < 2 ) continue; + if ( name.Length < 2 ) + continue; // Whitelisting individuals if ( name.StartsWith( "+" ) ) { PlayerInfo info; if ( !PlayerDB.FindPlayerInfo( name.Substring( 1 ), out info ) ) { player.Message( "More than one player found matching \"{0}\"", name.Substring( 1 ) ); continue; - } else if ( info == null ) { player.MessageNoPlayer( name.Substring( 1 ) ); continue; @@ -409,7 +398,6 @@ internal static void RealmAccess ( Player player, Command cmd, string worldName, // prevent players from whitelisting themselves to bypass protection - if ( realm.AccessSecurity.CheckDetailed( info ) == SecurityCheckResult.Allowed ) { player.Message( "{0}&S is already allowed to access {1}&S (by rank)", info.ClassyName, realm.ClassyName ); @@ -417,7 +405,8 @@ internal static void RealmAccess ( Player player, Command cmd, string worldName, } Player target = info.PlayerObject; - if ( target == player ) target = null; // to avoid duplicate messages + if ( target == player ) + target = null; // to avoid duplicate messages switch ( realm.AccessSecurity.Include( info ) ) { case PermissionOverride.Deny: @@ -480,7 +469,8 @@ internal static void RealmAccess ( Player player, Command cmd, string worldName, } Player target = info.PlayerObject; - if ( target == player ) target = null; // to avoid duplicate messages + if ( target == player ) + target = null; // to avoid duplicate messages switch ( realm.AccessSecurity.Exclude( info ) ) { case PermissionOverride.Deny: @@ -529,7 +519,6 @@ internal static void RealmAccess ( Player player, Command cmd, string worldName, Rank rank = RankManager.FindRank( name ); if ( rank == null ) { player.MessageNoRank( name ); - } else { // list players who are redundantly blacklisted var exceptionList = realm.AccessSecurity.ExceptionList; @@ -576,10 +565,7 @@ internal static void RealmAccess ( Player player, Command cmd, string worldName, } } - - internal static void RealmBuild ( Player player, Command cmd, string worldName, string name, string NameIfRankIsName ) { - - + internal static void RealmBuild( Player player, Command cmd, string worldName, string name, string NameIfRankIsName ) { // Print information about the current realm if ( worldName == null ) { if ( player.World == null ) { @@ -592,8 +578,8 @@ internal static void RealmBuild ( Player player, Command cmd, string worldName, // Find a realm by name World realm = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( realm == null ) return; - + if ( realm == null ) + return; if ( name == null ) { player.Message( realm.BuildSecurity.GetDescription( realm, "realm", "modified" ) ); @@ -602,7 +588,8 @@ internal static void RealmBuild ( Player player, Command cmd, string worldName, bool changesWereMade = false; do { - if ( name.Length < 2 ) continue; + if ( name.Length < 2 ) + continue; // Whitelisting individuals if ( name.StartsWith( "+" ) ) { PlayerInfo info; @@ -614,8 +601,6 @@ internal static void RealmBuild ( Player player, Command cmd, string worldName, continue; } - - if ( realm.BuildSecurity.CheckDetailed( info ) == SecurityCheckResult.Allowed ) { player.Message( "{0}&S is already allowed to build in {1}&S (by rank)", info.ClassyName, realm.ClassyName ); @@ -623,7 +608,8 @@ internal static void RealmBuild ( Player player, Command cmd, string worldName, } Player target = info.PlayerObject; - if ( target == player ) target = null; // to avoid duplicate messages + if ( target == player ) + target = null; // to avoid duplicate messages switch ( realm.BuildSecurity.Include( info ) ) { case PermissionOverride.Deny: @@ -685,7 +671,8 @@ internal static void RealmBuild ( Player player, Command cmd, string worldName, } Player target = info.PlayerObject; - if ( target == player ) target = null; // to avoid duplicate messages + if ( target == player ) + target = null; // to avoid duplicate messages switch ( realm.BuildSecurity.Exclude( info ) ) { case PermissionOverride.Deny: diff --git a/fCraft/Commands/Command Handlers/VoteHandler.cs b/fCraft/Commands/Command Handlers/VoteHandler.cs index ec8a44d..2e9bc04 100644 --- a/fCraft/Commands/Command Handlers/VoteHandler.cs +++ b/fCraft/Commands/Command Handlers/VoteHandler.cs @@ -24,13 +24,13 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; namespace fCraft { + public class VoteHandler { public static string Usage; public static int VotedYes; @@ -43,7 +43,7 @@ public class VoteHandler { public static string TargetName; public static string Question; - public static void NewVote () { + public static void NewVote() { Usage = "&A/Vote Yes | No | Ask | Kick | Abort"; VotedYes = 0; VotedNo = 0; @@ -51,7 +51,7 @@ public static void NewVote () { VoteIsOn = true; } - public static void VoteParams ( Player player, Command cmd ) { + public static void VoteParams( Player player, Command cmd ) { string option = cmd.Next(); if ( option == null ) { player.Message( "Invalid param" ); return; } switch ( option ) { @@ -148,21 +148,22 @@ public static void VoteParams ( Player player, Command cmd ) { } VoteThread = new Thread( new ThreadStart( delegate { - TargetName = target.Name; - if ( !Player.IsValidName( TargetName ) ) { - player.Message( "Invalid name" ); - return; - } - NewVote(); - VoteStarter = player.ClassyName; - Server.Players.Message( "{0}&S started a VoteKick for player: {1}", player.ClassyName, target.ClassyName ); - Server.Players.Message( "&WReason: {0}", VoteKickReason ); - Server.Players.Message( "&9Vote now! &S/Vote &AYes &Sor /Vote &CNo" ); - VoteIsOn = true; - Logger.Log( LogType.SystemActivity, "{0} started a votekick on player {1} reason: {2}", player.Name, target.Name, VoteKickReason ); - Thread.Sleep( 60000 ); - VoteKickCheck(); - } ) ); VoteThread.Start(); + TargetName = target.Name; + if ( !Player.IsValidName( TargetName ) ) { + player.Message( "Invalid name" ); + return; + } + NewVote(); + VoteStarter = player.ClassyName; + Server.Players.Message( "{0}&S started a VoteKick for player: {1}", player.ClassyName, target.ClassyName ); + Server.Players.Message( "&WReason: {0}", VoteKickReason ); + Server.Players.Message( "&9Vote now! &S/Vote &AYes &Sor /Vote &CNo" ); + VoteIsOn = true; + Logger.Log( LogType.SystemActivity, "{0} started a votekick on player {1} reason: {2}", player.Name, target.Name, VoteKickReason ); + Thread.Sleep( 60000 ); + VoteKickCheck(); + } ) ); + VoteThread.Start(); break; case "no": @@ -197,19 +198,20 @@ public static void VoteParams ( Player player, Command cmd ) { } VoteThread = new Thread( new ThreadStart( delegate { - NewVote(); - VoteStarter = player.ClassyName; - Server.Players.Message( "{0}&S Asked: {1}", player.ClassyName, Question ); - Server.Players.Message( "&9Vote now! &S/Vote &AYes &Sor /Vote &CNo" ); - VoteIsOn = true; - Thread.Sleep( 60000 ); - VoteCheck(); - } ) ); VoteThread.Start(); + NewVote(); + VoteStarter = player.ClassyName; + Server.Players.Message( "{0}&S Asked: {1}", player.ClassyName, Question ); + Server.Players.Message( "&9Vote now! &S/Vote &AYes &Sor /Vote &CNo" ); + VoteIsOn = true; + Thread.Sleep( 60000 ); + VoteCheck(); + } ) ); + VoteThread.Start(); break; } } - static void VoteCheck () { + private static void VoteCheck() { if ( VoteIsOn ) { Server.Players.Message( "{0}&S Asked: {1} \n&SResults are in! Yes: &A{2} &SNo: &C{3}", VoteStarter, Question, VotedYes, VotedNo ); @@ -220,7 +222,7 @@ static void VoteCheck () { } } - static void VoteKickCheck () { + private static void VoteKickCheck() { if ( VoteIsOn ) { Server.Players.Message( "{0}&S wanted to get {1} kicked. Reason: {2} \n&SResults are in! Yes: &A{3} &SNo: &C{4}", VoteStarter, TargetName, VoteKickReason, VotedYes, VotedNo ); @@ -258,4 +260,4 @@ static void VoteKickCheck () { } } } -} +} \ No newline at end of file diff --git a/fCraft/Commands/Command.cs b/fCraft/Commands/Command.cs index 81fa96f..198f07b 100644 --- a/fCraft/Commands/Command.cs +++ b/fCraft/Commands/Command.cs @@ -4,18 +4,25 @@ using JetBrains.Annotations; namespace fCraft { + /// A text scanner that aids parsing chat commands and their arguments. /// Breaks up a message into tokens at spaces. Treats quoted strings as whole tokens. public sealed class Command : ICloneable { + public CommandDescriptor Descriptor { get; private set; } + public int Offset { get; set; } + public readonly string RawMessage; + public string Name { get; private set; } // lowercase name of the command + public bool IsConfirmed; // whether this command has been confirmed by the user (with /ok) /// Creates a copy of an existing command. - public Command ( [NotNull] Command other ) { - if ( other == null ) throw new ArgumentNullException( "other" ); + public Command( [NotNull] Command other ) { + if ( other == null ) + throw new ArgumentNullException( "other" ); Offset = other.Offset; Descriptor = other.Descriptor; RawMessage = other.RawMessage; @@ -24,8 +31,9 @@ public Command ( [NotNull] Command other ) { } /// Creates a command from a raw message. - public Command ( [NotNull] string rawMessage ) { - if ( rawMessage == null ) throw new ArgumentNullException( "rawMessage" ); + public Command( [NotNull] string rawMessage ) { + if ( rawMessage == null ) + throw new ArgumentNullException( "rawMessage" ); Offset = 1; RawMessage = rawMessage; string name = Next(); @@ -36,21 +44,19 @@ public Command ( [NotNull] string rawMessage ) { Name = name.ToLower(); } - /// Creates a copy of this command. /// Use the copy constructor instead of this, if possible. - public object Clone () { + public object Clone() { return new Command( this ); } - /// Returns the next command argument. /// A single "argument" is either a word that ends with whitespace, /// or several words in double quotes (""). /// Next argument (string), or null if there are no more arguments. [DebuggerStepThrough] [CanBeNull] - public string Next () { + public string Next() { for ( ; Offset < RawMessage.Length; Offset++ ) { int t, j; if ( RawMessage[Offset] == '"' ) { @@ -70,7 +76,6 @@ public string Next () { return null; } - /// Checks whether there is another argument available. /// Does not modify the offset. public bool HasNext { @@ -80,14 +85,13 @@ public bool HasNext { } } - /// Returns the next command argument, parsed as an integer. /// Set to the argument's value if parsing succeeded, /// or zero if parsing failed or if there are no more arguments. /// Returns true if parsing succeeded, /// and false if parsing failed or if there are no more arguments. [DebuggerStepThrough] - public bool NextInt ( out int number ) { + public bool NextInt( out int number ) { string nextVal = Next(); if ( nextVal == null ) { number = 0; @@ -97,7 +101,6 @@ public bool NextInt ( out int number ) { } } - /// Checks whether there there is an int argument available. /// Does not modify the offset. public bool HasInt { @@ -121,13 +124,12 @@ public bool HasInt { } } - /// Returns the rest of command's text, from current offset to the end of string. /// If there is nothing to return (i.e. if string ends at the current offset), /// returns empty string. /// The rest of the command, or an empty string. [DebuggerStepThrough] - public string NextAll () { + public string NextAll() { for ( ; Offset < RawMessage.Length; Offset++ ) { if ( RawMessage[Offset] != ' ' ) return RawMessage.Substring( Offset ); @@ -135,7 +137,6 @@ public string NextAll () { return ""; } - /// Counts the number of arguments left in this command. /// Does not modify the offset. public int CountRemaining { @@ -143,7 +144,8 @@ public int CountRemaining { if ( HasNext ) { int startOffset = Offset; int i = 1; - while ( Next() != null ) i++; + while ( Next() != null ) + i++; Offset = startOffset; return i; } else { @@ -152,7 +154,6 @@ public int CountRemaining { } } - /// Counts the total number of arguments. /// Does not modify the offset. public int Count { @@ -160,24 +161,24 @@ public int Count { int startOffset = Offset; Rewind(); int i = 1; - while ( Next() != null ) i++; + while ( Next() != null ) + i++; Offset = startOffset; return i; } } - /// Resets the argument offset. /// After calling Rewind, arguments can be read from the beginning again. - public void Rewind () { + public void Rewind() { Offset = 1; Next(); } - [DebuggerStepThrough] - public Block NextBlock ( [NotNull] Player player ) { - if ( player == null ) throw new ArgumentNullException( "player" ); + public Block NextBlock( [NotNull] Player player ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); string blockName = Next(); Block targetBlock = Block.Undefined; if ( blockName != null ) { @@ -189,9 +190,9 @@ public Block NextBlock ( [NotNull] Player player ) { return targetBlock; } - - public Block NextBlockWithParam ( [NotNull] Player player, ref int param ) { - if ( player == null ) throw new ArgumentNullException( "player" ); + public Block NextBlockWithParam( [NotNull] Player player, ref int param ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); string jointString = Next(); if ( jointString == null ) { return Block.Undefined; @@ -214,7 +215,6 @@ public Block NextBlockWithParam ( [NotNull] Player player, ref int param ) { } else { player.Message( "Could not parse \"{0}\" as an integer.", paramString ); } - } else { targetBlock = Map.GetBlockByName( jointString ); if ( targetBlock == Block.Undefined ) { @@ -224,8 +224,7 @@ public Block NextBlockWithParam ( [NotNull] Player player, ref int param ) { return targetBlock; } - - public override string ToString () { + public override string ToString() { if ( IsConfirmed ) { return String.Format( "Command(\"{0}\",{1},confirmed)", RawMessage, Offset ); } else { @@ -233,4 +232,4 @@ public override string ToString () { } } } -} +} \ No newline at end of file diff --git a/fCraft/Commands/CommandCategory.cs b/fCraft/Commands/CommandCategory.cs index 4c1a313..6643edd 100644 --- a/fCraft/Commands/CommandCategory.cs +++ b/fCraft/Commands/CommandCategory.cs @@ -2,10 +2,12 @@ using System; namespace fCraft { + /// Command categories. A command may belong to more than one category. /// Use binary flag logic (value & flag == flag) to test whether a command belongs to a particular category. [Flags] public enum CommandCategory { + /// Default command category. Do not use it. None = 0, @@ -39,4 +41,4 @@ public enum CommandCategory { /// Commands that use advanced mathematics. Math = 512 } -} +} \ No newline at end of file diff --git a/fCraft/Commands/CommandDescriptor.cs b/fCraft/Commands/CommandDescriptor.cs index ba5de27..9495164 100644 --- a/fCraft/Commands/CommandDescriptor.cs +++ b/fCraft/Commands/CommandDescriptor.cs @@ -9,8 +9,7 @@ namespace fCraft { /// Delegate for command handlers/callbacks. /// Player who called the command. /// Command arguments. - public delegate void CommandHandler ( Player source, Command cmd ); - + public delegate void CommandHandler( Player source, Command cmd ); /// Describes a chat command. Defines properties, permission requirements, and usage information. /// Specifies a handler method. @@ -66,16 +65,15 @@ public sealed class CommandDescriptor : IClassy { /// Whether this command involves a selection that can be repeated with /static. Default: false public bool RepeatableSelection { get; set; } - /// Checks whether this command may be called by players of a given rank. - public bool CanBeCalledBy ( [NotNull] Rank rank ) { - if ( rank == null ) throw new ArgumentNullException( "rank" ); + public bool CanBeCalledBy( [NotNull] Rank rank ) { + if ( rank == null ) + throw new ArgumentNullException( "rank" ); return Permissions == null || Permissions.All( rank.Can ) || AnyPermission && Permissions.Any( rank.Can ); } - public Rank MinRank { get { if ( AnyPermission ) { @@ -86,18 +84,18 @@ public Rank MinRank { } } - /// Checks whether players of the given rank should see this command in /cmds list. /// Takes permissions and the hidden flag into account. - public bool IsVisibleTo ( [NotNull] Rank rank ) { - if ( rank == null ) throw new ArgumentNullException( "rank" ); + public bool IsVisibleTo( [NotNull] Rank rank ) { + if ( rank == null ) + throw new ArgumentNullException( "rank" ); return !IsHidden && CanBeCalledBy( rank ); } - /// Prints command usage syntax to the given player. - public void PrintUsage ( [NotNull] Player player ) { - if ( player == null ) throw new ArgumentNullException( "player" ); + public void PrintUsage( [NotNull] Player player ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); if ( Usage != null ) { player.Message( "Usage: &H{0}", Usage ); } else { @@ -105,9 +103,9 @@ public void PrintUsage ( [NotNull] Player player ) { } } - /// Prints a command HelpSection syntax to the given player. + /// Prints a command HelpSection syntax to the given player. /// If that fails, it will print the usage instead - public void PrintHelpSection ( Player player, string sectionName ) { + public void PrintHelpSection( Player player, string sectionName ) { string sectionHelp; if ( HelpSections != null && HelpSections.TryGetValue( sectionName.ToLower(), out sectionHelp ) ) { player.MessagePrefixed( "&S ", sectionHelp ); @@ -116,24 +114,26 @@ public void PrintHelpSection ( Player player, string sectionName ) { } } - /// Calls this command. /// Player who called the command. /// Command arguments. /// Whether CommandCalling and CommandCalled events should be raised. /// True if the command was called succesfully. /// False if the call was cancelled by the CommandCalling event. - public bool Call ( [NotNull] Player player, [NotNull] Command cmd, bool raiseEvent ) { - if ( player == null ) throw new ArgumentNullException( "player" ); - if ( cmd == null ) throw new ArgumentNullException( "cmd" ); - if ( raiseEvent && CommandManager.RaiseCommandCallingEvent( cmd, this, player ) ) return false; + public bool Call( [NotNull] Player player, [NotNull] Command cmd, bool raiseEvent ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); + if ( raiseEvent && CommandManager.RaiseCommandCallingEvent( cmd, this, player ) ) + return false; Handler( player, cmd ); - if ( raiseEvent ) CommandManager.RaiseCommandCalledEvent( cmd, this, player ); + if ( raiseEvent ) + CommandManager.RaiseCommandCalledEvent( cmd, this, player ); return true; } - - public override string ToString () { + public override string ToString() { return String.Format( "CommandDescriptor({0})", Name ); } diff --git a/fCraft/Commands/CommandManager.cs b/fCraft/Commands/CommandManager.cs index b928b45..a0702e7 100644 --- a/fCraft/Commands/CommandManager.cs +++ b/fCraft/Commands/CommandManager.cs @@ -6,15 +6,16 @@ using JetBrains.Annotations; namespace fCraft { + /// Static class that allows registration and parsing of all text commands. public static class CommandManager { - static readonly SortedList Aliases = new SortedList(); - static readonly SortedList Commands = new SortedList(); + private static readonly SortedList Aliases = new SortedList(); + private static readonly SortedList Commands = new SortedList(); public static readonly string[] ReservedCommandNames = new[] { "ok", "nvm", "dev" }; // Sets up all the command hooks - public static void Init () { + public static void Init() { DevCommands.Init(); ModerationCommands.Init(); BuildingCommands.Init(); @@ -32,52 +33,49 @@ public static void Init () { Aliases.Count ); } - /// Gets a list of all commands (includding hidden ones). - public static CommandDescriptor[] GetCommands () { + public static CommandDescriptor[] GetCommands() { return Commands.Values.ToArray(); } - /// Gets a list of ONLY hidden or non-hidden commands, not both. - public static CommandDescriptor[] GetCommands ( bool hidden ) { + public static CommandDescriptor[] GetCommands( bool hidden ) { return Commands.Values .Where( cmd => ( cmd.IsHidden == hidden ) ) .ToArray(); } - /// Gets a list of commands available to a specified rank. - public static CommandDescriptor[] GetCommands ( [NotNull] Rank rank, bool includeHidden ) { - if ( rank == null ) throw new ArgumentNullException( "rank" ); + public static CommandDescriptor[] GetCommands( [NotNull] Rank rank, bool includeHidden ) { + if ( rank == null ) + throw new ArgumentNullException( "rank" ); return Commands.Values .Where( cmd => ( !cmd.IsHidden || includeHidden ) && cmd.CanBeCalledBy( rank ) ) .ToArray(); } - /// Gets a list of commands in a specified category. /// Note that commands may belong to more than one category. - public static CommandDescriptor[] GetCommands ( CommandCategory category, bool includeHidden ) { + public static CommandDescriptor[] GetCommands( CommandCategory category, bool includeHidden ) { return Commands.Values .Where( cmd => ( includeHidden || !cmd.IsHidden ) && ( cmd.Category & category ) == category ) .ToArray(); } - /// Registers a custom command with fCraft. /// CommandRegistrationException may be thrown if the given descriptor does not meet all the requirements. - public static void RegisterCustomCommand ( [NotNull] CommandDescriptor descriptor ) { - if ( descriptor == null ) throw new ArgumentNullException( "descriptor" ); + public static void RegisterCustomCommand( [NotNull] CommandDescriptor descriptor ) { + if ( descriptor == null ) + throw new ArgumentNullException( "descriptor" ); descriptor.IsCustom = true; RegisterCommand( descriptor ); } - - internal static void RegisterCommand ( [NotNull] CommandDescriptor descriptor ) { - if ( descriptor == null ) throw new ArgumentNullException( "descriptor" ); + internal static void RegisterCommand( [NotNull] CommandDescriptor descriptor ) { + if ( descriptor == null ) + throw new ArgumentNullException( "descriptor" ); #if DEBUG if( descriptor.Category == CommandCategory.None && !descriptor.IsCustom ) { @@ -117,7 +115,8 @@ internal static void RegisterCommand ( [NotNull] CommandDescriptor descriptor ) descriptor.Usage = "/" + descriptor.Name; } - if ( RaiseCommandRegisteringEvent( descriptor ) ) return; + if ( RaiseCommandRegisteringEvent( descriptor ) ) + return; if ( Aliases.ContainsKey( normalizedName ) ) { Logger.Log( LogType.Warning, @@ -150,15 +149,15 @@ internal static void RegisterCommand ( [NotNull] CommandDescriptor descriptor ) RaiseCommandRegisteredEvent( descriptor ); } - /// Finds an instance of CommandDescriptor for a given command. /// Case-insensitive, but no autocompletion. /// Command to find. /// Whether to check command aliases. /// CommandDesriptor object if found, null if not found. [CanBeNull] - public static CommandDescriptor GetDescriptor ( [NotNull] string commandName, bool alsoCheckAliases ) { - if ( commandName == null ) throw new ArgumentNullException( "commandName" ); + public static CommandDescriptor GetDescriptor( [NotNull] string commandName, bool alsoCheckAliases ) { + if ( commandName == null ) + throw new ArgumentNullException( "commandName" ); commandName = commandName.ToLower(); if ( Commands.ContainsKey( commandName ) ) { return Commands[commandName]; @@ -169,15 +168,16 @@ public static CommandDescriptor GetDescriptor ( [NotNull] string commandName, bo } } - /// Parses and calls a specified command. /// Player who issued the command. /// Command to be parsed and executed. /// Whether this command is being called from a non-player (e.g. Console). /// True if the command was called, false if something prevented it from being called. - public static bool ParseCommand ( [NotNull] Player player, [NotNull] Command cmd, bool fromConsole ) { - if ( player == null ) throw new ArgumentNullException( "player" ); - if ( cmd == null ) throw new ArgumentNullException( "cmd" ); + public static bool ParseCommand( [NotNull] Player player, [NotNull] Command cmd, bool fromConsole ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); CommandDescriptor descriptor = GetDescriptor( cmd.Name, true ); if ( descriptor == null ) { @@ -207,14 +207,15 @@ public static bool ParseCommand ( [NotNull] Player player, [NotNull] Command cmd return false; } - /// Checks whether a command name is acceptible. /// Constraints are similar to Player.IsValidName, except for minimum length. /// Command name to check. /// True if the name is valid. - public static bool IsValidCommandName ( [NotNull] string name ) { - if ( name == null ) throw new ArgumentNullException( "name" ); - if ( name.Length == 0 || name.Length > 16 ) return false; + public static bool IsValidCommandName( [NotNull] string name ) { + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( name.Length == 0 || name.Length > 16 ) + return false; // ReSharper disable LoopCanBeConvertedToQuery for ( int i = 0; i < name.Length; i++ ) { char ch = name[i]; @@ -227,7 +228,6 @@ public static bool IsValidCommandName ( [NotNull] string name ) { return true; } - #region Events /// Occurs when a command is being registered (cancellable). @@ -242,82 +242,89 @@ public static bool IsValidCommandName ( [NotNull] string name ) { /// Occurs when the command has been called by a player or the console. public static event EventHandler CommandCalled; - - static bool RaiseCommandRegisteringEvent ( CommandDescriptor descriptor ) { + private static bool RaiseCommandRegisteringEvent( CommandDescriptor descriptor ) { var h = CommandRegistering; - if ( h == null ) return false; + if ( h == null ) + return false; var e = new CommandRegistringEventArgs( descriptor ); h( null, e ); return e.Cancel; } - - static void RaiseCommandRegisteredEvent ( CommandDescriptor descriptor ) { + private static void RaiseCommandRegisteredEvent( CommandDescriptor descriptor ) { var h = CommandRegistered; - if ( h != null ) h( null, new CommandRegisteredEventArgs( descriptor ) ); + if ( h != null ) + h( null, new CommandRegisteredEventArgs( descriptor ) ); } - - internal static bool RaiseCommandCallingEvent ( Command cmd, CommandDescriptor descriptor, Player player ) { + internal static bool RaiseCommandCallingEvent( Command cmd, CommandDescriptor descriptor, Player player ) { var h = CommandCalling; - if ( h == null ) return false; + if ( h == null ) + return false; var e = new CommandCallingEventArgs( cmd, descriptor, player ); h( null, e ); return e.Cancel; } - - internal static void RaiseCommandCalledEvent ( Command cmd, CommandDescriptor descriptor, Player player ) { + internal static void RaiseCommandCalledEvent( Command cmd, CommandDescriptor descriptor, Player player ) { var h = CommandCalled; - if ( h != null ) CommandCalled( null, new CommandCalledEventArgs( cmd, descriptor, player ) ); + if ( h != null ) + CommandCalled( null, new CommandCalledEventArgs( cmd, descriptor, player ) ); } - #endregion + #endregion Events } public sealed class CommandRegistrationException : Exception { - public CommandRegistrationException ( string message ) : base( message ) { } + + public CommandRegistrationException( string message ) + : base( message ) { + } + [StringFormatMethod( "message" )] - public CommandRegistrationException ( string message, params object[] args ) : + public CommandRegistrationException( string message, params object[] args ) : base( String.Format( message, args ) ) { } } } - namespace fCraft.Events { + public class CommandRegisteredEventArgs : EventArgs { - internal CommandRegisteredEventArgs ( CommandDescriptor commandDescriptor ) { + + internal CommandRegisteredEventArgs( CommandDescriptor commandDescriptor ) { CommandDescriptor = commandDescriptor; } public CommandDescriptor CommandDescriptor { get; private set; } } - public sealed class CommandRegistringEventArgs : CommandRegisteredEventArgs, ICancellableEvent { - internal CommandRegistringEventArgs ( CommandDescriptor commandDescriptor ) + + internal CommandRegistringEventArgs( CommandDescriptor commandDescriptor ) : base( commandDescriptor ) { } public bool Cancel { get; set; } } - public class CommandCalledEventArgs : EventArgs { - internal CommandCalledEventArgs ( Command command, CommandDescriptor commandDescriptor, Player player ) { + + internal CommandCalledEventArgs( Command command, CommandDescriptor commandDescriptor, Player player ) { Command = command; CommandDescriptor = commandDescriptor; Player = player; } public Command Command { get; private set; } + public CommandDescriptor CommandDescriptor { get; private set; } + public Player Player { get; private set; } } - public sealed class CommandCallingEventArgs : CommandCalledEventArgs, ICancellableEvent { - internal CommandCallingEventArgs ( Command command, CommandDescriptor commandDescriptor, Player player ) : + + internal CommandCallingEventArgs( Command command, CommandDescriptor commandDescriptor, Player player ) : base( command, commandDescriptor, player ) { } diff --git a/fCraft/Commands/DevCommands.cs b/fCraft/Commands/DevCommands.cs index 84c3532..9523d5b 100644 --- a/fCraft/Commands/DevCommands.cs +++ b/fCraft/Commands/DevCommands.cs @@ -1,14 +1,9 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; -using System.Drawing; + /*using LibNbt; using LibNbt.Exceptions; using LibNbt.Queries; using LibNbt.Tags;*/ -using System.IO.Compression; /* ---- Copyright (c) 2011-2013 Jon Baker, Glenn Marien and Lao Tszy All rights reserved. @@ -35,13 +30,15 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + namespace fCraft { - static class DevCommands { - public static void Init () { + internal static class DevCommands { + + public static void Init() { /* * NOTE: These commands are unfinished, under development and non-supported. - * If you are using a dev build of 800Craft, please comment these the below out to ensure + * If you are using a dev build of 800Craft, please comment these the below out to ensure * stability. * */ @@ -51,7 +48,7 @@ public static void Init () { //CommandManager.RegisterCommand(CdGame); } - static readonly CommandDescriptor CdGame = new CommandDescriptor { + private static readonly CommandDescriptor CdGame = new CommandDescriptor { Name = "Game", Category = CommandCategory.World, Permissions = new Permission[] { Permission.Games }, @@ -59,12 +56,13 @@ public static void Init () { Usage = "/Unfinished command.", Handler = GameHandler }; - private static void GameHandler ( Player player, Command cmd ) { + + private static void GameHandler( Player player, Command cmd ) { string GameMode = cmd.Next(); string Option = cmd.Next(); World world = player.World; /*if (world == WorldManager.MainWorld){ - player.Message("/Game cannot be used on the main world"); + player.Message("/Game cannot be used on the main world"); return; }*/ @@ -126,7 +124,7 @@ internal static void BotHandler ( Player player, Command cmd ) { } }*/ - static readonly CommandDescriptor CdSpell = new CommandDescriptor { + private static readonly CommandDescriptor CdSpell = new CommandDescriptor { Name = "Spell", Category = CommandCategory.Fun, Permissions = new[] { Permission.Chat }, @@ -137,8 +135,10 @@ internal static void BotHandler ( Player player, Command cmd ) { UsableByFrozenPlayers = false, Handler = SpellHandler, }; + public static SpellStartBehavior particleBehavior = new SpellStartBehavior(); - internal static void SpellHandler ( Player player, Command cmd ) { + + internal static void SpellHandler( Player player, Command cmd ) { World world = player.World; Vector3I pos1 = player.Position.ToBlockCoords(); Random _r = new Random(); @@ -152,4 +152,4 @@ internal static void SpellHandler ( Player player, Command cmd ) { } } } -} +} \ No newline at end of file diff --git a/fCraft/Commands/FunCommands.cs b/fCraft/Commands/FunCommands.cs index 6e82ee6..e28c973 100644 --- a/fCraft/Commands/FunCommands.cs +++ b/fCraft/Commands/FunCommands.cs @@ -26,15 +26,13 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ----*/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using RandomMaze; -using System.Threading; namespace fCraft { + internal static class FunCommands { - internal static void Init () { + + internal static void Init() { CommandManager.RegisterCommand( CdRandomMaze ); CommandManager.RegisterCommand( CdMazeCuboid ); CommandManager.RegisterCommand( CdFirework ); @@ -45,7 +43,7 @@ internal static void Init () { #region Possess / UnPossess - static readonly CommandDescriptor CdPossess = new CommandDescriptor { + private static readonly CommandDescriptor CdPossess = new CommandDescriptor { Name = "Possess", Category = CommandCategory.Fun, Permissions = new[] { Permission.Possess }, @@ -53,14 +51,15 @@ internal static void Init () { Handler = PossessHandler }; - static void PossessHandler ( Player player, Command cmd ) { + private static void PossessHandler( Player player, Command cmd ) { string targetName = cmd.Next(); if ( targetName == null ) { CdPossess.PrintUsage( player ); return; } Player target = Server.FindPlayerOrPrintMatches( player, targetName, false, true ); - if ( target == null ) return; + if ( target == null ) + return; if ( target.Immortal ) { player.Message( "You cannot possess {0}&S, they are immortal", target.ClassyName ); return; @@ -83,8 +82,7 @@ static void PossessHandler ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdUnpossess = new CommandDescriptor { + private static readonly CommandDescriptor CdUnpossess = new CommandDescriptor { Name = "unpossess", Category = CommandCategory.Fun, Permissions = new[] { Permission.Possess }, @@ -93,23 +91,24 @@ static void PossessHandler ( Player player, Command cmd ) { Handler = UnpossessHandler }; - static void UnpossessHandler ( Player player, Command cmd ) { + private static void UnpossessHandler( Player player, Command cmd ) { string targetName = cmd.Next(); if ( targetName == null ) { CdUnpossess.PrintUsage( player ); return; } Player target = Server.FindPlayerOrPrintMatches( player, targetName, true, true ); - if ( target == null ) return; + if ( target == null ) + return; if ( !player.StopPossessing( target ) ) { player.Message( "You are not currently possessing anyone." ); } } - #endregion + #endregion Possess / UnPossess - static readonly CommandDescriptor CdLife = new CommandDescriptor { + private static readonly CommandDescriptor CdLife = new CommandDescriptor { Name = "Life", Category = CommandCategory.Fun, Permissions = new[] { Permission.DrawAdvanced }, @@ -121,7 +120,7 @@ static void UnpossessHandler ( Player player, Command cmd ) { Handler = LifeHandlerFunc, }; - static readonly CommandDescriptor CdFirework = new CommandDescriptor { + private static readonly CommandDescriptor CdFirework = new CommandDescriptor { Name = "Firework", Category = CommandCategory.Fun, Permissions = new[] { Permission.Fireworks }, @@ -135,7 +134,7 @@ static void UnpossessHandler ( Player player, Command cmd ) { Handler = FireworkHandler }; - static void FireworkHandler ( Player player, Command cmd ) { + private static void FireworkHandler( Player player, Command cmd ) { if ( player.fireworkMode ) { player.fireworkMode = false; player.Message( "Firework Mode has been turned off." ); @@ -147,8 +146,7 @@ static void FireworkHandler ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdRandomMaze = new CommandDescriptor { + private static readonly CommandDescriptor CdRandomMaze = new CommandDescriptor { Name = "RandomMaze", Aliases = new string[] { "3dmaze" }, Category = CommandCategory.Fun, @@ -160,7 +158,8 @@ static void FireworkHandler ( Player player, Command cmd ) { Usage = "/randommaze [nolifts] [hints]", Handler = MazeHandler }; - static readonly CommandDescriptor CdMazeCuboid = new CommandDescriptor { + + private static readonly CommandDescriptor CdMazeCuboid = new CommandDescriptor { Name = "MazeCuboid", Aliases = new string[] { "Mc", "Mz", "Maze" }, Category = CommandCategory.Fun, @@ -172,7 +171,7 @@ static void FireworkHandler ( Player player, Command cmd ) { Handler = MazeCuboidHandler, }; - private static void MazeHandler ( Player p, Command cmd ) { + private static void MazeHandler( Player p, Command cmd ) { try { RandomMazeDrawOperation op = new RandomMazeDrawOperation( p, cmd ); BuildingCommands.DrawOperationBegin( p, cmd, op ); @@ -180,7 +179,8 @@ private static void MazeHandler ( Player p, Command cmd ) { Logger.Log( LogType.Error, "Error: " + e.Message ); } } - private static void MazeCuboidHandler ( Player p, Command cmd ) { + + private static void MazeCuboidHandler( Player p, Command cmd ) { try { MazeCuboidDrawOperation op = new MazeCuboidDrawOperation( p ); BuildingCommands.DrawOperationBegin( p, cmd, op ); @@ -188,7 +188,8 @@ private static void MazeCuboidHandler ( Player p, Command cmd ) { Logger.Log( LogType.Error, "Error: " + e.Message ); } } - private static void LifeHandlerFunc ( Player p, Command cmd ) { + + private static void LifeHandlerFunc( Player p, Command cmd ) { try { if ( !cmd.HasNext ) { p.Message( "&H/Life . Commands are Help, Create, Delete, Start, Stop, Set, List, Print" ); @@ -200,7 +201,5 @@ private static void LifeHandlerFunc ( Player p, Command cmd ) { p.Message( "Error: " + e.Message ); } } - - } -} +} \ No newline at end of file diff --git a/fCraft/Commands/InfoCommands.cs b/fCraft/Commands/InfoCommands.cs index 6caa206..1e376fe 100644 --- a/fCraft/Commands/InfoCommands.cs +++ b/fCraft/Commands/InfoCommands.cs @@ -10,12 +10,13 @@ using JetBrains.Annotations; namespace fCraft { + /// Contains commands that don't do anything besides displaying some information or text. /// Includes several chat commands. - static class InfoCommands { - const int PlayersPerPage = 30; + internal static class InfoCommands { + private const int PlayersPerPage = 30; - internal static void Init () { + internal static void Init() { CommandManager.RegisterCommand( CdInfo ); CommandManager.RegisterCommand( CdBanInfo ); CommandManager.RegisterCommand( CdRankInfo ); @@ -44,9 +45,10 @@ internal static void Init () { CommandManager.RegisterCommand( cdTaskDebug ); #endif } + #region 800Craft - /* ---- + /* ---- Copyright (c) 2011-2013 Jon Baker, Glenn Marien and Lao Tszy All rights reserved. @@ -73,7 +75,7 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ - static readonly CommandDescriptor CdWhoIs = new CommandDescriptor { + private static readonly CommandDescriptor CdWhoIs = new CommandDescriptor { Name = "WhoIs", Category = CommandCategory.Info, Permissions = new Permission[] { Permission.ViewOthersInfo }, @@ -81,7 +83,8 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY Usage = "/Whois DisplayedName", Handler = WhoIsHandler }; - private static void WhoIsHandler ( Player player, Command cmd ) { + + private static void WhoIsHandler( Player player, Command cmd ) { string Name = cmd.Next(); if ( string.IsNullOrEmpty( Name ) ) { CdWhoIs.PrintUsage( player ); @@ -104,7 +107,8 @@ private static void WhoIsHandler ( Player player, Command cmd ) { MessageManyMatches( player, Names ); } else { int offset; - if ( !cmd.NextInt( out offset ) ) offset = 0; + if ( !cmd.NextInt( out offset ) ) + offset = 0; if ( offset >= Names.Length ) offset = Math.Max( 0, Names.Length - 15 ); PlayerInfo[] Part = Names.Skip( offset ).Take( 15 ).ToArray(); @@ -120,15 +124,16 @@ private static void WhoIsHandler ( Player player, Command cmd ) { } } - static void MessageManyMatches ( Player player, PlayerInfo[] names ) { - if ( names == null ) throw new ArgumentNullException( "names" ); + private static void MessageManyMatches( Player player, PlayerInfo[] names ) { + if ( names == null ) + throw new ArgumentNullException( "names" ); string nameList = names.JoinToString( ", ", p => p.Rank.Color + p.Name + "&S(" + p.ClassyName + "&S)" ); player.Message( "More than one player matched with that DisplayedName: {0}", nameList ); } - static readonly CommandDescriptor CdList = new CommandDescriptor { + private static readonly CommandDescriptor CdList = new CommandDescriptor { Name = "List", Category = CommandCategory.Info, IsConsoleSafe = true, @@ -139,7 +144,7 @@ static void MessageManyMatches ( Player player, PlayerInfo[] names ) { Handler = ListHandler }; - internal static void ListHandler ( Player player, Command cmd ) { + internal static void ListHandler( Player player, Command cmd ) { string Option = cmd.Next(); if ( Option == null ) { CdList.PrintUsage( player ); @@ -151,6 +156,7 @@ internal static void ListHandler ( Player player, Command cmd ) { CdList.PrintUsage( player ); player.Message( " Sections include: Staff, DisplayedNames, Idles, Portals, Rank, Top10, Emotes" ); break; + case "emotes": string Usage = "Shows a list of all available emotes and their keywords. " + "There are 31 emotes, spanning 3 pages. Use &h/List emotes 2&s and &h/List emotes 3&s to see pages 2 and 3."; @@ -185,6 +191,7 @@ internal static void ListHandler ( Player player, Command cmd ) { player.Message( "Type /List Emotes {0} for the next page", page + 1 ); break; + case "top10": List WorldNames = new List( WorldManager.Worlds.Where( w => w.VisitCount > 0 ) .OrderBy( c => c.VisitCount ) @@ -198,6 +205,7 @@ internal static void ListHandler ( Player player, Command cmd ) { player.Message( "&WShowing worlds with the most visits: " + list ); WorldNames.Clear(); break; + case "idles": case "idle": var Idles = Server.Players.Where( p => p.IdleTime.TotalMinutes > 5 ).ToArray(); @@ -205,8 +213,10 @@ internal static void ListHandler ( Player player, Command cmd ) { if ( visiblePlayers.Count() > 0 ) player.Message( "Listing players idle for 5 mins or more: {0}", visiblePlayers.JoinToString( r => String.Format( "{0}&S (Idle {1}", r.ClassyName, r.IdleTime.ToMiniString() ) ) ); - else player.Message( "No players have been idle for more than 5 minutes" ); + else + player.Message( "No players have been idle for more than 5 minutes" ); break; + case "portals": if ( player.World == null ) { player.Message( "/List portals cannot be used from Console" ); @@ -226,6 +236,7 @@ internal static void ListHandler ( Player player, Command cmd ) { player.Message( output.ToString() ); } break; + case "staff": var StaffNames = PlayerDB.PlayerInfoList .Where( r => r.Rank.Can( Permission.ReadStaffChat ) && @@ -241,7 +252,8 @@ internal static void ListHandler ( Player player, Command cmd ) { player.MessageManyMatches( "staff", StaffNames ); } else { int offset; - if ( !cmd.NextInt( out offset ) ) offset = 0; + if ( !cmd.NextInt( out offset ) ) + offset = 0; if ( offset >= StaffNames.Length ) offset = Math.Max( 0, StaffNames.Length - PlayersPerPage ); PlayerInfo[] StaffPart = StaffNames.Skip( offset ).Take( PlayersPerPage ).ToArray(); @@ -274,7 +286,8 @@ internal static void ListHandler ( Player player, Command cmd ) { player.MessageManyMatches( "players", RankNames ); } else { int offset; - if ( !cmd.NextInt( out offset ) ) offset = 0; + if ( !cmd.NextInt( out offset ) ) + offset = 0; if ( offset >= RankNames.Length ) offset = Math.Max( 0, RankNames.Length - PlayersPerPage ); PlayerInfo[] RankPart = RankNames.Skip( offset ).Take( PlayersPerPage ).ToArray(); @@ -288,6 +301,7 @@ internal static void ListHandler ( Player player, Command cmd ) { offset + 1, offset + RankPart.Length, RankNames.Length ); } break; + case "displayednames": case "displayedname": case "dn": @@ -301,7 +315,8 @@ internal static void ListHandler ( Player player, Command cmd ) { player.MessageManyDisplayedNamesMatches( "DisplayedNames", DisplayedNames ); } else { int offset; - if ( !cmd.NextInt( out offset ) ) offset = 0; + if ( !cmd.NextInt( out offset ) ) + offset = 0; if ( offset >= DisplayedNames.Count() ) offset = Math.Max( 0, DisplayedNames.Length - 15 ); PlayerInfo[] DnPart = DisplayedNames.Skip( offset ).Take( 15 ).ToArray(); @@ -318,7 +333,7 @@ internal static void ListHandler ( Player player, Command cmd ) { } } - static readonly CommandDescriptor CdReqs = new CommandDescriptor { + private static readonly CommandDescriptor CdReqs = new CommandDescriptor { Name = "Requirements", Aliases = new[] { "reqs" }, Category = CommandCategory.Info, @@ -328,7 +343,7 @@ internal static void ListHandler ( Player player, Command cmd ) { Handler = ReqsHandler }; - internal static void ReqsHandler ( Player player, Command cmd ) { + internal static void ReqsHandler( Player player, Command cmd ) { string sectionName = cmd.Next(); if ( sectionName == null ) { @@ -352,7 +367,8 @@ internal static void ReqsHandler ( Player player, Command cmd ) { for ( int i = 0; i < sectionFiles.Length; i++ ) { string sectionFullName = Path.GetFileNameWithoutExtension( sectionFiles[i] ); - if ( sectionFullName == null ) continue; + if ( sectionFullName == null ) + continue; if ( sectionFullName.StartsWith( sectionName, StringComparison.OrdinalIgnoreCase ) ) { if ( sectionFullName.Equals( sectionName, StringComparison.OrdinalIgnoreCase ) ) { reqFileName = sectionFiles[i]; @@ -385,7 +401,7 @@ internal static void ReqsHandler ( Player player, Command cmd ) { } [CanBeNull] - static string[] GetReqSectionList () { + private static string[] GetReqSectionList() { if ( Directory.Exists( Paths.ReqPath ) ) { string[] sections = Directory.GetFiles( Paths.ReqPath, "*.txt", SearchOption.TopDirectoryOnly ) .Select( name => Path.GetFileNameWithoutExtension( name ) ) @@ -398,28 +414,29 @@ static string[] GetReqSectionList () { return null; } - static void PrintReqFile ( Player player, FileSystemInfo reqFile ) { + private static void PrintReqFile( Player player, FileSystemInfo reqFile ) { try { foreach ( string reqLine in File.ReadAllLines( reqFile.FullName ) ) { if ( reqLine.Trim().Length > 0 ) { player.Message( "&R{0}", Server.ReplaceTextKeywords( player, reqLine ) ); - } - } player.Message( "Your current time on the server is {0}" + " Hours", player.Info.TotalTime.TotalHours ); + } + player.Message( "Your current time on the server is {0}" + " Hours", player.Info.TotalTime.TotalHours ); } catch ( Exception ex ) { Logger.Log( LogType.Error, "InfoCommands.PrintReqFile: An error occured while trying to read {0}: {1}", reqFile.FullName, ex ); player.Message( "&WError reading the requirement file." ); } } - #endregion + + #endregion 800Craft #region Info - const int MaxAltsToPrint = 15; - static readonly Regex RegexNonNameChars = new Regex( @"[^a-zA-Z0-9_\*\?]", RegexOptions.Compiled ); + private const int MaxAltsToPrint = 15; + private static readonly Regex RegexNonNameChars = new Regex( @"[^a-zA-Z0-9_\*\?]", RegexOptions.Compiled ); - static readonly CommandDescriptor CdInfo = new CommandDescriptor { + private static readonly CommandDescriptor CdInfo = new CommandDescriptor { Name = "Info", Aliases = new[] { "whowas" }, Category = CommandCategory.Info, @@ -432,19 +449,17 @@ static void PrintReqFile ( Player player, FileSystemInfo reqFile ) { Handler = InfoHandler }; - internal static void InfoHandler ( Player player, Command cmd ) { + internal static void InfoHandler( Player player, Command cmd ) { string name = cmd.Next(); if ( name == null ) { // no name given, print own info PrintPlayerInfo( player, player.Info ); return; - } else if ( name.Equals( player.Name, StringComparison.OrdinalIgnoreCase ) ) { // own name given player.LastUsedPlayerName = player.Name; PrintPlayerInfo( player, player.Info ); return; - } else if ( !player.Can( Permission.ViewOthersInfo ) ) { // someone else's name or IP given, permission required. player.MessageNoAccess( Permission.ViewOthersInfo ); @@ -477,17 +492,14 @@ internal static void InfoHandler ( Player player, Command cmd ) { player.Message( "Info: Invalid IP range format. Use CIDR notation." ); return; } - } else if ( Server.IsIP( name ) && IPAddress.TryParse( name, out ip ) ) { // find players by IP infos = PlayerDB.FindPlayers( ip ); - } else if ( name.Contains( "*" ) || name.Contains( "?" ) ) { // find players by regex/wildcard string regexString = "^" + RegexNonNameChars.Replace( name, "" ).Replace( "*", ".*" ).Replace( "?", "." ) + "$"; Regex regex = new Regex( regexString, RegexOptions.IgnoreCase | RegexOptions.Compiled ); infos = PlayerDB.FindPlayers( regex ); - } else { // find players by partial matching PlayerInfo tempInfo; @@ -507,17 +519,16 @@ internal static void InfoHandler ( Player player, Command cmd ) { // only one match found; print it right away player.LastUsedPlayerName = infos[0].Name; PrintPlayerInfo( player, infos[0] ); - } else if ( infos.Length > 1 ) { // multiple matches found if ( infos.Length <= PlayersPerPage ) { // all fit to one page player.MessageManyMatches( "player", infos ); - } else { // pagination int offset; - if ( !cmd.NextInt( out offset ) ) offset = 0; + if ( !cmd.NextInt( out offset ) ) + offset = 0; if ( offset >= infos.Length ) { offset = Math.Max( 0, infos.Length - PlayersPerPage ); } @@ -534,16 +545,17 @@ internal static void InfoHandler ( Player player, Command cmd ) { offset + 1, offset + infosPart.Length, infos.Length ); } } - } else { // no matches found player.MessageNoPlayer( name ); } } - public static void PrintPlayerInfo ( [NotNull] Player player, [NotNull] PlayerInfo info ) { - if ( player == null ) throw new ArgumentNullException( "player" ); - if ( info == null ) throw new ArgumentNullException( "info" ); + public static void PrintPlayerInfo( [NotNull] Player player, [NotNull] PlayerInfo info ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( info == null ) + throw new ArgumentNullException( "info" ); Player target = info.PlayerObject; // hide online status when hidden @@ -553,7 +565,6 @@ public static void PrintPlayerInfo ( [NotNull] Player player, [NotNull] PlayerIn if ( info.LastIP.Equals( IPAddress.None ) ) { player.Message( "About {0}&S: Never seen before.", info.ClassyName ); - } else { if ( target != null ) { TimeSpan idle = target.IdleTime; @@ -660,6 +671,7 @@ public static void PrintPlayerInfo ( [NotNull] Player player, [NotNull] PlayerIn player.Message( " Account is &CBANNED&S. See &H/BanInfo" ); } break; + case BanStatus.IPBanExempt: if ( ipBan != null ) { player.Message( " IP is &CBANNED&S, but account is exempt. See &H/BanInfo" ); @@ -667,21 +679,21 @@ public static void PrintPlayerInfo ( [NotNull] Player player, [NotNull] PlayerIn player.Message( " IP is not banned, and account is exempt. See &H/BanInfo" ); } break; + case BanStatus.NotBanned: if ( ipBan != null ) { player.Message( " IP is &CBANNED&S. See &H/BanInfo" ); - } break; } - if ( !info.LastIP.Equals( IPAddress.None ) ) { // Show alts List altNames = new List(); int bannedAltCount = 0; foreach ( PlayerInfo playerFromSameIP in PlayerDB.FindPlayers( info.LastIP ) ) { - if ( playerFromSameIP == info ) continue; + if ( playerFromSameIP == info ) + continue; altNames.Add( playerFromSameIP ); if ( playerFromSameIP.IsBanned ) { bannedAltCount++; @@ -720,7 +732,6 @@ public static void PrintPlayerInfo ( [NotNull] Player player, [NotNull] PlayerIn } } - // Stats if ( info.BlocksDrawn > 500000000 ) { player.Message( " Built {0} and deleted {1} blocks, drew {2}M blocks, wrote {3} messages.", @@ -747,7 +758,6 @@ public static void PrintPlayerInfo ( [NotNull] Player player, [NotNull] PlayerIn info.MessagesWritten ); } - // More stats if ( info.TimesBannedOthers > 0 || info.TimesKickedOthers > 0 || info.PromoCount > 0 ) { player.Message( " Kicked {0}, Promoted {1} and banned {2} players.", info.TimesKickedOthers, info.PromoCount, info.TimesBannedOthers ); @@ -767,7 +777,6 @@ public static void PrintPlayerInfo ( [NotNull] Player player, [NotNull] PlayerIn } } - // Promotion/demotion if ( info.PreviousRank == null ) { if ( info.RankChangedBy == null ) { @@ -814,12 +823,11 @@ public static void PrintPlayerInfo ( [NotNull] Player player, [NotNull] PlayerIn } } - #endregion - + #endregion Info #region BanInfo - static readonly CommandDescriptor CdBanInfo = new CommandDescriptor { + private static readonly CommandDescriptor CdBanInfo = new CommandDescriptor { Name = "BanInfo", Category = CommandCategory.Info, IsConsoleSafe = true, @@ -830,7 +838,7 @@ public static void PrintPlayerInfo ( [NotNull] Player player, [NotNull] PlayerIn Handler = BanInfoHandler }; - internal static void BanInfoHandler ( Player player, Command cmd ) { + internal static void BanInfoHandler( Player player, Command cmd ) { string name = cmd.Next(); if ( cmd.HasNext ) { CdBanInfo.PrintUsage( player ); @@ -871,10 +879,10 @@ internal static void BanInfoHandler ( Player player, Command cmd ) { } else { player.Message( "{0} is currently NOT banned.", address ); } - } else { info = PlayerDB.FindPlayerInfoOrPrintMatches( player, name ); - if ( info == null ) return; + if ( info == null ) + return; address = info.LastIP; @@ -887,6 +895,7 @@ internal static void BanInfoHandler ( Player player, Command cmd ) { player.Message( "Player {0}&S is &CBANNED&S (but their IP is not).", info.ClassyName ); } break; + case BanStatus.IPBanExempt: if ( ipBan != null ) { player.Message( "Player {0}&S is exempt from an existing IP ban.", info.ClassyName ); @@ -894,6 +903,7 @@ internal static void BanInfoHandler ( Player player, Command cmd ) { player.Message( "Player {0}&S is exempt from IP bans.", info.ClassyName ); } break; + case BanStatus.NotBanned: if ( ipBan != null ) { player.Message( "Player {0}&s is not banned, but their IP is.", info.ClassyName ); @@ -943,7 +953,8 @@ internal static void BanInfoHandler ( Player player, Command cmd ) { List altNames = new List(); int bannedAltCount = 0; foreach ( PlayerInfo playerFromSameIP in PlayerDB.FindPlayers( address ) ) { - if ( playerFromSameIP == info ) continue; + if ( playerFromSameIP == info ) + continue; altNames.Add( playerFromSameIP ); if ( playerFromSameIP.IsBanned ) { bannedAltCount++; @@ -982,12 +993,11 @@ internal static void BanInfoHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion BanInfo #region RankInfo - static readonly CommandDescriptor CdRankInfo = new CommandDescriptor { + private static readonly CommandDescriptor CdRankInfo = new CommandDescriptor { Name = "RankInfo", Aliases = new[] { "rinfo" }, Category = CommandCategory.Info, @@ -999,7 +1009,7 @@ internal static void BanInfoHandler ( Player player, Command cmd ) { }; // Shows general information about a particular rank. - static void RankInfoHandler ( Player player, Command cmd ) { + private static void RankInfoHandler( Player player, Command cmd ) { Rank rank; string rankName = cmd.Next(); @@ -1033,7 +1043,8 @@ static void RankInfoHandler ( Player player, Command cmd ) { bool first = true; for ( int i = 0; i < sortedPermissionNames.Length; i++ ) { Permission p = sortedPermissionNames[i]; - if ( !first ) sb.Append( ',' ).Append( ' ' ); + if ( !first ) + sb.Append( ',' ).Append( ' ' ); Rank permissionLimit = rank.PermissionLimits[( int )p]; sb.Append( p ); if ( permissionLimit != null ) { @@ -1062,12 +1073,11 @@ static void RankInfoHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion RankInfo #region ServerInfo - static readonly CommandDescriptor CdServerInfo = new CommandDescriptor { + private static readonly CommandDescriptor CdServerInfo = new CommandDescriptor { Name = "ServerInfo", Aliases = new[] { "ServerReport", "Version", "SInfo" }, Category = CommandCategory.Info, @@ -1077,7 +1087,7 @@ static void RankInfoHandler ( Player player, Command cmd ) { Handler = ServerInfoHandler }; - internal static void ServerInfoHandler ( Player player, Command cmd ) { + internal static void ServerInfoHandler( Player player, Command cmd ) { if ( cmd.HasNext ) { CdServerInfo.PrintUsage( player ); return; @@ -1130,12 +1140,11 @@ internal static void ServerInfoHandler ( Player player, Command cmd ) { WorldManager.Worlds.Count( w => w.IsHidden ) ); } - #endregion - + #endregion ServerInfo #region Ranks - static readonly CommandDescriptor CdRanks = new CommandDescriptor { + private static readonly CommandDescriptor CdRanks = new CommandDescriptor { Name = "Ranks", Category = CommandCategory.Info, IsConsoleSafe = true, @@ -1144,7 +1153,7 @@ internal static void ServerInfoHandler ( Player player, Command cmd ) { Handler = RanksHandler }; - internal static void RanksHandler ( Player player, Command cmd ) { + internal static void RanksHandler( Player player, Command cmd ) { if ( cmd.HasNext ) { CdRanks.PrintUsage( player ); return; @@ -1159,14 +1168,13 @@ internal static void RanksHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Ranks #region Rules - const string DefaultRules = "Rules: Use common sense!"; + private const string DefaultRules = "Rules: Use common sense!"; - static readonly CommandDescriptor CdRules = new CommandDescriptor { + private static readonly CommandDescriptor CdRules = new CommandDescriptor { Name = "Rules", Category = CommandCategory.Info, IsConsoleSafe = true, @@ -1175,7 +1183,7 @@ internal static void RanksHandler ( Player player, Command cmd ) { Handler = RulesHandler }; - internal static void RulesHandler ( Player player, Command cmd ) { + internal static void RulesHandler( Player player, Command cmd ) { string sectionName = cmd.Next(); // if no section name is given @@ -1209,17 +1217,16 @@ internal static void RulesHandler ( Player player, Command cmd ) { for ( int i = 0; i < sectionFiles.Length; i++ ) { string sectionFullName = Path.GetFileNameWithoutExtension( sectionFiles[i] ); - if ( sectionFullName == null ) continue; + if ( sectionFullName == null ) + continue; if ( sectionFullName.StartsWith( sectionName, StringComparison.OrdinalIgnoreCase ) ) { if ( sectionFullName.Equals( sectionName, StringComparison.OrdinalIgnoreCase ) ) { // if there is an exact match, break out of the loop early ruleFileName = sectionFiles[i]; break; - } else if ( ruleFileName == null ) { // if there is a partial match, keep going to check for multiple matches ruleFileName = sectionFiles[i]; - } else { var matches = sectionFiles.Select( f => Path.GetFileNameWithoutExtension( f ) ) .Where( sn => sn != null && sn.StartsWith( sectionName, StringComparison.OrdinalIgnoreCase ) ); @@ -1237,7 +1244,6 @@ internal static void RulesHandler ( Player player, Command cmd ) { player.Message( "Rule section \"{0}\":", sectionFullName ); // ReSharper restore AssignNullToNotNullAttribute PrintRuleFile( player, new FileInfo( ruleFileName ) ); - } else { var sectionList = GetRuleSectionList(); if ( sectionList == null ) { @@ -1249,9 +1255,8 @@ internal static void RulesHandler ( Player player, Command cmd ) { } } - [CanBeNull] - static string[] GetRuleSectionList () { + private static string[] GetRuleSectionList() { if ( Directory.Exists( Paths.RulesPath ) ) { string[] sections = Directory.GetFiles( Paths.RulesPath, "*.txt", SearchOption.TopDirectoryOnly ) .Select( name => Path.GetFileNameWithoutExtension( name ) ) @@ -1264,8 +1269,7 @@ static string[] GetRuleSectionList () { return null; } - - static void PrintRuleFile ( Player player, FileSystemInfo ruleFile ) { + private static void PrintRuleFile( Player player, FileSystemInfo ruleFile ) { try { string[] ruleLines = File.ReadAllLines( ruleFile.FullName ); foreach ( string ruleLine in ruleLines ) { @@ -1281,12 +1285,11 @@ static void PrintRuleFile ( Player player, FileSystemInfo ruleFile ) { } } - #endregion - + #endregion Rules #region Measure - static readonly CommandDescriptor CdMeasure = new CommandDescriptor { + private static readonly CommandDescriptor CdMeasure = new CommandDescriptor { Name = "Measure", Category = CommandCategory.Info | CommandCategory.Building, RepeatableSelection = true, @@ -1294,7 +1297,7 @@ static void PrintRuleFile ( Player player, FileSystemInfo ruleFile ) { Handler = MeasureHandler }; - internal static void MeasureHandler ( Player player, Command cmd ) { + internal static void MeasureHandler( Player player, Command cmd ) { if ( cmd.HasNext ) { CdMeasure.PrintUsage( player ); return; @@ -1303,9 +1306,9 @@ internal static void MeasureHandler ( Player player, Command cmd ) { player.Message( "Measure: Select the area to be measured" ); } - const int TopBlocksToList = 5; + private const int TopBlocksToList = 5; - internal static void MeasureCallback ( Player player, Vector3I[] marks, object tag ) { + internal static void MeasureCallback( Player player, Vector3I[] marks, object tag ) { BoundingBox box = new BoundingBox( marks[0], marks[1] ); player.Message( "Measure: {0} x {1} wide, {2} tall, {3} blocks.", box.Width, @@ -1341,12 +1344,11 @@ internal static void MeasureCallback ( Player player, Vector3I[] marks, object t topBlocks.Length, blockString ); } - #endregion - + #endregion Measure #region Players - static readonly CommandDescriptor CdPlayers = new CommandDescriptor { + private static readonly CommandDescriptor CdPlayers = new CommandDescriptor { Name = "Players", Aliases = new[] { "who" }, Category = CommandCategory.Info, @@ -1357,7 +1359,7 @@ internal static void MeasureCallback ( Player player, Vector3I[] marks, object t Handler = PlayersHandler }; - internal static void PlayersHandler ( Player player, Command cmd ) { + internal static void PlayersHandler( Player player, Command cmd ) { string param = cmd.Next(); Player[] players; string worldName = null; @@ -1372,11 +1374,11 @@ internal static void PlayersHandler ( Player player, Command cmd ) { CdPlayers.PrintUsage( player ); return; } - } else { // Try to find the world World world = WorldManager.FindWorldOrPrintMatches( player, param ); - if ( world == null ) return; + if ( world == null ) + return; worldName = param; // If found, grab its player list @@ -1395,14 +1397,11 @@ internal static void PlayersHandler ( Player player, Command cmd ) { .OrderBy( p => p, PlayerListSorter.Instance ) .ToArray(); - if ( visiblePlayers.Length == 0 ) { player.Message( "There are no players {0}", qualifier ); - } else if ( visiblePlayers.Length <= PlayersPerPage || player.IsSuper ) { player.MessagePrefixed( "&S ", "&SThere are {0} players {1}: {2}", visiblePlayers.Length, qualifier, visiblePlayers.JoinToClassyString() ); - } else { if ( offset >= visiblePlayers.Length ) { offset = Math.Max( 0, visiblePlayers.Length - PlayersPerPage ); @@ -1427,14 +1426,14 @@ internal static void PlayersHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Players #region Where - const string Compass = "N . . . ne. . . E . . . se. . . S . . . sw. . . W . . . nw. . . " + + private const string Compass = "N . . . ne. . . E . . . se. . . S . . . sw. . . W . . . nw. . . " + "N . . . ne. . . E . . . se. . . S . . . sw. . . W . . . nw. . . "; - static readonly CommandDescriptor CdWhere = new CommandDescriptor { + + private static readonly CommandDescriptor CdWhere = new CommandDescriptor { Name = "Where", Aliases = new[] { "compass", "whereis", "whereami" }, Category = CommandCategory.Info, @@ -1447,7 +1446,7 @@ internal static void PlayersHandler ( Player player, Command cmd ) { Handler = WhereHandler }; - static void WhereHandler ( Player player, Command cmd ) { + private static void WhereHandler( Player player, Command cmd ) { string name = cmd.Next(); if ( cmd.HasNext ) { CdWhere.PrintUsage( player ); @@ -1457,7 +1456,8 @@ static void WhereHandler ( Player player, Command cmd ) { if ( name != null ) { target = Server.FindPlayerOrPrintMatches( player, name, false, true ); - if ( target == null ) return; + if ( target == null ) + return; } else if ( target.World == null ) { player.Message( "When called from console, &H/Where&S requires a player name." ); return; @@ -1484,8 +1484,7 @@ static void WhereHandler ( Player player, Command cmd ) { GetCompassString( target.Position.R ) ); } - - public static string GetCompassString ( byte rotation ) { + public static string GetCompassString( byte rotation ) { int offset = ( int )( rotation / 255f * 64f ) + 32; return String.Format( "&F[{0}&C{1}&F{2}]", @@ -1494,14 +1493,13 @@ public static string GetCompassString ( byte rotation ) { Compass.Substring( offset + 2, 11 ) ); } - #endregion - + #endregion Where #region Help - const string HelpPrefix = "&S "; + private const string HelpPrefix = "&S "; - static readonly CommandDescriptor CdHelp = new CommandDescriptor { + private static readonly CommandDescriptor CdHelp = new CommandDescriptor { Name = "Help", Aliases = new[] { "herp", "man" }, Category = CommandCategory.Info, @@ -1512,12 +1510,11 @@ public static string GetCompassString ( byte rotation ) { Handler = HelpHandler }; - internal static void HelpHandler ( Player player, Command cmd ) { + internal static void HelpHandler( Player player, Command cmd ) { string commandName = cmd.Next(); if ( commandName == "commands" ) { CdCommands.Call( player, cmd, false ); - } else if ( commandName != null ) { CommandDescriptor descriptor = CommandManager.GetDescriptor( commandName, true ); if ( descriptor == null ) { @@ -1555,7 +1552,6 @@ internal static void HelpHandler ( Player player, Command cmd ) { player.MessageNoAccess( descriptor ); } } - } else { player.Message( " To see a list of all commands, write &H/Commands" ); player.Message( " To see detailed help for a command, write &H/Help Command" ); @@ -1568,12 +1564,11 @@ internal static void HelpHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Help #region Commands - static readonly CommandDescriptor CdCommands = new CommandDescriptor { + private static readonly CommandDescriptor CdCommands = new CommandDescriptor { Name = "Commands", Aliases = new[] { "cmds", "cmdlist" }, Category = CommandCategory.Info, @@ -1585,7 +1580,7 @@ internal static void HelpHandler ( Player player, Command cmd ) { Handler = CommandsHandler }; - internal static void CommandsHandler ( Player player, Command cmd ) { + internal static void CommandsHandler( Player player, Command cmd ) { string param = cmd.Next(); CommandDescriptor[] cd; CommandCategory category; @@ -1611,7 +1606,6 @@ internal static void CommandsHandler ( Player player, Command cmd ) { if ( param == null ) { prefix = "Available commands"; cd = CommandManager.GetCommands( player.Info.Rank, false ); - } else if ( param.StartsWith( "@" ) ) { string rankName = param.Substring( 1 ); Rank rank = RankManager.FindRank( rankName ); @@ -1622,19 +1616,15 @@ internal static void CommandsHandler ( Player player, Command cmd ) { prefix = String.Format( "Commands available to {0}&S", rank.ClassyName ); cd = CommandManager.GetCommands( rank, false ); } - } else if ( param.Equals( "all", StringComparison.OrdinalIgnoreCase ) ) { prefix = "All commands"; cd = CommandManager.GetCommands(); - } else if ( param.Equals( "hidden", StringComparison.OrdinalIgnoreCase ) ) { prefix = "Hidden commands"; cd = CommandManager.GetCommands( true ); - } else if ( EnumUtil.TryParse( param, out category, true ) ) { prefix = String.Format( "{0} commands", category ); cd = CommandManager.GetCommands( category, false ); - } else { CdCommands.PrintUsage( player ); return; @@ -1643,12 +1633,11 @@ internal static void CommandsHandler ( Player player, Command cmd ) { player.MessagePrefixed( "&S ", "{0}: {1}", prefix, cd.JoinToClassyString() ); } - #endregion - + #endregion Commands #region Colors - static readonly CommandDescriptor CdColors = new CommandDescriptor { + private static readonly CommandDescriptor CdColors = new CommandDescriptor { Name = "Colors", Aliases = new[] { "colours" }, Category = CommandCategory.Info | CommandCategory.Chat, @@ -1658,7 +1647,7 @@ internal static void CommandsHandler ( Player player, Command cmd ) { Handler = ColorsHandler }; - internal static void ColorsHandler ( Player player, Command cmd ) { + internal static void ColorsHandler( Player player, Command cmd ) { if ( cmd.HasNext ) { CdColors.PrintUsage( player ); return; @@ -1672,8 +1661,7 @@ internal static void ColorsHandler ( Player player, Command cmd ) { player.Message( sb.ToString() ); } - #endregion - + #endregion Colors #if DEBUG_SCHEDULER static CommandDescriptor cdTaskDebug = new CommandDescriptor { diff --git a/fCraft/Commands/MaintenanceCommands.cs b/fCraft/Commands/MaintenanceCommands.cs index ad24678..914a5a8 100644 --- a/fCraft/Commands/MaintenanceCommands.cs +++ b/fCraft/Commands/MaintenanceCommands.cs @@ -9,10 +9,11 @@ using JetBrains.Annotations; namespace fCraft { + /// Several yet-undocumented commands, mostly related to AutoRank. - static class MaintenanceCommands { + internal static class MaintenanceCommands { - internal static void Init () { + internal static void Init() { CommandManager.RegisterCommand( CdDumpStats ); CommandManager.RegisterCommand( CdMassRank ); @@ -73,6 +74,7 @@ internal static void Init () { } ); #endif } + #region 800Craft /* ---- @@ -101,7 +103,8 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ - static readonly CommandDescriptor CdFixRealms = new CommandDescriptor { + + private static readonly CommandDescriptor CdFixRealms = new CommandDescriptor { Name = "Fixrealms", Category = CommandCategory.Maintenance, IsConsoleSafe = false, @@ -111,13 +114,14 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY Handler = FixRealms }; - static void FixRealms ( Player player, Command cmd ) { + private static void FixRealms( Player player, Command cmd ) { int Count = 0; player.Message( "Managing worlds..." ); new System.Threading.Thread( new System.Threading.ThreadStart( delegate { foreach ( World w in WorldManager.Worlds ) { foreach ( PlayerInfo p in PlayerDB.PlayerInfoList ) { - if ( p == null || w == null ) return; + if ( p == null || w == null ) + return; if ( p.Name == w.Name ) { w.IsHidden = false; w.IsRealm = true; @@ -129,7 +133,7 @@ static void FixRealms ( Player player, Command cmd ) { player.Message( "Converted {0} worlds to Realms", Count.ToString() ); } - static readonly CommandDescriptor CdNick = new CommandDescriptor { + private static readonly CommandDescriptor CdNick = new CommandDescriptor { Name = "Nick", Category = CommandCategory.Maintenance, IsConsoleSafe = true, @@ -139,7 +143,7 @@ static void FixRealms ( Player player, Command cmd ) { Handler = NickHandler }; - static void NickHandler ( Player player, Command cmd ) { + private static void NickHandler( Player player, Command cmd ) { string targetName = cmd.Next(); string valName = cmd.NextAll(); @@ -149,9 +153,11 @@ static void NickHandler ( Player player, Command cmd ) { } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches( player, targetName ); - if ( info == null ) return; + if ( info == null ) + return; string oldDisplayedName = info.DisplayedName; - if ( valName.Length == 0 ) valName = null; + if ( valName.Length == 0 ) + valName = null; if ( valName == info.DisplayedName ) { if ( valName == null ) { player.Message( "Nick: DisplayedName for {0} is not set.", @@ -180,11 +186,12 @@ static void NickHandler ( Player player, Command cmd ) { valName ); } } - #endregion + + #endregion 800Craft #region DumpStats - static readonly CommandDescriptor CdDumpStats = new CommandDescriptor { + private static readonly CommandDescriptor CdDumpStats = new CommandDescriptor { Name = "DumpStats", Category = CommandCategory.Maintenance, IsConsoleSafe = true, @@ -196,9 +203,9 @@ static void NickHandler ( Player player, Command cmd ) { Handler = DumpStatsHandler }; - const int TopPlayersToList = 5; + private const int TopPlayersToList = 5; - static void DumpStatsHandler ( Player player, Command cmd ) { + private static void DumpStatsHandler( Player player, Command cmd ) { string fileName = cmd.Next(); if ( fileName == null ) { CdDumpStats.PrintUsage( player ); @@ -249,7 +256,8 @@ static void DumpStatsHandler ( Player player, Command cmd ) { // ReSharper disable LoopCanBeConvertedToQuery for ( int i = 0; i < infos.Length; i++ ) { // ReSharper restore LoopCanBeConvertedToQuery - if ( infos[i].Rank == rank ) rankPlayers.Add( infos[i] ); + if ( infos[i].Rank == rank ) + rankPlayers.Add( infos[i] ); } if ( rankPlayers.Count == 0 ) { writer.WriteLine( "{0}: 0 players, 0 banned, 0 inactive", rank.Name ); @@ -265,7 +273,7 @@ static void DumpStatsHandler ( Player player, Command cmd ) { player.Message( "Stats saved to \"{0}\"", fileName ); } - static void DumpPlayerGroupStats ( TextWriter writer, IList infos, string groupName ) { + private static void DumpPlayerGroupStats( TextWriter writer, IList infos, string groupName ) { RankStats stat = new RankStats(); foreach ( Rank rank2 in RankManager.Ranks ) { stat.PreviousRank.Add( rank2, 0 ); @@ -295,13 +303,13 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s stat.TimesKicked += infos[i].TimesKicked; stat.TimesKickedOthers += infos[i].TimesKickedOthers; stat.TimesBannedOthers += infos[i].TimesBannedOthers; - if ( infos[i].PreviousRank != null ) stat.PreviousRank[infos[i].PreviousRank]++; + if ( infos[i].PreviousRank != null ) + stat.PreviousRank[infos[i].PreviousRank]++; } stat.BlockRatio = stat.BlocksBuilt / ( double )Math.Max( stat.BlocksDeleted, 1 ); stat.BlocksChanged = stat.BlocksDeleted + stat.BlocksBuilt; - stat.TimeSinceFirstLoginMedian = DateTime.UtcNow.Subtract( infos.OrderByDescending( info => info.FirstLoginDate ) .ElementAt( infos.Count / 2 ).FirstLoginDate ); stat.TimeSinceLastLoginMedian = DateTime.UtcNow.Subtract( infos.OrderByDescending( info => info.LastLoginDate ) @@ -321,7 +329,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s stat.TimesKickedOthersMedian = infos.OrderByDescending( info => info.TimesKickedOthers ).ElementAt( infos.Count / 2 ).TimesKickedOthers; stat.TimesBannedOthersMedian = infos.OrderByDescending( info => info.TimesBannedOthers ).ElementAt( infos.Count / 2 ).TimesBannedOthers; - stat.TopTimeSinceFirstLogin = infos.OrderBy( info => info.FirstLoginDate ).ToArray(); stat.TopTimeSinceLastLogin = infos.OrderBy( info => info.LastLoginDate ).ToArray(); stat.TopTotalTime = infos.OrderByDescending( info => info.TotalTime ).ToArray(); @@ -336,7 +343,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s stat.TopTimesKickedOthers = infos.OrderByDescending( info => info.TimesKickedOthers ).ToArray(); stat.TopTimesBannedOthers = infos.OrderByDescending( info => info.TimesBannedOthers ).ToArray(); - writer.WriteLine( "{0}: {1} players, {2} banned, {3} inactive", groupName, totalCount, bannedCount, inactiveCount ); writer.WriteLine( " TimeSinceFirstLogin: {0} mean, {1} median, {2} total", @@ -358,7 +364,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s } writer.WriteLine(); - writer.WriteLine( " TimeSinceLastLogin: {0} mean, {1} median, {2} total", TimeSpan.FromTicks( stat.TimeSinceLastLogin.Ticks / infos.Count ).ToCompactString(), stat.TimeSinceLastLoginMedian.ToCompactString(), @@ -378,7 +383,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s } writer.WriteLine(); - writer.WriteLine( " TotalTime: {0} mean, {1} median, {2} total", TimeSpan.FromTicks( stat.TotalTime.Ticks / infos.Count ).ToCompactString(), stat.TotalTimeMedian.ToCompactString(), @@ -398,8 +402,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s } writer.WriteLine(); - - writer.WriteLine( " BlocksBuilt: {0} mean, {1} median, {2} total", stat.BlocksBuilt / infos.Count, stat.BlocksBuiltMedian, @@ -419,7 +421,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s } writer.WriteLine(); - writer.WriteLine( " BlocksDeleted: {0} mean, {1} median, {2} total", stat.BlocksDeleted / infos.Count, stat.BlocksDeletedMedian, @@ -439,8 +440,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s } writer.WriteLine(); - - writer.WriteLine( " BlocksChanged: {0} mean, {1} median, {2} total", stat.BlocksChanged / infos.Count, stat.BlocksChangedMedian, @@ -460,7 +459,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s } writer.WriteLine(); - writer.WriteLine( " BlocksDrawn: {0} mean, {1} median, {2} total", stat.BlocksDrawn / infos.Count, stat.BlocksDrawnMedian, @@ -479,7 +477,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s } } - writer.WriteLine( " BlockRatio: {0:0.000} mean, {1:0.000} median", stat.BlockRatio, stat.BlockRatioMedian ); @@ -498,7 +495,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s } writer.WriteLine(); - writer.WriteLine( " TimesVisited: {0} mean, {1} median, {2} total", stat.TimesVisited / infos.Count, stat.TimesVisitedMedian, @@ -518,7 +514,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s } writer.WriteLine(); - writer.WriteLine( " MessagesWritten: {0} mean, {1} median, {2} total", stat.MessagesWritten / infos.Count, stat.MessagesWrittenMedian, @@ -538,7 +533,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s } writer.WriteLine(); - writer.WriteLine( " TimesKicked: {0:0.0} mean, {1} median, {2} total", stat.TimesKicked / ( double )infos.Count, stat.TimesKickedMedian, @@ -558,7 +552,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s } writer.WriteLine(); - writer.WriteLine( " TimesKickedOthers: {0:0.0} mean, {1} median, {2} total", stat.TimesKickedOthers / ( double )infos.Count, stat.TimesKickedOthersMedian, @@ -578,7 +571,6 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s } writer.WriteLine(); - writer.WriteLine( " TimesBannedOthers: {0:0.0} mean, {1} median, {2} total", stat.TimesBannedOthers / ( double )infos.Count, stat.TimesBannedOthersMedian, @@ -599,8 +591,7 @@ static void DumpPlayerGroupStats ( TextWriter writer, IList infos, s writer.WriteLine(); } - - sealed class RankStats { + private sealed class RankStats { public TimeSpan TimeSinceFirstLogin; public TimeSpan TimeSinceLastLogin; public TimeSpan TotalTime; @@ -645,12 +636,11 @@ sealed class RankStats { public PlayerInfo[] TopTimesBannedOthers; } - #endregion - + #endregion DumpStats #region AutoRank - static readonly CommandDescriptor CdAutoRankAll = new CommandDescriptor { + private static readonly CommandDescriptor CdAutoRankAll = new CommandDescriptor { Name = "AutoRankAll", Category = CommandCategory.Maintenance | CommandCategory.Moderation, IsConsoleSafe = true, @@ -661,7 +651,7 @@ sealed class RankStats { Handler = AutoRankAllHandler }; - static void AutoRankAllHandler ( Player player, Command cmd ) { + private static void AutoRankAllHandler( Player player, Command cmd ) { string rankName = cmd.Next(); Rank rank = null; if ( rankName != null ) { @@ -681,9 +671,11 @@ static void AutoRankAllHandler ( Player player, Command cmd ) { DoAutoRankAll( player, list, false, "~AutoRankAll" ); } - internal static void DoAutoRankAll ( [NotNull] Player player, [NotNull] PlayerInfo[] list, bool silent, string message ) { - if ( player == null ) throw new ArgumentNullException( "player" ); - if ( list == null ) throw new ArgumentNullException( "list" ); + internal static void DoAutoRankAll( [NotNull] Player player, [NotNull] PlayerInfo[] list, bool silent, string message ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( list == null ) + throw new ArgumentNullException( "list" ); if ( !AutoRankManager.HasCriteria ) { player.Message( "AutoRankAll: No criteria found." ); @@ -713,12 +705,11 @@ internal static void DoAutoRankAll ( [NotNull] Player player, [NotNull] PlayerIn player.Message( "AutoRankAll: Worked for {0}ms, {1} players promoted, {2} demoted.", sw.ElapsedMilliseconds, promoted, demoted ); } - #endregion - + #endregion AutoRank #region MassRank - static readonly CommandDescriptor CdMassRank = new CommandDescriptor { + private static readonly CommandDescriptor CdMassRank = new CommandDescriptor { Name = "MassRank", Category = CommandCategory.Maintenance | CommandCategory.Moderation, IsHidden = true, @@ -729,7 +720,7 @@ internal static void DoAutoRankAll ( [NotNull] Player player, [NotNull] PlayerIn Handler = MassRankHandler }; - static void MassRankHandler ( Player player, Command cmd ) { + private static void MassRankHandler( Player player, Command cmd ) { string fromRankName = cmd.Next(); string toRankName = cmd.Next(); string reason = cmd.NextAll(); @@ -770,12 +761,11 @@ static void MassRankHandler ( Player player, Command cmd ) { player.Message( "MassRank: done, {0} records affected.", affected ); } - #endregion - + #endregion MassRank #region SetInfo - static readonly CommandDescriptor CdSetInfo = new CommandDescriptor { + private static readonly CommandDescriptor CdSetInfo = new CommandDescriptor { Name = "SetInfo", Category = CommandCategory.Maintenance | CommandCategory.Moderation, IsConsoleSafe = true, @@ -817,7 +807,7 @@ static void MassRankHandler ( Player player, Command cmd ) { Handler = SetInfoHandler }; - static void SetInfoHandler ( Player player, Command cmd ) { + private static void SetInfoHandler( Player player, Command cmd ) { string targetName = cmd.Next(); string propertyName = cmd.Next(); string valName = cmd.NextAll(); @@ -828,7 +818,8 @@ static void SetInfoHandler ( Player player, Command cmd ) { } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches( player, targetName ); - if ( info == null ) return; + if ( info == null ) + return; switch ( propertyName.ToLower() ) { case "timeskicked": @@ -925,7 +916,8 @@ static void SetInfoHandler ( Player player, Command cmd ) { break; case "banreason": - if ( valName.Length == 0 ) valName = null; + if ( valName.Length == 0 ) + valName = null; if ( SetPlayerInfoField( player, "BanReason", info, info.BanReason, valName ) ) { info.BanReason = valName; break; @@ -934,7 +926,8 @@ static void SetInfoHandler ( Player player, Command cmd ) { } case "unbanreason": - if ( valName.Length == 0 ) valName = null; + if ( valName.Length == 0 ) + valName = null; if ( SetPlayerInfoField( player, "UnbanReason", info, info.UnbanReason, valName ) ) { info.UnbanReason = valName; break; @@ -943,7 +936,8 @@ static void SetInfoHandler ( Player player, Command cmd ) { } case "rankreason": - if ( valName.Length == 0 ) valName = null; + if ( valName.Length == 0 ) + valName = null; if ( SetPlayerInfoField( player, "RankReason", info, info.RankChangeReason, valName ) ) { info.RankChangeReason = valName; break; @@ -952,7 +946,8 @@ static void SetInfoHandler ( Player player, Command cmd ) { } case "kickreason": - if ( valName.Length == 0 ) valName = null; + if ( valName.Length == 0 ) + valName = null; if ( SetPlayerInfoField( player, "KickReason", info, info.LastKickReason, valName ) ) { info.LastKickReason = valName; break; @@ -963,7 +958,8 @@ static void SetInfoHandler ( Player player, Command cmd ) { case "displayedname": case "dn": string oldDisplayedName = info.DisplayedName; - if ( valName.Length == 0 ) valName = null; + if ( valName.Length == 0 ) + valName = null; if ( valName == info.DisplayedName ) { if ( valName == null ) { player.Message( "SetInfo: DisplayedName for {0} is not set.", @@ -1002,11 +998,14 @@ static void SetInfoHandler ( Player player, Command cmd ) { info.LastModified = DateTime.UtcNow; } - static bool SetPlayerInfoField ( [NotNull] Player player, [NotNull] string fieldName, [NotNull] IClassy info, - [CanBeNull] string oldValue, [CanBeNull] string newValue ) { - if ( player == null ) throw new ArgumentNullException( "player" ); - if ( fieldName == null ) throw new ArgumentNullException( "fieldName" ); - if ( info == null ) throw new ArgumentNullException( "info" ); + private static bool SetPlayerInfoField( [NotNull] Player player, [NotNull] string fieldName, [NotNull] IClassy info, + [CanBeNull] string oldValue, [CanBeNull] string newValue ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( fieldName == null ) + throw new ArgumentNullException( "fieldName" ); + if ( info == null ) + throw new ArgumentNullException( "info" ); if ( newValue == oldValue ) { if ( newValue == null ) { player.Message( "SetInfo: {0} for {1}&S is not set.", @@ -1032,7 +1031,7 @@ static bool SetPlayerInfoField ( [NotNull] Player player, [NotNull] string field return true; } - static bool ValidateInt ( string stringVal, int min, int max ) { + private static bool ValidateInt( string stringVal, int min, int max ) { int val; if ( Int32.TryParse( stringVal, out val ) ) { return ( val >= min && val <= max ); @@ -1041,12 +1040,11 @@ static bool ValidateInt ( string stringVal, int min, int max ) { } } - #endregion - + #endregion SetInfo #region Reload - static readonly CommandDescriptor CdReload = new CommandDescriptor { + private static readonly CommandDescriptor CdReload = new CommandDescriptor { Name = "Reload", Aliases = new[] { "configreload", "reloadconfig", "autorankreload", "reloadautorank" }, Category = CommandCategory.Maintenance, @@ -1060,7 +1058,7 @@ static bool ValidateInt ( string stringVal, int min, int max ) { Handler = ReloadHandler }; - static void ReloadHandler ( Player player, Command cmd ) { + private static void ReloadHandler( Player player, Command cmd ) { string whatToReload = cmd.Next(); if ( whatToReload == null ) { CdReload.PrintUsage( player ); @@ -1113,12 +1111,11 @@ static void ReloadHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Reload #region Shutdown, Restart - static readonly CommandDescriptor CdShutdown = new CommandDescriptor { + private static readonly CommandDescriptor CdShutdown = new CommandDescriptor { Name = "Shutdown", Category = CommandCategory.Maintenance, Permissions = new[] { Permission.ShutdownServer }, @@ -1130,9 +1127,9 @@ static void ReloadHandler ( Player player, Command cmd ) { Handler = ShutdownHandler }; - static readonly TimeSpan DefaultShutdownTime = TimeSpan.FromSeconds( 5 ); + private static readonly TimeSpan DefaultShutdownTime = TimeSpan.FromSeconds( 5 ); - static void ShutdownHandler ( Player player, Command cmd ) { + private static void ShutdownHandler( Player player, Command cmd ) { string delayString = cmd.Next(); TimeSpan delayTime = DefaultShutdownTime; string reason = ""; @@ -1182,9 +1179,7 @@ static void ShutdownHandler ( Player player, Command cmd ) { } } - - - static readonly CommandDescriptor CdRestart = new CommandDescriptor { + private static readonly CommandDescriptor CdRestart = new CommandDescriptor { Name = "Restart", Category = CommandCategory.Maintenance, Permissions = new[] { Permission.ShutdownServer }, @@ -1196,7 +1191,7 @@ static void ShutdownHandler ( Player player, Command cmd ) { Handler = RestartHandler }; - static void RestartHandler ( Player player, Command cmd ) { + private static void RestartHandler( Player player, Command cmd ) { string delayString = cmd.Next(); TimeSpan delayTime = DefaultShutdownTime; string reason = ""; @@ -1247,12 +1242,11 @@ static void RestartHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Shutdown, Restart #region PruneDB - static readonly CommandDescriptor CdPruneDB = new CommandDescriptor { + private static readonly CommandDescriptor CdPruneDB = new CommandDescriptor { Name = "PruneDB", Category = CommandCategory.Maintenance, IsConsoleSafe = true, @@ -1262,7 +1256,7 @@ static void RestartHandler ( Player player, Command cmd ) { Handler = PruneDBHandler }; - static void PruneDBHandler ( Player player, Command cmd ) { + private static void PruneDBHandler( Player player, Command cmd ) { if ( !cmd.IsConfirmed ) { player.MessageNow( "PruneDB: Finding inactive players..." ); int inactivePlayers = PlayerDB.CountInactivePlayers(); @@ -1277,19 +1271,17 @@ static void PruneDBHandler ( Player player, Command cmd ) { } } - - static void PruneDBTask ( SchedulerTask task ) { + private static void PruneDBTask( SchedulerTask task ) { int removedCount = PlayerDB.RemoveInactivePlayers(); Player player = ( Player )task.UserState; player.Message( "PruneDB: Removed {0} inactive players!", removedCount ); } - #endregion - + #endregion PruneDB #region Importing - static readonly CommandDescriptor CdImport = new CommandDescriptor { + private static readonly CommandDescriptor CdImport = new CommandDescriptor { Name = "Import", Aliases = new[] { "importbans", "importranks" }, Category = CommandCategory.Maintenance, @@ -1301,7 +1293,7 @@ static void PruneDBTask ( SchedulerTask task ) { Handler = ImportHandler }; - static void ImportHandler ( Player player, Command cmd ) { + private static void ImportHandler( Player player, Command cmd ) { string action = cmd.Next(); if ( action == null ) { CdImport.PrintUsage( player ); @@ -1331,8 +1323,7 @@ static void ImportHandler ( Player player, Command cmd ) { } } - - static void ImportBans ( Player player, Command cmd ) { + private static void ImportBans( Player player, Command cmd ) { string serverName = cmd.Next(); string file = cmd.Next(); @@ -1364,6 +1355,7 @@ static void ImportBans ( Player player, Command cmd ) { return; } break; + default: player.Message( "800Craft does not support importing from {0}", serverName ); return; @@ -1384,7 +1376,6 @@ static void ImportBans ( Player player, Command cmd ) { PlayerInfo info = PlayerDB.FindPlayerInfoExact( name ) ?? PlayerDB.AddFakeEntry( name, RankChangeType.Default ); info.Ban( player, reason, true, true ); - } else { player.Message( "Could not parse \"{0}\" as either name or IP. Skipping.", name ); } @@ -1398,14 +1389,12 @@ static void ImportBans ( Player player, Command cmd ) { IPBanList.Save(); } - - static void ImportRanks ( Player player, Command cmd ) { + private static void ImportRanks( Player player, Command cmd ) { string serverName = cmd.Next(); string fileName = cmd.Next(); string rankName = cmd.Next(); bool silent = ( cmd.Next() != null ); - // Make sure all parameters are specified if ( serverName == null || fileName == null || rankName == null ) { CdImport.PrintUsage( player ); @@ -1440,6 +1429,7 @@ static void ImportRanks ( Player player, Command cmd ) { return; } break; + default: player.Message( "800Craft does not support importing from {0}", serverName ); return; @@ -1469,10 +1459,9 @@ static void ImportRanks ( Player player, Command cmd ) { PlayerDB.Save(); } - #endregion - + #endregion Importing - static readonly CommandDescriptor CdInfoSwap = new CommandDescriptor { + private static readonly CommandDescriptor CdInfoSwap = new CommandDescriptor { Name = "InfoSwap", Category = CommandCategory.Maintenance, IsConsoleSafe = true, @@ -1483,7 +1472,7 @@ static void ImportRanks ( Player player, Command cmd ) { Handler = DoPlayerDB }; - static void DoPlayerDB ( Player player, Command cmd ) { + private static void DoPlayerDB( Player player, Command cmd ) { string p1Name = cmd.Next(); string p2Name = cmd.Next(); if ( p1Name == null || p2Name == null ) { @@ -1492,9 +1481,11 @@ static void DoPlayerDB ( Player player, Command cmd ) { } PlayerInfo p1 = PlayerDB.FindPlayerInfoOrPrintMatches( player, p1Name ); - if ( p1 == null ) return; + if ( p1 == null ) + return; PlayerInfo p2 = PlayerDB.FindPlayerInfoOrPrintMatches( player, p2Name ); - if ( p2 == null ) return; + if ( p2 == null ) + return; if ( p1 == p2 ) { player.Message( "InfoSwap: Please specify 2 different players." ); @@ -1516,4 +1507,4 @@ static void DoPlayerDB ( Player player, Command cmd ) { } } } -} +} \ No newline at end of file diff --git a/fCraft/Commands/MathCommands.cs b/fCraft/Commands/MathCommands.cs index 2a8aa61..8ad1ca3 100644 --- a/fCraft/Commands/MathCommands.cs +++ b/fCraft/Commands/MathCommands.cs @@ -24,18 +24,16 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft; using fCraft.Drawing; namespace fCraft { + public class MathCommands { public const int MaxCalculationExceptions = 100; - public static void Init () { + public static void Init() { CommandManager.RegisterCommand( CdFunc ); CommandManager.RegisterCommand( CdFuncSurf ); CommandManager.RegisterCommand( CdFuncFill ); @@ -46,7 +44,8 @@ public static void Init () { CommandManager.RegisterCommand( CdStartParam ); CommandManager.RegisterCommand( CdClearParam ); } - const string commonFuncHelp = "Can also be x=f(y, z) or y=f(x, z). "; + + private const string commonFuncHelp = "Can also be x=f(y, z) or y=f(x, z). "; private const string commonHelp = "Allowed operators: +, -, *, /, %, ^. Comparison and logical operators: >, <, =, &, |, !." + @@ -54,15 +53,15 @@ public static void Init () { "Functions: sqrt, sq, exp, lg, ln, log(num, base), abs, sign, sin, cos, tan, sinh, cosh, tanh. Example: 1-exp(-1/sq(x)). " + "'sq' stands for 'square', i.e. sq(x) is x*x. "; - const string commonScalingHelp = + private const string commonScalingHelp = "Select 2 points to define a volume (same as e.g. for cuboid), where the function will be drawn. " + "Coords are whole numbers from 0 to the corresponding cuboid dimension length. " + "Using 'u' as a scaling switch coords to be [0, 1] along the corresponding cuboid axis. " + "'uu' switches coords to be [-1, 1] along the corresponding cuboid axis."; - const string copyright = "\n(C) 2012 Lao Tszy"; + private const string copyright = "\n(C) 2012 Lao Tszy"; - static readonly CommandDescriptor CdFunc = new CommandDescriptor { + private static readonly CommandDescriptor CdFunc = new CommandDescriptor { Name = "Func", Aliases = new string[] { "fu" }, Category = CommandCategory.Math, @@ -75,7 +74,7 @@ public static void Init () { Handler = FuncHandler, }; - static readonly CommandDescriptor CdFuncSurf = new CommandDescriptor { + private static readonly CommandDescriptor CdFuncSurf = new CommandDescriptor { Name = "FuncSurf", Aliases = new string[] { "fus" }, Category = CommandCategory.Math, @@ -88,7 +87,7 @@ public static void Init () { Handler = FuncSHandler, }; - static readonly CommandDescriptor CdFuncFill = new CommandDescriptor { + private static readonly CommandDescriptor CdFuncFill = new CommandDescriptor { Name = "FuncFill", Aliases = new string[] { "fuf" }, Category = CommandCategory.Math, @@ -102,7 +101,7 @@ public static void Init () { }; //inequality - static readonly CommandDescriptor CdIneq = new CommandDescriptor { + private static readonly CommandDescriptor CdIneq = new CommandDescriptor { Name = "Ineq", Aliases = new string[] { "ie" }, Category = CommandCategory.Math, @@ -116,7 +115,7 @@ public static void Init () { }; //equality - static readonly CommandDescriptor CdEq = new CommandDescriptor { + private static readonly CommandDescriptor CdEq = new CommandDescriptor { Name = "Eq", Aliases = new string[] { }, Category = CommandCategory.Math, @@ -130,7 +129,7 @@ public static void Init () { }; //parametrized manifold - static readonly CommandDescriptor CdSetCoord = new CommandDescriptor { + private static readonly CommandDescriptor CdSetCoord = new CommandDescriptor { Name = "SetCoordParm", Aliases = new string[] { "SetCP", "scp" }, Category = CommandCategory.Math, @@ -144,7 +143,7 @@ public static void Init () { Handler = PrepareParametrizedManifold.SetParametrization, }; - static readonly CommandDescriptor CdSetParam = new CommandDescriptor { + private static readonly CommandDescriptor CdSetParam = new CommandDescriptor { Name = "SetParamIter", Aliases = new string[] { "SetPI", "spi" }, Category = CommandCategory.Math, @@ -158,7 +157,7 @@ public static void Init () { Handler = PrepareParametrizedManifold.SetParamIteration, }; - static readonly CommandDescriptor CdStartParam = new CommandDescriptor { + private static readonly CommandDescriptor CdStartParam = new CommandDescriptor { Name = "StartParmDraw", Aliases = new string[] { "StartPD", "spd" }, Category = CommandCategory.Math, @@ -170,7 +169,7 @@ public static void Init () { Handler = StartParametrizedDraw, }; - static readonly CommandDescriptor CdClearParam = new CommandDescriptor { + private static readonly CommandDescriptor CdClearParam = new CommandDescriptor { Name = "ClearParmDraw", Aliases = new string[] { "ClearPD", "cpd" }, Category = CommandCategory.Math, @@ -182,20 +181,21 @@ public static void Init () { Handler = PrepareParametrizedManifold.ClearParametrization, }; - - //Those handler functions would be a template function when this c# could + //Those handler functions would be a template function when this c# could //accept constructors with params for the template param types. //One still can use two-fase-construction to enable templetization here, //but this seems to me even uglier than copy-pasted handlers - private static void FuncHandler ( Player player, Command cmd ) { + private static void FuncHandler( Player player, Command cmd ) { FuncDrawOperation operation = new FuncDrawOperationPoints( player, cmd ); DrawOperationBegin( player, cmd, operation ); } - private static void FuncSHandler ( Player player, Command cmd ) { + + private static void FuncSHandler( Player player, Command cmd ) { FuncDrawOperation operation = new FuncDrawOperationSurface( player, cmd ); DrawOperationBegin( player, cmd, operation ); } - private static void FuncFHandler ( Player player, Command cmd ) { + + private static void FuncFHandler( Player player, Command cmd ) { try { FuncDrawOperation operation = new FuncDrawOperationFill( player, cmd ); DrawOperationBegin( player, cmd, operation ); @@ -203,7 +203,8 @@ private static void FuncFHandler ( Player player, Command cmd ) { player.Message( "Error: " + e.Message ); } } - private static void InequalityHandler ( Player player, Command cmd ) { + + private static void InequalityHandler( Player player, Command cmd ) { try { InequalityDrawOperation operation = new InequalityDrawOperation( player, cmd ); DrawOperationBegin( player, cmd, operation ); @@ -211,7 +212,8 @@ private static void InequalityHandler ( Player player, Command cmd ) { player.Message( "Error: " + e.Message ); } } - private static void EqualityHandler ( Player player, Command cmd ) { + + private static void EqualityHandler( Player player, Command cmd ) { try { EqualityDrawOperation operation = new EqualityDrawOperation( player, cmd ); DrawOperationBegin( player, cmd, operation ); @@ -219,7 +221,8 @@ private static void EqualityHandler ( Player player, Command cmd ) { player.Message( "Error: " + e.Message ); } } - private static void StartParametrizedDraw ( Player player, Command cmd ) { + + private static void StartParametrizedDraw( Player player, Command cmd ) { try { ManifoldDrawOperation operation = new ManifoldDrawOperation( player, cmd ); DrawOperationBegin( player, cmd, operation ); @@ -228,9 +231,8 @@ private static void StartParametrizedDraw ( Player player, Command cmd ) { } } - //copy-paste from BuildingCommands - private static void DrawOperationBegin ( Player player, Command cmd, DrawOperation op ) { + private static void DrawOperationBegin( Player player, Command cmd, DrawOperation op ) { IBrushInstance instance = player.Brush.MakeInstance( player, cmd, op ); if ( instance != null ) { op.Brush = instance; @@ -238,7 +240,8 @@ private static void DrawOperationBegin ( Player player, Command cmd, DrawOperati player.Message( "{0}: Click {1} blocks or use &H/Mark&S to make a selection.", new object[] { op.Description, op.ExpectedMarks } ); } } - private static void DrawOperationCallback ( Player player, Vector3I[] marks, object tag ) { + + private static void DrawOperationCallback( Player player, Vector3I[] marks, object tag ) { DrawOperation operation = ( DrawOperation )tag; if ( operation.Prepare( marks ) ) { if ( !player.CanDraw( operation.BlocksTotalEstimate ) ) { @@ -251,5 +254,4 @@ private static void DrawOperationCallback ( Player player, Vector3I[] marks, obj } } } -} - +} \ No newline at end of file diff --git a/fCraft/Commands/ModerationCommands.cs b/fCraft/Commands/ModerationCommands.cs index 2c15133..44009a7 100644 --- a/fCraft/Commands/ModerationCommands.cs +++ b/fCraft/Commands/ModerationCommands.cs @@ -7,13 +7,14 @@ using JetBrains.Annotations; namespace fCraft { + /// /// Most commands for server moderation - kick, ban, rank change, etc - are here. /// - static class ModerationCommands { - const string BanCommonHelp = "Ban information can be viewed with &H/BanInfo"; + internal static class ModerationCommands { + private const string BanCommonHelp = "Ban information can be viewed with &H/BanInfo"; - internal static void Init () { + internal static void Init() { CdBan.Help += BanCommonHelp; CdBanIP.Help += BanCommonHelp; CdBanAll.Help += BanCommonHelp; @@ -69,6 +70,7 @@ internal static void Init () { CommandManager.RegisterCommand( CdImmortal ); CommandManager.RegisterCommand( CdTitle ); } + #region 800Craft /* ---- @@ -99,7 +101,7 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ----*/ public static List BassText = new List(); - static readonly CommandDescriptor CdTitle = new CommandDescriptor { + private static readonly CommandDescriptor CdTitle = new CommandDescriptor { Name = "Title", Category = CommandCategory.Moderation, IsConsoleSafe = true, @@ -109,7 +111,7 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY Handler = TitleHandler }; - static void TitleHandler ( Player player, Command cmd ) { + private static void TitleHandler( Player player, Command cmd ) { string targetName = cmd.Next(); string titleName = cmd.NextAll(); @@ -119,9 +121,11 @@ static void TitleHandler ( Player player, Command cmd ) { } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches( player, targetName ); - if ( info == null ) return; + if ( info == null ) + return; string oldTitle = info.TitleName; - if ( titleName.Length == 0 ) titleName = null; + if ( titleName.Length == 0 ) + titleName = null; if ( titleName == info.TitleName ) { if ( titleName == null ) { player.Message( "Title: Title for {0} is not set.", @@ -159,7 +163,7 @@ static void TitleHandler ( Player player, Command cmd ) { } } - static readonly CommandDescriptor CdImmortal = new CommandDescriptor { + private static readonly CommandDescriptor CdImmortal = new CommandDescriptor { Name = "Immortal", Aliases = new[] { "Invincible", "God" }, Category = CommandCategory.Moderation, @@ -171,7 +175,7 @@ static void TitleHandler ( Player player, Command cmd ) { Handler = ImmortalHandler }; - internal static void ImmortalHandler ( Player player, Command cmd ) { + internal static void ImmortalHandler( Player player, Command cmd ) { if ( player.Immortal ) { player.Immortal = false; Server.Players.Message( "{0}&S is no longer Immortal", player.ClassyName ); @@ -180,7 +184,8 @@ internal static void ImmortalHandler ( Player player, Command cmd ) { player.Immortal = true; Server.Players.Message( "{0}&S is now Immortal", player.ClassyName ); } - static readonly CommandDescriptor CdModerate = new CommandDescriptor { + + private static readonly CommandDescriptor CdModerate = new CommandDescriptor { Name = "Moderate", Aliases = new[] { "MuteAll", "Moderation" }, Category = CommandCategory.Moderation, @@ -192,7 +197,7 @@ internal static void ImmortalHandler ( Player player, Command cmd ) { Handler = ModerateHandler }; - internal static void ModerateHandler ( Player player, Command cmd ) { + internal static void ModerateHandler( Player player, Command cmd ) { string Option = cmd.Next(); if ( Option == null ) { if ( Server.Moderation ) { @@ -216,7 +221,8 @@ internal static void ModerateHandler ( Player player, Command cmd ) { return; } Player target = Server.FindPlayerOrPrintMatches( player, name, false, true ); - if ( target == null ) return; + if ( target == null ) + return; if ( Server.VoicedPlayers.Contains( target ) ) { player.Message( "{0}&S is already voiced", target.ClassyName ); return; @@ -230,7 +236,8 @@ internal static void ModerateHandler ( Player player, Command cmd ) { return; } Player target = Server.FindPlayerOrPrintMatches( player, name, false, true ); - if ( target == null ) return; + if ( target == null ) + return; if ( !Server.VoicedPlayers.Contains( target ) ) { player.Message( "&WError: {0}&S does not have voiced status", target.ClassyName ); return; @@ -245,7 +252,7 @@ internal static void ModerateHandler ( Player player, Command cmd ) { } } - static readonly CommandDescriptor CdKill = new CommandDescriptor { + private static readonly CommandDescriptor CdKill = new CommandDescriptor { Name = "Kill", Category = CommandCategory.Moderation | CommandCategory.Fun, Aliases = new[] { "Slay" }, @@ -257,7 +264,7 @@ internal static void ModerateHandler ( Player player, Command cmd ) { Handler = KillHandler }; - internal static void KillHandler ( Player player, Command cmd ) { + internal static void KillHandler( Player player, Command cmd ) { string name = cmd.Next(); string OReason = cmd.NextAll(); if ( name == null ) { @@ -266,7 +273,8 @@ internal static void KillHandler ( Player player, Command cmd ) { } Player target = Server.FindPlayerOrPrintMatches( player, name, false, true ); - if ( target == null ) return; + if ( target == null ) + return; if ( target.Immortal ) { player.Message( "&SYou failed to kill {0}&S, they are immortal", target.ClassyName ); return; @@ -302,7 +310,7 @@ internal static void KillHandler ( Player player, Command cmd ) { } } - static readonly CommandDescriptor CdSlap = new CommandDescriptor { + private static readonly CommandDescriptor CdSlap = new CommandDescriptor { Name = "Slap", IsConsoleSafe = true, NotRepeatable = true, @@ -315,7 +323,7 @@ internal static void KillHandler ( Player player, Command cmd ) { Handler = Slap }; - static void Slap ( Player player, Command cmd ) { + private static void Slap( Player player, Command cmd ) { string name = cmd.Next(); string item = cmd.Next(); if ( name == null ) { @@ -323,7 +331,8 @@ static void Slap ( Player player, Command cmd ) { return; } Player target = Server.FindPlayerOrPrintMatches( player, name, false, true ); - if ( target == null ) return; + if ( target == null ) + return; if ( target.Immortal ) { player.Message( "&SYou failed to slap {0}&S, they are immortal", target.ClassyName ); return; @@ -371,7 +380,7 @@ static void Slap ( Player player, Command cmd ) { } } - static readonly CommandDescriptor CdTPZone = new CommandDescriptor { + private static readonly CommandDescriptor CdTPZone = new CommandDescriptor { Name = "Tpzone", IsConsoleSafe = false, Aliases = new[] { "tpz", "zonetp" }, @@ -382,7 +391,7 @@ static void Slap ( Player player, Command cmd ) { Handler = TPZone }; - static void TPZone ( Player player, Command cmd ) { + private static void TPZone( Player player, Command cmd ) { string zoneName = cmd.Next(); if ( zoneName == null ) { player.Message( "No zone name specified. See &W/Help tpzone" ); @@ -401,7 +410,7 @@ static void TPZone ( Player player, Command cmd ) { } } - static readonly CommandDescriptor CdImpersonate = new CommandDescriptor { + private static readonly CommandDescriptor CdImpersonate = new CommandDescriptor { Name = "Impersonate", Category = CommandCategory.Moderation | CommandCategory.Fun, IsConsoleSafe = true, @@ -413,7 +422,7 @@ static void TPZone ( Player player, Command cmd ) { Handler = ImpersonateHandler }; - static void ImpersonateHandler ( Player player, Command cmd ) { + private static void ImpersonateHandler( Player player, Command cmd ) { //entityChanged should be set to true for the skin update to happen in real time string iName = cmd.Next(); if ( iName == null && player.iName == null ) { @@ -437,7 +446,7 @@ static void ImpersonateHandler ( Player player, Command cmd ) { player.entityChanged = true; } - static readonly CommandDescriptor CdTempBan = new CommandDescriptor { + private static readonly CommandDescriptor CdTempBan = new CommandDescriptor { Name = "Tempban", Category = CommandCategory.Moderation, IsConsoleSafe = true, @@ -448,7 +457,7 @@ static void ImpersonateHandler ( Player player, Command cmd ) { Handler = Tempban }; - static void Tempban ( Player player, Command cmd ) { + private static void Tempban( Player player, Command cmd ) { string targetName = cmd.Next(); string timeString = cmd.Next(); TimeSpan duration; @@ -498,7 +507,8 @@ static void Tempban ( Player player, Command cmd ) { Server.Message( "&SPlayer {0}&S was Banned by {1}&S for {2}", target.ClassyName, player.ClassyName, duration.ToMiniString() ); - if ( reason.Length > 0 ) Server.Message( "&Wreason: {0}", reason ); + if ( reason.Length > 0 ) + Server.Message( "&Wreason: {0}", reason ); Logger.Log( LogType.UserActivity, "Player {0} was Banned by {1} for {2}", target.Name, player.Name, duration.ToMiniString() ); } catch ( PlayerOpException ex ) { @@ -512,7 +522,7 @@ static void Tempban ( Player player, Command cmd ) { } } - static readonly CommandDescriptor CdBasscannon = new CommandDescriptor { + private static readonly CommandDescriptor CdBasscannon = new CommandDescriptor { Name = "Basscannon", Category = CommandCategory.Moderation | CommandCategory.Fun, IsConsoleSafe = true, @@ -524,7 +534,7 @@ static void Tempban ( Player player, Command cmd ) { Handler = Basscannon }; - internal static void Basscannon ( Player player, Command cmd ) { + internal static void Basscannon( Player player, Command cmd ) { string name = cmd.Next(); string reason = cmd.NextAll(); @@ -534,7 +544,8 @@ internal static void Basscannon ( Player player, Command cmd ) { } Player target = Server.FindPlayerOrPrintMatches( player, name, false, true ); - if ( target == null ) return; + if ( target == null ) + return; if ( ConfigKey.RequireKickReason.Enabled() && String.IsNullOrEmpty( reason ) ) { player.Message( "&WPlease specify a reason: &W/Basscannon PlayerName Reason" ); @@ -555,7 +566,8 @@ internal static void Basscannon ( Player player, Command cmd ) { BassText.Add( "Pow pow POW!!!" ); } string line = BassText[new Random().Next( 0, BassText.Count )].Trim(); - if ( line.Length == 0 ) return; + if ( line.Length == 0 ) + return; Server.Message( "&9{0}", line ); } catch ( PlayerOpException ex ) { player.Message( ex.MessageColored ); @@ -569,7 +581,7 @@ internal static void Basscannon ( Player player, Command cmd ) { } } - static readonly CommandDescriptor CdWarn = new CommandDescriptor { + private static readonly CommandDescriptor CdWarn = new CommandDescriptor { Name = "Warn", Category = CommandCategory.Moderation, IsConsoleSafe = true, @@ -580,7 +592,7 @@ internal static void Basscannon ( Player player, Command cmd ) { Handler = Warn }; - internal static void Warn ( Player player, Command cmd ) { + internal static void Warn( Player player, Command cmd ) { string name = cmd.Next(); if ( name == null ) { @@ -615,7 +627,7 @@ internal static void Warn ( Player player, Command cmd ) { } } - static readonly CommandDescriptor CdUnWarn = new CommandDescriptor { + private static readonly CommandDescriptor CdUnWarn = new CommandDescriptor { Name = "Unwarn", Category = CommandCategory.Moderation, IsConsoleSafe = true, @@ -625,7 +637,7 @@ internal static void Warn ( Player player, Command cmd ) { Handler = UnWarn }; - internal static void UnWarn ( Player player, Command cmd ) { + internal static void UnWarn( Player player, Command cmd ) { string name = cmd.Next(); if ( name == null ) { player.Message( "No player specified." ); @@ -650,8 +662,7 @@ internal static void UnWarn ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdDisconnect = new CommandDescriptor { + private static readonly CommandDescriptor CdDisconnect = new CommandDescriptor { Name = "Disconnect", Category = CommandCategory.Moderation, IsConsoleSafe = true, @@ -663,7 +674,7 @@ internal static void UnWarn ( Player player, Command cmd ) { Handler = dc }; - internal static void dc ( Player player, Command cmd ) { + internal static void dc( Player player, Command cmd ) { string name = cmd.Next(); if ( name == null ) { player.Message( "Please enter a name" ); @@ -671,7 +682,8 @@ internal static void dc ( Player player, Command cmd ) { } Player target = Server.FindPlayerOrPrintMatches( player, name, false, true ); - if ( target == null ) return; + if ( target == null ) + return; if ( player.Can( Permission.Gtfo, target.Info.Rank ) ) { try { @@ -689,11 +701,12 @@ internal static void dc ( Player player, Command cmd ) { player.Message( "{0}&S is ranked {1}", target.ClassyName, target.Info.Rank.ClassyName ); } } - #endregion + + #endregion 800Craft #region Ban / Unban - static readonly CommandDescriptor CdBan = new CommandDescriptor { + private static readonly CommandDescriptor CdBan = new CommandDescriptor { Name = "Ban", Category = CommandCategory.Moderation, IsConsoleSafe = true, @@ -704,14 +717,15 @@ internal static void dc ( Player player, Command cmd ) { Handler = BanHandler }; - static void BanHandler ( Player player, Command cmd ) { + private static void BanHandler( Player player, Command cmd ) { string targetName = cmd.Next(); if ( targetName == null ) { CdBan.PrintUsage( player ); return; } PlayerInfo target = PlayerDB.FindPlayerInfoOrPrintMatches( player, targetName ); - if ( target == null ) return; + if ( target == null ) + return; string reason = cmd.NextAll(); try { Player targetPlayer = target.PlayerObject; @@ -725,9 +739,7 @@ static void BanHandler ( Player player, Command cmd ) { } } - - - static readonly CommandDescriptor CdBanIP = new CommandDescriptor { + private static readonly CommandDescriptor CdBanIP = new CommandDescriptor { Name = "BanIP", Category = CommandCategory.Moderation, IsConsoleSafe = true, @@ -739,7 +751,7 @@ static void BanHandler ( Player player, Command cmd ) { Handler = BanIPHandler }; - static void BanIPHandler ( Player player, Command cmd ) { + private static void BanIPHandler( Player player, Command cmd ) { string targetNameOrIP = cmd.Next(); if ( targetNameOrIP == null ) { CdBanIP.PrintUsage( player ); @@ -756,7 +768,8 @@ static void BanIPHandler ( Player player, Command cmd ) { } } else { PlayerInfo target = PlayerDB.FindPlayerInfoOrPrintMatches( player, targetNameOrIP ); - if ( target == null ) return; + if ( target == null ) + return; try { if ( target.LastIP.Equals( IPAddress.Any ) || target.LastIP.Equals( IPAddress.None ) ) { target.Ban( player, reason, true, true ); @@ -772,9 +785,7 @@ static void BanIPHandler ( Player player, Command cmd ) { } } - - - static readonly CommandDescriptor CdBanAll = new CommandDescriptor { + private static readonly CommandDescriptor CdBanAll = new CommandDescriptor { Name = "BanAll", Category = CommandCategory.Moderation, IsConsoleSafe = true, @@ -787,7 +798,7 @@ static void BanIPHandler ( Player player, Command cmd ) { Handler = BanAllHandler }; - static void BanAllHandler ( Player player, Command cmd ) { + private static void BanAllHandler( Player player, Command cmd ) { string targetNameOrIP = cmd.Next(); if ( targetNameOrIP == null ) { CdBanAll.PrintUsage( player ); @@ -804,7 +815,8 @@ static void BanAllHandler ( Player player, Command cmd ) { } } else { PlayerInfo target = PlayerDB.FindPlayerInfoOrPrintMatches( player, targetNameOrIP ); - if ( target == null ) return; + if ( target == null ) + return; try { if ( target.LastIP.Equals( IPAddress.Any ) || target.LastIP.Equals( IPAddress.None ) ) { target.Ban( player, reason, true, true ); @@ -820,9 +832,7 @@ static void BanAllHandler ( Player player, Command cmd ) { } } - - - static readonly CommandDescriptor CdUnban = new CommandDescriptor { + private static readonly CommandDescriptor CdUnban = new CommandDescriptor { Name = "Unban", Category = CommandCategory.Moderation, IsConsoleSafe = true, @@ -833,14 +843,15 @@ static void BanAllHandler ( Player player, Command cmd ) { Handler = UnbanHandler }; - static void UnbanHandler ( Player player, Command cmd ) { + private static void UnbanHandler( Player player, Command cmd ) { string targetName = cmd.Next(); if ( targetName == null ) { CdUnban.PrintUsage( player ); return; } PlayerInfo target = PlayerDB.FindPlayerInfoOrPrintMatches( player, targetName ); - if ( target == null ) return; + if ( target == null ) + return; string reason = cmd.NextAll(); try { target.Unban( player, reason, true, true ); @@ -849,9 +860,7 @@ static void UnbanHandler ( Player player, Command cmd ) { } } - - - static readonly CommandDescriptor CdUnbanIP = new CommandDescriptor { + private static readonly CommandDescriptor CdUnbanIP = new CommandDescriptor { Name = "UnbanIP", Category = CommandCategory.Moderation, IsConsoleSafe = true, @@ -863,7 +872,7 @@ static void UnbanHandler ( Player player, Command cmd ) { Handler = UnbanIPHandler }; - static void UnbanIPHandler ( Player player, Command cmd ) { + private static void UnbanIPHandler( Player player, Command cmd ) { string targetNameOrIP = cmd.Next(); if ( targetNameOrIP == null ) { CdUnbanIP.PrintUsage( player ); @@ -877,7 +886,8 @@ static void UnbanIPHandler ( Player player, Command cmd ) { targetAddress.UnbanIP( player, reason, true, true ); } else { PlayerInfo target = PlayerDB.FindPlayerInfoOrPrintMatches( player, targetNameOrIP ); - if ( target == null ) return; + if ( target == null ) + return; if ( target.LastIP.Equals( IPAddress.Any ) || target.LastIP.Equals( IPAddress.None ) ) { target.Unban( player, reason, true, true ); } else { @@ -889,9 +899,7 @@ static void UnbanIPHandler ( Player player, Command cmd ) { } } - - - static readonly CommandDescriptor CdUnbanAll = new CommandDescriptor { + private static readonly CommandDescriptor CdUnbanAll = new CommandDescriptor { Name = "UnbanAll", Category = CommandCategory.Moderation, IsConsoleSafe = true, @@ -903,7 +911,7 @@ static void UnbanIPHandler ( Player player, Command cmd ) { Handler = UnbanAllHandler }; - static void UnbanAllHandler ( Player player, Command cmd ) { + private static void UnbanAllHandler( Player player, Command cmd ) { string targetNameOrIP = cmd.Next(); if ( targetNameOrIP == null ) { CdUnbanAll.PrintUsage( player ); @@ -917,7 +925,8 @@ static void UnbanAllHandler ( Player player, Command cmd ) { targetAddress.UnbanAll( player, reason, true, true ); } else { PlayerInfo target = PlayerDB.FindPlayerInfoOrPrintMatches( player, targetNameOrIP ); - if ( target == null ) return; + if ( target == null ) + return; if ( target.LastIP.Equals( IPAddress.Any ) || target.LastIP.Equals( IPAddress.None ) ) { target.Unban( player, reason, true, true ); } else { @@ -929,8 +938,7 @@ static void UnbanAllHandler ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdBanEx = new CommandDescriptor { + private static readonly CommandDescriptor CdBanEx = new CommandDescriptor { Name = "BanEx", Category = CommandCategory.Moderation, IsConsoleSafe = true, @@ -941,7 +949,7 @@ static void UnbanAllHandler ( Player player, Command cmd ) { Handler = BanExHandler }; - static void BanExHandler ( Player player, Command cmd ) { + private static void BanExHandler( Player player, Command cmd ) { string playerName = cmd.Next(); if ( playerName == null || playerName.Length < 2 || ( playerName[0] != '-' && playerName[0] != '+' ) ) { CdBanEx.PrintUsage( player ); @@ -950,7 +958,8 @@ static void BanExHandler ( Player player, Command cmd ) { bool addExemption = ( playerName[0] == '+' ); string targetName = playerName.Substring( 1 ); PlayerInfo target = PlayerDB.FindPlayerInfoOrPrintMatches( player, targetName ); - if ( target == null ) return; + if ( target == null ) + return; switch ( target.BanStatus ) { case BanStatus.Banned: @@ -962,6 +971,7 @@ static void BanExHandler ( Player player, Command cmd ) { target.ClassyName ); } break; + case BanStatus.IPBanExempt: if ( addExemption ) { player.Message( "IP-Ban exemption already exists for player {0}", target.ClassyName ); @@ -971,6 +981,7 @@ static void BanExHandler ( Player player, Command cmd ) { target.BanStatus = BanStatus.NotBanned; } break; + case BanStatus.NotBanned: if ( addExemption ) { player.Message( "IP-Ban exemption added for player {0}", @@ -984,12 +995,11 @@ static void BanExHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Ban / Unban #region Kick - static readonly CommandDescriptor CdKick = new CommandDescriptor { + private static readonly CommandDescriptor CdKick = new CommandDescriptor { Name = "Kick", Aliases = new[] { "k" }, Category = CommandCategory.Moderation, @@ -1001,7 +1011,7 @@ static void BanExHandler ( Player player, Command cmd ) { Handler = KickHandler }; - static void KickHandler ( Player player, Command cmd ) { + private static void KickHandler( Player player, Command cmd ) { string name = cmd.Next(); if ( name == null ) { player.Message( "Usage: &H/Kick PlayerName [Message]" ); @@ -1010,7 +1020,8 @@ static void KickHandler ( Player player, Command cmd ) { // find the target Player target = Server.FindPlayerOrPrintMatches( player, name, false, true ); - if ( target == null ) return; + if ( target == null ) + return; string reason = cmd.NextAll(); DateTime previousKickDate = target.Info.LastKickDate; @@ -1022,7 +1033,6 @@ static void KickHandler ( Player player, Command cmd ) { Player targetPlayer = target; target.Kick( player, reason, LeaveReason.Kick, true, true, true ); WarnIfOtherPlayersOnIP( player, target.Info, targetPlayer ); - } catch ( PlayerOpException ex ) { player.Message( ex.MessageColored ); if ( ex.ErrorCode == PlayerOpExceptionCode.ReasonRequired ) { @@ -1047,12 +1057,11 @@ static void KickHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Kick #region Changing Rank (Promotion / Demotion) - static readonly CommandDescriptor CdRank = new CommandDescriptor { + private static readonly CommandDescriptor CdRank = new CommandDescriptor { Name = "Rank", Aliases = new[] { "user", "promote", "demote" }, Category = CommandCategory.Moderation, @@ -1065,7 +1074,7 @@ static void KickHandler ( Player player, Command cmd ) { Handler = RankHandler }; - public static void RankHandler ( Player player, Command cmd ) { + public static void RankHandler( Player player, Command cmd ) { string name = cmd.Next(); string newRankName = cmd.Next(); @@ -1126,13 +1135,11 @@ public static void RankHandler ( Player player, Command cmd ) { } } - - #endregion - + #endregion Changing Rank (Promotion / Demotion) #region Hide - static readonly CommandDescriptor CdHide = new CommandDescriptor { + private static readonly CommandDescriptor CdHide = new CommandDescriptor { Name = "Hide", Category = CommandCategory.Moderation, Permissions = new[] { Permission.Hide }, @@ -1144,7 +1151,7 @@ public static void RankHandler ( Player player, Command cmd ) { Handler = HideHandler }; - static void HideHandler ( Player player, Command cmd ) { + private static void HideHandler( Player player, Command cmd ) { if ( player.Info.IsHidden ) { player.Message( "You are already hidden." ); return; @@ -1177,9 +1184,7 @@ static void HideHandler ( Player player, Command cmd ) { Player.RaisePlayerHideChangedEvent( player ); } - - - static readonly CommandDescriptor CdUnhide = new CommandDescriptor { + private static readonly CommandDescriptor CdUnhide = new CommandDescriptor { Name = "Unhide", Category = CommandCategory.Moderation, Permissions = new[] { Permission.Hide }, @@ -1189,8 +1194,9 @@ static void HideHandler ( Player player, Command cmd ) { Handler = UnhideHandler }; - static void UnhideHandler ( Player player, Command cmd ) { - if ( player.World == null ) PlayerOpException.ThrowNoWorld( player ); + private static void UnhideHandler( Player player, Command cmd ) { + if ( player.World == null ) + PlayerOpException.ThrowNoWorld( player ); if ( !player.Info.IsHidden ) { player.Message( "You are not currently hidden." ); @@ -1219,12 +1225,11 @@ static void UnhideHandler ( Player player, Command cmd ) { Player.RaisePlayerHideChangedEvent( player ); } - #endregion - + #endregion Hide #region Set Spawn - static readonly CommandDescriptor CdSetSpawn = new CommandDescriptor { + private static readonly CommandDescriptor CdSetSpawn = new CommandDescriptor { Name = "SetSpawn", Category = CommandCategory.Moderation | CommandCategory.World, Permissions = new[] { Permission.SetSpawn }, @@ -1234,10 +1239,10 @@ static void UnhideHandler ( Player player, Command cmd ) { Handler = SetSpawnHandler }; - public static void SetSpawnHandler ( Player player, Command cmd ) { + public static void SetSpawnHandler( Player player, Command cmd ) { World playerWorld = player.World; - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); - + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); string playerName = cmd.Next(); if ( playerName == null ) { @@ -1249,7 +1254,6 @@ public static void SetSpawnHandler ( Player player, Command cmd ) { Logger.Log( LogType.UserActivity, "{0} changed the spawned point.", player.Name ); - } else if ( player.Can( Permission.Bring ) ) { Player[] infos = playerWorld.FindPlayers( player, playerName ); if ( infos.Length == 1 ) { @@ -1262,10 +1266,8 @@ public static void SetSpawnHandler ( Player player, Command cmd ) { player.Info.Rank.GetLimit( Permission.Bring ).ClassyName ); player.Message( "{0}&S is ranked {1}", target.ClassyName, target.Info.Rank.ClassyName ); } - } else if ( infos.Length > 0 ) { player.MessageManyMatches( "player", infos ); - } else { infos = Server.FindPlayers( player, playerName, true ); if ( infos.Length > 0 ) { @@ -1279,12 +1281,11 @@ public static void SetSpawnHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Set Spawn #region Freeze - static readonly CommandDescriptor CdFreeze = new CommandDescriptor { + private static readonly CommandDescriptor CdFreeze = new CommandDescriptor { Name = "Freeze", Aliases = new[] { "f" }, Category = CommandCategory.Moderation, @@ -1297,7 +1298,7 @@ public static void SetSpawnHandler ( Player player, Command cmd ) { Handler = FreezeHandler }; - static void FreezeHandler ( Player player, Command cmd ) { + private static void FreezeHandler( Player player, Command cmd ) { string name = cmd.Next(); if ( name == null ) { CdFreeze.PrintUsage( player ); @@ -1305,7 +1306,8 @@ static void FreezeHandler ( Player player, Command cmd ) { } Player target = Server.FindPlayerOrPrintMatches( player, name, false, true ); - if ( target == null ) return; + if ( target == null ) + return; try { target.Info.Freeze( player, true, true ); @@ -1314,8 +1316,7 @@ static void FreezeHandler ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdUnfreeze = new CommandDescriptor { + private static readonly CommandDescriptor CdUnfreeze = new CommandDescriptor { Name = "Unfreeze", Aliases = new[] { "uf" }, Category = CommandCategory.Moderation, @@ -1326,7 +1327,7 @@ static void FreezeHandler ( Player player, Command cmd ) { Handler = UnfreezeHandler }; - static void UnfreezeHandler ( Player player, Command cmd ) { + private static void UnfreezeHandler( Player player, Command cmd ) { string name = cmd.Next(); if ( name == null ) { CdFreeze.PrintUsage( player ); @@ -1334,7 +1335,8 @@ static void UnfreezeHandler ( Player player, Command cmd ) { } Player target = Server.FindPlayerOrPrintMatches( player, name, false, true ); - if ( target == null ) return; + if ( target == null ) + return; try { target.Info.Unfreeze( player, true, true ); @@ -1343,12 +1345,11 @@ static void UnfreezeHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Freeze #region TP - static readonly CommandDescriptor CdTP = new CommandDescriptor { + private static readonly CommandDescriptor CdTP = new CommandDescriptor { Name = "TP", Category = CommandCategory.Moderation, Permissions = new[] { Permission.Teleport }, @@ -1358,7 +1359,7 @@ static void UnfreezeHandler ( Player player, Command cmd ) { Handler = TPHandler }; - static void TPHandler ( Player player, Command cmd ) { + private static void TPHandler( Player player, Command cmd ) { string name = cmd.Next(); if ( name == null ) { CdTP.PrintUsage( player ); @@ -1369,10 +1370,8 @@ static void TPHandler ( Player player, Command cmd ) { cmd.Rewind(); int x, y, z; if ( cmd.NextInt( out x ) && cmd.NextInt( out y ) && cmd.NextInt( out z ) ) { - if ( x <= -1024 || x >= 1024 || y <= -1024 || y >= 1024 || z <= -1024 || z >= 1024 ) { player.Message( "Coordinates are outside the valid range!" ); - } else { player.TeleportTo( new Position { X = ( short )( x * 32 + 16 ), @@ -1385,7 +1384,6 @@ static void TPHandler ( Player player, Command cmd ) { } else { CdTP.PrintUsage( player ); } - } else { if ( name == "-" ) { if ( player.LastUsedPlayerName != null ) { @@ -1399,11 +1397,11 @@ static void TPHandler ( Player player, Command cmd ) { if ( matches.Length == 1 ) { Player target = matches[0]; World targetWorld = target.World; - if ( targetWorld == null ) PlayerOpException.ThrowNoWorld( target ); + if ( targetWorld == null ) + PlayerOpException.ThrowNoWorld( target ); if ( targetWorld == player.World ) { player.TeleportTo( target.Position ); - } else { switch ( targetWorld.AccessSecurity.CheckDetailed( player.Info ) ) { case SecurityCheckResult.Allowed: @@ -1417,11 +1415,13 @@ static void TPHandler ( Player player, Command cmd ) { player.StopSpectating(); player.JoinWorld( targetWorld, WorldChangeReason.Tp, target.Position ); break; + case SecurityCheckResult.BlackListed: player.Message( "Cannot teleport to {0}&S because you are blacklisted on world {1}", target.ClassyName, targetWorld.ClassyName ); break; + case SecurityCheckResult.RankTooLow: player.Message( "Cannot teleport to {0}&S because world {1}&S requires {2}+&S to join.", target.ClassyName, @@ -1431,10 +1431,8 @@ static void TPHandler ( Player player, Command cmd ) { // TODO: case PermissionType.RankTooHigh: } } - } else if ( matches.Length > 1 ) { player.MessageManyMatches( "player", matches ); - } else { // Try to guess if player typed "/TP" instead of "/Join" World[] worlds = WorldManager.FindWorlds( player, name ); @@ -1450,12 +1448,11 @@ static void TPHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion TP #region Bring / WorldBring / BringAll - static readonly CommandDescriptor CdBring = new CommandDescriptor { + private static readonly CommandDescriptor CdBring = new CommandDescriptor { Name = "Bring", IsConsoleSafe = true, Aliases = new[] { "summon", "fetch" }, @@ -1467,7 +1464,7 @@ static void TPHandler ( Player player, Command cmd ) { Handler = BringHandler }; - static void BringHandler ( Player player, Command cmd ) { + private static void BringHandler( Player player, Command cmd ) { string name = cmd.Next(); if ( name == null ) { CdBring.PrintUsage( player ); @@ -1479,17 +1476,20 @@ static void BringHandler ( Player player, Command cmd ) { Player toPlayer = player; if ( toName != null ) { toPlayer = Server.FindPlayerOrPrintMatches( player, toName, false, true ); - if ( toPlayer == null ) return; + if ( toPlayer == null ) + return; } else if ( toPlayer.World == null ) { player.Message( "When used from console, /Bring requires both names to be given." ); return; } World world = toPlayer.World; - if ( world == null ) PlayerOpException.ThrowNoWorld( toPlayer ); + if ( world == null ) + PlayerOpException.ThrowNoWorld( toPlayer ); Player target = Server.FindPlayerOrPrintMatches( player, name, false, true ); - if ( target == null ) return; + if ( target == null ) + return; if ( !player.Can( Permission.Bring, target.Info.Rank ) ) { player.Message( "You may only bring players ranked {0}&S or lower.", @@ -1503,7 +1503,6 @@ static void BringHandler ( Player player, Command cmd ) { // teleport within the same world target.TeleportTo( toPlayer.Position ); target.Message( "&8You were summoned by {0}", player.ClassyName ); - } else { // teleport to a different world SecurityCheckResult check = world.AccessSecurity.CheckDetailed( target.Info ); @@ -1528,8 +1527,7 @@ static void BringHandler ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdWorldBring = new CommandDescriptor { + private static readonly CommandDescriptor CdWorldBring = new CommandDescriptor { Name = "WBring", IsConsoleSafe = true, Category = CommandCategory.Moderation, @@ -1539,7 +1537,7 @@ static void BringHandler ( Player player, Command cmd ) { Handler = WorldBringHandler }; - static void WorldBringHandler ( Player player, Command cmd ) { + private static void WorldBringHandler( Player player, Command cmd ) { string playerName = cmd.Next(); string worldName = cmd.Next(); if ( playerName == null || worldName == null ) { @@ -1550,7 +1548,8 @@ static void WorldBringHandler ( Player player, Command cmd ) { Player target = Server.FindPlayerOrPrintMatches( player, playerName, false, true ); World world = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( target == null || world == null ) return; + if ( target == null || world == null ) + return; if ( target == player ) { player.Message( "&WYou cannot &H/WBring&W yourself." ); @@ -1592,8 +1591,7 @@ static void WorldBringHandler ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdBringAll = new CommandDescriptor { + private static readonly CommandDescriptor CdBringAll = new CommandDescriptor { Name = "BringAll", Category = CommandCategory.Moderation, Permissions = new[] { Permission.Bring, Permission.BringAll }, @@ -1604,8 +1602,9 @@ static void WorldBringHandler ( Player player, Command cmd ) { Handler = BringAllHandler }; - static void BringAllHandler ( Player player, Command cmd ) { - if ( player.World == null ) PlayerOpException.ThrowNoWorld( player ); + private static void BringAllHandler( Player player, Command cmd ) { + if ( player.World == null ) + PlayerOpException.ThrowNoWorld( player ); List targetWorlds = new List(); List targetRanks = new List(); @@ -1633,7 +1632,8 @@ static void BringAllHandler ( Player player, Command cmd ) { allWorlds = true; } else { World world = WorldManager.FindWorldOrPrintMatches( player, arg ); - if ( world == null ) return; + if ( world == null ) + return; targetWorlds.Add( world ); } } @@ -1679,7 +1679,6 @@ static void BringAllHandler ( Player player, Command cmd ) { int count = 0; - // Actually bring all the players foreach ( Player targetPlayer in targetPlayers.CanBeSeen( player ) .RankedAtMost( bringLimit ) ) { @@ -1690,7 +1689,6 @@ static void BringAllHandler ( Player player, Command cmd ) { if ( targetPlayer.Info.IsFrozen ) { targetPlayer.Position = player.Position; } - } else { // teleport to a different world BringPlayerToWorld( player, targetPlayer, player.World, false, true ); @@ -1706,13 +1704,14 @@ static void BringAllHandler ( Player player, Command cmd ) { } } - - - static void BringPlayerToWorld ( [NotNull] Player player, [NotNull] Player target, [NotNull] World world, - bool overridePermissions, bool usePlayerPosition ) { - if ( player == null ) throw new ArgumentNullException( "player" ); - if ( target == null ) throw new ArgumentNullException( "target" ); - if ( world == null ) throw new ArgumentNullException( "world" ); + private static void BringPlayerToWorld( [NotNull] Player player, [NotNull] Player target, [NotNull] World world, + bool overridePermissions, bool usePlayerPosition ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( target == null ) + throw new ArgumentNullException( "target" ); + if ( world == null ) + throw new ArgumentNullException( "world" ); switch ( world.AccessSecurity.CheckDetailed( target.Info ) ) { case SecurityCheckResult.Allowed: case SecurityCheckResult.WhiteListed: @@ -1755,12 +1754,11 @@ static void BringPlayerToWorld ( [NotNull] Player player, [NotNull] Player targe } } - #endregion - + #endregion Bring / WorldBring / BringAll #region Patrol & SpecPatrol - static readonly CommandDescriptor CdPatrol = new CommandDescriptor { + private static readonly CommandDescriptor CdPatrol = new CommandDescriptor { Name = "Patrol", Aliases = new[] { "pat" }, Category = CommandCategory.Moderation, @@ -1769,9 +1767,10 @@ static void BringPlayerToWorld ( [NotNull] Player player, [NotNull] Player targe Handler = PatrolHandler }; - static void PatrolHandler ( Player player, Command cmd ) { + private static void PatrolHandler( Player player, Command cmd ) { World playerWorld = player.World; - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); Player target = playerWorld.GetNextPatrolTarget( player ); if ( target == null ) { @@ -1783,8 +1782,7 @@ static void PatrolHandler ( Player player, Command cmd ) { player.Message( "Patrol: Teleporting to {0}", target.ClassyName ); } - - static readonly CommandDescriptor CdSpecPatrol = new CommandDescriptor { + private static readonly CommandDescriptor CdSpecPatrol = new CommandDescriptor { Name = "SpecPatrol", Aliases = new[] { "spat" }, Category = CommandCategory.Moderation, @@ -1793,9 +1791,10 @@ static void PatrolHandler ( Player player, Command cmd ) { Handler = SpecPatrolHandler }; - static void SpecPatrolHandler ( Player player, Command cmd ) { + private static void SpecPatrolHandler( Player player, Command cmd ) { World playerWorld = player.World; - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); Player target = playerWorld.GetNextPatrolTarget( player, p => player.Can( Permission.Spectate, p.Info.Rank ), @@ -1809,14 +1808,13 @@ static void SpecPatrolHandler ( Player player, Command cmd ) { player.Spectate( target ); } - #endregion - + #endregion Patrol & SpecPatrol #region Mute / Unmute - static readonly TimeSpan MaxMuteDuration = TimeSpan.FromDays( 700 ); // 100w0d + private static readonly TimeSpan MaxMuteDuration = TimeSpan.FromDays( 700 ); // 100w0d - static readonly CommandDescriptor CdMute = new CommandDescriptor { + private static readonly CommandDescriptor CdMute = new CommandDescriptor { Name = "Mute", Category = CommandCategory.Moderation | CommandCategory.Chat, IsConsoleSafe = true, @@ -1826,7 +1824,7 @@ static void SpecPatrolHandler ( Player player, Command cmd ) { Handler = MuteHandler }; - static void MuteHandler ( Player player, Command cmd ) { + private static void MuteHandler( Player player, Command cmd ) { string targetName = cmd.Next(); string timeString = cmd.Next(); TimeSpan duration; @@ -1846,7 +1844,8 @@ static void MuteHandler ( Player player, Command cmd ) { // find the target Player target = Server.FindPlayerOrPrintMatches( player, targetName, false, true ); - if ( target == null ) return; + if ( target == null ) + return; // actually mute try { @@ -1856,8 +1855,7 @@ static void MuteHandler ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdUnmute = new CommandDescriptor { + private static readonly CommandDescriptor CdUnmute = new CommandDescriptor { Name = "Unmute", Category = CommandCategory.Moderation | CommandCategory.Chat, IsConsoleSafe = true, @@ -1867,7 +1865,7 @@ static void MuteHandler ( Player player, Command cmd ) { Handler = UnmuteHandler }; - static void UnmuteHandler ( Player player, Command cmd ) { + private static void UnmuteHandler( Player player, Command cmd ) { string targetName = cmd.Next(); if ( String.IsNullOrEmpty( targetName ) ) { CdUnmute.PrintUsage( player ); @@ -1876,7 +1874,8 @@ static void UnmuteHandler ( Player player, Command cmd ) { // find target Player target = Server.FindPlayerOrPrintMatches( player, targetName, false, true ); - if ( target == null ) return; + if ( target == null ) + return; try { target.Info.Unmute( player, true, true ); @@ -1885,12 +1884,11 @@ static void UnmuteHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Mute / Unmute #region Spectate / Unspectate - static readonly CommandDescriptor CdSpectate = new CommandDescriptor { + private static readonly CommandDescriptor CdSpectate = new CommandDescriptor { Name = "Spectate", Aliases = new[] { "follow", "spec" }, Category = CommandCategory.Moderation, @@ -1899,7 +1897,7 @@ static void UnmuteHandler ( Player player, Command cmd ) { Handler = SpectateHandler }; - static void SpectateHandler ( Player player, Command cmd ) { + private static void SpectateHandler( Player player, Command cmd ) { string targetName = cmd.Next(); if ( targetName == null ) { PlayerInfo lastSpec = player.LastSpectatedPlayer; @@ -1917,7 +1915,8 @@ static void SpectateHandler ( Player player, Command cmd ) { } Player target = Server.FindPlayerOrPrintMatches( player, targetName, false, true ); - if ( target == null ) return; + if ( target == null ) + return; if ( target == player ) { player.Message( "You cannot spectate yourself." ); @@ -1937,8 +1936,7 @@ static void SpectateHandler ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdUnspectate = new CommandDescriptor { + private static readonly CommandDescriptor CdUnspectate = new CommandDescriptor { Name = "Unspectate", Aliases = new[] { "unfollow", "unspec" }, Category = CommandCategory.Moderation, @@ -1947,17 +1945,16 @@ static void SpectateHandler ( Player player, Command cmd ) { Handler = UnspectateHandler }; - static void UnspectateHandler ( Player player, Command cmd ) { + private static void UnspectateHandler( Player player, Command cmd ) { if ( !player.StopSpectating() ) { player.Message( "You are not currently spectating anyone." ); } } - #endregion - + #endregion Spectate / Unspectate // freeze target if player is allowed to do so - static void FreezeIfAllowed ( Player player, PlayerInfo targetInfo ) { + private static void FreezeIfAllowed( Player player, PlayerInfo targetInfo ) { if ( targetInfo.IsOnline && !targetInfo.IsFrozen && player.Can( Permission.Freeze, targetInfo.Rank ) ) { try { targetInfo.Freeze( player, true, true ); @@ -1966,9 +1963,8 @@ static void FreezeIfAllowed ( Player player, PlayerInfo targetInfo ) { } } - // warn player if others are still online from target's IP - static void WarnIfOtherPlayersOnIP ( Player player, PlayerInfo targetInfo, Player except ) { + private static void WarnIfOtherPlayersOnIP( Player player, PlayerInfo targetInfo, Player except ) { Player[] otherPlayers = Server.Players.FromIP( targetInfo.LastIP ) .Except( except ) .ToArray(); diff --git a/fCraft/Commands/System.Drawing/FontHandler.cs b/fCraft/Commands/System.Drawing/FontHandler.cs index dbcff7d..cfb7204 100644 --- a/fCraft/Commands/System.Drawing/FontHandler.cs +++ b/fCraft/Commands/System.Drawing/FontHandler.cs @@ -1,9 +1,5 @@ using System; -using System.IO; -using System.Collections.Generic; using System.Drawing; -using System.Linq; -using System.Text; /* ---- Copyright (c) 2011-2013 Jon Baker, Glenn Marien and Lao Tszy @@ -31,18 +27,24 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + namespace fCraft { + public class FontHandler { + #region Instance and Drawing + public Player player; //player using command public int blockCount; //blockcount for player message. ++ when drawing - int blocks = 0, //drawn blocks + + private int blocks = 0, //drawn blocks blocksDenied = 0; //denied blocks (zones, ect) - fCraft.Drawing.UndoState undoState; //undostate - Direction direction; //direction of the blocks (x++-- ect) + + private fCraft.Drawing.UndoState undoState; //undostate + private Direction direction; //direction of the blocks (x++-- ect) //instance - public FontHandler ( Block textColor, Vector3I[] Marks, Player p, Direction dir ) { + public FontHandler( Block textColor, Vector3I[] Marks, Player p, Direction dir ) { direction = dir; blockCount = 0; player = p; @@ -53,7 +55,7 @@ public FontHandler ( Block textColor, Vector3I[] Marks, Player p, Direction dir undoState = player.DrawBegin( null ); } - public void CreateGraphicsAndDraw ( string Sentence ) { + public void CreateGraphicsAndDraw( string Sentence ) { SizeF size = MeasureTextSize( Sentence, player.font ); //measure the text size to create a bmp) Bitmap img = new Bitmap( ( int )size.Width, ( int )size.Height ); //make an image based on string size using ( Graphics g = Graphics.FromImage( img ) ) { //IDisposable @@ -66,7 +68,8 @@ public void CreateGraphicsAndDraw ( string Sentence ) { img.Dispose(); //gtfo homeslice } } - public void Draw ( Bitmap img ) { + + public void Draw( Bitmap img ) { //guess how big the draw will be int Count = 0; for ( int x = 0; x < img.Width; x++ ) { @@ -96,6 +99,7 @@ public void Draw ( Bitmap img ) { } } break; + case Direction.two: for ( int x = 0; x < img.Width; x++ ) { for ( int z = 0; z < img.Height; z++ ) { @@ -108,6 +112,7 @@ public void Draw ( Bitmap img ) { } } break; + case Direction.three: for ( int y = 0; y < img.Width; y++ ) { for ( int z = 0; z < img.Height; z++ ) { @@ -120,6 +125,7 @@ public void Draw ( Bitmap img ) { } } break; + case Direction.four: for ( int y = 0; y < img.Width; y++ ) { for ( int z = 0; z < img.Height; z++ ) { @@ -132,14 +138,17 @@ public void Draw ( Bitmap img ) { } } break; + default: break; //if blockcount = 0, message is shown and returned } } - #endregion + + #endregion Instance and Drawing #region Helpers - public static Bitmap Crop ( Bitmap bmp ) { + + public static Bitmap Crop( Bitmap bmp ) { int w = bmp.Width; int h = bmp.Height; Func allWhiteRow = row => { @@ -158,13 +167,15 @@ public static Bitmap Crop ( Bitmap bmp ) { for ( int row = 0; row < h; ++row ) { if ( allWhiteRow( row ) ) topmost = row; - else break; + else + break; } int bottommost = 0; for ( int row = h - 1; row >= 0; --row ) { if ( allWhiteRow( row ) ) bottommost = row; - else break; + else + break; } int leftmost = 0, rightmost = 0; for ( int col = 0; col < w; ++col ) { @@ -179,8 +190,10 @@ public static Bitmap Crop ( Bitmap bmp ) { else break; } - if ( rightmost == 0 ) rightmost = w; // As reached left - if ( bottommost == 0 ) bottommost = h; // As reached top. + if ( rightmost == 0 ) + rightmost = w; // As reached left + if ( bottommost == 0 ) + bottommost = h; // As reached top. int croppedWidth = rightmost - leftmost; int croppedHeight = bottommost - topmost; if ( croppedWidth == 0 ) {// No border on left or right @@ -190,7 +203,8 @@ public static Bitmap Crop ( Bitmap bmp ) { if ( croppedHeight == 0 ) {// No border on top or bottom topmost = 0; croppedHeight = h; - } try { + } + try { var target = new Bitmap( croppedWidth, croppedHeight ); using ( Graphics g = Graphics.FromImage( target ) ) { g.DrawImage( bmp, @@ -203,14 +217,16 @@ public static Bitmap Crop ( Bitmap bmp ) { return bmp; //return original image, I guess } } + //Measure the size of the string length using IDisposable. Backport from 800Craft Client - public static SizeF MeasureTextSize ( string text, Font font ) { + public static SizeF MeasureTextSize( string text, Font font ) { using ( Bitmap bmp = new Bitmap( 1, 1 ) ) { using ( Graphics g = Graphics.FromImage( bmp ) ) { return g.MeasureString( text, font ); } } } + //stores information needed for each pixel public struct PixelData { public static int X; @@ -220,15 +236,21 @@ public struct PixelData { } //stolen from BuildingCommands + #region DrawOneBlock - static void DrawOneBlock ( Player player, Map map, Block drawBlock, Vector3I coord, + + private static void DrawOneBlock( Player player, Map map, Block drawBlock, Vector3I coord, BlockChangeContext context, ref int blocks, ref int blocksDenied, fCraft.Drawing.UndoState undoState ) { - if ( map == null ) return; - if ( player == null ) throw new ArgumentNullException( "player" ); + if ( map == null ) + return; + if ( player == null ) + throw new ArgumentNullException( "player" ); - if ( !map.InBounds( coord ) ) return; + if ( !map.InBounds( coord ) ) + return; Block block = map.GetBlock( coord ); - if ( block == drawBlock ) return; + if ( block == drawBlock ) + return; if ( player.CanPlace( map, coord, drawBlock, context ) != CanPlaceResult.Allowed ) { blocksDenied++; @@ -246,7 +268,9 @@ static void DrawOneBlock ( Player player, Map map, Block drawBlock, Vector3I coo } blocks++; } - #endregion - #endregion + + #endregion DrawOneBlock + + #endregion Helpers } -} +} \ No newline at end of file diff --git a/fCraft/Commands/System.Drawing/ShapesLib.cs b/fCraft/Commands/System.Drawing/ShapesLib.cs index 8042878..8ae25fb 100644 --- a/fCraft/Commands/System.Drawing/ShapesLib.cs +++ b/fCraft/Commands/System.Drawing/ShapesLib.cs @@ -1,9 +1,6 @@ using System; -using System.IO; using System.Collections.Generic; using System.Drawing; -using System.Linq; -using System.Text; /* ---- Copyright (c) 2011-2013 Jon Baker, Glenn Marien and Lao Tszy @@ -32,22 +29,25 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ - namespace fCraft { + public class ShapesLib { + #region Instancing public Player player; //player using command public int blockCount; //blockcount for player message. ++ when drawing - int blocks = 0, //drawn blocks + + private int blocks = 0, //drawn blocks blocksDenied = 0; //denied blocks (zones, ect) - fCraft.Drawing.UndoState undoState; //undostate - Direction direction; //direction of the blocks (x++-- ect) - Vector3I[] marks; - int Radius = 0; + + private fCraft.Drawing.UndoState undoState; //undostate + private Direction direction; //direction of the blocks (x++-- ect) + private Vector3I[] marks; + private int Radius = 0; //instance - public ShapesLib ( Block BlockColor, Vector3I[] Marks, Player p, int radius, Direction dir ) { + public ShapesLib( Block BlockColor, Vector3I[] Marks, Player p, int radius, Direction dir ) { marks = Marks; direction = dir; blockCount = 0; @@ -60,14 +60,15 @@ public ShapesLib ( Block BlockColor, Vector3I[] Marks, Player p, int radius, Dir Radius = radius; } - #endregion + #endregion Instancing #region GoldenSpiral - public void DrawSpiral () { + + public void DrawSpiral() { DrawBitmap( Radius, Radius ); } - private void DrawBitmap ( int Width, int Height ) { + private void DrawBitmap( int Width, int Height ) { // Determine the first rectangle's orientation and dimensions. double phi = ( 1 + Math.Sqrt( 5 ) ) / 2; RectOrientations orientation; @@ -107,7 +108,6 @@ private void DrawBitmap ( int Width, int Height ) { // Make the Bitmap. Bitmap bm = new Bitmap( client_wid, client_hgt ); { - // Draw the rectangles. using ( Graphics gr = Graphics.FromImage( bm ) ) { gr.FillRectangle( Brushes.White, 0, 0, bm.Width, bm.Height ); @@ -147,30 +147,33 @@ private void DrawBitmap ( int Width, int Height ) { } } - private void DrawPhiRectanglesOnGraphics ( Graphics gr, List points, double x, double y, double wid, double hgt, RectOrientations orientation ) { - if ( ( wid < 1 ) || ( hgt < 1 ) ) return; + private void DrawPhiRectanglesOnGraphics( Graphics gr, List points, double x, double y, double wid, double hgt, RectOrientations orientation ) { + if ( ( wid < 1 ) || ( hgt < 1 ) ) + return; RectangleF rect; switch ( orientation ) { case RectOrientations.RemoveLeft: rect = new RectangleF( ( float )x, ( float )y, ( float )( 2 * hgt ), ( float )( 2 * hgt ) ); break; + case RectOrientations.RemoveTop: rect = new RectangleF( ( float )( x - wid ), ( float )y, ( float )( 2 * wid ), ( float )( 2 * wid ) ); break; + case RectOrientations.RemoveRight: rect = new RectangleF( ( float )( x + wid - 2 * hgt ), ( float )( y - hgt ), ( float )( 2 * hgt ), ( float )( 2 * hgt ) ); break; + case RectOrientations.RemoveBottom: rect = new RectangleF( ( float )x, ( float )( y + hgt - 2 * wid ), ( float )( 2 * wid ), ( float )( 2 * wid ) ); break; } - // Recursively draw the next rectangle. switch ( orientation ) { case RectOrientations.RemoveLeft: @@ -179,17 +182,20 @@ private void DrawPhiRectanglesOnGraphics ( Graphics gr, List points, dou wid -= hgt; orientation = RectOrientations.RemoveTop; break; + case RectOrientations.RemoveTop: points.Add( new PointF( ( float )x, ( float )y ) ); y += wid; hgt -= wid; orientation = RectOrientations.RemoveRight; break; + case RectOrientations.RemoveRight: points.Add( new PointF( ( float )( x + wid ), ( float )y ) ); wid -= hgt; orientation = RectOrientations.RemoveBottom; break; + case RectOrientations.RemoveBottom: points.Add( new PointF( ( float )( x + wid ), ( float )( y + hgt ) ) ); hgt -= wid; @@ -198,6 +204,7 @@ private void DrawPhiRectanglesOnGraphics ( Graphics gr, List points, dou } DrawPhiRectanglesOnGraphics( gr, points, x, y, wid, hgt, orientation ); } + private enum RectOrientations { RemoveLeft, RemoveTop, @@ -205,10 +212,11 @@ private enum RectOrientations { RemoveBottom } - #endregion + #endregion GoldenSpiral #region Polygon - public void DrawRegularPolygon ( int sides, int startingAngle, bool FillPoly ) { + + public void DrawRegularPolygon( int sides, int startingAngle, bool FillPoly ) { //Get the location for each vertex of the polygon Point center = new Point( Radius / 2, Radius / 2 ); Point[] verticies = CalculateVertices( sides, Radius / 2, startingAngle, center ); @@ -230,7 +238,7 @@ public void DrawRegularPolygon ( int sides, int startingAngle, bool FillPoly ) { polygon.Dispose(); } - private Point[] CalculateVertices ( int sides, int radius, int startingAngle, Point center ) { + private Point[] CalculateVertices( int sides, int radius, int startingAngle, Point center ) { if ( sides < 3 ) throw new ArgumentException( "Polygon must have 3 sides or more." ); @@ -245,12 +253,13 @@ private Point[] CalculateVertices ( int sides, int radius, int startingAngle, Po return points.ToArray(); } - #endregion + + #endregion Polygon #region Multi-point star // Draw the indicated star in the rectangle. - public void DrawStar ( int num_points, int Radius, bool Fill ) { + public void DrawStar( int num_points, int Radius, bool Fill ) { Bitmap bmp = new Bitmap( Radius, Radius ); using ( Graphics g = Graphics.FromImage( bmp ) ) { g.FillRectangle( Brushes.White, 0, 0, bmp.Width, bmp.Height ); @@ -271,7 +280,7 @@ public void DrawStar ( int num_points, int Radius, bool Fill ) { } // Generate the points for a star. - private PointF[] MakeStarPoints ( double start_theta, int num_points, int Radius ) { + private PointF[] MakeStarPoints( double start_theta, int num_points, int Radius ) { double theta, dtheta; PointF[] result; float cx = Radius; @@ -313,9 +322,10 @@ private PointF[] MakeStarPoints ( double start_theta, int num_points, int Radius } // Calculate the inner star radius. - private double CalculateConcaveRadius ( int num_points, int skip ) { + private double CalculateConcaveRadius( int num_points, int skip ) { // For really small numbers of points. - if ( num_points < 5 ) return 0.33f; + if ( num_points < 5 ) + return 0.33f; // Calculate angles to key points. double dtheta = 2 * Math.PI / num_points; @@ -354,7 +364,7 @@ private double CalculateConcaveRadius ( int num_points, int skip ) { // Find the point of intersection between // the lines p1 --> p2 and p3 --> p4. - private void FindIntersection ( PointF p1, PointF p2, PointF p3, PointF p4, + private void FindIntersection( PointF p1, PointF p2, PointF p3, PointF p4, out bool lines_intersect, out bool segments_intersect, out PointF intersection, out PointF close_p1, out PointF close_p2 ) { // Get the segments' parameters. @@ -405,10 +415,11 @@ private void FindIntersection ( PointF p1, PointF p2, PointF p3, PointF p4, close_p2 = new PointF( p3.X + dx34 * t2, p3.Y + dy34 * t2 ); } - #endregion + #endregion Multi-point star #region Draw - public void Draw ( Bitmap img ) { + + public void Draw( Bitmap img ) { //guess how big the draw will be int Count = 0; for ( int x = 0; x < img.Width; x++ ) { @@ -438,6 +449,7 @@ public void Draw ( Bitmap img ) { } } break; + case Direction.two: for ( int x = 0; x < img.Width; x++ ) { for ( int z = 0; z < img.Height; z++ ) { @@ -450,6 +462,7 @@ public void Draw ( Bitmap img ) { } } break; + case Direction.three: for ( int y = 0; y < img.Width; y++ ) { for ( int z = 0; z < img.Height; z++ ) { @@ -462,6 +475,7 @@ public void Draw ( Bitmap img ) { } } break; + case Direction.four: for ( int y = 0; y < img.Width; y++ ) { for ( int z = 0; z < img.Height; z++ ) { @@ -474,15 +488,17 @@ public void Draw ( Bitmap img ) { } } break; + default: break; //if blockcount = 0, message is shown and returned } } - #endregion + + #endregion Draw #region Helpers - private Point DegreesToXY ( float degrees, float radius, Point origin ) { + private Point DegreesToXY( float degrees, float radius, Point origin ) { Point xy = new Point(); double radians = degrees * Math.PI / 180.0; @@ -492,7 +508,7 @@ private Point DegreesToXY ( float degrees, float radius, Point origin ) { return xy; } - public static Bitmap Crop ( Bitmap bmp ) { + public static Bitmap Crop( Bitmap bmp ) { int w = bmp.Width; int h = bmp.Height; Func allWhiteRow = row => { @@ -511,13 +527,15 @@ public static Bitmap Crop ( Bitmap bmp ) { for ( int row = 0; row < h; ++row ) { if ( allWhiteRow( row ) ) topmost = row; - else break; + else + break; } int bottommost = 0; for ( int row = h - 1; row >= 0; --row ) { if ( allWhiteRow( row ) ) bottommost = row; - else break; + else + break; } int leftmost = 0, rightmost = 0; for ( int col = 0; col < w; ++col ) { @@ -532,8 +550,10 @@ public static Bitmap Crop ( Bitmap bmp ) { else break; } - if ( rightmost == 0 ) rightmost = w; // As reached left - if ( bottommost == 0 ) bottommost = h; // As reached top. + if ( rightmost == 0 ) + rightmost = w; // As reached left + if ( bottommost == 0 ) + bottommost = h; // As reached top. int croppedWidth = rightmost - leftmost; int croppedHeight = bottommost - topmost; if ( croppedWidth == 0 ) {// No border on left or right @@ -543,7 +563,8 @@ public static Bitmap Crop ( Bitmap bmp ) { if ( croppedHeight == 0 ) {// No border on top or bottom topmost = 0; croppedHeight = h; - } try { + } + try { var target = new Bitmap( croppedWidth, croppedHeight ); using ( Graphics g = Graphics.FromImage( target ) ) { g.DrawImage( bmp, @@ -556,6 +577,7 @@ public static Bitmap Crop ( Bitmap bmp ) { return bmp; //return original image, I guess } } + //stores information needed for each pixel public struct PixelData { public static int X; @@ -565,15 +587,21 @@ public struct PixelData { } //stolen from BuildingCommands + #region DrawOneBlock - static void DrawOneBlock ( Player player, Map map, Block drawBlock, Vector3I coord, + + private static void DrawOneBlock( Player player, Map map, Block drawBlock, Vector3I coord, BlockChangeContext context, ref int blocks, ref int blocksDenied, fCraft.Drawing.UndoState undoState ) { - if ( map == null ) return; - if ( player == null ) throw new ArgumentNullException( "player" ); + if ( map == null ) + return; + if ( player == null ) + throw new ArgumentNullException( "player" ); - if ( !map.InBounds( coord ) ) return; + if ( !map.InBounds( coord ) ) + return; Block block = map.GetBlock( coord ); - if ( block == drawBlock ) return; + if ( block == drawBlock ) + return; if ( player.CanPlace( map, coord, drawBlock, context ) != CanPlaceResult.Allowed ) { blocksDenied++; @@ -591,7 +619,9 @@ static void DrawOneBlock ( Player player, Map map, Block drawBlock, Vector3I coo } blocks++; } - #endregion - #endregion + + #endregion DrawOneBlock + + #endregion Helpers } -} +} \ No newline at end of file diff --git a/fCraft/Commands/WorldCommands.cs b/fCraft/Commands/WorldCommands.cs index 1a862ff..e27ffed 100644 --- a/fCraft/Commands/WorldCommands.cs +++ b/fCraft/Commands/WorldCommands.cs @@ -3,20 +3,19 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using fCraft.MapConversion; -using JetBrains.Annotations; +using System.Text; using fCraft.Drawing; +using fCraft.MapConversion; using fCraft.Portals; -using System.Text; -using System.Threading; -using fCraft.Events; +using JetBrains.Annotations; namespace fCraft { + /// Contains commands related to world management. - static class WorldCommands { - const int WorldNamesPerPage = 30; + internal static class WorldCommands { + private const int WorldNamesPerPage = 30; - internal static void Init () { + internal static void Init() { CommandManager.RegisterCommand( CdBlockDB ); CommandManager.RegisterCommand( CdBlockInfo ); @@ -59,6 +58,7 @@ internal static void Init () { Player.JoinedWorld += FeedSettings.PlayerJoiningWorld; Player.PlacingBlock += FeedSettings.PlayerPlacingBlock; } + #region 800Craft /* ---- @@ -88,7 +88,7 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ - static readonly CommandDescriptor CdFeed = new CommandDescriptor { + private static readonly CommandDescriptor CdFeed = new CommandDescriptor { Name = "Feed", Category = CommandCategory.Building, Permissions = new Permission[] { Permission.EditPlayerDB }, @@ -98,7 +98,7 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY Handler = FeedHandler, }; - static void FeedHandler ( Player player, Command cmd ) { + private static void FeedHandler( Player player, Command cmd ) { string Option = cmd.Next(); if ( Option == null ) { player.Message( "Argument cannot be null, try /Feed " ); @@ -145,7 +145,7 @@ static void FeedHandler ( Player player, Command cmd ) { } } - static void FeedCallback ( Player player, Vector3I[] marks, object tag ) { + private static void FeedCallback( Player player, Vector3I[] marks, object tag ) { Direction direction = DirectionFinder.GetDirection( marks ); if ( Math.Abs( marks[1].X - marks[0].X ) > Math.Abs( marks[1].Y - marks[0].Y ) ) { if ( marks[0].X < marks[1].X ) { @@ -159,8 +159,8 @@ static void FeedCallback ( Player player, Vector3I[] marks, object tag ) { } else { direction = Direction.four; } - } - else return; + } else + return; System.Drawing.Bitmap bmp = fCraft.Properties.Resources.font; FeedData data = new FeedData( Block.Lava, marks[0], bmp, player.World, direction, player ); data.StartPos = marks[0]; @@ -170,39 +170,45 @@ static void FeedCallback ( Player player, Vector3I[] marks, object tag ) { for ( int x = data.StartPos.X; x < data.StartPos.X + 60; x++ ) { for ( int z = data.StartPos.Z; z < data.StartPos.Z + 9; z++ ) { player.World.Map.QueueUpdate( new BlockUpdate( null, ( short )x, ( short )data.StartPos.Y, ( short )z, Block.Black ) ); - x1 = x; z1 = z; + x1 = x; + z1 = z; } } data.EndPos = new Vector3I( x1, marks[0].Y, z1 ); data.FinishPos = new Vector3I( x1, marks[0].Y, z1 ); - + break; case Direction.two: for ( int x = data.StartPos.X; x > data.StartPos.X - 60; x-- ) { for ( int z = data.StartPos.Z; z < data.StartPos.Z + 9; z++ ) { player.World.Map.QueueUpdate( new BlockUpdate( null, ( short )x, ( short )data.StartPos.Y, ( short )z, Block.Black ) ); - x1 = x; z1 = z; + x1 = x; + z1 = z; } } data.EndPos = new Vector3I( x1, marks[0].Y, z1 ); data.FinishPos = new Vector3I( x1, marks[0].Y, z1 ); break; + case Direction.three: for ( int y = data.StartPos.Y; y < data.StartPos.Y + 60; y++ ) { for ( int z = data.StartPos.Z; z < data.StartPos.Z + 9; z++ ) { player.World.Map.QueueUpdate( new BlockUpdate( null, ( short )data.StartPos.X, ( short )y, ( short )z, Block.Black ) ); - y1 = y; z1 = z; + y1 = y; + z1 = z; } } data.EndPos = new Vector3I( marks[0].X, y1, z1 ); data.FinishPos = new Vector3I( marks[0].X, y1, z1 ); break; + case Direction.four: for ( int y = data.StartPos.Y; y > data.StartPos.Y - 60; y-- ) { for ( int z = data.StartPos.Z; z < data.StartPos.Z + 9; z++ ) { player.World.Map.QueueUpdate( new BlockUpdate( null, ( short )data.StartPos.X, ( short )y, ( short )z, Block.Black ) ); - y1 = y; z1 = z; + y1 = y; + z1 = z; } } data.EndPos = new Vector3I( marks[0].X, y1, z1 ); @@ -212,7 +218,8 @@ static void FeedCallback ( Player player, Vector3I[] marks, object tag ) { } #region Physics - static readonly CommandDescriptor CdPhysics = new CommandDescriptor { + + private static readonly CommandDescriptor CdPhysics = new CommandDescriptor { Name = "Physics", Category = CommandCategory.World, Permissions = new Permission[] { Permission.Physics }, @@ -238,7 +245,7 @@ static void FeedCallback ( Player player, Vector3I[] marks, object tag ) { Handler = PhysicsHandler }; - private static void PhysicsHandler ( Player player, Command cmd ) { + private static void PhysicsHandler( Player player, Command cmd ) { string option = cmd.Next(); World world = player.World; if ( option == null ) { @@ -261,6 +268,7 @@ private static void PhysicsHandler ( Player player, Command cmd ) { return; } break; + case "gun": if ( NextOp.ToLower() == "on" ) { world.EnableGunPhysics( player, true ); @@ -271,6 +279,7 @@ private static void PhysicsHandler ( Player player, Command cmd ) { return; } break; + case "plant": if ( NextOp.ToLower() == "off" ) { world.DisablePlantPhysics( player, true ); @@ -281,6 +290,7 @@ private static void PhysicsHandler ( Player player, Command cmd ) { return; } break; + case "fireworks": case "firework": if ( NextOp.ToLower() == "on" ) { @@ -303,6 +313,7 @@ private static void PhysicsHandler ( Player player, Command cmd ) { return; } break; + case "water": if ( NextOp.ToLower() == "on" ) { world.EnableWaterPhysics( player, true ); @@ -313,19 +324,25 @@ private static void PhysicsHandler ( Player player, Command cmd ) { return; } break; + case "all": if ( NextOp.ToLower() == "on" ) { if ( !world.tntPhysics ) { world.EnableTNTPhysics( player, false ); - } if ( !world.sandPhysics ) { + } + if ( !world.sandPhysics ) { world.EnableSandPhysics( player, false ); - } if ( !world.fireworkPhysics ) { + } + if ( !world.fireworkPhysics ) { world.EnableFireworkPhysics( player, false ); - } if ( !world.waterPhysics ) { + } + if ( !world.waterPhysics ) { world.EnableWaterPhysics( player, false ); - } if ( !world.plantPhysics ) { + } + if ( !world.plantPhysics ) { world.EnablePlantPhysics( player, false ); - } if ( !world.gunPhysics ) { + } + if ( !world.gunPhysics ) { world.EnableGunPhysics( player, false ); } Server.Players.Message( "{0}&S turned ALL Physics on for {1}", player.ClassyName, world.ClassyName ); @@ -333,15 +350,20 @@ private static void PhysicsHandler ( Player player, Command cmd ) { } else if ( NextOp.ToLower() == "off" ) { if ( world.tntPhysics ) { world.DisableTNTPhysics( player, false ); - } if ( world.sandPhysics ) { + } + if ( world.sandPhysics ) { world.DisableSandPhysics( player, false ); - } if ( world.fireworkPhysics ) { + } + if ( world.fireworkPhysics ) { world.DisableFireworkPhysics( player, false ); - } if ( world.waterPhysics ) { + } + if ( world.waterPhysics ) { world.DisableWaterPhysics( player, false ); - } if ( world.plantPhysics ) { + } + if ( world.plantPhysics ) { world.DisablePlantPhysics( player, false ); - } if ( world.gunPhysics ) { + } + if ( world.gunPhysics ) { world.DisableGunPhysics( player, false ); } Server.Players.Message( "{0}&S turned ALL Physics off for {1}", player.ClassyName, world.ClassyName ); @@ -349,15 +371,18 @@ private static void PhysicsHandler ( Player player, Command cmd ) { } break; - default: CdPhysics.PrintUsage( player ); + default: + CdPhysics.PrintUsage( player ); break; } WorldManager.SaveWorldList(); } - #endregion + + #endregion Physics #region MessageBlocks - static readonly CommandDescriptor CdMessageBlock = new CommandDescriptor { + + private static readonly CommandDescriptor CdMessageBlock = new CommandDescriptor { Name = "MessageBlock", Aliases = new[] { "mb" }, Category = CommandCategory.Building, @@ -380,7 +405,8 @@ private static void PhysicsHandler ( Player player, Command cmd ) { }, Handler = MessageBlock }; - static void MessageBlock ( Player player, Command cmd ) { + + private static void MessageBlock( Player player, Command cmd ) { string option = cmd.Next(); if ( option == null ) { CdMessageBlock.PrintUsage( player ); @@ -467,7 +493,7 @@ static void MessageBlock ( Player player, Command cmd ) { } } - static void MessageBlockTestCallback ( Player player, Vector3I[] marks, object tag ) { + private static void MessageBlockTestCallback( Player player, Vector3I[] marks, object tag ) { Vector3I Pos = marks[0]; MessageBlock messageblock = MessageBlockHandler.GetMessageBlock( player.World, Pos ); if ( messageblock == null ) { @@ -477,7 +503,7 @@ static void MessageBlockTestCallback ( Player player, Vector3I[] marks, object t } } - static void MessageBlockAdd ( Player player, Vector3I[] marks, object tag ) { + private static void MessageBlockAdd( Player player, Vector3I[] marks, object tag ) { string Message = ( string )tag; Vector3I mark = marks[0]; if ( !player.Info.Rank.AllowSecurityCircumvention ) { @@ -487,6 +513,7 @@ static void MessageBlockAdd ( Player player, Vector3I[] marks, object tag ) { player.Message( "Cannot add a MessageBlock to world {0}&S: You are barred from building here.", player.World.ClassyName ); return; + case SecurityCheckResult.RankTooLow: player.Message( "Cannot add a MessageBlock to world {0}&S: You are not allowed to build here.", player.World.ClassyName ); @@ -519,11 +546,12 @@ static void MessageBlockAdd ( Player player, Vector3I[] marks, object tag ) { Logger.Log( LogType.UserActivity, "{0} created MessageBlock {1} (on world {2})", player.Name, MessageBlock.Name, player.World.Name ); player.Message( "MessageBlock created on world {0}&S with name {1}", player.World.ClassyName, MessageBlock.Name ); } - #endregion + + #endregion MessageBlocks #region portals - static readonly CommandDescriptor CdPortal = new CommandDescriptor { + private static readonly CommandDescriptor CdPortal = new CommandDescriptor { Name = "Portal", Category = CommandCategory.World, Permissions = new Permission[] { Permission.UsePortal }, @@ -551,11 +579,12 @@ static void MessageBlockAdd ( Player player, Vector3I[] marks, object tag ) { Handler = PortalH }; - struct PDATA { + private struct PDATA { public bool custom; public DrawOperation op; } - private static void PortalH ( Player player, Command command ) { + + private static void PortalH( Player player, Command command ) { try { String option = command.Next(); @@ -566,7 +595,8 @@ private static void PortalH ( Player player, Command command ) { string blockTypeOrName = command.Next(); DrawOperation operation = new CuboidDrawOperation( player ); NormalBrush brush = new NormalBrush( Block.Water, Block.Water ); - if ( blockTypeOrName == null ) blockTypeOrName = "water"; + if ( blockTypeOrName == null ) + blockTypeOrName = "water"; if ( blockTypeOrName.ToLower().Equals( "lava" ) ) { brush = new NormalBrush( Block.Lava, Block.Lava ); } else if ( !blockTypeOrName.ToLower().Equals( "water" ) ) { @@ -579,7 +609,8 @@ private static void PortalH ( Player player, Command command ) { operation.Brush = brush; if ( world != null && WorldManager.FindWorldExact( world ) != null ) { player.PortalWorld = world; - } else player.PortalWorld = player.World.Name; + } else + player.PortalWorld = player.World.Name; player.SelectionStart( operation.ExpectedMarks, PortalCreateCallback, new PDATA() { op = operation, custom = CustomOutput }, Permission.Draw ); player.Message( "Click {0} blocks or use &H/Mark&S to mark the area of the portal.", operation.ExpectedMarks ); @@ -587,7 +618,6 @@ private static void PortalH ( Player player, Command command ) { return; //custom, continue in Selectstart } if ( world != null && WorldManager.FindWorldExact( world ) != null ) { - string portalName = command.Next(); if ( portalName == null ) { @@ -704,7 +734,7 @@ private static void PortalH ( Player player, Command command ) { } } - static void PortalCreateCallback ( Player player, Vector3I[] marks, object tag ) { + private static void PortalCreateCallback( Player player, Vector3I[] marks, object tag ) { try { World world = WorldManager.FindWorldExact( player.PortalWorld ); @@ -712,7 +742,8 @@ static void PortalCreateCallback ( Player player, Vector3I[] marks, object tag ) PDATA pd = ( PDATA )tag; DrawOperation op = pd.op; bool CustomOutput = pd.custom; - if ( !op.Prepare( marks ) ) return; + if ( !op.Prepare( marks ) ) + return; if ( !player.CanDraw( op.BlocksTotalEstimate ) ) { player.MessageNow( "You are only allowed to run draw commands that affect up to {0} blocks. This one would affect {1} blocks.", player.Info.Rank.DrawLimit, @@ -768,9 +799,10 @@ static void PortalCreateCallback ( Player player, Vector3I[] marks, object tag ) Logger.Log( LogType.Error, "WorldCommands.PortalCreateCallback: " + ex ); } } - #endregion - static readonly CommandDescriptor CdWorldSearch = new CommandDescriptor { + #endregion portals + + private static readonly CommandDescriptor CdWorldSearch = new CommandDescriptor { Name = "Worldsearch", Aliases = new[] { "ws" }, Category = CommandCategory.World, @@ -781,7 +813,7 @@ static void PortalCreateCallback ( Player player, Vector3I[] marks, object tag ) Handler = WorldSearchHandler }; - static void WorldSearchHandler ( Player player, Command cmd ) { + private static void WorldSearchHandler( Player player, Command cmd ) { string worldName = cmd.Next(); if ( worldName == null ) { CdWorldSearch.PrintUsage( player ); @@ -799,7 +831,8 @@ static void WorldSearchHandler ( Player player, Command cmd ) { player.MessageManyMatches( "worlds", WorldNames ); } else { int offset; - if ( !cmd.NextInt( out offset ) ) offset = 0; + if ( !cmd.NextInt( out offset ) ) + offset = 0; if ( offset >= WorldNames.Count() ) offset = Math.Max( 0, WorldNames.Length - 30 ); @@ -819,8 +852,7 @@ static void WorldSearchHandler ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdRealm = new CommandDescriptor { + private static readonly CommandDescriptor CdRealm = new CommandDescriptor { Name = "Realm", Category = CommandCategory.World, Permissions = new[] { Permission.Realm }, @@ -831,7 +863,7 @@ static void WorldSearchHandler ( Player player, Command cmd ) { Handler = Realm, }; - internal static void Realm ( Player player, Command cmd ) { + internal static void Realm( Player player, Command cmd ) { string playerName = player.Name.Replace( ".", "-" ); string Choice = cmd.Next(); @@ -872,13 +904,15 @@ internal static void Realm ( Player player, Command cmd ) { Choice = player.World.Name; World world = WorldManager.FindWorldOrPrintMatches( player, Choice ); - if ( world == null ) player.Message( "You need to enter a realm name" ); + if ( world == null ) + player.Message( "You need to enter a realm name" ); if ( world.IsRealm ) { Server.Players.Message( "{0}&S likes realm {1}.", player.ClassyName, world.ClassyName ); return; - } else player.Message( "You are not in a Realm" ); + } else + player.Message( "You are not in a Realm" ); break; @@ -922,7 +956,8 @@ internal static void Realm ( Player player, Command cmd ) { } RealmHandler.RealmLoad( player, cmd, playerName + ".fcm", playerName, RankManager.HighestRank.Name, RankManager.DefaultBuildRank.Name ); World realmworld = WorldManager.FindWorldExact( playerName ); - if ( realmworld == null ) return; + if ( realmworld == null ) + return; if ( !realmworld.AccessSecurity.Check( player.Info ) ) { realmworld.AccessSecurity.Include( player.Info ); } @@ -935,7 +970,8 @@ internal static void Realm ( Player player, Command cmd ) { case "control": World w1 = WorldManager.FindWorldExact( playerName ); - if ( w1 == null ) return; + if ( w1 == null ) + return; if ( !w1.AccessSecurity.Check( player.Info ) ) { w1.AccessSecurity.Include( player.Info ); player.Message( "You have regained access control of your realm" ); @@ -983,24 +1019,30 @@ internal static void Realm ( Player player, Command cmd ) { } if ( onOff.ToLower() == "off" ) { world.DisableWaterPhysics( player, true ); - } else player.Message( "&WInvalid option: /Realm Physics [Type] [On/Off]" ); + } else + player.Message( "&WInvalid option: /Realm Physics [Type] [On/Off]" ); break; + case "plant": if ( onOff.ToLower() == "on" ) { world.EnablePlantPhysics( player, true ); } if ( onOff.ToLower() == "off" ) { world.DisablePlantPhysics( player, true ); - } else player.Message( "&WInvalid option: /Realm Physics [Type] [On/Off]" ); + } else + player.Message( "&WInvalid option: /Realm Physics [Type] [On/Off]" ); break; + case "gun": if ( onOff.ToLower() == "on" ) { world.EnableGunPhysics( player, true ); } if ( onOff.ToLower() == "off" ) { world.DisableGunPhysics( player, true ); - } else player.Message( "&WInvalid option: /Realm Physics [Type] [On/Off]" ); + } else + player.Message( "&WInvalid option: /Realm Physics [Type] [On/Off]" ); break; + case "firework": case "fireworks": if ( onOff.ToLower() == "on" ) { @@ -1008,9 +1050,12 @@ internal static void Realm ( Player player, Command cmd ) { } if ( onOff.ToLower() == "off" ) { world.DisableFireworkPhysics( player, true ); - } else player.Message( "&WInvalid option: /Realm Physics [Type] [On/Off]" ); + } else + player.Message( "&WInvalid option: /Realm Physics [Type] [On/Off]" ); break; - default: player.Message( "&WInvalid option: /Realm physics [Plant|Water|Gun|Fireworks] On/Off" ); + + default: + player.Message( "&WInvalid option: /Realm physics [Plant|Water|Gun|Fireworks] On/Off" ); break; } break; @@ -1064,7 +1109,6 @@ internal static void Realm ( Player player, Command cmd ) { } PlayerInfo targetUnallow = PlayerDB.FindPlayerInfoOrPrintMatches( player, Unallow ); - if ( targetUnallow == null ) { player.Message( "Please enter the name of the player you want to stop building in your Realm." ); return; @@ -1090,7 +1134,6 @@ internal static void Realm ( Player player, Command cmd ) { } Player targetBan = Server.FindPlayerOrPrintMatches( player, Ban, false, true ); - if ( targetBan == null ) { player.Message( "Please enter the name of the player you want to ban from your Realm." ); return; @@ -1138,7 +1181,7 @@ internal static void Realm ( Player player, Command cmd ) { #region BlockDB - static readonly CommandDescriptor CdBlockDB = new CommandDescriptor { + private static readonly CommandDescriptor CdBlockDB = new CommandDescriptor { Name = "BlockDB", Category = CommandCategory.World, IsConsoleSafe = true, @@ -1176,7 +1219,7 @@ internal static void Realm ( Player player, Command cmd ) { Handler = BlockDBHandler }; - static void BlockDBHandler ( Player player, Command cmd ) { + private static void BlockDBHandler( Player player, Command cmd ) { if ( !BlockDB.IsEnabledGlobally ) { player.Message( "&WBlockDB is disabled on this server." ); return; @@ -1212,7 +1255,8 @@ static void BlockDBHandler ( Player player, Command cmd ) { } World world = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( world == null ) return; + if ( world == null ) + return; BlockDB db = world.BlockDB; using ( db.GetWriteLock() ) { @@ -1250,12 +1294,10 @@ static void BlockDBHandler ( Player player, Command cmd ) { // enables BlockDB if ( db.EnabledState == YesNoAuto.Yes ) { player.Message( "BlockDB is already manually enabled on world {0}", world.ClassyName ); - } else if ( db.EnabledState == YesNoAuto.Auto && db.IsEnabled ) { db.EnabledState = YesNoAuto.Yes; WorldManager.SaveWorldList(); player.Message( "BlockDB was auto-enabled, and is now manually enabled on world {0}", world.ClassyName ); - } else { Logger.Log( LogType.UserActivity, "BlockDB: Player {0} enabled BlockDB on world {1} (was {2})", @@ -1270,7 +1312,6 @@ static void BlockDBHandler ( Player player, Command cmd ) { // disables BlockDB if ( db.EnabledState == YesNoAuto.No ) { player.Message( "BlockDB is already manually disabled on world {0}", world.ClassyName ); - } else if ( db.IsEnabled ) { if ( cmd.IsConfirmed ) { db.EnabledState = YesNoAuto.No; @@ -1330,11 +1371,9 @@ static void BlockDBHandler ( Player player, Command cmd ) { if ( limitString.Equals( "none", StringComparison.OrdinalIgnoreCase ) ) { limitNumber = 0; - } else if ( !Int32.TryParse( limitString, out limitNumber ) ) { CdBlockDB.PrintUsage( player ); return; - } else if ( limitNumber < 0 ) { player.Message( "BlockDB: Limit must be non-negative." ); return; @@ -1344,20 +1383,17 @@ static void BlockDBHandler ( Player player, Command cmd ) { if ( db.Limit == limitNumber ) { player.Message( "BlockDB: Limit for world {0}&S is already set to {1}", world.ClassyName, limitDisplayString ); - } else if ( !cmd.IsConfirmed && limitNumber != 0 ) { Logger.Log( LogType.UserActivity, "BlockDB: Asked {0} to confirm changing BlockDB limit on world {1}", player.Name, world.Name ); player.Confirm( cmd, "BlockDB: Change limit? Some old data for world {0}&S may be discarded.", world.ClassyName ); - } else { db.Limit = limitNumber; WorldManager.SaveWorldList(); player.Message( "BlockDB: Limit for world {0}&S set to {1}", world.ClassyName, limitDisplayString ); } - } else { player.Message( "Block tracking is disabled on world {0}", world.ClassyName ); } @@ -1382,7 +1418,6 @@ static void BlockDBHandler ( Player player, Command cmd ) { TimeSpan limit; if ( limitString.Equals( "none", StringComparison.OrdinalIgnoreCase ) ) { limit = TimeSpan.Zero; - } else if ( !limitString.TryParseMiniTimespan( out limit ) ) { CdBlockDB.PrintUsage( player ); return; @@ -1400,13 +1435,11 @@ static void BlockDBHandler ( Player player, Command cmd ) { player.Message( "BlockDB: Time limit for world {0}&S is already set to {1}", world.ClassyName, db.TimeLimit.ToMiniString() ); } - } else if ( !cmd.IsConfirmed && limit != TimeSpan.Zero ) { Logger.Log( LogType.UserActivity, "BlockDB: Asked {0} to confirm changing BlockDB time limit on world {1}", player.Name, world.Name ); player.Confirm( cmd, "BlockDB: Change time limit? Some old data for world {0}&S may be discarded.", world.ClassyName ); - } else { db.TimeLimit = limit; WorldManager.SaveWorldList(); @@ -1418,7 +1451,6 @@ static void BlockDBHandler ( Player player, Command cmd ) { world.ClassyName, db.TimeLimit.ToMiniString() ); } } - } else { player.Message( "Block tracking is disabled on world {0}", world.ClassyName ); } @@ -1455,7 +1487,6 @@ static void BlockDBHandler ( Player player, Command cmd ) { player.Message( "BlockDB preloading is {0} for world {1}", ( db.IsPreloaded ? "ON" : "OFF" ), world.ClassyName ); - } else if ( param.Equals( "on", StringComparison.OrdinalIgnoreCase ) ) { // turns preload on if ( db.IsPreloaded ) { @@ -1465,7 +1496,6 @@ static void BlockDBHandler ( Player player, Command cmd ) { WorldManager.SaveWorldList(); player.Message( "BlockDB preloading is now enabled on world {0}", world.ClassyName ); } - } else if ( param.Equals( "off", StringComparison.OrdinalIgnoreCase ) ) { // turns preload off if ( !db.IsPreloaded ) { @@ -1475,7 +1505,6 @@ static void BlockDBHandler ( Player player, Command cmd ) { WorldManager.SaveWorldList(); player.Message( "BlockDB preloading is now disabled on world {0}", world.ClassyName ); } - } else { CdBlockDB.PrintUsage( player ); } @@ -1492,12 +1521,11 @@ static void BlockDBHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion BlockDB #region BlockInfo - static readonly CommandDescriptor CdBlockInfo = new CommandDescriptor { + private static readonly CommandDescriptor CdBlockInfo = new CommandDescriptor { Name = "BInfo", Category = CommandCategory.World, Aliases = new[] { "b", "bi", "whodid", "about" }, @@ -1508,9 +1536,10 @@ static void BlockDBHandler ( Player player, Command cmd ) { Handler = BlockInfoHandler }; - static void BlockInfoHandler ( Player player, Command cmd ) { + private static void BlockInfoHandler( Player player, Command cmd ) { World playerWorld = player.World; - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); // Make sure BlockDB is usable if ( !BlockDB.IsEnabledGlobally ) { @@ -1535,7 +1564,6 @@ static void BlockInfoHandler ( Player player, Command cmd ) { coords.Y = Math.Min( map.Length - 1, Math.Max( 0, coords.Y ) ); coords.Z = Math.Min( map.Height - 1, Math.Max( 0, coords.Z ) ); BlockInfoSelectionCallback( player, new[] { coords }, null ); - } else { // Otherwise, start a selection player.Message( "BInfo: Click a block to look it up." ); @@ -1543,7 +1571,7 @@ static void BlockInfoHandler ( Player player, Command cmd ) { } } - static void BlockInfoSelectionCallback ( Player player, Vector3I[] marks, object tag ) { + private static void BlockInfoSelectionCallback( Player player, Vector3I[] marks, object tag ) { var args = new BlockInfoLookupArgs { Player = player, World = player.World, @@ -1553,15 +1581,15 @@ static void BlockInfoSelectionCallback ( Player player, Vector3I[] marks, object Scheduler.NewBackgroundTask( BlockInfoSchedulerCallback, args ).RunOnce(); } - - sealed class BlockInfoLookupArgs { + private sealed class BlockInfoLookupArgs { public Player Player; public World World; public Vector3I Coordinate; } - const int MaxBlockChangesToList = 15; - static void BlockInfoSchedulerCallback ( SchedulerTask task ) { + private const int MaxBlockChangesToList = 15; + + private static void BlockInfoSchedulerCallback( SchedulerTask task ) { BlockInfoLookupArgs args = ( BlockInfoLookupArgs )task.UserState; if ( !args.World.BlockDB.IsEnabled ) { args.Player.Message( "&WBlockDB is disabled in this world." ); @@ -1590,12 +1618,15 @@ static void BlockInfoSchedulerCallback ( SchedulerTask task ) { case BlockChangeContext.Manual: contextString = ""; break; + case BlockChangeContext.PaintedCombo: contextString = " (Painted)"; break; + case BlockChangeContext.RedoneCombo: contextString = " (Redone)"; break; + default: if ( ( entry.Context & BlockChangeContext.Drawn ) == BlockChangeContext.Drawn && entry.Context != BlockChangeContext.Drawn ) { @@ -1623,12 +1654,13 @@ static void BlockInfoSchedulerCallback ( SchedulerTask task ) { } } - #endregion - #endregion + #endregion BlockInfo + + #endregion 800Craft #region Env - static readonly CommandDescriptor CdEnv = new CommandDescriptor { + private static readonly CommandDescriptor CdEnv = new CommandDescriptor { Name = "Env", Category = CommandCategory.World, Permissions = new[] { Permission.ManageWorlds }, @@ -1663,7 +1695,7 @@ static void BlockInfoSchedulerCallback ( SchedulerTask task ) { Handler = EnvHandler }; - static void EnvHandler ( Player player, Command cmd ) { + private static void EnvHandler( Player player, Command cmd ) { if ( !ConfigKey.WoMEnableEnvExtensions.Enabled() ) { player.Message( "Env command is disabled on this server." ); return; @@ -1675,7 +1707,8 @@ static void EnvHandler ( Player player, Command cmd ) { return; } else { world = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( world == null ) return; + if ( world == null ) + return; } string variable = cmd.Next(); @@ -1694,7 +1727,9 @@ static void EnvHandler ( Player player, Command cmd ) { } return; } + #region 800Craft + //Copyright (C) <2011 - 2013> using open source texture packs from various sources if ( variable.ToLower() == "terrain" ) { if ( valueText == null ) { @@ -1706,66 +1741,87 @@ static void EnvHandler ( Player player, Command cmd ) { case "normal": world.Terrain = "bc4acee575474f5266105430c3cc628b8b3948a2"; break; + case "arbot": world.Terrain = "1e3eb03d8efaa862679d36c9044ce47e861ea25e"; break; + case "cool": world.Terrain = "165917066357092a2e7f6b0ec358c05b36b0efa7"; break; + case "deadly": world.Terrain = "cb45307db4addbaac1504529fef79d773a6e31f5"; break; + case "shroom": world.Terrain = "f31b086dbae92cc1741476a3697506192b8f5814"; break; + case "prometheus": world.Terrain = "f66479f2d6c812806c3e768442d45a08a868ad16"; break; + case "woodpunk": world.Terrain = "dff99c37e4a792e10c3b775e6bded725f18ed6fe"; break; + case "simple": world.Terrain = "85f783c3a70c0c9d523eb39e080c2ed95f45bfc2"; break; + case "highres": world.Terrain = "f3dac271d7bce9954baad46e183a6a910a30d13b"; break; + case "hexeretic": world.Terrain = "d8e75476281087c8482ac636a8b8e4a59fadd525"; break; + case "tron": world.Terrain = "ba851c9544ba5e4eed3a8fc9b8b5bf25a4dd45e0"; break; + case "8bit": world.Terrain = "5a3fb1994e2ae526815ceaaca3a4dac0051aa890"; break; + case "mario": world.Terrain = "e98a37ddccbc6144306bd08f41248324965c4e5a"; break; + case "fall": world.Terrain = "b7c6dcb7a858639077f95ef94e8e2d51bedc3307"; break; + case "dokucraft": world.Terrain = "a101cadafd02019e14d727d3329a923a40ef040b"; break; + case "indev": world.Terrain = "73d1ef4441725bdcc9ac3616205faa3dff46e12a"; break; + case "doomcraft": world.Terrain = "8b72beb6fea6ed1e01c1e32e08edf5f784bc919c"; break; + case "messa": world.Terrain = "db0feeac8702704a3146a71365622db55fb5a4c4"; break; + case "portal": world.Terrain = "d4b455134394763296994d0c819b0ac0ea338457"; break; + case "snow": world.Terrain = "0b18fb3b41874ac5fbcb43532d62e6b742adc25e"; break; + case "zelda": world.Terrain = "b25e3bffe57c4f6a35ae42bb6116fcb21c50fa6f"; break; + default: player.Message( "&A/Env [WorldName] terrain [Normal, arbot, cool, deadly, shroom, prometheus, woodpunk, fall, snow, tron, " + "mario, highres, 8bit, simple, indev, messa, portal, dokucraft, doomcraft, hexeretic, zelda " ); @@ -1787,7 +1843,8 @@ static void EnvHandler ( Player player, Command cmd ) { return; } } - #endregion + + #endregion 800Craft if ( variable.Equals( "normal", StringComparison.OrdinalIgnoreCase ) ) { if ( cmd.IsConfirmed ) { @@ -1929,7 +1986,7 @@ static void EnvHandler ( Player player, Command cmd ) { } } - static int ParseHexColor ( string text ) { + private static int ParseHexColor( string text ) { byte red, green, blue; switch ( text.Length ) { case 3: @@ -1937,30 +1994,36 @@ static int ParseHexColor ( string text ) { green = ( byte )( HexToValue( text[1] ) * 16 + HexToValue( text[1] ) ); blue = ( byte )( HexToValue( text[2] ) * 16 + HexToValue( text[2] ) ); break; + case 4: - if ( text[0] != '#' ) throw new FormatException(); + if ( text[0] != '#' ) + throw new FormatException(); red = ( byte )( HexToValue( text[1] ) * 16 + HexToValue( text[1] ) ); green = ( byte )( HexToValue( text[2] ) * 16 + HexToValue( text[2] ) ); blue = ( byte )( HexToValue( text[3] ) * 16 + HexToValue( text[3] ) ); break; + case 6: red = ( byte )( HexToValue( text[0] ) * 16 + HexToValue( text[1] ) ); green = ( byte )( HexToValue( text[2] ) * 16 + HexToValue( text[3] ) ); blue = ( byte )( HexToValue( text[4] ) * 16 + HexToValue( text[5] ) ); break; + case 7: - if ( text[0] != '#' ) throw new FormatException(); + if ( text[0] != '#' ) + throw new FormatException(); red = ( byte )( HexToValue( text[1] ) * 16 + HexToValue( text[2] ) ); green = ( byte )( HexToValue( text[3] ) * 16 + HexToValue( text[4] ) ); blue = ( byte )( HexToValue( text[5] ) * 16 + HexToValue( text[6] ) ); break; + default: throw new FormatException(); } return red * 256 * 256 + green * 256 + blue; } - static byte HexToValue ( char c ) { + private static byte HexToValue( char c ) { if ( c >= '0' && c <= '9' ) { return ( byte )( c - '0' ); } else if ( c >= 'A' && c <= 'F' ) { @@ -1972,7 +2035,7 @@ static byte HexToValue ( char c ) { } } - static void TimeCheck ( SchedulerTask task ) { + private static void TimeCheck( SchedulerTask task ) { foreach ( World world in WorldManager.Worlds ) { if ( world.RealisticEnv ) { int sky; @@ -2087,12 +2150,11 @@ static void TimeCheck ( SchedulerTask task ) { } } - #endregion - + #endregion Env #region Gen - static readonly CommandDescriptor CdGenerate = new CommandDescriptor { + private static readonly CommandDescriptor CdGenerate = new CommandDescriptor { Name = "Gen", Category = CommandCategory.World, IsConsoleSafe = true, @@ -2102,7 +2164,7 @@ static void TimeCheck ( SchedulerTask task ) { Handler = GenHandler }; - static void GenHandler ( Player player, Command cmd ) { + private static void GenHandler( Player player, Command cmd ) { World playerWorld = player.World; string themeName = cmd.Next(); string templateName; @@ -2120,10 +2182,8 @@ static void GenHandler ( Player player, Command cmd ) { // parse special template names (which do not need a theme) if ( themeName.Equals( "ocean" ) ) { genOcean = true; - } else if ( themeName.Equals( "empty" ) ) { genEmpty = true; - } else { templateName = cmd.Next(); if ( templateName == null ) { @@ -2136,19 +2196,15 @@ static void GenHandler ( Player player, Command cmd ) { if ( themeName.Equals( "grass", StringComparison.OrdinalIgnoreCase ) ) { theme = MapGenTheme.Forest; noTrees = true; - } else if ( templateName.Equals( "grass", StringComparison.OrdinalIgnoreCase ) ) { theme = MapGenTheme.Forest; noTrees = true; swapThemeAndTemplate = true; - } else if ( EnumUtil.TryParse( themeName, out theme, true ) ) { noTrees = ( theme != MapGenTheme.Forest ); - } else if ( EnumUtil.TryParse( templateName, out theme, true ) ) { noTrees = ( theme != MapGenTheme.Forest ); swapThemeAndTemplate = true; - } else { player.Message( "Gen: Unrecognized theme \"{0}\". Available themes are: Grass, {1}", themeName, @@ -2260,7 +2316,6 @@ static void GenHandler ( Player player, Command cmd ) { player.Confirm( cmd, "Replace THIS MAP with a generated one ({0})?", templateFullName ); return; } - } else { if ( cmd.HasNext ) { CdGenerate.PrintUsage( player ); @@ -2296,13 +2351,10 @@ static void GenHandler ( Player player, Command cmd ) { if ( genEmpty ) { map = MapGenerator.GenerateEmpty( mapWidth, mapLength, mapHeight ); - } else if ( genOcean ) { map = MapGenerator.GenerateOcean( mapWidth, mapLength, mapHeight ); - } else if ( genFlatgrass ) { map = MapGenerator.GenerateFlatgrass( mapWidth, mapLength, mapHeight ); - } else { MapGeneratorArgs args = MapGenerator.MakeTemplate( template ); if ( theme == MapGenTheme.Desert ) { @@ -2330,7 +2382,8 @@ static void GenHandler ( Player player, Command cmd ) { player.Message( "&WAn error occured while saving generated map to {0}", fileName ); } } else { - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); player.MessageNow( "Generation done. Changing map..." ); playerWorld.MapChangedBy = player.Name; playerWorld.ChangeMap( map ); @@ -2338,11 +2391,11 @@ static void GenHandler ( Player player, Command cmd ) { Server.RequestGC(); } - #endregion + #endregion Gen #region Join - static readonly CommandDescriptor CdJoin = new CommandDescriptor { + private static readonly CommandDescriptor CdJoin = new CommandDescriptor { Name = "Join", Aliases = new[] { "j", "load", "goto", "map" }, Category = CommandCategory.World, @@ -2351,7 +2404,7 @@ static void GenHandler ( Player player, Command cmd ) { Handler = JoinHandler }; - static void JoinHandler ( Player player, Command cmd ) { + private static void JoinHandler( Player player, Command cmd ) { string worldName = cmd.Next(); if ( worldName == null ) { CdJoin.PrintUsage( player ); @@ -2371,7 +2424,6 @@ static void JoinHandler ( Player player, Command cmd ) { if ( worlds.Length > 1 ) { player.MessageManyMatches( "world", worlds ); - } else if ( worlds.Length == 1 ) { World world = worlds[0]; player.LastUsedWorldName = world.Name; @@ -2387,16 +2439,17 @@ static void JoinHandler ( Player player, Command cmd ) { player.Message( "ERROR: Failed to join world. See log for details." ); } break; + case SecurityCheckResult.BlackListed: player.Message( "Cannot join world {0}&S: you are blacklisted.", world.ClassyName ); break; + case SecurityCheckResult.RankTooLow: player.Message( "Cannot join world {0}&S: must be {1}+", world.ClassyName, world.AccessSecurity.MinRank.ClassyName ); break; } - } else { // no worlds found - see if player meant to type in "/Join" and not "/TP" Player[] players = Server.FindPlayers( player, worldName, true ); @@ -2410,12 +2463,11 @@ static void JoinHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Join #region WLock, WUnlock - static readonly CommandDescriptor CdWorldLock = new CommandDescriptor { + private static readonly CommandDescriptor CdWorldLock = new CommandDescriptor { Name = "WLock", Aliases = new[] { "lock" }, Category = CommandCategory.World, @@ -2430,7 +2482,7 @@ static void JoinHandler ( Player player, Command cmd ) { Handler = WorldLockHandler }; - static void WorldLockHandler ( Player player, Command cmd ) { + private static void WorldLockHandler( Player player, Command cmd ) { string worldName = cmd.Next(); World world; @@ -2448,12 +2500,11 @@ static void WorldLockHandler ( Player player, Command cmd ) { return; } else { world = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( world == null ) return; + if ( world == null ) + return; } - } else if ( player.World != null ) { world = player.World; - } else { player.Message( "When called from console, /WLock requires a world name." ); return; @@ -2466,8 +2517,7 @@ static void WorldLockHandler ( Player player, Command cmd ) { } } - - static readonly CommandDescriptor CdWorldUnlock = new CommandDescriptor { + private static readonly CommandDescriptor CdWorldUnlock = new CommandDescriptor { Name = "WUnlock", Aliases = new[] { "unlock" }, Category = CommandCategory.World, @@ -2478,7 +2528,7 @@ static void WorldLockHandler ( Player player, Command cmd ) { Handler = WorldUnlockHandler }; - static void WorldUnlockHandler ( Player player, Command cmd ) { + private static void WorldUnlockHandler( Player player, Command cmd ) { string worldName = cmd.Next(); World world; @@ -2496,12 +2546,11 @@ static void WorldUnlockHandler ( Player player, Command cmd ) { return; } else { world = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( world == null ) return; + if ( world == null ) + return; } - } else if ( player.World != null ) { world = player.World; - } else { player.Message( "When called from console, /WLock requires a world name." ); return; @@ -2514,26 +2563,26 @@ static void WorldUnlockHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion WLock, WUnlock #region Spawn - static readonly CommandDescriptor CdSpawn = new CommandDescriptor { + private static readonly CommandDescriptor CdSpawn = new CommandDescriptor { Name = "Spawn", Category = CommandCategory.World, Help = "Teleports you to the current map's spawn.", Handler = SpawnHandler }; - static void SpawnHandler ( Player player, Command cmd ) { - if ( player.World == null ) PlayerOpException.ThrowNoWorld( player ); + private static void SpawnHandler( Player player, Command cmd ) { + if ( player.World == null ) + PlayerOpException.ThrowNoWorld( player ); player.TeleportTo( player.World.LoadMap().Spawn ); } - #endregion + #endregion Spawn - static readonly CommandDescriptor CdWorldSet = new CommandDescriptor { + private static readonly CommandDescriptor CdWorldSet = new CommandDescriptor { Name = "WSet", Category = CommandCategory.World, IsConsoleSafe = true, @@ -2551,7 +2600,7 @@ static void SpawnHandler ( Player player, Command cmd ) { Handler = WorldSetHandler }; - static void WorldSetHandler ( Player player, Command cmd ) { + private static void WorldSetHandler( Player player, Command cmd ) { string worldName = cmd.Next(); string varName = cmd.Next(); string value = cmd.NextAll(); @@ -2561,7 +2610,8 @@ static void WorldSetHandler ( Player player, Command cmd ) { } World world = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( world == null ) return; + if ( world == null ) + return; switch ( varName.ToLower() ) { case "hide": @@ -2602,7 +2652,6 @@ static void WorldSetHandler ( Player player, Command cmd ) { if ( String.IsNullOrEmpty( value ) ) { player.Message( GetBackupSettingsString( world ) ); return; - } else if ( value.Equals( "off", StringComparison.OrdinalIgnoreCase ) || value.StartsWith( "disable", StringComparison.OrdinalIgnoreCase ) ) { // Disable backups on the world @@ -2621,7 +2670,6 @@ static void WorldSetHandler ( Player player, Command cmd ) { } else { world.BackupEnabledState = YesNoAuto.Auto; } - } else if ( value.TryParseMiniTimespan( out backupInterval ) ) { if ( backupInterval == TimeSpan.Zero ) { // Set world's backup interval to 0, which is equivalent to disabled @@ -2671,14 +2719,12 @@ static void WorldSetHandler ( Player player, Command cmd ) { } } - - static void MessageSameBackupSettings ( Player player, World world ) { + private static void MessageSameBackupSettings( Player player, World world ) { player.Message( "Backup settings for {0}&S are already \"{1}\"", world.ClassyName, world.BackupSettingDescription ); } - - static string GetBackupSettingsString ( World world ) { + private static string GetBackupSettingsString( World world ) { switch ( world.BackupEnabledState ) { case YesNoAuto.Yes: return String.Format( "World {0}&S is backed up every {1}", @@ -2704,7 +2750,7 @@ static string GetBackupSettingsString ( World world ) { #region Worlds - static readonly CommandDescriptor CdWorlds = new CommandDescriptor { + private static readonly CommandDescriptor CdWorlds = new CommandDescriptor { Name = "Worlds", Category = CommandCategory.World | CommandCategory.Info, IsConsoleSafe = true, @@ -2719,7 +2765,7 @@ static string GetBackupSettingsString ( World world ) { Handler = WorldsHandler }; - static void WorldsHandler ( Player player, Command cmd ) { + private static void WorldsHandler( Player player, Command cmd ) { string param = cmd.Next(); World[] worlds; @@ -2731,7 +2777,6 @@ static void WorldsHandler ( Player player, Command cmd ) { listName = "available worlds"; extraParam = ""; worlds = WorldManager.Worlds.Where( w => !w.IsRealm ).Where( player.CanSee ).ToArray(); - } else { switch ( Char.ToLower( param[0] ) ) { case 'a': @@ -2739,21 +2784,25 @@ static void WorldsHandler ( Player player, Command cmd ) { extraParam = "all "; worlds = WorldManager.Worlds; break; + case 'h': listName = "hidden worlds"; extraParam = "hidden "; worlds = WorldManager.Worlds.Where( w => !player.CanSee( w ) ).ToArray(); break; + case 'r': listName = "Available Realms"; extraParam = "realms"; worlds = WorldManager.Worlds.Where( w => w.IsRealm ).ToArray(); break; + case 'p': listName = "populated worlds"; extraParam = "populated "; worlds = WorldManager.Worlds.Where( w => w.Players.Any( player.CanSee ) ).ToArray(); break; + case '@': if ( param.Length == 1 ) { CdWorlds.PrintUsage( player ); @@ -2770,6 +2819,7 @@ static void WorldsHandler ( Player player, Command cmd ) { worlds = WorldManager.Worlds.Where( w => ( w.BuildSecurity.MinRank <= rank ) && player.CanSee( w ) ) .ToArray(); break; + default: CdWorlds.PrintUsage( player ); return; @@ -2782,11 +2832,9 @@ static void WorldsHandler ( Player player, Command cmd ) { if ( worlds.Length == 0 ) { player.Message( "There are no {0}.", listName ); - } else if ( worlds.Length <= WorldNamesPerPage || player.IsSuper ) { player.MessagePrefixed( "&S ", "&SThere are {0} {1}: {2}", worlds.Length, listName, worlds.JoinToClassyString() ); - } else { if ( offset >= worlds.Length ) { offset = Math.Max( 0, worlds.Length - WorldNamesPerPage ); @@ -2805,12 +2853,11 @@ static void WorldsHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion Worlds #region WorldAccess - static readonly CommandDescriptor CdWorldAccess = new CommandDescriptor { + private static readonly CommandDescriptor CdWorldAccess = new CommandDescriptor { Name = "WAccess", Category = CommandCategory.World, IsConsoleSafe = true, @@ -2822,8 +2869,9 @@ static void WorldsHandler ( Player player, Command cmd ) { Handler = WorldAccessHandler }; - static void WorldAccessHandler ( [NotNull] Player player, Command cmd ) { - if ( player == null ) throw new ArgumentNullException( "player" ); + private static void WorldAccessHandler( [NotNull] Player player, Command cmd ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); string worldName = cmd.Next(); // Print information about the current world @@ -2838,8 +2886,8 @@ static void WorldAccessHandler ( [NotNull] Player player, Command cmd ) { // Find a world by name World world = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( world == null ) return; - + if ( world == null ) + return; string name = cmd.Next(); if ( name == null ) { @@ -2860,7 +2908,8 @@ static void WorldAccessHandler ( [NotNull] Player player, Command cmd ) { break; } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches( player, name.Substring( 1 ) ); - if ( info == null ) return; + if ( info == null ) + return; // prevent players from whitelisting themselves to bypass protection if ( player.Info == info && !player.Info.Rank.AllowSecurityCircumvention ) { @@ -2885,7 +2934,8 @@ static void WorldAccessHandler ( [NotNull] Player player, Command cmd ) { } Player target = info.PlayerObject; - if ( target == player ) target = null; // to avoid duplicate messages + if ( target == player ) + target = null; // to avoid duplicate messages switch ( world.AccessSecurity.Include( info ) ) { case PermissionOverride.Deny: @@ -2938,7 +2988,8 @@ static void WorldAccessHandler ( [NotNull] Player player, Command cmd ) { break; } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches( player, name.Substring( 1 ) ); - if ( info == null ) return; + if ( info == null ) + return; if ( world.AccessSecurity.CheckDetailed( info ) == SecurityCheckResult.RankTooHigh || world.AccessSecurity.CheckDetailed( info ) == SecurityCheckResult.RankTooLow ) { @@ -2948,7 +2999,8 @@ static void WorldAccessHandler ( [NotNull] Player player, Command cmd ) { } Player target = info.PlayerObject; - if ( target == player ) target = null; // to avoid duplicate messages + if ( target == player ) + target = null; // to avoid duplicate messages switch ( world.AccessSecurity.Exclude( info ) ) { case PermissionOverride.Deny: @@ -2999,13 +3051,11 @@ static void WorldAccessHandler ( [NotNull] Player player, Command cmd ) { Rank rank = RankManager.FindRank( name ); if ( rank == null ) { player.MessageNoRank( name ); - } else if ( !player.Info.Rank.AllowSecurityCircumvention && world.AccessSecurity.MinRank > rank && world.AccessSecurity.MinRank > player.Info.Rank ) { player.Message( "&WYou must be ranked {0}&W+ to lower the access rank for world {1}", world.AccessSecurity.MinRank.ClassyName, world.ClassyName ); - } else { // list players who are redundantly blacklisted var exceptionList = world.AccessSecurity.ExceptionList; @@ -3052,12 +3102,11 @@ static void WorldAccessHandler ( [NotNull] Player player, Command cmd ) { } } - #endregion - + #endregion WorldAccess #region WorldBuild - static readonly CommandDescriptor CdWorldBuild = new CommandDescriptor { + private static readonly CommandDescriptor CdWorldBuild = new CommandDescriptor { Name = "WBuild", Category = CommandCategory.World, IsConsoleSafe = true, @@ -3069,8 +3118,9 @@ static void WorldAccessHandler ( [NotNull] Player player, Command cmd ) { Handler = WorldBuildHandler }; - static void WorldBuildHandler ( [NotNull] Player player, Command cmd ) { - if ( player == null ) throw new ArgumentNullException( "player" ); + private static void WorldBuildHandler( [NotNull] Player player, Command cmd ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); string worldName = cmd.Next(); // Print information about the current world @@ -3085,8 +3135,8 @@ static void WorldBuildHandler ( [NotNull] Player player, Command cmd ) { // Find a world by name World world = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( world == null ) return; - + if ( world == null ) + return; string name = cmd.Next(); if ( name == null ) { @@ -3103,7 +3153,8 @@ static void WorldBuildHandler ( [NotNull] Player player, Command cmd ) { break; } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches( player, name.Substring( 1 ) ); - if ( info == null ) return; + if ( info == null ) + return; // prevent players from whitelisting themselves to bypass protection if ( player.Info == info && !player.Info.Rank.AllowSecurityCircumvention ) { @@ -3128,7 +3179,8 @@ static void WorldBuildHandler ( [NotNull] Player player, Command cmd ) { } Player target = info.PlayerObject; - if ( target == player ) target = null; // to avoid duplicate messages + if ( target == player ) + target = null; // to avoid duplicate messages switch ( world.BuildSecurity.Include( info ) ) { case PermissionOverride.Deny: @@ -3181,7 +3233,8 @@ static void WorldBuildHandler ( [NotNull] Player player, Command cmd ) { break; } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches( player, name.Substring( 1 ) ); - if ( info == null ) return; + if ( info == null ) + return; if ( world.BuildSecurity.CheckDetailed( info ) == SecurityCheckResult.RankTooHigh || world.BuildSecurity.CheckDetailed( info ) == SecurityCheckResult.RankTooLow ) { @@ -3191,7 +3244,8 @@ static void WorldBuildHandler ( [NotNull] Player player, Command cmd ) { } Player target = info.PlayerObject; - if ( target == player ) target = null; // to avoid duplicate messages + if ( target == player ) + target = null; // to avoid duplicate messages switch ( world.BuildSecurity.Exclude( info ) ) { case PermissionOverride.Deny: @@ -3296,12 +3350,11 @@ static void WorldBuildHandler ( [NotNull] Player player, Command cmd ) { } } - #endregion - + #endregion WorldBuild #region WorldFlush - static readonly CommandDescriptor CdWorldFlush = new CommandDescriptor { + private static readonly CommandDescriptor CdWorldFlush = new CommandDescriptor { Name = "WFlush", Category = CommandCategory.World, IsConsoleSafe = true, @@ -3312,14 +3365,14 @@ static void WorldBuildHandler ( [NotNull] Player player, Command cmd ) { Handler = WorldFlushHandler }; - static void WorldFlushHandler ( Player player, Command cmd ) { + private static void WorldFlushHandler( Player player, Command cmd ) { string worldName = cmd.Next(); World world = player.World; if ( worldName != null ) { world = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( world == null ) return; - + if ( world == null ) + return; } else if ( world == null ) { player.Message( "When using /WFlush from console, you must specify a world name." ); return; @@ -3337,12 +3390,11 @@ static void WorldFlushHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion WorldFlush #region WorldInfo - static readonly CommandDescriptor CdWorldInfo = new CommandDescriptor { + private static readonly CommandDescriptor CdWorldInfo = new CommandDescriptor { Name = "WInfo", Aliases = new[] { "mapinfo" }, Category = CommandCategory.World | CommandCategory.Info, @@ -3354,7 +3406,7 @@ static void WorldFlushHandler ( Player player, Command cmd ) { Handler = WorldInfoHandler }; - static void WorldInfoHandler ( Player player, Command cmd ) { + private static void WorldInfoHandler( Player player, Command cmd ) { string worldName = cmd.Next(); if ( worldName == null ) { if ( player.World == null ) { @@ -3366,7 +3418,8 @@ static void WorldInfoHandler ( Player player, Command cmd ) { } World world = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( world == null ) return; + if ( world == null ) + return; player.Message( "World {0}&S has {1} player(s) on.", world.ClassyName, @@ -3441,12 +3494,11 @@ static void WorldInfoHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion WorldInfo #region WorldLoad - static readonly CommandDescriptor CdWorldLoad = new CommandDescriptor { + private static readonly CommandDescriptor CdWorldLoad = new CommandDescriptor { Name = "WLoad", Aliases = new[] { "wadd" }, Category = CommandCategory.World, @@ -3466,8 +3518,7 @@ static void WorldInfoHandler ( Player player, Command cmd ) { Handler = WorldLoadHandler }; - - static void WorldLoadHandler ( Player player, Command cmd ) { + private static void WorldLoadHandler( Player player, Command cmd ) { string fileName = cmd.Next(); string worldName = cmd.Next(); @@ -3483,7 +3534,8 @@ static void WorldLoadHandler ( Player player, Command cmd ) { } string fullFileName = WorldManager.FindMapFile( player, fileName ); - if ( fullFileName == null ) return; + if ( fullFileName == null ) + return; // Loading map into current world if ( worldName == null ) { @@ -3511,8 +3563,6 @@ static void WorldLoadHandler ( Player player, Command cmd ) { Logger.Log( LogType.UserActivity, "{0} loaded new map for world \"{1}\" from {2}", player.Name, world.Name, fileName ); - - } else { // Loading to some other (or new) world if ( !World.IsValidName( worldName ) ) { @@ -3584,7 +3634,6 @@ static void WorldLoadHandler ( Player player, Command cmd ) { Logger.Log( LogType.UserActivity, "{0} loaded new map for world \"{1}\" from {2}", player.Name, world.Name, fullFileName ); - } else { // Adding a new world string targetFullFileName = Path.Combine( Paths.MapPath, worldName + ".fcm" ); @@ -3649,12 +3698,11 @@ static void WorldLoadHandler ( Player player, Command cmd ) { Server.RequestGC(); } - #endregion - + #endregion WorldLoad #region WorldMain - static readonly CommandDescriptor CdWorldMain = new CommandDescriptor { + private static readonly CommandDescriptor CdWorldMain = new CommandDescriptor { Name = "WMain", Category = CommandCategory.World, IsConsoleSafe = true, @@ -3666,7 +3714,7 @@ static void WorldLoadHandler ( Player player, Command cmd ) { Handler = WorldMainHandler }; - static void WorldMainHandler ( Player player, Command cmd ) { + private static void WorldMainHandler( Player player, Command cmd ) { string param = cmd.Next(); if ( param == null ) { player.Message( "Main world is {0}", WorldManager.MainWorld.ClassyName ); @@ -3707,7 +3755,6 @@ static void WorldMainHandler ( Player player, Command cmd ) { SetRankMainWorld( player, rank, world ); } } - } else { World world = WorldManager.FindWorldOrPrintMatches( player, param ); if ( world != null ) { @@ -3716,8 +3763,7 @@ static void WorldMainHandler ( Player player, Command cmd ) { } } - - static void SetRankMainWorld ( Player player, Rank rank, World world ) { + private static void SetRankMainWorld( Player player, Rank rank, World world ) { if ( world == rank.MainWorld ) { player.Message( "World {0}&S is already set as main for {1}&S.", world.ClassyName, rank.ClassyName ); @@ -3755,11 +3801,9 @@ static void SetRankMainWorld ( Player player, Rank rank, World world ) { player.Name, world.Name, rank.Name ); } - - static void SetMainWorld ( Player player, World world ) { + private static void SetMainWorld( Player player, World world ) { if ( world == WorldManager.MainWorld ) { player.Message( "World {0}&S is already set as main.", world.ClassyName ); - } else if ( !player.Info.Rank.AllowSecurityCircumvention && !player.CanJoin( world ) ) { // Prevent players from exploiting /WMain to gain access to restricted maps switch ( world.AccessSecurity.CheckDetailed( player.Info ) ) { @@ -3767,11 +3811,11 @@ static void SetMainWorld ( Player player, World world ) { case SecurityCheckResult.RankTooLow: player.Message( "You are not allowed to set {0}&S as the main world (by rank).", world.ClassyName ); return; + case SecurityCheckResult.BlackListed: player.Message( "You are not allowed to set {0}&S as the main world (blacklisted).", world.ClassyName ); return; } - } else { if ( world.AccessSecurity.HasRestrictions ) { world.AccessSecurity.Reset(); @@ -3797,12 +3841,11 @@ static void SetMainWorld ( Player player, World world ) { } } - #endregion - + #endregion WorldMain #region WorldRename - static readonly CommandDescriptor CdWorldRename = new CommandDescriptor { + private static readonly CommandDescriptor CdWorldRename = new CommandDescriptor { Name = "WRename", Category = CommandCategory.World, IsConsoleSafe = true, @@ -3812,7 +3855,7 @@ static void SetMainWorld ( Player player, World world ) { Handler = WorldRenameHandler }; - static void WorldRenameHandler ( Player player, Command cmd ) { + private static void WorldRenameHandler( Player player, Command cmd ) { string oldName = cmd.Next(); string newName = cmd.Next(); if ( oldName == null || newName == null ) { @@ -3821,7 +3864,8 @@ static void WorldRenameHandler ( Player player, Command cmd ) { } World oldWorld = WorldManager.FindWorldOrPrintMatches( player, oldName ); - if ( oldWorld == null ) return; + if ( oldWorld == null ) + return; oldName = oldWorld.Name; if ( !World.IsValidName( newName ) ) { @@ -3847,16 +3891,20 @@ static void WorldRenameHandler ( Player player, Command cmd ) { case WorldOpExceptionCode.NoChangeNeeded: player.MessageNow( "WRename: World is already named \"{0}\"", oldName ); return; + case WorldOpExceptionCode.DuplicateWorldName: player.MessageNow( "WRename: Another world named \"{0}\" already exists.", newName ); return; + case WorldOpExceptionCode.InvalidWorldName: player.MessageNow( "WRename: Invalid world name: \"{0}\"", newName ); return; + case WorldOpExceptionCode.MapMoveError: player.MessageNow( "WRename: World \"{0}\" was renamed to \"{1}\", but the map file could not be moved due to an error: {2}", oldName, newName, ex.InnerException ); return; + default: player.MessageNow( "&WWRename: Unexpected error renaming world \"{0}\": {1}", oldName, ex.Message ); Logger.Log( LogType.Error, @@ -3875,12 +3923,11 @@ static void WorldRenameHandler ( Player player, Command cmd ) { player.ClassyName, oldName, newName ); } - #endregion - + #endregion WorldRename #region WorldSave - static readonly CommandDescriptor CdWorldSave = new CommandDescriptor { + private static readonly CommandDescriptor CdWorldSave = new CommandDescriptor { Name = "WSave", Aliases = new[] { "save" }, Category = CommandCategory.World, @@ -3893,7 +3940,7 @@ static void WorldRenameHandler ( Player player, Command cmd ) { Handler = WorldSaveHandler }; - static void WorldSaveHandler ( Player player, Command cmd ) { + private static void WorldSaveHandler( Player player, Command cmd ) { string p1 = cmd.Next(), p2 = cmd.Next(); if ( p1 == null ) { CdWorldSave.PrintUsage( player ); @@ -3910,7 +3957,8 @@ static void WorldSaveHandler ( Player player, Command cmd ) { } } else { world = WorldManager.FindWorldOrPrintMatches( player, p1 ); - if ( world == null ) return; + if ( world == null ) + return; fileName = p2; } @@ -3977,12 +4025,11 @@ static void WorldSaveHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion WorldSave #region WorldUnload - static readonly CommandDescriptor CdWorldUnload = new CommandDescriptor { + private static readonly CommandDescriptor CdWorldUnload = new CommandDescriptor { Name = "WUnload", Aliases = new[] { "wremove", "wdelete" }, Category = CommandCategory.World, @@ -3994,7 +4041,7 @@ static void WorldSaveHandler ( Player player, Command cmd ) { Handler = WorldUnloadHandler }; - static void WorldUnloadHandler ( Player player, Command cmd ) { + private static void WorldUnloadHandler( Player player, Command cmd ) { string worldName = cmd.Next(); if ( worldName == null ) { CdWorldUnload.PrintUsage( player ); @@ -4002,7 +4049,8 @@ static void WorldUnloadHandler ( Player player, Command cmd ) { } World world = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( world == null ) return; + if ( world == null ) + return; try { WorldManager.RemoveWorld( world ); @@ -4013,10 +4061,12 @@ static void WorldUnloadHandler ( Player player, Command cmd ) { "Assign a new main world before deleting this one.", world.ClassyName ); return; + case WorldOpExceptionCode.WorldNotFound: player.MessageNow( "&WWorld {0}&W is already unloaded.", world.ClassyName ); return; + default: player.MessageNow( "&WUnexpected error occured while unloading world {0}&W: {1}", world.ClassyName, ex.GetType().Name ); @@ -4040,6 +4090,6 @@ static void WorldUnloadHandler ( Player player, Command cmd ) { Server.RequestGC(); } - #endregion + #endregion WorldUnload } } \ No newline at end of file diff --git a/fCraft/Commands/ZoneCommands.cs b/fCraft/Commands/ZoneCommands.cs index 81972bd..87ad291 100644 --- a/fCraft/Commands/ZoneCommands.cs +++ b/fCraft/Commands/ZoneCommands.cs @@ -1,15 +1,13 @@ // Copyright 2009-2013 Matvei Stefarov using System; using fCraft.MapConversion; -using System.Collections.Generic; -using fCraft.Events; -using fCraft.Doors; namespace fCraft { + /// Contains commands related to zone management. - static class ZoneCommands { + internal static class ZoneCommands { - internal static void Init () { + internal static void Init() { CommandManager.RegisterCommand( CdZoneAdd ); CommandManager.RegisterCommand( CdZoneEdit ); CommandManager.RegisterCommand( CdZoneInfo ); @@ -19,9 +17,10 @@ internal static void Init () { CommandManager.RegisterCommand( CdZoneRename ); CommandManager.RegisterCommand( CdZoneTest ); } + #region ZoneAdd - static readonly CommandDescriptor CdZoneAdd = new CommandDescriptor { + private static readonly CommandDescriptor CdZoneAdd = new CommandDescriptor { Name = "ZAdd", Category = CommandCategory.Zone, Aliases = new[] { "zone" }, @@ -33,9 +32,10 @@ internal static void Init () { Handler = ZoneAddHandler }; - static void ZoneAddHandler ( Player player, Command cmd ) { + private static void ZoneAddHandler( Player player, Command cmd ) { World playerWorld = player.World; - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); string givenZoneName = cmd.Next(); if ( givenZoneName == null ) { @@ -50,6 +50,7 @@ static void ZoneAddHandler ( Player player, Command cmd ) { player.Message( "Cannot add zones to world {0}&S: You are barred from building here.", playerWorld.ClassyName ); return; + case SecurityCheckResult.RankTooLow: player.Message( "Cannot add zones to world {0}&S: You are not allowed to build here.", playerWorld.ClassyName ); @@ -67,7 +68,8 @@ static void ZoneAddHandler ( Player player, Command cmd ) { // Find the target player PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches( player, givenZoneName ); - if ( info == null ) return; + if ( info == null ) + return; // Make sure that the name is not taken already. // If a zone named after the player already exists, try adding a number after the name (e.g. "Notch2") @@ -104,8 +106,8 @@ static void ZoneAddHandler ( Player player, Command cmd ) { if ( minRank != null ) { string name; while ( ( name = cmd.Next() ) != null ) { - - if ( name.Length == 0 ) continue; + if ( name.Length == 0 ) + continue; if ( name.ToLower().StartsWith( "msg=" ) ) { newZone.Message = name.Substring( 4 ) + " " + ( cmd.NextAll() ?? "" ); @@ -114,7 +116,8 @@ static void ZoneAddHandler ( Player player, Command cmd ) { } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches( player, name.Substring( 1 ) ); - if ( info == null ) return; + if ( info == null ) + return; if ( name.StartsWith( "+" ) ) { newZone.Controller.Include( info ); @@ -133,9 +136,10 @@ static void ZoneAddHandler ( Player player, Command cmd ) { player.SelectionStart( 2, ZoneAddCallback, newZone, CdZoneAdd.Permissions ); } - static void ZoneAddCallback ( Player player, Vector3I[] marks, object tag ) { + private static void ZoneAddCallback( Player player, Vector3I[] marks, object tag ) { World playerWorld = player.World; - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); if ( !player.Info.Rank.AllowSecurityCircumvention ) { SecurityCheckResult buildCheck = playerWorld.BuildSecurity.CheckDetailed( player.Info ); @@ -144,6 +148,7 @@ static void ZoneAddCallback ( Player player, Vector3I[] marks, object tag ) { player.Message( "Cannot add zones to world {0}&S: You are barred from building here.", playerWorld.ClassyName ); return; + case SecurityCheckResult.RankTooLow: player.Message( "Cannot add zones to world {0}&S: You are not allowed to build here.", playerWorld.ClassyName ); @@ -176,12 +181,11 @@ static void ZoneAddCallback ( Player player, Vector3I[] marks, object tag ) { } } - #endregion - + #endregion ZoneAdd #region ZoneEdit - static readonly CommandDescriptor CdZoneEdit = new CommandDescriptor { + private static readonly CommandDescriptor CdZoneEdit = new CommandDescriptor { Name = "ZEdit", Category = CommandCategory.Zone, Permissions = new[] { Permission.ManageZones }, @@ -192,7 +196,7 @@ static void ZoneAddCallback ( Player player, Vector3I[] marks, object tag ) { Handler = ZoneEditHandler }; - static void ZoneEditHandler ( Player player, Command cmd ) { + private static void ZoneEditHandler( Player player, Command cmd ) { bool changesWereMade = false; string zoneName = cmd.Next(); if ( zoneName == null ) { @@ -214,7 +218,8 @@ static void ZoneEditHandler ( Player player, Command cmd ) { break; } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches( player, name.Substring( 1 ) ); - if ( info == null ) return; + if ( info == null ) + return; // prevent players from whitelisting themselves to bypass protection if ( !player.Info.Rank.AllowSecurityCircumvention && player.Info == info ) { @@ -231,42 +236,45 @@ static void ZoneEditHandler ( Player player, Command cmd ) { info.ClassyName, zone.ClassyName ); changesWereMade = true; break; + case PermissionOverride.None: player.Message( "{0}&S is now included in zone {1}", info.ClassyName, zone.ClassyName ); changesWereMade = true; break; + case PermissionOverride.Allow: player.Message( "{0}&S is already included in zone {1}", info.ClassyName, zone.ClassyName ); break; } - } else if ( name.StartsWith( "-" ) ) { if ( name.Length == 1 ) { CdZoneEdit.PrintUsage( player ); break; } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches( player, name.Substring( 1 ) ); - if ( info == null ) return; + if ( info == null ) + return; switch ( zone.Controller.Exclude( info ) ) { case PermissionOverride.Deny: player.Message( "{0}&S is already excluded from zone {1}", info.ClassyName, zone.ClassyName ); break; + case PermissionOverride.None: player.Message( "{0}&S is now excluded from zone {1}", info.ClassyName, zone.ClassyName ); changesWereMade = true; break; + case PermissionOverride.Allow: player.Message( "{0}&S is no longer included in zone {1}", info.ClassyName, zone.ClassyName ); changesWereMade = true; break; } - } else if ( name.ToLower().StartsWith( "msg=" ) ) { zone.Message = name.Substring( 4 ) + " " + ( cmd.NextAll() ?? "" ); changesWereMade = true; @@ -303,10 +311,9 @@ static void ZoneEditHandler ( Player player, Command cmd ) { #endregion ZoneEdit - #region ZoneInfo - static readonly CommandDescriptor CdZoneInfo = new CommandDescriptor { + private static readonly CommandDescriptor CdZoneInfo = new CommandDescriptor { Name = "ZInfo", Aliases = new[] { "ZoneInfo" }, Category = CommandCategory.Zone | CommandCategory.Info, @@ -316,7 +323,7 @@ static void ZoneEditHandler ( Player player, Command cmd ) { Handler = ZoneInfoHandler }; - static void ZoneInfoHandler ( Player player, Command cmd ) { + private static void ZoneInfoHandler( Player player, Command cmd ) { string zoneName = cmd.Next(); if ( zoneName == null ) { player.Message( "No zone name specified. See &H/Help ZInfo" ); @@ -373,12 +380,11 @@ static void ZoneInfoHandler ( Player player, Command cmd ) { player.Message( " Zone has no custom deny build message" ); } - #endregion - + #endregion ZoneInfo #region ZoneList - static readonly CommandDescriptor CdZoneList = new CommandDescriptor { + private static readonly CommandDescriptor CdZoneList = new CommandDescriptor { Name = "Zones", Category = CommandCategory.Zone | CommandCategory.Info, IsConsoleSafe = true, @@ -388,18 +394,17 @@ static void ZoneInfoHandler ( Player player, Command cmd ) { Handler = ZoneListHandler }; - static void ZoneListHandler ( Player player, Command cmd ) { + private static void ZoneListHandler( Player player, Command cmd ) { World world = player.World; string worldName = cmd.Next(); if ( worldName != null ) { world = WorldManager.FindWorldOrPrintMatches( player, worldName ); - if ( world == null ) return; + if ( world == null ) + return; player.Message( "List of zones on {0}&S:", world.ClassyName ); - } else if ( world != null ) { player.Message( "List of zones on this world:" ); - } else { player.Message( "When used from console, &H/Zones&S command requires a world name." ); return; @@ -430,12 +435,11 @@ static void ZoneListHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion ZoneList #region ZoneMark - static readonly CommandDescriptor CdZoneMark = new CommandDescriptor { + private static readonly CommandDescriptor CdZoneMark = new CommandDescriptor { Name = "ZMark", Category = CommandCategory.Zone | CommandCategory.Building, Usage = "/ZMark ZoneName", @@ -443,7 +447,7 @@ static void ZoneListHandler ( Player player, Command cmd ) { Handler = ZoneMarkHandler }; - static void ZoneMarkHandler ( Player player, Command cmd ) { + private static void ZoneMarkHandler( Player player, Command cmd ) { if ( player.SelectionMarksExpected == 0 ) { player.MessageNow( "Cannot use ZMark - no selection in progress." ); } else if ( player.SelectionMarksExpected == 2 ) { @@ -467,12 +471,11 @@ static void ZoneMarkHandler ( Player player, Command cmd ) { } } - #endregion - + #endregion ZoneMark #region ZoneRemove - static readonly CommandDescriptor CdZoneRemove = new CommandDescriptor { + private static readonly CommandDescriptor CdZoneRemove = new CommandDescriptor { Name = "ZRemove", Aliases = new[] { "zdelete" }, Category = CommandCategory.Zone, @@ -482,7 +485,7 @@ static void ZoneMarkHandler ( Player player, Command cmd ) { Handler = ZoneRemoveHandler }; - static void ZoneRemoveHandler ( Player player, Command cmd ) { + private static void ZoneRemoveHandler( Player player, Command cmd ) { string zoneName = cmd.Next(); if ( zoneName == null ) { CdZoneRemove.PrintUsage( player ); @@ -497,6 +500,7 @@ static void ZoneRemoveHandler ( Player player, Command cmd ) { case SecurityCheckResult.BlackListed: player.Message( "You are not allowed to remove zone {0}: you are blacklisted.", zone.ClassyName ); return; + case SecurityCheckResult.RankTooLow: player.Message( "You are not allowed to remove zone {0}.", zone.ClassyName ); return; @@ -510,18 +514,16 @@ static void ZoneRemoveHandler ( Player player, Command cmd ) { if ( zones.Remove( zone.Name ) ) { player.Message( "Zone \"{0}\" removed.", zone.Name ); } - } else { player.MessageNoZone( zoneName ); } } - #endregion - + #endregion ZoneRemove #region ZoneRename - static readonly CommandDescriptor CdZoneRename = new CommandDescriptor { + private static readonly CommandDescriptor CdZoneRename = new CommandDescriptor { Name = "ZRename", Category = CommandCategory.Zone, Permissions = new[] { Permission.ManageZones }, @@ -530,9 +532,10 @@ static void ZoneRemoveHandler ( Player player, Command cmd ) { Handler = ZoneRenameHandler }; - static void ZoneRenameHandler ( Player player, Command cmd ) { + private static void ZoneRenameHandler( Player player, Command cmd ) { World playerWorld = player.World; - if ( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); + if ( playerWorld == null ) + PlayerOpException.ThrowNoWorld( player ); // make sure that both parameters are given string oldName = cmd.Next(); @@ -581,12 +584,11 @@ static void ZoneRenameHandler ( Player player, Command cmd ) { player.Name, fullOldName, newName, playerWorld.Name ); } - #endregion - + #endregion ZoneRename #region ZoneTest - static readonly CommandDescriptor CdZoneTest = new CommandDescriptor { + private static readonly CommandDescriptor CdZoneTest = new CommandDescriptor { Name = "ZTest", Category = CommandCategory.Zone | CommandCategory.Info, RepeatableSelection = true, @@ -594,12 +596,12 @@ static void ZoneRenameHandler ( Player player, Command cmd ) { Handler = ZoneTestHandler }; - static void ZoneTestHandler ( Player player, Command cmd ) { + private static void ZoneTestHandler( Player player, Command cmd ) { player.SelectionStart( 1, ZoneTestCallback, null ); player.Message( "Click the block that you would like to test." ); } - static void ZoneTestCallback ( Player player, Vector3I[] marks, object tag ) { + private static void ZoneTestCallback( Player player, Vector3I[] marks, object tag ) { Zone[] allowed, denied; if ( player.WorldMap.Zones.CheckDetailed( marks[0], player, out allowed, out denied ) ) { foreach ( Zone zone in allowed ) { @@ -615,6 +617,6 @@ static void ZoneTestCallback ( Player player, Vector3I[] marks, object tag ) { } } - #endregion + #endregion ZoneTest } } \ No newline at end of file diff --git a/fCraft/Doors/Door.cs b/fCraft/Doors/Door.cs index 2329e03..976674e 100644 --- a/fCraft/Doors/Door.cs +++ b/fCraft/Doors/Door.cs @@ -24,28 +24,32 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft.Drawing; -using System.Threading; using System.Runtime.Serialization; +using fCraft.Drawing; namespace fCraft.Doors { + public class Door { + public String Name { get; set; } + public String Creator { get; set; } + public DateTime Created { get; set; } + public String World { get; set; } + public Vector3I[] AffectedBlocks { get; set; } + public DoorRange Range { get; set; } - public Door () { + public Door() { //empty } - public Door ( String world, Vector3I[] affectedBlocks, String Name, String Creator ) { + public Door( String world, Vector3I[] affectedBlocks, String Name, String Creator ) { this.World = world; this.AffectedBlocks = affectedBlocks; this.Range = Door.CalculateRange( this ); @@ -54,7 +58,7 @@ public Door ( String world, Vector3I[] affectedBlocks, String Name, String Creat this.Created = DateTime.UtcNow; } - public static DoorRange CalculateRange ( Door Door ) { + public static DoorRange CalculateRange( Door Door ) { DoorRange range = new DoorRange( 0, 0, 0, 0, 0, 0 ); foreach ( Vector3I block in Door.AffectedBlocks ) { @@ -110,7 +114,7 @@ public static DoorRange CalculateRange ( Door Door ) { return range; } - public bool IsInRange ( Player player ) { + public bool IsInRange( Player player ) { if ( ( player.Position.X / 32 ) <= Range.Xmax && ( player.Position.X / 32 ) >= Range.Xmin ) { if ( ( player.Position.Y / 32 ) <= Range.Ymax && ( player.Position.Y / 32 ) >= Range.Ymin ) { if ( ( ( player.Position.Z / 32 ) - 1 ) <= Range.Zmax && ( ( player.Position.Z / 32 ) - 1 ) >= Range.Zmin ) { @@ -122,7 +126,7 @@ public bool IsInRange ( Player player ) { return false; } - public bool IsInRange ( Vector3I vector ) { + public bool IsInRange( Vector3I vector ) { if ( vector.X <= Range.Xmax && vector.X >= Range.Xmin ) { if ( vector.Y <= Range.Ymax && vector.Y >= Range.Ymin ) { if ( vector.Z <= Range.Zmax && vector.Z >= Range.Zmin ) { @@ -134,7 +138,7 @@ public bool IsInRange ( Vector3I vector ) { return false; } - public static String GenerateName ( World world ) { + public static String GenerateName( World world ) { if ( world.Map.Doors != null ) { if ( world.Map.Doors.Count > 0 ) { bool found = false; @@ -163,7 +167,7 @@ public static String GenerateName ( World world ) { return "Door1"; } - public static bool DoesNameExist ( World world, String name ) { + public static bool DoesNameExist( World world, String name ) { if ( world.Map.Doors != null ) { if ( world.Map.Doors.Count > 0 ) { foreach ( Door Door in world.Map.Doors ) { @@ -176,9 +180,8 @@ public static bool DoesNameExist ( World world, String name ) { return false; } - - public void Remove ( Player requester ) { + public void Remove( Player requester ) { NormalBrush brush = new NormalBrush( Block.Air, Block.Air ); DrawOperation removeOperation = new CuboidDrawOperation( requester ); removeOperation.AnnounceCompletion = false; @@ -189,7 +192,6 @@ public void Remove ( Player requester ) { this.AffectedBlocks[0] = new Vector3I( Range.Xmin, Range.Ymin, Range.Zmin ); this.AffectedBlocks[1] = new Vector3I( Range.Xmax, Range.Ymax, Range.Zmax ); - if ( !removeOperation.Prepare( this.AffectedBlocks ) ) { throw new DoorException( "Unable to remove Door." ); } @@ -201,7 +203,7 @@ public void Remove ( Player requester ) { } } - public string Serialize () { + public string Serialize() { SerializedData data = new SerializedData( this ); DataContractSerializer serializer = new DataContractSerializer( typeof( SerializedData ) ); System.IO.MemoryStream s = new System.IO.MemoryStream(); @@ -209,7 +211,7 @@ public string Serialize () { return Convert.ToBase64String( s.ToArray() ); } - public static Door Deserialize ( string name, string sdata, Map map ) { + public static Door Deserialize( string name, string sdata, Map map ) { byte[] bdata = Convert.FromBase64String( sdata ); Door Door = new Door(); DataContractSerializer serializer = new DataContractSerializer( typeof( SerializedData ) ); @@ -218,30 +220,41 @@ public static Door Deserialize ( string name, string sdata, Map map ) { data.UpdateDoor( Door ); return Door; } + [DataContract] private class SerializedData { + [DataMember] public String Name; + [DataMember] public String Creator; + [DataMember] public DateTime Created; + [DataMember] public String World; + [DataMember] public int XMin; + [DataMember] public int XMax; + [DataMember] public int YMin; + [DataMember] public int YMax; + [DataMember] public int ZMin; + [DataMember] public int ZMax; - public SerializedData ( Door Door ) { + public SerializedData( Door Door ) { lock ( Door ) { Name = Door.Name; Creator = Door.Creator; @@ -256,7 +269,7 @@ public SerializedData ( Door Door ) { } } - public void UpdateDoor ( Door Door ) { + public void UpdateDoor( Door Door ) { Door.Name = Name; Door.Creator = Creator; Door.Created = Created; @@ -265,4 +278,4 @@ public void UpdateDoor ( Door Door ) { } } } -} +} \ No newline at end of file diff --git a/fCraft/Doors/DoorException.cs b/fCraft/Doors/DoorException.cs index 60e75d9..ee48530 100644 --- a/fCraft/Doors/DoorException.cs +++ b/fCraft/Doors/DoorException.cs @@ -24,19 +24,16 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -namespace fCraft.Doors -{ - class DoorException : Exception - { - public DoorException(String message) - : base(message) - { +namespace fCraft.Doors { + + internal class DoorException : Exception { + + public DoorException( String message ) + : base( message ) { // Do nothing } } -} +} \ No newline at end of file diff --git a/fCraft/Doors/DoorHandler.cs b/fCraft/Doors/DoorHandler.cs index c1ac6e1..6586e92 100644 --- a/fCraft/Doors/DoorHandler.cs +++ b/fCraft/Doors/DoorHandler.cs @@ -24,22 +24,21 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Collections; +using System.Collections.Generic; namespace fCraft.Doors { - class DoorHandler { + internal class DoorHandler { private static DoorHandler instance; - private DoorHandler () { + private DoorHandler() { // Empty, singleton } - public static DoorHandler GetInstance () { + public static DoorHandler GetInstance() { if ( instance == null ) { instance = new DoorHandler(); Player.Clicked += new EventHandler( PlayerClickedDoor ); @@ -50,14 +49,16 @@ public static DoorHandler GetInstance () { } //cuboid over-fix? - public static void PlayerPlacedDoor ( object sender, Events.PlayerPlacingBlockEventArgs e ) { - if ( e.Map.Doors == null ) return; + public static void PlayerPlacedDoor( object sender, Events.PlayerPlacingBlockEventArgs e ) { + if ( e.Map.Doors == null ) + return; if ( e.Map.World != null ) { if ( e.Map != null ) { if ( e.Map.Doors.Count > 0 ) { lock ( e.Map.Doors.SyncRoot ) { foreach ( Door door in e.Map.Doors ) { - if ( e.Map == null ) break; + if ( e.Map == null ) + break; if ( door.IsInRange( e.Coords ) ) { e.Result = CanPlaceResult.Revert; } @@ -68,10 +69,12 @@ public static void PlayerPlacedDoor ( object sender, Events.PlayerPlacingBlockEv } } - public static void PlayerClickedDoor ( object sender, Events.PlayerClickedEventArgs e ) { + public static void PlayerClickedDoor( object sender, Events.PlayerClickedEventArgs e ) { if ( e.Action == ClickAction.Delete ) { - if ( e.Player.World.Map.Doors == null ) return; - if ( e.Player.IsMakingSelection ) return; + if ( e.Player.World.Map.Doors == null ) + return; + if ( e.Player.IsMakingSelection ) + return; lock ( openDoorsLock ) { foreach ( Door door in e.Player.World.Map.Doors ) { if ( door.IsInRange( e.Coords ) ) { @@ -85,8 +88,7 @@ public static void PlayerClickedDoor ( object sender, Events.PlayerClickedEventA } } - - public static Door GetDoor ( Vector3I Coords, Player player ) { + public static Door GetDoor( Vector3I Coords, Player player ) { Door Door = null; try { if ( player.World.Map.Doors != null && player.World.Map.Doors.Count > 0 ) { @@ -105,10 +107,10 @@ public static Door GetDoor ( Vector3I Coords, Player player ) { return Door; } - public Vector3I[] GetAffectedBlocks ( Door door ) { + public Vector3I[] GetAffectedBlocks( Door door ) { Vector3I[] temp = new Vector3I[] { }; List temp2 = new List(); - for(int x = door.Range.Xmin; x < door.Range.Xmax; x++) + for ( int x = door.Range.Xmin; x < door.Range.Xmax; x++ ) for ( int y = door.Range.Ymin; y < door.Range.Ymax; y++ ) for ( int z = door.Range.Zmin; z < door.Range.Zmax; z++ ) { temp2.Add( new Vector3I( x, y, z ) ); @@ -117,7 +119,7 @@ public Vector3I[] GetAffectedBlocks ( Door door ) { return temp; } - public static int GetPlayerOwnedDoorsNumber ( World world, Player player ) { + public static int GetPlayerOwnedDoorsNumber( World world, Player player ) { int Number = 0; foreach ( Door door in world.Map.Doors ) { if ( door.Creator == player.Name ) { @@ -127,7 +129,7 @@ public static int GetPlayerOwnedDoorsNumber ( World world, Player player ) { return Number; } - public Door GetDoor ( World world, Vector3I block ) { + public Door GetDoor( World world, Vector3I block ) { Door Door = null; try { if ( world.Map.Doors != null && world.Map.Doors.Count > 0 ) { @@ -146,7 +148,7 @@ public Door GetDoor ( World world, Vector3I block ) { return Door; } - public static void CreateDoor ( Door Door, World source ) { + public static void CreateDoor( Door Door, World source ) { World world = WorldManager.FindWorldExact( Door.World ); if ( source.Map.Doors == null ) { @@ -156,22 +158,24 @@ public static void CreateDoor ( Door Door, World source ) { source.Map.Doors.Add( Door ); } } - static List openDoors = new List(); - static readonly object openDoorsLock = new object(); - static readonly TimeSpan DoorCloseTimer = TimeSpan.FromMilliseconds( 1500 ); - struct DoorInfo { + private static List openDoors = new List(); + private static readonly object openDoorsLock = new object(); + private static readonly TimeSpan DoorCloseTimer = TimeSpan.FromMilliseconds( 1500 ); + + private struct DoorInfo { public readonly Door Door; public readonly Block[] Buffer; public readonly Map WorldMap; - public DoorInfo ( Door door, Block[] buffer, Map worldMap ) { + + public DoorInfo( Door door, Block[] buffer, Map worldMap ) { Door = door; Buffer = buffer; WorldMap = worldMap; } } - static void doorTimer_Elapsed ( SchedulerTask task ) { + private static void doorTimer_Elapsed( SchedulerTask task ) { DoorInfo info = ( DoorInfo )task.UserState; int counter = 0; for ( int x = info.Door.Range.Xmin; x <= info.Door.Range.Xmax; x++ ) { @@ -186,7 +190,7 @@ static void doorTimer_Elapsed ( SchedulerTask task ) { lock ( openDoorsLock ) { openDoors.Remove( info.Door ); } } - static void openDoor ( Door door, Player player ) { + private static void openDoor( Door door, Player player ) { int sx = door.Range.Xmin; int ex = door.Range.Xmax; int sy = door.Range.Ymin; @@ -212,4 +216,4 @@ static void openDoor ( Door door, Player player ) { Scheduler.NewTask( doorTimer_Elapsed ).RunOnce( info, DoorCloseTimer ); } } -} +} \ No newline at end of file diff --git a/fCraft/Doors/DoorRange.cs b/fCraft/Doors/DoorRange.cs index e374974..be7b4f5 100644 --- a/fCraft/Doors/DoorRange.cs +++ b/fCraft/Doors/DoorRange.cs @@ -24,27 +24,27 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -namespace fCraft.Doors -{ +namespace fCraft.Doors { + /// /// Class used for rapid check if user is in range of Door /// - public class DoorRange - { + public class DoorRange { + public int Xmin { get; set; } + public int Xmax { get; set; } + public int Ymin { get; set; } + public int Ymax { get; set; } + public int Zmin { get; set; } + public int Zmax { get; set; } - public DoorRange(int Xmin, int Xmax, int Ymin, int Ymax, int Zmin, int Zmax) - { + public DoorRange( int Xmin, int Xmax, int Ymin, int Ymax, int Zmin, int Zmax ) { this.Xmin = Xmin; this.Xmax = Xmax; this.Ymin = Ymin; @@ -53,4 +53,4 @@ public DoorRange(int Xmin, int Xmax, int Ymin, int Ymax, int Zmin, int Zmax) this.Zmax = Zmax; } } -} +} \ No newline at end of file diff --git a/fCraft/Doors/DoorSerialization.cs b/fCraft/Doors/DoorSerialization.cs index e211533..d3e98f0 100644 --- a/fCraft/Doors/DoorSerialization.cs +++ b/fCraft/Doors/DoorSerialization.cs @@ -24,25 +24,22 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; +using System.Collections; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; using System.IO; -using System.Collections; -using System.Runtime.Serialization; using fCraft.MapConversion; -namespace fCraft.Doors -{ - public class DoorSerialization : IConverterExtension - { +namespace fCraft.Doors { + + public class DoorSerialization : IConverterExtension { private static readonly object SaveLoadLock = new object(); private static List _group = new List { "door" }; - public IEnumerable AcceptedGroups { get { return _group; } } - public int Serialize ( Map map, Stream stream, IMapConverterEx converter ) { + public IEnumerable AcceptedGroups { get { return _group; } } + + public int Serialize( Map map, Stream stream, IMapConverterEx converter ) { BinaryWriter writer = new BinaryWriter( stream ); int count = 0; if ( map.Doors != null ) { @@ -56,24 +53,21 @@ public int Serialize ( Map map, Stream stream, IMapConverterEx converter ) { return count; } - public void Deserialize(string group, string key, string value, Map map) - { - try - { - Door Door = Door.Deserialize(key, value, map); - if ( map.Doors == null ) map.Doors = new ArrayList(); + public void Deserialize( string group, string key, string value, Map map ) { + try { + Door Door = Door.Deserialize( key, value, map ); + if ( map.Doors == null ) + map.Doors = new ArrayList(); if ( map.Doors.Count >= 1 ) { if ( map.Doors.Contains( key ) ) { - Logger.Log( LogType.Error, "Map loading warning: duplicate Door name found: " + key + ", ignored" ); - return; + Logger.Log( LogType.Error, "Map loading warning: duplicate Door name found: " + key + ", ignored" ); + return; } } - map.Doors.Add(Door); - } - catch (Exception ex) - { - Logger.Log(LogType.Error, "Door.Deserialize: Error deserializing Door {0}: {1}", key, ex); - } + map.Doors.Add( Door ); + } catch ( Exception ex ) { + Logger.Log( LogType.Error, "Door.Deserialize: Error deserializing Door {0}: {1}", key, ex ); + } } } -} +} \ No newline at end of file diff --git a/fCraft/Drawing/Axis.cs b/fCraft/Drawing/Axis.cs index aae6514..e61d662 100644 --- a/fCraft/Drawing/Axis.cs +++ b/fCraft/Drawing/Axis.cs @@ -1,7 +1,10 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft.Drawing { + public enum Axis { - X, Y, Z + X, + Y, + Z } } \ No newline at end of file diff --git a/fCraft/Drawing/BrushManager.cs b/fCraft/Drawing/BrushManager.cs index 54fa997..5bcbafd 100644 --- a/fCraft/Drawing/BrushManager.cs +++ b/fCraft/Drawing/BrushManager.cs @@ -4,11 +4,12 @@ using JetBrains.Annotations; namespace fCraft.Drawing { + public static class BrushManager { - static readonly Dictionary BrushFactories = new Dictionary(); - static readonly Dictionary BrushAliases = new Dictionary(); + private static readonly Dictionary BrushFactories = new Dictionary(); + private static readonly Dictionary BrushAliases = new Dictionary(); - static readonly CommandDescriptor CdBrush = new CommandDescriptor { + private static readonly CommandDescriptor CdBrush = new CommandDescriptor { Name = "Brush", Category = CommandCategory.Building, Permissions = new[] { Permission.Draw, Permission.DrawAdvanced }, @@ -17,18 +18,17 @@ public static class BrushManager { Handler = BrushHandler }; - - static void BrushHandler( Player player, Command cmd ) { + private static void BrushHandler( Player player, Command cmd ) { string brushName = cmd.Next(); - if( brushName == null ) { + if ( brushName == null ) { player.Message( player.Brush.Description ); } else { IBrushFactory brushFactory = GetBrushFactory( brushName ); - if( brushFactory == null ) { + if ( brushFactory == null ) { player.Message( "Unrecognized brush \"{0}\"", brushName ); } else { IBrush newBrush = brushFactory.MakeBrush( player, cmd ); - if( newBrush != null ) { + if ( newBrush != null ) { player.Brush = newBrush; player.Message( "Brush set to {0}", player.Brush.Description ); } @@ -36,7 +36,6 @@ static void BrushHandler( Player player, Command cmd ) { } } - internal static void Init() { CommandManager.RegisterCommand( CdBrush ); RegisterBrush( NormalBrushFactory.Instance ); @@ -48,19 +47,19 @@ internal static void Init() { RegisterBrush( ReplaceBrushFactory.Instance ); RegisterBrush( ReplaceNotBrushFactory.Instance ); RegisterBrush( ReplaceBrushBrushFactory.Instance ); - RegisterBrush(DiagonalBrushFactory.Instance); + RegisterBrush( DiagonalBrushFactory.Instance ); } - public static void RegisterBrush( [NotNull] IBrushFactory factory ) { - if( factory == null ) throw new ArgumentNullException( "factory" ); + if ( factory == null ) + throw new ArgumentNullException( "factory" ); string helpString = String.Format( "{0} brush: {1}", factory.Name, factory.Help ); string lowerName = factory.Name.ToLower(); BrushFactories.Add( lowerName, factory ); - if( factory.Aliases != null ) { + if ( factory.Aliases != null ) { helpString += "Aliases: " + factory.Aliases.JoinToString(); - foreach( string alias in factory.Aliases ) { + foreach ( string alias in factory.Aliases ) { BrushAliases.Add( alias.ToLower(), factory ); } } @@ -68,13 +67,13 @@ public static void RegisterBrush( [NotNull] IBrushFactory factory ) { CdBrush.Help += factory.Name + " "; } - [CanBeNull] public static IBrushFactory GetBrushFactory( [NotNull] string brushName ) { - if( brushName == null ) throw new ArgumentNullException( "brushName" ); + if ( brushName == null ) + throw new ArgumentNullException( "brushName" ); IBrushFactory factory; string lowerName = brushName.ToLower(); - if( BrushFactories.TryGetValue( lowerName, out factory ) || + if ( BrushFactories.TryGetValue( lowerName, out factory ) || BrushAliases.TryGetValue( lowerName, out factory ) ) { return factory; } else { diff --git a/fCraft/Drawing/Brushes/AbstractPerlinNoiseBrush.cs b/fCraft/Drawing/Brushes/AbstractPerlinNoiseBrush.cs index 511cbe7..a5b182f 100644 --- a/fCraft/Drawing/Brushes/AbstractPerlinNoiseBrush.cs +++ b/fCraft/Drawing/Brushes/AbstractPerlinNoiseBrush.cs @@ -4,27 +4,34 @@ using JetBrains.Annotations; namespace fCraft.Drawing { + public abstract class AbstractPerlinNoiseBrush : IBrushInstance { + public int Seed { get; set; } + public float Coverage { get; set; } + // ReSharper disable MemberCanBeProtected.Global public float Frequency { get; set; } + // ReSharper restore MemberCanBeProtected.Global public int Octaves { get; set; } + public float Persistence { get; set; } protected Block[] Blocks { get; set; } + protected int[] BlockRatios { get; set; } - float[] computedThresholds; - float normMultiplier, normConstant; - PerlinNoise3D noise3D; + private float[] computedThresholds; + private float normMultiplier, normConstant; + private PerlinNoise3D noise3D; - static readonly object SeedGenLock = new object(); - static readonly Random SeedGenerator = new Random(); + private static readonly object SeedGenLock = new object(); + private static readonly Random SeedGenerator = new Random(); protected AbstractPerlinNoiseBrush() { - lock( SeedGenLock ) { + lock ( SeedGenLock ) { Seed = SeedGenerator.Next(); } Blocks = new Block[0]; @@ -47,9 +54,9 @@ protected AbstractPerlinNoiseBrush( Block[] blocks, int[] ratios ) BlockRatios = ratios; } - protected AbstractPerlinNoiseBrush( [NotNull] AbstractPerlinNoiseBrush other ) { - if( other == null ) throw new ArgumentNullException( "other" ); + if ( other == null ) + throw new ArgumentNullException( "other" ); Blocks = other.Blocks; BlockRatios = other.BlockRatios; Seed = other.Seed; @@ -59,12 +66,13 @@ protected AbstractPerlinNoiseBrush( [NotNull] AbstractPerlinNoiseBrush other ) { Persistence = other.Persistence; } - public virtual bool Begin( [NotNull] Player player, [NotNull] DrawOperation op ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( op == null ) throw new ArgumentNullException( "op" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); - if( op.Bounds.Volume > 32 * 32 * 32 ) { + if ( op.Bounds.Volume > 32 * 32 * 32 ) { player.Message( "{0} brush: Preparing, please wait...", Brush.Factory.Name ); } @@ -77,15 +85,15 @@ public virtual bool Begin( [NotNull] Player player, [NotNull] DrawOperation op ) // generate and normalize the raw (float) data float[, ,] rawData = new float[op.Bounds.Width, op.Bounds.Length, op.Bounds.Height]; - for( int x = 0; x < op.Bounds.Width; x++ ) { - for( int y = 0; y < op.Bounds.Length; y++ ) { - for( int z = 0; z < op.Bounds.Height; z++ ) { + for ( int x = 0; x < op.Bounds.Width; x++ ) { + for ( int y = 0; y < op.Bounds.Length; y++ ) { + for ( int z = 0; z < op.Bounds.Height; z++ ) { rawData[x, y, z] = noise3D.Compute( x, y, z ); } } } Noise.Normalize( rawData, out normMultiplier, out normConstant ); - if( MapAllValues( rawData ) ) { + if ( MapAllValues( rawData ) ) { Noise.Normalize( rawData, out normMultiplier, out normConstant ); } @@ -94,17 +102,17 @@ public virtual bool Begin( [NotNull] Player player, [NotNull] DrawOperation op ) int blocksSoFar = BlockRatios[0]; computedThresholds = new float[Blocks.Length]; computedThresholds[0] = 0; - for( int i = 1; i < Blocks.Length; i++ ) { - float desiredCoverage = blocksSoFar / (float)totalBlocks; + for ( int i = 1; i < Blocks.Length; i++ ) { + float desiredCoverage = blocksSoFar / ( float )totalBlocks; computedThresholds[i] = Noise.FindThreshold( rawData, desiredCoverage ); blocksSoFar += BlockRatios[i]; } return true; } - public virtual Block NextBlock( [NotNull] DrawOperation op ) { - if( op == null ) throw new ArgumentNullException( "op" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); Vector3I relativeCoords = op.Coords - op.Bounds.MinVertex; float value = noise3D.Compute( relativeCoords.X, relativeCoords.Y, relativeCoords.Z ); @@ -115,30 +123,25 @@ public virtual Block NextBlock( [NotNull] DrawOperation op ) { value = MapValue( value ); // find the right block type for given value - for( int i = 1; i < Blocks.Length; i++ ) { - if( computedThresholds[i] > value ) { + for ( int i = 1; i < Blocks.Length; i++ ) { + if ( computedThresholds[i] > value ) { return Blocks[i - 1]; } } return Blocks[Blocks.Length - 1]; } - protected abstract float MapValue( float rawValue ); - protected abstract bool MapAllValues( float[, ,] rawValues ); - - public virtual void End() { } - + public virtual void End() { + } public abstract IBrush Brush { get; } - public abstract string InstanceDescription { get; } - public bool HasAlternateBlock { get { return false; } } diff --git a/fCraft/Drawing/Brushes/CheckeredBrush.cs b/fCraft/Drawing/Brushes/CheckeredBrush.cs index 07bb284..31d77fd 100644 --- a/fCraft/Drawing/Brushes/CheckeredBrush.cs +++ b/fCraft/Drawing/Brushes/CheckeredBrush.cs @@ -3,10 +3,11 @@ using JetBrains.Annotations; namespace fCraft.Drawing { + public sealed class CheckeredBrushFactory : IBrushFactory { public static readonly CheckeredBrushFactory Instance = new CheckeredBrushFactory(); - CheckeredBrushFactory() { + private CheckeredBrushFactory() { Aliases = new[] { "ch" }; } @@ -16,53 +17,53 @@ public string Name { public string[] Aliases { get; private set; } - const string HelpString = "Checkered brush: Fills the area with alternating checkered pattern. " + + private const string HelpString = "Checkered brush: Fills the area with alternating checkered pattern. " + "If only one block name is given, leaves every other block untouched."; + public string Help { get { return HelpString; } } - public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); Block block = cmd.NextBlock( player ); Block altBlock = cmd.NextBlock( player ); return new CheckeredBrush( block, altBlock ); } } - public sealed class CheckeredBrush : IBrushInstance, IBrush { + public Block Block1 { get; private set; } - public Block Block2 { get; private set; } + public Block Block2 { get; private set; } public CheckeredBrush( Block block1, Block block2 ) { Block1 = block1; Block2 = block2; } - public CheckeredBrush( [NotNull] CheckeredBrush other ) { - if( other == null ) throw new ArgumentNullException( "other" ); + if ( other == null ) + throw new ArgumentNullException( "other" ); Block1 = other.Block1; Block2 = other.Block2; } - #region IBrush members public IBrushFactory Factory { get { return CheckeredBrushFactory.Instance; } } - public string Description { get { - if( Block2 != Block.Undefined ) { + if ( Block2 != Block.Undefined ) { return String.Format( "{0}({1},{2})", Factory.Name, Block1, Block2 ); - } else if( Block1 != Block.Undefined ) { + } else if ( Block1 != Block.Undefined ) { return String.Format( "{0}({1})", Factory.Name, Block1 ); } else { return Factory.Name; @@ -70,21 +71,23 @@ public string Description { } } - [CanBeNull] public IBrushInstance MakeInstance( [NotNull] Player player, [NotNull] Command cmd, [NotNull] DrawOperation op ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); - if( op == null ) throw new ArgumentNullException( "op" ); - - if( cmd.HasNext ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); + + if ( cmd.HasNext ) { Block block = cmd.NextBlock( player ); - if( block == Block.Undefined ) return null; + if ( block == Block.Undefined ) + return null; Block altBlock = cmd.NextBlock( player ); Block1 = block; Block2 = altBlock; - - } else if( Block1 == Block.Undefined ) { + } else if ( Block1 == Block.Undefined ) { player.Message( "{0}: Please specify at least one block.", Factory.Name ); return null; } @@ -92,8 +95,7 @@ public IBrushInstance MakeInstance( [NotNull] Player player, [NotNull] Command c return new CheckeredBrush( this ); } - #endregion - + #endregion IBrush members #region IBrushInstance members @@ -101,38 +103,37 @@ public IBrush Brush { get { return this; } } - public bool HasAlternateBlock { get { return false; } } - public string InstanceDescription { get { return Description; } } - public bool Begin( [NotNull] Player player, [NotNull] DrawOperation state ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( state == null ) throw new ArgumentNullException( "state" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( state == null ) + throw new ArgumentNullException( "state" ); return true; } - public Block NextBlock( [NotNull] DrawOperation state ) { - if( state == null ) throw new ArgumentNullException( "state" ); - if( ((state.Coords.X + state.Coords.Y + state.Coords.Z) & 1) == 1 ) { + if ( state == null ) + throw new ArgumentNullException( "state" ); + if ( ( ( state.Coords.X + state.Coords.Y + state.Coords.Z ) & 1 ) == 1 ) { return Block1; } else { return Block2; } } + public void End() { + } - public void End() { } - - #endregion + #endregion IBrushInstance members } } \ No newline at end of file diff --git a/fCraft/Drawing/Brushes/CloudyBrush.cs b/fCraft/Drawing/Brushes/CloudyBrush.cs index ecea123..5845d97 100644 --- a/fCraft/Drawing/Brushes/CloudyBrush.cs +++ b/fCraft/Drawing/Brushes/CloudyBrush.cs @@ -5,10 +5,12 @@ using JetBrains.Annotations; namespace fCraft.Drawing { + public sealed class CloudyBrushFactory : IBrushFactory { public static readonly CloudyBrushFactory Instance = new CloudyBrushFactory(); - CloudyBrushFactory() { } + private CloudyBrushFactory() { + } public string Name { get { return "Cloudy"; } @@ -19,25 +21,28 @@ public string[] Aliases { get { return null; } } - const string HelpString = "Cloudy brush: Creates a swirling pattern of two or more block types. " + + private const string HelpString = "Cloudy brush: Creates a swirling pattern of two or more block types. " + "If only one block name is given, leaves every other block untouched."; + public string Help { get { return HelpString; } } - [CanBeNull] public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); List blocks = new List(); List blockRatios = new List(); - while( cmd.HasNext ) { + while ( cmd.HasNext ) { int ratio = 1; Block block = cmd.NextBlockWithParam( player, ref ratio ); - if( block == Block.Undefined ) return null; - if( ratio < 0 || ratio > CloudyBrush.MaxRatio ) { + if ( block == Block.Undefined ) + return null; + if ( ratio < 0 || ratio > CloudyBrush.MaxRatio ) { player.Message( "{0} brush: Invalid block ratio ({1}). Must be between 1 and {2}.", Name, ratio, CloudyBrush.MaxRatio ); return null; @@ -46,9 +51,9 @@ public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { blockRatios.Add( ratio ); } - if( blocks.Count == 0 ) { + if ( blocks.Count == 0 ) { return new CloudyBrush(); - } else if( blocks.Count == 1 ) { + } else if ( blocks.Count == 1 ) { return new CloudyBrush( blocks[0], blockRatios[0] ); } else { return new CloudyBrush( blocks.ToArray(), blockRatios.ToArray() ); @@ -56,7 +61,6 @@ public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { } } - public sealed class CloudyBrush : AbstractPerlinNoiseBrush, IBrush { public const int MaxRatio = 10000; @@ -75,28 +79,27 @@ public CloudyBrush( AbstractPerlinNoiseBrush other ) : base( other ) { } - #region IBrush members public IBrushFactory Factory { get { return CloudyBrushFactory.Instance; } } - public string Description { get { - if( Blocks.Length == 0 ) { + if ( Blocks.Length == 0 ) { return Factory.Name; - } else if( Blocks.Length == 1 || ( Blocks.Length == 2 && Blocks[1] == Block.Undefined ) ) { + } else if ( Blocks.Length == 1 || ( Blocks.Length == 2 && Blocks[1] == Block.Undefined ) ) { return String.Format( "{0}({1})", Factory.Name, Blocks[0] ); } else { StringBuilder sb = new StringBuilder(); sb.Append( Factory.Name ); sb.Append( '(' ); - for( int i = 0; i < Blocks.Length; i++ ) { - if( i != 0 ) sb.Append( ',' ).Append( ' ' ); + for ( int i = 0; i < Blocks.Length; i++ ) { + if ( i != 0 ) + sb.Append( ',' ).Append( ' ' ); sb.Append( Blocks[i] ); - if( BlockRatios[i] > 1 ) { + if ( BlockRatios[i] > 1 ) { sb.Append( '/' ); sb.Digits( BlockRatios[i] ); } @@ -107,44 +110,46 @@ public string Description { } } - [CanBeNull] public IBrushInstance MakeInstance( [NotNull] Player player, [NotNull] Command cmd, [NotNull] DrawOperation state ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); - if( state == null ) throw new ArgumentNullException( "state" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); + if ( state == null ) + throw new ArgumentNullException( "state" ); List blocks = new List(); List blockRatios = new List(); - while( cmd.HasNext ) { + while ( cmd.HasNext ) { int ratio = 1; Block block = cmd.NextBlockWithParam( player, ref ratio ); - if( ratio < 0 || ratio > MaxRatio ) { + if ( ratio < 0 || ratio > MaxRatio ) { player.Message( "Invalid block ratio ({0}). Must be between 1 and {1}.", ratio, MaxRatio ); return null; } - if( block == Block.Undefined ) return null; + if ( block == Block.Undefined ) + return null; blocks.Add( block ); blockRatios.Add( ratio ); } - if( blocks.Count == 0 ) { - if( Blocks.Length == 0 ) { + if ( blocks.Count == 0 ) { + if ( Blocks.Length == 0 ) { player.Message( "{0} brush: Please specify at least one block.", Factory.Name ); return null; } else { return new CloudyBrush( this ); } - } else if( blocks.Count == 1 ) { + } else if ( blocks.Count == 1 ) { return new CloudyBrush( blocks[0], blockRatios[0] ); } else { return new CloudyBrush( blocks.ToArray(), blockRatios.ToArray() ); } } - #endregion - + #endregion IBrush members #region AbstractPerlinNoiseBrush members @@ -158,7 +163,6 @@ public override string InstanceDescription { } } - protected override float MapValue( float rawValue ) { return rawValue; } @@ -167,6 +171,6 @@ protected override bool MapAllValues( float[, ,] rawValues ) { return false; } - #endregion + #endregion AbstractPerlinNoiseBrush members } } \ No newline at end of file diff --git a/fCraft/Drawing/Brushes/DiagonalBrush.cs b/fCraft/Drawing/Brushes/DiagonalBrush.cs index 6133ea0..183373e 100644 --- a/fCraft/Drawing/Brushes/DiagonalBrush.cs +++ b/fCraft/Drawing/Brushes/DiagonalBrush.cs @@ -1,150 +1,145 @@ // Copyright (C) <2012> (http://au70.net) // Copyright 2009 - 2012 Matvei Stefarov using System; -using JetBrains.Annotations; using System.Collections.Generic; -namespace fCraft.Drawing -{ - public sealed class DiagonalBrushFactory : IBrushFactory - { +using JetBrains.Annotations; + +namespace fCraft.Drawing { + + public sealed class DiagonalBrushFactory : IBrushFactory { public static readonly DiagonalBrushFactory Instance = new DiagonalBrushFactory(); - DiagonalBrushFactory() - { - Aliases = new[] { "zigzag" }; + + private DiagonalBrushFactory() { + Aliases = new[] { "zigzag" }; } - public string Name - { + + public string Name { get { return "Diagonal"; } } + public string[] Aliases { get; private set; } - const string HelpString = "Diagonal brush: Fills the area with in a diagonal pattern of 2 block types. " + + + private const string HelpString = "Diagonal brush: Fills the area with in a diagonal pattern of 2 block types. " + "If only one block name is given, leaves every other block untouched."; - public string Help - { + + public string Help { get { return HelpString; } } - public IBrush MakeBrush([NotNull] Player player, Command cmd) - { - if (player == null) throw new ArgumentNullException("player"); - if (cmd == null) throw new ArgumentNullException("cmd"); - if (!cmd.HasNext) - { - if (player.LastUsedBlockType != (Block)255) - return new DiagonalBrush(new[] { player.LastUsedBlockType }); - else return new DiagonalBrush(new[] { Block.Stone }); + public IBrush MakeBrush( [NotNull] Player player, Command cmd ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); + if ( !cmd.HasNext ) { + if ( player.LastUsedBlockType != ( Block )255 ) + return new DiagonalBrush( new[] { player.LastUsedBlockType } ); + else + return new DiagonalBrush( new[] { Block.Stone } ); } Stack temp = new Stack(); - while (cmd.HasNext) - { - Block block = cmd.NextBlock(player); - if (block == Block.Undefined) return null; - temp.Push(block); + while ( cmd.HasNext ) { + Block block = cmd.NextBlock( player ); + if ( block == Block.Undefined ) + return null; + temp.Push( block ); } - return new DiagonalBrush(temp.ToArray()); + return new DiagonalBrush( temp.ToArray() ); } } - public sealed class DiagonalBrush : IBrushInstance, IBrush - { + public sealed class DiagonalBrush : IBrushInstance, IBrush { + public Block[] Blocks { get; private set; } - public DiagonalBrush(Block[] blocks) - { + public DiagonalBrush( Block[] blocks ) { Blocks = blocks; } - public DiagonalBrush([NotNull] DiagonalBrush other) - { - if (other == null) throw new ArgumentNullException("other"); + public DiagonalBrush( [NotNull] DiagonalBrush other ) { + if ( other == null ) + throw new ArgumentNullException( "other" ); Blocks = other.Blocks; } #region IBrush members - public IBrushFactory Factory - { + + public IBrushFactory Factory { get { return DiagonalBrushFactory.Instance; } } - public string Description - { - get - { - if (Blocks.Length == 0) - { - return String.Format("{0}({1},{2})", Factory.Name, Blocks.JoinToString()); - } - else - { + public string Description { + get { + if ( Blocks.Length == 0 ) { + return String.Format( "{0}({1},{2})", Factory.Name, Blocks.JoinToString() ); + } else { return Factory.Name; } } } [CanBeNull] - public IBrushInstance MakeInstance([NotNull] Player player, [NotNull] Command cmd, [NotNull] DrawOperation op) - { - if (player == null) throw new ArgumentNullException("player"); - if (cmd == null) throw new ArgumentNullException("cmd"); - if (op == null) throw new ArgumentNullException("op"); + public IBrushInstance MakeInstance( [NotNull] Player player, [NotNull] Command cmd, [NotNull] DrawOperation op ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); Stack temp = new Stack(); Block[] b; - while (cmd.HasNext) - { - Block block = cmd.NextBlock(player); - if (block == Block.Undefined) return null; - temp.Push(block); + while ( cmd.HasNext ) { + Block block = cmd.NextBlock( player ); + if ( block == Block.Undefined ) + return null; + temp.Push( block ); } - if (temp.Count > 0) - { + if ( temp.Count > 0 ) { b = temp.ToArray(); - } - else if (player.LastUsedBlockType != Block.Undefined) - { + } else if ( player.LastUsedBlockType != Block.Undefined ) { b = new[] { player.LastUsedBlockType, Block.Air }; - } - else - { + } else { b = new[] { Block.Stone, Block.Air }; } - return new DiagonalBrush(b); + return new DiagonalBrush( b ); } - #endregion + + #endregion IBrush members #region IBrushInstance members - public IBrush Brush - { + + public IBrush Brush { get { return this; } } - public bool HasAlternateBlock - { + public bool HasAlternateBlock { get { return false; } } - public string InstanceDescription - { - get - { + public string InstanceDescription { + get { return Description; } } - public bool Begin([NotNull] Player player, [NotNull] DrawOperation state) - { - if (player == null) throw new ArgumentNullException("player"); - if (state == null) throw new ArgumentNullException("state"); - if (Blocks.Length == 0) { player.Message("&WError: No block types given"); return false; } + public bool Begin( [NotNull] Player player, [NotNull] DrawOperation state ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( state == null ) + throw new ArgumentNullException( "state" ); + if ( Blocks.Length == 0 ) { player.Message( "&WError: No block types given" ); return false; } return true; } - public Block NextBlock([NotNull] DrawOperation state) - { - if (state == null) throw new ArgumentNullException("state"); - return Blocks[(state.Coords.X + state.Coords.Y + state.Coords.Z) % Blocks.Length]; + public Block NextBlock( [NotNull] DrawOperation state ) { + if ( state == null ) + throw new ArgumentNullException( "state" ); + return Blocks[( state.Coords.X + state.Coords.Y + state.Coords.Z ) % Blocks.Length]; + } + + public void End() { } - public void End() { } - #endregion + #endregion IBrushInstance members } } \ No newline at end of file diff --git a/fCraft/Drawing/Brushes/MarbledBrush.cs b/fCraft/Drawing/Brushes/MarbledBrush.cs index 8c9196e..617e3ae 100644 --- a/fCraft/Drawing/Brushes/MarbledBrush.cs +++ b/fCraft/Drawing/Brushes/MarbledBrush.cs @@ -5,10 +5,12 @@ using JetBrains.Annotations; namespace fCraft.Drawing { + public sealed class MarbledBrushFactory : IBrushFactory { public static readonly MarbledBrushFactory Instance = new MarbledBrushFactory(); - MarbledBrushFactory() { } + private MarbledBrushFactory() { + } public string Name { get { return "Marbled"; } @@ -19,25 +21,28 @@ public string[] Aliases { get { return null; } } - const string HelpString = "Marbled brush: Creates a turbulent pattern of two or more block types. " + + private const string HelpString = "Marbled brush: Creates a turbulent pattern of two or more block types. " + "If only one block name is given, leaves every other block untouched."; + public string Help { get { return HelpString; } } - [CanBeNull] public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); List blocks = new List(); List blockRatios = new List(); - while( cmd.HasNext ) { + while ( cmd.HasNext ) { int ratio = 1; Block block = cmd.NextBlockWithParam( player, ref ratio ); - if( block == Block.Undefined ) return null; - if( ratio < 0 || ratio > MarbledBrush.MaxRatio ) { + if ( block == Block.Undefined ) + return null; + if ( ratio < 0 || ratio > MarbledBrush.MaxRatio ) { player.Message( "{0} brush: Invalid block ratio ({1}). Must be between 1 and {2}.", Name, ratio, MarbledBrush.MaxRatio ); return null; @@ -46,9 +51,9 @@ public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { blockRatios.Add( ratio ); } - if( blocks.Count == 0 ) { + if ( blocks.Count == 0 ) { return new MarbledBrush(); - } else if( blocks.Count == 1 ) { + } else if ( blocks.Count == 1 ) { return new MarbledBrush( blocks[0], blockRatios[0] ); } else { return new MarbledBrush( blocks.ToArray(), blockRatios.ToArray() ); @@ -56,7 +61,6 @@ public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { } } - public sealed class MarbledBrush : AbstractPerlinNoiseBrush, IBrush { public const int MaxRatio = 10000; @@ -79,28 +83,27 @@ public MarbledBrush( AbstractPerlinNoiseBrush other ) Frequency = 0.1f; } - #region IBrush members public IBrushFactory Factory { get { return MarbledBrushFactory.Instance; } } - public string Description { get { - if( Blocks.Length == 0 ) { + if ( Blocks.Length == 0 ) { return Factory.Name; - } else if( Blocks.Length == 1 || (Blocks.Length == 2 && Blocks[1] == Block.Undefined) ) { + } else if ( Blocks.Length == 1 || ( Blocks.Length == 2 && Blocks[1] == Block.Undefined ) ) { return String.Format( "{0}({1})", Factory.Name, Blocks[0] ); } else { StringBuilder sb = new StringBuilder(); sb.Append( Factory.Name ); sb.Append( '(' ); - for( int i = 0; i < Blocks.Length; i++ ) { - if( i != 0 ) sb.Append( ',' ).Append( ' ' ); + for ( int i = 0; i < Blocks.Length; i++ ) { + if ( i != 0 ) + sb.Append( ',' ).Append( ' ' ); sb.Append( Blocks[i] ); - if( BlockRatios[i] > 1 ) { + if ( BlockRatios[i] > 1 ) { sb.Append( '/' ); sb.Digits( BlockRatios[i] ); } @@ -111,44 +114,46 @@ public string Description { } } - [CanBeNull] public IBrushInstance MakeInstance( [NotNull] Player player, [NotNull] Command cmd, [NotNull] DrawOperation state ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); - if( state == null ) throw new ArgumentNullException( "state" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); + if ( state == null ) + throw new ArgumentNullException( "state" ); List blocks = new List(); List blockRatios = new List(); - while( cmd.HasNext ) { + while ( cmd.HasNext ) { int ratio = 1; Block block = cmd.NextBlockWithParam( player, ref ratio ); - if( ratio < 0 || ratio > MaxRatio ) { + if ( ratio < 0 || ratio > MaxRatio ) { player.Message( "Invalid block ratio ({0}). Must be between 1 and {1}.", ratio, MaxRatio ); return null; } - if( block == Block.Undefined ) return null; + if ( block == Block.Undefined ) + return null; blocks.Add( block ); blockRatios.Add( ratio ); } - if( blocks.Count == 0 ) { - if( Blocks.Length == 0 ) { + if ( blocks.Count == 0 ) { + if ( Blocks.Length == 0 ) { player.Message( "{0} brush: Please specify at least one block.", Factory.Name ); return null; } else { return new MarbledBrush( this ); } - } else if( blocks.Count == 1 ) { + } else if ( blocks.Count == 1 ) { return new MarbledBrush( blocks[0], blockRatios[0] ); } else { return new MarbledBrush( blocks.ToArray(), blockRatios.ToArray() ); } } - #endregion - + #endregion IBrush members #region AbstractPerlinNoiseBrush members @@ -156,27 +161,25 @@ public override IBrush Brush { get { return this; } } - public override string InstanceDescription { get { return Description; } } - protected override float MapValue( float rawValue ) { return Math.Abs( rawValue * 2 - 1 ); } protected unsafe override bool MapAllValues( float[, ,] rawValues ) { - fixed( float* ptr = rawValues ) { - for( int i = 0; i < rawValues.Length; i++ ) { + fixed ( float* ptr = rawValues ) { + for ( int i = 0; i < rawValues.Length; i++ ) { ptr[i] = Math.Abs( ptr[i] * 2 - 1 ); } } return false; } - #endregion + #endregion AbstractPerlinNoiseBrush members } } \ No newline at end of file diff --git a/fCraft/Drawing/Brushes/NormalBrush.cs b/fCraft/Drawing/Brushes/NormalBrush.cs index dc82f1c..45bf995 100644 --- a/fCraft/Drawing/Brushes/NormalBrush.cs +++ b/fCraft/Drawing/Brushes/NormalBrush.cs @@ -3,27 +3,27 @@ using JetBrains.Annotations; namespace fCraft.Drawing { + public sealed class NormalBrushFactory : IBrushFactory, IBrush { public static readonly NormalBrushFactory Instance = new NormalBrushFactory(); - NormalBrushFactory() { + private NormalBrushFactory() { Aliases = new[] { "default", "-" }; } - public string Name { get { return "Normal"; } } public string[] Aliases { get; private set; } - const string HelpString = "Normal brush: Fills the area with solid color. " + + private const string HelpString = "Normal brush: Fills the area with solid color. " + "If no block name is given, uses the last block that player has placed."; + public string Help { get { return HelpString; } } - public string Description { get { return Name; } } @@ -32,29 +32,34 @@ public IBrushFactory Factory { get { return this; } } - public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); return this; } - [CanBeNull] public IBrushInstance MakeInstance( [NotNull] Player player, [NotNull] Command cmd, [NotNull] DrawOperation state ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); - if( state == null ) throw new ArgumentNullException( "state" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); + if ( state == null ) + throw new ArgumentNullException( "state" ); Block block = Block.Undefined, altBlock = Block.Undefined; - if( cmd.HasNext ) { + if ( cmd.HasNext ) { block = cmd.NextBlock( player ); - if( block == Block.Undefined ) return null; + if ( block == Block.Undefined ) + return null; - if( cmd.HasNext ) { + if ( cmd.HasNext ) { altBlock = cmd.NextBlock( player ); - if( altBlock == Block.Undefined ) return null; + if ( altBlock == Block.Undefined ) + return null; } } @@ -62,9 +67,10 @@ public IBrushInstance MakeInstance( [NotNull] Player player, [NotNull] Command c } } - public sealed class NormalBrush : IBrushInstance { + public Block Block { get; set; } + public Block AltBlock { get; set; } public bool HasAlternateBlock { @@ -73,9 +79,9 @@ public bool HasAlternateBlock { public string InstanceDescription { get { - if( Block == Block.Undefined ) { + if ( Block == Block.Undefined ) { return Brush.Factory.Name; - } else if( AltBlock == Block.Undefined ) { + } else if ( AltBlock == Block.Undefined ) { return String.Format( "{0}({1})", Brush.Factory.Name, Block ); } else { return String.Format( "{0}({1},{2})", Brush.Factory.Name, Block, AltBlock ); @@ -93,19 +99,20 @@ public NormalBrush( Block block ) { } public NormalBrush( Block block, Block altBlock ) { - if( block == Block.Undefined && altBlock != Block.Undefined ) { + if ( block == Block.Undefined && altBlock != Block.Undefined ) { throw new ArgumentException( "Block must not be undefined if altblock is set.", "block" ); } Block = block; AltBlock = altBlock; } - public bool Begin( [NotNull] Player player, [NotNull] DrawOperation state ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( state == null ) throw new ArgumentNullException( "state" ); - if( Block == Block.Undefined ) { - if( player.LastUsedBlockType == Block.Undefined ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( state == null ) + throw new ArgumentNullException( "state" ); + if ( Block == Block.Undefined ) { + if ( player.LastUsedBlockType == Block.Undefined ) { player.Message( "Cannot deduce desired block. Click a block or type out the block name." ); return false; } else { @@ -115,17 +122,17 @@ public bool Begin( [NotNull] Player player, [NotNull] DrawOperation state ) { return true; } - public Block NextBlock( [NotNull] DrawOperation state ) { - if( state == null ) throw new ArgumentNullException( "state" ); - if( state.UseAlternateBlock ) { + if ( state == null ) + throw new ArgumentNullException( "state" ); + if ( state.UseAlternateBlock ) { return AltBlock; } else { return Block; } } - - public void End() { } + public void End() { + } } } \ No newline at end of file diff --git a/fCraft/Drawing/Brushes/RainbowBrush.cs b/fCraft/Drawing/Brushes/RainbowBrush.cs index 00dc7c8..4200836 100644 --- a/fCraft/Drawing/Brushes/RainbowBrush.cs +++ b/fCraft/Drawing/Brushes/RainbowBrush.cs @@ -3,10 +3,12 @@ using JetBrains.Annotations; namespace fCraft.Drawing { + public sealed class RainbowBrush : IBrushFactory, IBrush, IBrushInstance { public static readonly RainbowBrush Instance = new RainbowBrush(); - RainbowBrush() { } + private RainbowBrush() { + } public bool HasAlternateBlock { get { return false; } @@ -21,12 +23,12 @@ public string[] Aliases { get { return null; } } - const string HelpString = "Rainbow brush: Creates a diagonal 7-color rainbow pattern."; + private const string HelpString = "Rainbow brush: Creates a diagonal 7-color rainbow pattern."; + public string Help { get { return HelpString; } } - public string Description { get { return Name; } } @@ -35,17 +37,15 @@ public IBrushFactory Factory { get { return this; } } - public IBrush MakeBrush( Player player, Command cmd ) { return this; } - public IBrushInstance MakeInstance( Player player, Command cmd, DrawOperation state ) { return this; } - static readonly Block[] Rainbow = new[]{ + private static readonly Block[] Rainbow = new[]{ Block.Red, Block.Orange, Block.Yellow, @@ -64,18 +64,20 @@ public IBrush Brush { } public bool Begin( [NotNull] Player player, [NotNull] DrawOperation state ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( state == null ) throw new ArgumentNullException( "state" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( state == null ) + throw new ArgumentNullException( "state" ); return true; } - public Block NextBlock( [NotNull] DrawOperation state ) { - if( state == null ) throw new ArgumentNullException( "state" ); - return Rainbow[(state.Coords.X + state.Coords.Y + state.Coords.Z) % 7]; + if ( state == null ) + throw new ArgumentNullException( "state" ); + return Rainbow[( state.Coords.X + state.Coords.Y + state.Coords.Z ) % 7]; } - - public void End() { } + public void End() { + } } } \ No newline at end of file diff --git a/fCraft/Drawing/Brushes/RandomBrush.cs b/fCraft/Drawing/Brushes/RandomBrush.cs index 9084149..a0d0d7c 100644 --- a/fCraft/Drawing/Brushes/RandomBrush.cs +++ b/fCraft/Drawing/Brushes/RandomBrush.cs @@ -6,10 +6,11 @@ using JetBrains.Annotations; namespace fCraft.Drawing { + public sealed class RandomBrushFactory : IBrushFactory { public static readonly RandomBrushFactory Instance = new RandomBrushFactory(); - RandomBrushFactory() { + private RandomBrushFactory() { Aliases = new[] { "rand" }; } @@ -19,25 +20,28 @@ public string Name { public string[] Aliases { get; private set; } - const string HelpString = "Random brush: Chaotic pattern of two or more random block types. " + + private const string HelpString = "Random brush: Chaotic pattern of two or more random block types. " + "If only one block name is given, leaves every other block untouched."; + public string Help { get { return HelpString; } } - [CanBeNull] public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); List blocks = new List(); List blockRatios = new List(); - while( cmd.HasNext ) { + while ( cmd.HasNext ) { int ratio = 1; Block block = cmd.NextBlockWithParam( player, ref ratio ); - if( block == Block.Undefined ) return null; - if( ratio < 0 || ratio > RandomBrush.MaxRatio ) { + if ( block == Block.Undefined ) + return null; + if ( ratio < 0 || ratio > RandomBrush.MaxRatio ) { player.Message( "{0} brush: Invalid block ratio ({1}). Must be between 1 and {2}.", Name, ratio, RandomBrush.MaxRatio ); return null; @@ -46,9 +50,9 @@ public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { blockRatios.Add( ratio ); } - if( blocks.Count == 0 ) { + if ( blocks.Count == 0 ) { return new RandomBrush(); - } else if( blocks.Count == 1 ) { + } else if ( blocks.Count == 1 ) { return new RandomBrush( blocks[0], blockRatios[0] ); } else { return new RandomBrush( blocks.ToArray(), blockRatios.ToArray() ); @@ -56,71 +60,69 @@ public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { } } - public unsafe sealed class RandomBrush : IBrushInstance, IBrush { public const int MaxRatio = 10000; public Block[] Blocks { get; private set; } + public int[] BlockRatios { get; private set; } - readonly Block[] actualBlocks; - readonly int seed = new Random().Next(); + + private readonly Block[] actualBlocks; + private readonly int seed = new Random().Next(); public RandomBrush() { Blocks = new Block[0]; BlockRatios = new int[0]; } - public RandomBrush( Block oneBlock, int ratio ) { Blocks = new[] { oneBlock, Block.Undefined }; BlockRatios = new[] { ratio, 1 }; actualBlocks = new[] { oneBlock, Block.Undefined }; } - public RandomBrush( Block[] blocks, int[] ratios ) { Blocks = blocks; BlockRatios = ratios; actualBlocks = new Block[BlockRatios.Sum()]; int c = 0; - for( int i = 0; i < Blocks.Length; i++ ) { - for( int j = 0; j < BlockRatios[i]; j++ ) { + for ( int i = 0; i < Blocks.Length; i++ ) { + for ( int j = 0; j < BlockRatios[i]; j++ ) { actualBlocks[c] = Blocks[i]; c++; } } } - public RandomBrush( [NotNull] RandomBrush other ) { - if( other == null ) throw new ArgumentNullException( "other" ); + if ( other == null ) + throw new ArgumentNullException( "other" ); Blocks = other.Blocks; BlockRatios = other.BlockRatios; actualBlocks = other.actualBlocks; } - #region IBrush members public IBrushFactory Factory { get { return RandomBrushFactory.Instance; } } - public string Description { get { - if( Blocks.Length == 0 ) { + if ( Blocks.Length == 0 ) { return Factory.Name; - } else if( Blocks.Length == 1 || (Blocks.Length == 2 && Blocks[1] == Block.Undefined) ) { + } else if ( Blocks.Length == 1 || ( Blocks.Length == 2 && Blocks[1] == Block.Undefined ) ) { return String.Format( "{0}({1})", Factory.Name, Blocks[0] ); } else { StringBuilder sb = new StringBuilder(); sb.Append( Factory.Name ); sb.Append( '(' ); - for( int i = 0; i < Blocks.Length; i++ ) { - if( i != 0 ) sb.Append( ',' ).Append( ' ' ); + for ( int i = 0; i < Blocks.Length; i++ ) { + if ( i != 0 ) + sb.Append( ',' ).Append( ' ' ); sb.Append( Blocks[i] ); - if( BlockRatios[i] > 1 ) { + if ( BlockRatios[i] > 1 ) { sb.Append( '/' ); sb.Digits( BlockRatios[i] ); } @@ -131,44 +133,46 @@ public string Description { } } - [CanBeNull] public IBrushInstance MakeInstance( [NotNull] Player player, [NotNull] Command cmd, [NotNull] DrawOperation state ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); - if( state == null ) throw new ArgumentNullException( "state" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); + if ( state == null ) + throw new ArgumentNullException( "state" ); List blocks = new List(); List blockRatios = new List(); - while( cmd.HasNext ) { + while ( cmd.HasNext ) { int ratio = 1; Block block = cmd.NextBlockWithParam( player, ref ratio ); - if( ratio < 0 || ratio > MaxRatio ) { + if ( ratio < 0 || ratio > MaxRatio ) { player.Message( "Invalid block ratio ({0}). Must be between 1 and {1}.", ratio, MaxRatio ); return null; } - if( block == Block.Undefined ) return null; + if ( block == Block.Undefined ) + return null; blocks.Add( block ); blockRatios.Add( ratio ); } - if( blocks.Count == 0 ) { - if( Blocks.Length == 0 ) { + if ( blocks.Count == 0 ) { + if ( Blocks.Length == 0 ) { player.Message( "{0} brush: Please specify at least one block.", Factory.Name ); return null; } else { return new RandomBrush( this ); } - } else if( blocks.Count == 1 ) { + } else if ( blocks.Count == 1 ) { return new RandomBrush( blocks[0], blockRatios[0] ); } else { return new RandomBrush( blocks.ToArray(), blockRatios.ToArray() ); } } - #endregion - + #endregion IBrush members #region IBrushInstance members @@ -176,39 +180,38 @@ public IBrush Brush { get { return this; } } - public bool HasAlternateBlock { get { return false; } } - public string InstanceDescription { get { return Description; } } - public bool Begin( [NotNull] Player player, [NotNull] DrawOperation op ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( op == null ) throw new ArgumentNullException( "op" ); - if( Blocks == null || Blocks.Length == 0 ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); + if ( Blocks == null || Blocks.Length == 0 ) { throw new InvalidOperationException( "No blocks given." ); } return true; } - public Block NextBlock( [NotNull] DrawOperation op ) { - if( op == null ) throw new ArgumentNullException( "op" ); - int n = seed ^ (op.Coords.X + 1290 * op.Coords.Y + 1664510 * op.Coords.Z); - n = (n << 13) ^ n; - n = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7FFFFFFF; - double derp = (((double)n) / (double)0x7FFFFFFF) * actualBlocks.Length; - return actualBlocks[(int)Math.Floor( derp )]; + if ( op == null ) + throw new ArgumentNullException( "op" ); + int n = seed ^ ( op.Coords.X + 1290 * op.Coords.Y + 1664510 * op.Coords.Z ); + n = ( n << 13 ) ^ n; + n = ( n * ( n * n * 15731 + 789221 ) + 1376312589 ) & 0x7FFFFFFF; + double derp = ( ( ( double )n ) / ( double )0x7FFFFFFF ) * actualBlocks.Length; + return actualBlocks[( int )Math.Floor( derp )]; } + public void End() { + } - public void End() { } - - #endregion + #endregion IBrushInstance members } } \ No newline at end of file diff --git a/fCraft/Drawing/Brushes/ReplaceBrush.cs b/fCraft/Drawing/Brushes/ReplaceBrush.cs index 6f37bf8..4864d4d 100644 --- a/fCraft/Drawing/Brushes/ReplaceBrush.cs +++ b/fCraft/Drawing/Brushes/ReplaceBrush.cs @@ -4,10 +4,11 @@ using JetBrains.Annotations; namespace fCraft.Drawing { + public sealed class ReplaceBrushFactory : IBrushFactory { public static readonly ReplaceBrushFactory Instance = new ReplaceBrushFactory(); - ReplaceBrushFactory() { + private ReplaceBrushFactory() { Aliases = new[] { "r" }; } @@ -17,27 +18,30 @@ public string Name { public string[] Aliases { get; private set; } - const string HelpString = "Replace brush: Replaces blocks of a given type(s) with another type. " + + private const string HelpString = "Replace brush: Replaces blocks of a given type(s) with another type. " + "Usage similar to &H/Replace&S command."; + public string Help { get { return HelpString; } } - [CanBeNull] public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); Stack blocks = new Stack(); - while( cmd.HasNext ) { + while ( cmd.HasNext ) { Block block = cmd.NextBlock( player ); - if( block == Block.Undefined ) return null; + if ( block == Block.Undefined ) + return null; blocks.Push( block ); } - if( blocks.Count == 0 ) { + if ( blocks.Count == 0 ) { return new ReplaceBrush(); - } else if( blocks.Count == 1 ) { + } else if ( blocks.Count == 1 ) { return new ReplaceBrush( blocks.ToArray(), Block.Undefined ); } else { Block replacement = blocks.Pop(); @@ -46,38 +50,38 @@ public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { } } - public sealed class ReplaceBrush : IBrushInstance, IBrush { + public Block[] Blocks { get; private set; } + public Block Replacement { get; private set; } - public ReplaceBrush() { } + public ReplaceBrush() { + } public ReplaceBrush( Block[] blocks, Block replacement ) { Blocks = blocks; Replacement = replacement; } - public ReplaceBrush( [NotNull] ReplaceBrush other ) { - if( other == null ) throw new ArgumentNullException( "other" ); + if ( other == null ) + throw new ArgumentNullException( "other" ); Blocks = other.Blocks; Replacement = other.Replacement; } - #region IBrush members public IBrushFactory Factory { get { return ReplaceBrushFactory.Instance; } } - public string Description { get { - if( Blocks == null ) { + if ( Blocks == null ) { return Factory.Name; - } else if( Replacement == Block.Undefined ) { + } else if ( Replacement == Block.Undefined ) { return String.Format( "{0}({1} -> ?)", Factory.Name, Blocks.JoinToString() ); @@ -92,32 +96,36 @@ public string Description { [CanBeNull] public IBrushInstance MakeInstance( [NotNull] Player player, [NotNull] Command cmd, [NotNull] DrawOperation op ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); - if( op == null ) throw new ArgumentNullException( "op" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); Stack blocks = new Stack(); - while( cmd.HasNext ) { + while ( cmd.HasNext ) { Block block = cmd.NextBlock( player ); - if( block == Block.Undefined ) return null; + if ( block == Block.Undefined ) + return null; blocks.Push( block ); } - if( blocks.Count == 0 && Blocks == null ) { + if ( blocks.Count == 0 && Blocks == null ) { player.Message( "Replace brush requires at least 1 block." ); return null; } - if( blocks.Count > 0 ) { - if( blocks.Count > 1 ) Replacement = blocks.Pop(); + if ( blocks.Count > 0 ) { + if ( blocks.Count > 1 ) + Replacement = blocks.Pop(); Blocks = blocks.ToArray(); } return new ReplaceBrush( this ); } - #endregion - + #endregion IBrush members #region IBrushInstance members @@ -125,25 +133,24 @@ public IBrush Brush { get { return this; } } - public bool HasAlternateBlock { get { return false; } } - public string InstanceDescription { get { return Description; } } - public bool Begin( [NotNull] Player player, [NotNull] DrawOperation op ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( op == null ) throw new ArgumentNullException( "op" ); - if( Blocks == null || Blocks.Length == 0 ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); + if ( Blocks == null || Blocks.Length == 0 ) { throw new InvalidOperationException( "No blocks given." ); } - if( Replacement == Block.Undefined ) { - if( player.LastUsedBlockType == Block.Undefined ) { + if ( Replacement == Block.Undefined ) { + if ( player.LastUsedBlockType == Block.Undefined ) { player.Message( "Cannot deduce desired replacement block. Click a block or type out the block name." ); return false; } else { @@ -154,23 +161,23 @@ public bool Begin( [NotNull] Player player, [NotNull] DrawOperation op ) { return true; } - public Block NextBlock( [NotNull] DrawOperation op ) { - if( op == null ) throw new ArgumentNullException( "op" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); Block block = op.Map.GetBlock( op.Coords ); // ReSharper disable LoopCanBeConvertedToQuery - for( int i = 0; i < Blocks.Length; i++ ) { + for ( int i = 0; i < Blocks.Length; i++ ) { // ReSharper restore LoopCanBeConvertedToQuery - if( block == Blocks[i] ) { + if ( block == Blocks[i] ) { return Replacement; } } return Block.Undefined; } + public void End() { + } - public void End() { } - - #endregion + #endregion IBrushInstance members } } \ No newline at end of file diff --git a/fCraft/Drawing/Brushes/ReplaceBrushBrush.cs b/fCraft/Drawing/Brushes/ReplaceBrushBrush.cs index d5eb674..34c3763 100644 --- a/fCraft/Drawing/Brushes/ReplaceBrushBrush.cs +++ b/fCraft/Drawing/Brushes/ReplaceBrushBrush.cs @@ -3,11 +3,12 @@ using JetBrains.Annotations; namespace fCraft.Drawing { + public sealed class ReplaceBrushBrushFactory : IBrushFactory { public static readonly ReplaceBrushBrushFactory Instance = new ReplaceBrushBrushFactory(); - ReplaceBrushBrushFactory() { - Aliases=new[] { "rb" }; + private ReplaceBrushBrushFactory() { + Aliases = new[] { "rb" }; } public string Name { @@ -16,39 +17,43 @@ public string Name { public string[] Aliases { get; private set; } - const string HelpString = "ReplaceBrush brush: Replaces blocks of a given type with output of another brush. " + + private const string HelpString = "ReplaceBrush brush: Replaces blocks of a given type with output of another brush. " + "Usage: &H/Brush rb "; + public string Help { get { return HelpString; } } [CanBeNull] public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); - if( !cmd.HasNext ) { + if ( !cmd.HasNext ) { player.Message( "ReplaceBrush usage: &H/Brush rb " ); return null; } Block block = cmd.NextBlock( player ); - if( block == Block.Undefined ) return null; + if ( block == Block.Undefined ) + return null; string brushName = cmd.Next(); - if( brushName == null || !CommandManager.IsValidCommandName( brushName ) ) { + if ( brushName == null || !CommandManager.IsValidCommandName( brushName ) ) { player.Message( "ReplaceBrush usage: &H/Brush rb " ); return null; } IBrushFactory brushFactory = BrushManager.GetBrushFactory( brushName ); - if( brushFactory == null ) { + if ( brushFactory == null ) { player.Message( "Unrecognized brush \"{0}\"", brushName ); return null; } IBrush newBrush = brushFactory.MakeBrush( player, cmd ); - if( newBrush == null ) { + if ( newBrush == null ) { return null; } @@ -56,32 +61,33 @@ public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { } } - public sealed class ReplaceBrushBrush : IBrushInstance, IBrush { + public Block Block { get; private set; } + public IBrush Replacement { get; private set; } + public IBrushInstance ReplacementInstance { get; private set; } public ReplaceBrushBrush( Block block, [NotNull] IBrush replacement ) { - Block=block; - Replacement=replacement; + Block = block; + Replacement = replacement; } public ReplaceBrushBrush( [NotNull] ReplaceBrushBrush other ) { - if( other == null ) throw new ArgumentNullException( "other" ); + if ( other == null ) + throw new ArgumentNullException( "other" ); Block = other.Block; Replacement = other.Replacement; ReplacementInstance = other.ReplacementInstance; } - #region IBrush members public IBrushFactory Factory { get { return ReplaceBrushBrushFactory.Instance; } } - public string Description { get { return String.Format( "{0}({1} -> {2})", @@ -91,31 +97,34 @@ public string Description { } } - [CanBeNull] public IBrushInstance MakeInstance( [NotNull] Player player, [NotNull] Command cmd, [NotNull] DrawOperation op ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); - if( op == null ) throw new ArgumentNullException( "op" ); - - if( cmd.HasNext ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); + + if ( cmd.HasNext ) { Block block = cmd.NextBlock( player ); - if( block == Block.Undefined ) return null; + if ( block == Block.Undefined ) + return null; string brushName = cmd.Next(); - if( brushName == null || !CommandManager.IsValidCommandName( brushName ) ) { + if ( brushName == null || !CommandManager.IsValidCommandName( brushName ) ) { player.Message( "ReplaceBrush usage: &H/Brush rb " ); return null; } IBrushFactory brushFactory = BrushManager.GetBrushFactory( brushName ); - if( brushFactory == null ) { + if ( brushFactory == null ) { player.Message( "Unrecognized brush \"{0}\"", brushName ); return null; } IBrush replacement = brushFactory.MakeBrush( player, cmd ); - if( replacement == null ) { + if ( replacement == null ) { return null; } Block = block; @@ -123,13 +132,13 @@ public IBrushInstance MakeInstance( [NotNull] Player player, [NotNull] Command c } ReplacementInstance = Replacement.MakeInstance( player, cmd, op ); - if( ReplacementInstance == null ) return null; + if ( ReplacementInstance == null ) + return null; return new ReplaceBrushBrush( this ); } - #endregion - + #endregion IBrush members #region IBrushInstance members @@ -137,39 +146,37 @@ public IBrush Brush { get { return this; } } - public bool HasAlternateBlock { get { return false; } } - public string InstanceDescription { get { return Description; } } - public bool Begin( [NotNull] Player player, [NotNull] DrawOperation op ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( op == null ) throw new ArgumentNullException( "op" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); op.Context |= BlockChangeContext.Replaced; return ReplacementInstance.Begin( player, op ); } - public Block NextBlock( [NotNull] DrawOperation op ) { - if( op == null ) throw new ArgumentNullException( "op" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); Block block = op.Map.GetBlock( op.Coords ); - if( block == Block ) { + if ( block == Block ) { return ReplacementInstance.NextBlock( op ); } return Block.Undefined; } - public void End() { ReplacementInstance.End(); } - #endregion + #endregion IBrushInstance members } } \ No newline at end of file diff --git a/fCraft/Drawing/Brushes/ReplaceNotBrush.cs b/fCraft/Drawing/Brushes/ReplaceNotBrush.cs index 6ead243..f5d87f6 100644 --- a/fCraft/Drawing/Brushes/ReplaceNotBrush.cs +++ b/fCraft/Drawing/Brushes/ReplaceNotBrush.cs @@ -4,10 +4,11 @@ using JetBrains.Annotations; namespace fCraft.Drawing { + public sealed class ReplaceNotBrushFactory : IBrushFactory { public static readonly ReplaceNotBrushFactory Instance = new ReplaceNotBrushFactory(); - ReplaceNotBrushFactory() { + private ReplaceNotBrushFactory() { Aliases = new[] { "rn" }; } @@ -17,27 +18,30 @@ public string Name { public string[] Aliases { get; private set; } - const string HelpString = "ReplaceNot brush: Replaces all blocks except the given type(s) with another type. " + + private const string HelpString = "ReplaceNot brush: Replaces all blocks except the given type(s) with another type. " + "Usage similar to &H/ReplaceNot&S command."; + public string Help { get { return HelpString; } } - [CanBeNull] public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); Stack blocks = new Stack(); - while( cmd.HasNext ) { + while ( cmd.HasNext ) { Block block = cmd.NextBlock( player ); - if( block == Block.Undefined ) return null; + if ( block == Block.Undefined ) + return null; blocks.Push( block ); } - if( blocks.Count == 0 ) { + if ( blocks.Count == 0 ) { return new ReplaceNotBrush(); - } else if( blocks.Count == 1 ) { + } else if ( blocks.Count == 1 ) { return new ReplaceNotBrush( blocks.ToArray(), Block.Undefined ); } else { Block replacement = blocks.Pop(); @@ -46,38 +50,38 @@ public IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ) { } } - public sealed class ReplaceNotBrush : IBrushInstance, IBrush { + public Block[] Blocks { get; private set; } + public Block Replacement { get; private set; } - public ReplaceNotBrush() { } + public ReplaceNotBrush() { + } public ReplaceNotBrush( Block[] blocks, Block replacement ) { Blocks = blocks; Replacement = replacement; } - public ReplaceNotBrush( [NotNull] ReplaceNotBrush other ) { - if( other == null ) throw new ArgumentNullException( "other" ); + if ( other == null ) + throw new ArgumentNullException( "other" ); Blocks = other.Blocks; Replacement = other.Replacement; } - #region IBrush members public IBrushFactory Factory { get { return ReplaceNotBrushFactory.Instance; } } - public string Description { get { - if( Blocks == null ) { + if ( Blocks == null ) { return Factory.Name; - } else if( Replacement == Block.Undefined ) { + } else if ( Replacement == Block.Undefined ) { return String.Format( "{0}({1} -> ?)", Factory.Name, Blocks.JoinToString() ); @@ -90,35 +94,38 @@ public string Description { } } - [CanBeNull] public IBrushInstance MakeInstance( [NotNull] Player player, [NotNull] Command cmd, [NotNull] DrawOperation op ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( cmd == null ) throw new ArgumentNullException( "cmd" ); - if( op == null ) throw new ArgumentNullException( "op" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); Stack blocks = new Stack(); - while( cmd.HasNext ) { + while ( cmd.HasNext ) { Block block = cmd.NextBlock( player ); - if( block == Block.Undefined ) return null; + if ( block == Block.Undefined ) + return null; blocks.Push( block ); } - if( blocks.Count == 0 && Blocks == null ) { + if ( blocks.Count == 0 && Blocks == null ) { player.Message( "ReplaceNot brush requires at least 1 block." ); return null; } - if( blocks.Count > 0 ) { - if( blocks.Count > 1 ) Replacement = blocks.Pop(); + if ( blocks.Count > 0 ) { + if ( blocks.Count > 1 ) + Replacement = blocks.Pop(); Blocks = blocks.ToArray(); } return new ReplaceNotBrush( this ); } - #endregion - + #endregion IBrush members #region IBrushInstance members @@ -126,25 +133,24 @@ public IBrush Brush { get { return this; } } - public bool HasAlternateBlock { get { return false; } } - public string InstanceDescription { get { return Description; } } - public bool Begin( [NotNull] Player player, [NotNull] DrawOperation op ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( op == null ) throw new ArgumentNullException( "op" ); - if( Blocks == null || Blocks.Length == 0 ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); + if ( Blocks == null || Blocks.Length == 0 ) { throw new InvalidOperationException( "No blocks given." ); } - if( Replacement == Block.Undefined ) { - if( player.LastUsedBlockType == Block.Undefined ) { + if ( Replacement == Block.Undefined ) { + if ( player.LastUsedBlockType == Block.Undefined ) { player.Message( "Cannot deduce desired replacement block. Click a block or type out the block name." ); return false; } else { @@ -155,23 +161,23 @@ public bool Begin( [NotNull] Player player, [NotNull] DrawOperation op ) { return true; } - public Block NextBlock( [NotNull] DrawOperation op ) { - if( op == null ) throw new ArgumentNullException( "op" ); + if ( op == null ) + throw new ArgumentNullException( "op" ); Block block = op.Map.GetBlock( op.Coords ); // ReSharper disable LoopCanBeConvertedToQuery - for( int i = 0; i < Blocks.Length; i++ ) { + for ( int i = 0; i < Blocks.Length; i++ ) { // ReSharper restore LoopCanBeConvertedToQuery - if( block == Blocks[i] ) { + if ( block == Blocks[i] ) { return Block.Undefined; } } return Replacement; } + public void End() { + } - public void End() { } - - #endregion + #endregion IBrushInstance members } } \ No newline at end of file diff --git a/fCraft/Drawing/CopyState.cs b/fCraft/Drawing/CopyState.cs index 75db605..7eb204f 100644 --- a/fCraft/Drawing/CopyState.cs +++ b/fCraft/Drawing/CopyState.cs @@ -3,7 +3,9 @@ using JetBrains.Annotations; namespace fCraft.Drawing { + public sealed class CopyState : ICloneable { + public CopyState( Vector3I mark1, Vector3I mark2 ) { BoundingBox box = new BoundingBox( mark1, mark2 ); Orientation = new Vector3I( mark1.X <= mark2.X ? 1 : -1, @@ -13,8 +15,9 @@ public CopyState( Vector3I mark1, Vector3I mark2 ) { } public CopyState( [NotNull] CopyState original ) { - if( original == null ) throw new ArgumentNullException(); - Buffer = (Block[, ,])original.Buffer.Clone(); + if ( original == null ) + throw new ArgumentNullException(); + Buffer = ( Block[, ,] )original.Buffer.Clone(); Orientation = original.Orientation; Slot = original.Slot; OriginWorld = original.OriginWorld; @@ -22,7 +25,8 @@ public CopyState( [NotNull] CopyState original ) { } public CopyState( [NotNull] CopyState original, [NotNull] Block[, ,] buffer ) { - if( original == null ) throw new ArgumentNullException(); + if ( original == null ) + throw new ArgumentNullException(); Buffer = buffer; Orientation = original.Orientation; Slot = original.Slot; @@ -31,19 +35,22 @@ public CopyState( [NotNull] CopyState original, [NotNull] Block[, ,] buffer ) { } public Block[, ,] Buffer { get; set; } + public Vector3I Dimensions { get { return new Vector3I( Buffer.GetLength( 0 ), Buffer.GetLength( 1 ), Buffer.GetLength( 2 ) ); } } + public Vector3I Orientation { get; set; } + public int Slot { get; set; } // using "string" instead of "World" here // to avoid keeping World on the GC after it has been removed. public string OriginWorld { get; set; } - public DateTime CopyTime { get; set; } + public DateTime CopyTime { get; set; } public object Clone() { return new CopyState( this ); diff --git a/fCraft/Drawing/DrawOpWithBrush.cs b/fCraft/Drawing/DrawOpWithBrush.cs index e9e1ddf..b0ef2e0 100644 --- a/fCraft/Drawing/DrawOpWithBrush.cs +++ b/fCraft/Drawing/DrawOpWithBrush.cs @@ -2,6 +2,7 @@ using System; namespace fCraft.Drawing { + /// A self-contained DrawOperation that prodivides its own brush. /// Purpose of this class is mostly to take care of the boilerplate code. public abstract class DrawOpWithBrush : DrawOperation, IBrushFactory, IBrush, IBrushInstance { @@ -16,10 +17,8 @@ protected DrawOpWithBrush( Player player ) public abstract bool ReadParams( Command cmd ); - protected abstract Block NextBlock(); - #region IBrushFactory Members string IBrushFactory.Name { @@ -38,8 +37,7 @@ IBrush IBrushFactory.MakeBrush( Player player, Command cmd ) { return this; } - #endregion - + #endregion IBrushFactory Members #region IBrush Members @@ -52,15 +50,14 @@ string IBrush.Description { } IBrushInstance IBrush.MakeInstance( Player player, Command cmd, DrawOperation op ) { - if( ReadParams( cmd ) ) { + if ( ReadParams( cmd ) ) { return this; } else { return null; } } - #endregion - + #endregion IBrush Members #region IBrushInstance Members @@ -84,8 +81,9 @@ Block IBrushInstance.NextBlock( DrawOperation op ) { return NextBlock(); } - void IBrushInstance.End() { } + void IBrushInstance.End() { + } - #endregion + #endregion IBrushInstance Members } } \ No newline at end of file diff --git a/fCraft/Drawing/DrawOperation.cs b/fCraft/Drawing/DrawOperation.cs index 2b4b8d0..27dbc68 100644 --- a/fCraft/Drawing/DrawOperation.cs +++ b/fCraft/Drawing/DrawOperation.cs @@ -9,8 +9,10 @@ // ReSharper disable UnusedMemberInSuper.Global // ReSharper disable MemberCanBeProtected.Global namespace fCraft.Drawing { + /// Abstract class representing a drawing operation. public abstract class DrawOperation { + /// Expected number of marks to pass to DrawOperation.Prepare() public virtual int ExpectedMarks { get { return 2; } @@ -30,7 +32,7 @@ public virtual int ExpectedMarks { [NotNull] public IBrushInstance Brush { get; set; } - /// Block change context, to be reported to BlockDB and Player.PlacingBlock/PlacedBlock events. + /// Block change context, to be reported to BlockDB and Player.PlacingBlock/PlacedBlock events. /// Should include BlockChangeContext.Drawn flag. public BlockChangeContext Context { get; set; } @@ -86,12 +88,12 @@ public int BlocksLeftToProcess { /// Approximate completion percentage of this command. public int PercentDone { get { - if( !HasBegun ) { + if ( !HasBegun ) { return 0; - }else if( IsDone ) { + } else if ( IsDone ) { return 100; } else { - return Math.Min( 100, Math.Max( 0, (BlocksProcessed * 100) / BlocksTotalEstimate ) ); + return Math.Min( 100, Math.Max( 0, ( BlocksProcessed * 100 ) / BlocksTotalEstimate ) ); } } } @@ -121,23 +123,22 @@ public virtual string Description { /// Whether completion or cancellation of this DrawOperation should be logged. public bool LogCompletion { get; set; } + private const int MaxBlocksToProcessPerBatch = 25000; + private int batchStartProcessedCount; - const int MaxBlocksToProcessPerBatch = 25000; - int batchStartProcessedCount; protected bool TimeToEndBatch { get { - return (BlocksProcessed - batchStartProcessedCount) > MaxBlocksToProcessPerBatch; + return ( BlocksProcessed - batchStartProcessedCount ) > MaxBlocksToProcessPerBatch; } } - internal void StartBatch() { batchStartProcessedCount = BlocksProcessed; } - protected DrawOperation( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Player = player; Map = player.WorldMap; @@ -146,27 +147,28 @@ protected DrawOperation( [NotNull] Player player ) { LogCompletion = true; } - public virtual bool Prepare( [NotNull] Vector3I[] marks ) { - if( marks == null ) throw new ArgumentNullException( "marks" ); - if( marks.Length != ExpectedMarks ) { + if ( marks == null ) + throw new ArgumentNullException( "marks" ); + if ( marks.Length != ExpectedMarks ) { string msg = String.Format( "Wrong number of marks ({0}), expecting {1}.", marks.Length, ExpectedMarks ); throw new ArgumentException( msg, "marks" ); } Marks = marks; - if( marks.Length == 2 ) { + if ( marks.Length == 2 ) { Bounds = new BoundingBox( Marks[0], Marks[1] ); } - if( Brush == null ) throw new NullReferenceException( Name + ": Brush not set" ); + if ( Brush == null ) + throw new NullReferenceException( Name + ": Brush not set" ); return Brush.Begin( Player, this ); } - public virtual bool Begin() { - if( !RaiseBeginningEvent( this ) ) return false; + if ( !RaiseBeginningEvent( this ) ) + return false; UndoState = Player.DrawBegin( this ); StartTime = DateTime.UtcNow; HasBegun = true; @@ -175,17 +177,14 @@ public virtual bool Begin() { return true; } - public abstract int DrawBatch( int maxBlocksToDraw ); - public void Cancel() { IsCancelled = true; } - internal void End() { - if( IsCancelled ) { + if ( IsCancelled ) { OnCancellation(); } else { OnCompletion(); @@ -195,11 +194,10 @@ internal void End() { RaiseEndedEvent( this ); } - protected bool DrawOneBlock() { BlocksProcessed++; - if( !Map.InBounds( Coords ) ) { + if ( !Map.InBounds( Coords ) ) { BlocksSkipped++; return false; } @@ -209,33 +207,34 @@ protected bool DrawOneBlock() { #endif Block newBlock = Brush.NextBlock( this ); - if( newBlock == Block.Undefined ) return false; + if ( newBlock == Block.Undefined ) + return false; int blockIndex = Map.Index( Coords ); - Block oldBlock = (Block)Map.Blocks[blockIndex]; - if( oldBlock == newBlock ) { + Block oldBlock = ( Block )Map.Blocks[blockIndex]; + if ( oldBlock == newBlock ) { BlocksSkipped++; return false; } - if( Player.CanPlace( Map, Coords, newBlock, Context ) != CanPlaceResult.Allowed ) { + if ( Player.CanPlace( Map, Coords, newBlock, Context ) != CanPlaceResult.Allowed ) { BlocksDenied++; return false; } - Map.Blocks[blockIndex] = (byte)newBlock; + Map.Blocks[blockIndex] = ( byte )newBlock; World world = Map.World; - if( world != null && !world.IsFlushing ) { + if ( world != null && !world.IsFlushing ) { world.Players.SendLowPriority( PacketWriter.MakeSetBlock( Coords, newBlock ) ); } Player.RaisePlayerPlacedBlockEvent( Player, Map, Coords, oldBlock, newBlock, Context ); - if( !UndoState.IsTooLargeToUndo ) { - if( !UndoState.Add( Coords, oldBlock ) ) { + if ( !UndoState.IsTooLargeToUndo ) { + if ( !UndoState.Add( Coords, oldBlock ) ) { Player.LastDrawOp = null; Player.Message( "{0}: Too many blocks to undo.", Description ); } @@ -245,9 +244,8 @@ protected bool DrawOneBlock() { return true; } - // Contributed by Conrad "Redshift" Morgan - protected static IEnumerable LineEnumerator( Vector3I a, Vector3I b) { + protected static IEnumerable LineEnumerator( Vector3I a, Vector3I b ) { Vector3I pixel = a; Vector3I d = b - a; Vector3I inc = new Vector3I( Math.Sign( d.X ), @@ -257,23 +255,29 @@ protected static IEnumerable LineEnumerator( Vector3I a, Vector3I b) { Vector3I d2 = d * 2; int x, y, z; - if( (d.X >= d.Y) && (d.X >= d.Z) ) { - x = 0; y = 1; z = 2; - } else if( (d.Y >= d.X) && (d.Y >= d.Z) ) { - x = 1; y = 2; z = 0; + if ( ( d.X >= d.Y ) && ( d.X >= d.Z ) ) { + x = 0; + y = 1; + z = 2; + } else if ( ( d.Y >= d.X ) && ( d.Y >= d.Z ) ) { + x = 1; + y = 2; + z = 0; } else { - x = 2; y = 0; z = 1; + x = 2; + y = 0; + z = 1; } int err1 = d2[y] - d[x]; int err2 = d2[z] - d[x]; - for( int i = 0; i < d[x]; i++ ) { + for ( int i = 0; i < d[x]; i++ ) { yield return pixel; - if( err1 > 0 ) { + if ( err1 > 0 ) { pixel[y] += inc[y]; err1 -= d2[x]; } - if( err2 > 0 ) { + if ( err2 > 0 ) { pixel[z] += inc[z]; err2 -= d2[x]; } @@ -285,12 +289,10 @@ protected static IEnumerable LineEnumerator( Vector3I a, Vector3I b) { yield return b; } - - - void OnCompletion() { - if( AnnounceCompletion ) { - if( BlocksUpdated > 0 ) { - if( BlocksDenied > 0 ) { + private void OnCompletion() { + if ( AnnounceCompletion ) { + if ( BlocksUpdated > 0 ) { + if ( BlocksDenied > 0 ) { Player.Message( "{0}: Finished in {1}, updated {2} blocks. &WSkipped {3} blocks due to permission issues.", Description, DateTime.UtcNow.Subtract( StartTime ).ToMiniString(), @@ -302,7 +304,7 @@ void OnCompletion() { BlocksUpdated ); } } else { - if( BlocksDenied > 0 ) { + if ( BlocksDenied > 0 ) { Player.Message( "{0}: Finished in {1}, no changes made. &WSkipped {2} blocks due to permission issues.", Description, DateTime.UtcNow.Subtract( StartTime ).ToMiniString(), @@ -314,7 +316,7 @@ void OnCompletion() { } } } - if( AnnounceCompletion && Map.World != null ) { + if ( AnnounceCompletion && Map.World != null ) { Logger.Log( LogType.UserActivity, "Player {0} executed {1} on world {2} (between {3} and {4}). Processed {5}, Updated {6}, Skipped {7}, Denied {8} blocks.", Player.Name, Description, Map.World.Name, @@ -323,10 +325,9 @@ void OnCompletion() { } } - - void OnCancellation() { - if( AnnounceCompletion ) { - if( BlocksDenied > 0 ) { + private void OnCancellation() { + if ( AnnounceCompletion ) { + if ( BlocksDenied > 0 ) { Player.Message( "{0}: Cancelled after {1}. Processed {2}, updated {3}. Skipped {4} due to permission issues.", Description, DateTime.UtcNow.Subtract( StartTime ).ToMiniString(), @@ -338,7 +339,7 @@ void OnCancellation() { BlocksProcessed, BlocksUpdated ); } } - if( LogCompletion && Map.World != null ) { + if ( LogCompletion && Map.World != null ) { Logger.Log( LogType.UserActivity, "Player {0} cancelled {1} on world {2}. Processed {3}, Updated {4}, Skipped {5}, Denied {6} blocks.", Player, Description, Map.World.Name, @@ -362,13 +363,16 @@ void TestForDuplicateModification() { #region Events public static event EventHandler Beginning; + public static event EventHandler Began; + public static event EventHandler Ended; // Returns false if cancelled protected static bool RaiseBeginningEvent( DrawOperation op ) { var h = Beginning; - if( h == null ) return true; + if ( h == null ) + return true; var e = new DrawOperationBeginningEventArgs( op ); h( null, e ); return !e.Cancel; @@ -376,32 +380,39 @@ protected static bool RaiseBeginningEvent( DrawOperation op ) { protected static void RaiseBeganEvent( DrawOperation op ) { var h = Began; - if( h != null ) h( null, new DrawOperationEventArgs( op ) ); + if ( h != null ) + h( null, new DrawOperationEventArgs( op ) ); } protected static void RaiseEndedEvent( DrawOperation op ) { var h = Ended; - if( h != null ) h( null, new DrawOperationEventArgs( op ) ); + if ( h != null ) + h( null, new DrawOperationEventArgs( op ) ); } - #endregion + #endregion Events } } namespace fCraft.Events { - public sealed class DrawOperationEventArgs : EventArgs{ + + public sealed class DrawOperationEventArgs : EventArgs { + public DrawOperationEventArgs( DrawOperation drawOp ) { DrawOp = drawOp; } + public DrawOperation DrawOp { get; private set; } } - public sealed class DrawOperationBeginningEventArgs : EventArgs, ICancellableEvent { + public DrawOperationBeginningEventArgs( DrawOperation drawOp ) { DrawOp = drawOp; } + public DrawOperation DrawOp { get; private set; } + public bool Cancel { get; set; } } } \ No newline at end of file diff --git a/fCraft/Drawing/DrawOps/BlockDBDrawOperation.cs b/fCraft/Drawing/DrawOps/BlockDBDrawOperation.cs index a5d982b..9fbb5a4 100644 --- a/fCraft/Drawing/DrawOps/BlockDBDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/BlockDBDrawOperation.cs @@ -2,19 +2,18 @@ using System; namespace fCraft.Drawing { + /// Draw operation that applies changes from a given BlockDBEntry array. public sealed class BlockDBDrawOperation : DrawOpWithBrush { - BlockDBEntry[] changes; - int entryIndex; - Block block; - readonly string commandName; - + private BlockDBEntry[] changes; + private int entryIndex; + private Block block; + private readonly string commandName; public override string Name { get { return commandName; } } - public override string Description { get { if ( String.IsNullOrEmpty( paramDescription ) ) { @@ -24,37 +23,38 @@ public override string Description { } } } - readonly string paramDescription; + private readonly string paramDescription; public override int ExpectedMarks { get { return expectedMarks; } } - readonly int expectedMarks; + private readonly int expectedMarks; - public BlockDBDrawOperation ( Player player, string commandName, string paramDescription, int expectedMarks ) + public BlockDBDrawOperation( Player player, string commandName, string paramDescription, int expectedMarks ) : base( player ) { - if ( commandName == null ) throw new ArgumentNullException( "commandName" ); + if ( commandName == null ) + throw new ArgumentNullException( "commandName" ); this.paramDescription = paramDescription; this.commandName = commandName; this.expectedMarks = expectedMarks; } - - public bool Prepare ( Vector3I[] marks, BlockDBEntry[] changesToApply ) { - if ( changesToApply == null ) throw new ArgumentNullException( "changesToApply" ); + public bool Prepare( Vector3I[] marks, BlockDBEntry[] changesToApply ) { + if ( changesToApply == null ) + throw new ArgumentNullException( "changesToApply" ); changes = changesToApply; return Prepare( marks ); } - - public override bool Prepare ( Vector3I[] marks ) { + public override bool Prepare( Vector3I[] marks ) { if ( changes == null ) { throw new InvalidOperationException( "Call the other overload to set entriesToUndo" ); } Brush = this; - if ( !base.Prepare( marks ) ) return false; + if ( !base.Prepare( marks ) ) + return false; BlocksTotalEstimate = changes.Length; if ( marks.Length != 2 ) { Bounds = FindBounds(); @@ -62,24 +62,29 @@ public override bool Prepare ( Vector3I[] marks ) { return true; } - - BoundingBox FindBounds () { - if ( changes.Length == 0 ) return BoundingBox.Empty; + private BoundingBox FindBounds() { + if ( changes.Length == 0 ) + return BoundingBox.Empty; Vector3I min = new Vector3I( int.MaxValue, int.MaxValue, int.MaxValue ); Vector3I max = new Vector3I( int.MinValue, int.MinValue, int.MinValue ); for ( int i = 0; i < changes.Length; i++ ) { - if ( changes[i].X < min.X ) min.X = changes[i].X; - if ( changes[i].Y < min.Y ) min.Y = changes[i].Y; - if ( changes[i].Z < min.Z ) min.Z = changes[i].Z; - if ( changes[i].X > max.X ) max.X = changes[i].X; - if ( changes[i].Y > max.Y ) max.Y = changes[i].Y; - if ( changes[i].Z > max.Z ) max.Z = changes[i].Z; + if ( changes[i].X < min.X ) + min.X = changes[i].X; + if ( changes[i].Y < min.Y ) + min.Y = changes[i].Y; + if ( changes[i].Z < min.Z ) + min.Z = changes[i].Z; + if ( changes[i].X > max.X ) + max.X = changes[i].X; + if ( changes[i].Y > max.Y ) + max.Y = changes[i].Y; + if ( changes[i].Z > max.Z ) + max.Z = changes[i].Z; } return new BoundingBox( min, max ); } - - public override int DrawBatch ( int maxBlocksToDraw ) { + public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; for ( ; entryIndex < changes.Length; entryIndex++ ) { BlockDBEntry entry = changes[entryIndex]; @@ -102,13 +107,11 @@ public override int DrawBatch ( int maxBlocksToDraw ) { return blocksDone; } - - protected override Block NextBlock () { + protected override Block NextBlock() { return block; } - - public override bool ReadParams ( Command cmd ) { + public override bool ReadParams( Command cmd ) { return true; } } diff --git a/fCraft/Drawing/DrawOps/CuboidDrawOperation.cs b/fCraft/Drawing/DrawOps/CuboidDrawOperation.cs index e2531d5..57426b3 100644 --- a/fCraft/Drawing/DrawOps/CuboidDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/CuboidDrawOperation.cs @@ -1,7 +1,9 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft.Drawing { + public sealed class CuboidDrawOperation : DrawOperation { + public override string Name { get { return "Cuboid"; } } @@ -10,23 +12,23 @@ public CuboidDrawOperation( Player player ) : base( player ) { } - public override bool Prepare( Vector3I[] marks ) { - if( !base.Prepare( marks ) ) return false; + if ( !base.Prepare( marks ) ) + return false; BlocksTotalEstimate = Bounds.Volume; Coords = Bounds.MinVertex; return true; } - public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; - for( ; Coords.X <= Bounds.XMax; Coords.X++ ) { - for( ; Coords.Y <= Bounds.YMax; Coords.Y++ ) { - for( ; Coords.Z <= Bounds.ZMax; Coords.Z++ ) { - if( !DrawOneBlock() ) continue; + for ( ; Coords.X <= Bounds.XMax; Coords.X++ ) { + for ( ; Coords.Y <= Bounds.YMax; Coords.Y++ ) { + for ( ; Coords.Z <= Bounds.ZMax; Coords.Z++ ) { + if ( !DrawOneBlock() ) + continue; blocksDone++; - if( blocksDone >= maxBlocksToDraw ) { + if ( blocksDone >= maxBlocksToDraw ) { Coords.Z++; return blocksDone; } @@ -34,7 +36,7 @@ public override int DrawBatch( int maxBlocksToDraw ) { Coords.Z = Bounds.ZMin; } Coords.Y = Bounds.YMin; - if( TimeToEndBatch ) { + if ( TimeToEndBatch ) { Coords.X++; return blocksDone; } diff --git a/fCraft/Drawing/DrawOps/CuboidHollowDrawOperation.cs b/fCraft/Drawing/DrawOps/CuboidHollowDrawOperation.cs index 43a9dd8..79fc5e7 100644 --- a/fCraft/Drawing/DrawOps/CuboidHollowDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/CuboidHollowDrawOperation.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; namespace fCraft.Drawing { + public sealed class CuboidHollowDrawOperation : DrawOperation { - bool fillInner; + private bool fillInner; public override string Name { get { return "CuboidH"; } @@ -14,14 +15,14 @@ public CuboidHollowDrawOperation( Player player ) : base( player ) { } - public override bool Prepare( Vector3I[] marks ) { - if( !base.Prepare( marks ) ) return false; + if ( !base.Prepare( marks ) ) + return false; fillInner = Brush.HasAlternateBlock && Bounds.Width > 2 && Bounds.Length > 2 && Bounds.Height > 2; BlocksTotalEstimate = Bounds.Volume; - if( !fillInner ) { + if ( !fillInner ) { BlocksTotalEstimate -= Math.Max( 0, Bounds.Width - 2 ) * Math.Max( 0, Bounds.Length - 2 ) * Math.Max( 0, Bounds.Height - 2 ); } @@ -29,58 +30,59 @@ public override bool Prepare( Vector3I[] marks ) { return true; } + private IEnumerator coordEnumerator; - IEnumerator coordEnumerator; public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; - while( coordEnumerator.MoveNext() ) { + while ( coordEnumerator.MoveNext() ) { Coords = coordEnumerator.Current; - if( DrawOneBlock() ) { + if ( DrawOneBlock() ) { blocksDone++; - if( blocksDone >= maxBlocksToDraw ) return blocksDone; + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; } - if( TimeToEndBatch ) return blocksDone; + if ( TimeToEndBatch ) + return blocksDone; } IsDone = true; return blocksDone; } - - IEnumerable BlockEnumerator() { - for( int x = Bounds.XMin; x <= Bounds.XMax; x++ ) { - for( int y = Bounds.YMin; y <= Bounds.YMax; y++ ) { + private IEnumerable BlockEnumerator() { + for ( int x = Bounds.XMin; x <= Bounds.XMax; x++ ) { + for ( int y = Bounds.YMin; y <= Bounds.YMax; y++ ) { yield return new Vector3I( x, y, Bounds.ZMin ); - if( Bounds.ZMin != Bounds.ZMax ) { + if ( Bounds.ZMin != Bounds.ZMax ) { yield return new Vector3I( x, y, Bounds.ZMax ); } } } - if( Bounds.Height > 2 ) { - for( int x = Bounds.XMin; x <= Bounds.XMax; x++ ) { - for( int z = Bounds.ZMin + 1; z < Bounds.ZMax; z++ ) { + if ( Bounds.Height > 2 ) { + for ( int x = Bounds.XMin; x <= Bounds.XMax; x++ ) { + for ( int z = Bounds.ZMin + 1; z < Bounds.ZMax; z++ ) { yield return new Vector3I( x, Bounds.YMin, z ); - if( Bounds.YMin != Bounds.YMax ) { + if ( Bounds.YMin != Bounds.YMax ) { yield return new Vector3I( x, Bounds.YMax, z ); } } } - for( int y = Bounds.YMin + 1; y < Bounds.YMax; y++ ) { - for( int z = Bounds.ZMin + 1; z < Bounds.ZMax; z++ ) { + for ( int y = Bounds.YMin + 1; y < Bounds.YMax; y++ ) { + for ( int z = Bounds.ZMin + 1; z < Bounds.ZMax; z++ ) { yield return new Vector3I( Bounds.XMin, y, z ); - if( Bounds.XMin != Bounds.XMax ) { + if ( Bounds.XMin != Bounds.XMax ) { yield return new Vector3I( Bounds.XMax, y, z ); } } } } - if( fillInner ) { + if ( fillInner ) { UseAlternateBlock = true; - for( int x = Bounds.XMin + 1; x < Bounds.XMax; x++ ) { - for( int y = Bounds.YMin + 1; y < Bounds.YMax; y++ ) { - for( int z = Bounds.ZMin + 1; z < Bounds.ZMax; z++ ) { + for ( int x = Bounds.XMin + 1; x < Bounds.XMax; x++ ) { + for ( int y = Bounds.YMin + 1; y < Bounds.YMax; y++ ) { + for ( int z = Bounds.ZMin + 1; z < Bounds.ZMax; z++ ) { yield return new Vector3I( x, y, z ); } } diff --git a/fCraft/Drawing/DrawOps/CuboidWireframeDrawOperation.cs b/fCraft/Drawing/DrawOps/CuboidWireframeDrawOperation.cs index a3439b1..d4ac108 100644 --- a/fCraft/Drawing/DrawOps/CuboidWireframeDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/CuboidWireframeDrawOperation.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; namespace fCraft.Drawing { + public sealed class CuboidWireframeDrawOperation : DrawOperation { + public override string Name { get { return "CuboidW"; } } @@ -12,14 +14,14 @@ public CuboidWireframeDrawOperation( Player player ) : base( player ) { } - public override bool Prepare( Vector3I[] marks ) { - if( !base.Prepare( marks ) ) return false; + if ( !base.Prepare( marks ) ) + return false; int hollowVolume = Math.Max( 0, Bounds.Width - 2 ) * Math.Max( 0, Bounds.Length - 2 ) * Math.Max( 0, Bounds.Height - 2 ); - int sideVolumeX = Math.Max( 0, Bounds.Width - 2 ) * Math.Max( 0, Bounds.Length - 2 ) * (Bounds.ZMax != Bounds.ZMin ? 2 : 1); - int sideVolumeY = Math.Max( 0, Bounds.Length - 2 ) * Math.Max( 0, Bounds.Height - 2 ) * (Bounds.XMax != Bounds.XMin ? 2 : 1); - int sideVolumeZ = Math.Max( 0, Bounds.Height - 2 ) * Math.Max( 0, Bounds.Width - 2 ) * (Bounds.YMax != Bounds.YMin ? 2 : 1); + int sideVolumeX = Math.Max( 0, Bounds.Width - 2 ) * Math.Max( 0, Bounds.Length - 2 ) * ( Bounds.ZMax != Bounds.ZMin ? 2 : 1 ); + int sideVolumeY = Math.Max( 0, Bounds.Length - 2 ) * Math.Max( 0, Bounds.Height - 2 ) * ( Bounds.XMax != Bounds.XMin ? 2 : 1 ); + int sideVolumeZ = Math.Max( 0, Bounds.Height - 2 ) * Math.Max( 0, Bounds.Width - 2 ) * ( Bounds.YMax != Bounds.YMin ? 2 : 1 ); BlocksTotalEstimate = Bounds.Volume - hollowVolume - sideVolumeX - sideVolumeY - sideVolumeZ; @@ -27,73 +29,83 @@ public override bool Prepare( Vector3I[] marks ) { return true; } + private IEnumerator coordEnumerator; - IEnumerator coordEnumerator; public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; - while( coordEnumerator.MoveNext() ) { + while ( coordEnumerator.MoveNext() ) { Coords = coordEnumerator.Current; - if( DrawOneBlock() ) { + if ( DrawOneBlock() ) { blocksDone++; - if( blocksDone >= maxBlocksToDraw ) return blocksDone; + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; } - if( TimeToEndBatch ) return blocksDone; + if ( TimeToEndBatch ) + return blocksDone; } IsDone = true; return blocksDone; } - - IEnumerable BlockEnumerator() { + private IEnumerable BlockEnumerator() { // Draw cuboid vertices yield return new Vector3I( Bounds.XMin, Bounds.YMin, Bounds.ZMin ); - if( Bounds.XMin != Bounds.XMax ) yield return new Vector3I( Bounds.XMax, Bounds.YMin, Bounds.ZMin ); - if( Bounds.YMin != Bounds.YMax ) yield return new Vector3I( Bounds.XMin, Bounds.YMax, Bounds.ZMin ); - if( Bounds.ZMin != Bounds.ZMax ) yield return new Vector3I( Bounds.XMin, Bounds.YMin, Bounds.ZMax ); + if ( Bounds.XMin != Bounds.XMax ) + yield return new Vector3I( Bounds.XMax, Bounds.YMin, Bounds.ZMin ); + if ( Bounds.YMin != Bounds.YMax ) + yield return new Vector3I( Bounds.XMin, Bounds.YMax, Bounds.ZMin ); + if ( Bounds.ZMin != Bounds.ZMax ) + yield return new Vector3I( Bounds.XMin, Bounds.YMin, Bounds.ZMax ); - if( Bounds.XMin != Bounds.XMax && Bounds.YMin != Bounds.YMax ) + if ( Bounds.XMin != Bounds.XMax && Bounds.YMin != Bounds.YMax ) yield return new Vector3I( Bounds.XMax, Bounds.YMax, Bounds.ZMin ); - if( Bounds.YMin != Bounds.YMax && Bounds.ZMin != Bounds.ZMax ) + if ( Bounds.YMin != Bounds.YMax && Bounds.ZMin != Bounds.ZMax ) yield return new Vector3I( Bounds.XMin, Bounds.YMax, Bounds.ZMax ); - if( Bounds.ZMin != Bounds.ZMax && Bounds.XMin != Bounds.XMax ) + if ( Bounds.ZMin != Bounds.ZMax && Bounds.XMin != Bounds.XMax ) yield return new Vector3I( Bounds.XMax, Bounds.YMin, Bounds.ZMax ); - if( Bounds.XMin != Bounds.XMax && Bounds.YMin != Bounds.YMax && Bounds.ZMin != Bounds.ZMax ) + if ( Bounds.XMin != Bounds.XMax && Bounds.YMin != Bounds.YMax && Bounds.ZMin != Bounds.ZMax ) yield return new Vector3I( Bounds.XMax, Bounds.YMax, Bounds.ZMax ); // Draw edges along the X axis - if( Bounds.Width > 2 ) { - for( int x = Bounds.XMin + 1; x < Bounds.XMax; x++ ) { + if ( Bounds.Width > 2 ) { + for ( int x = Bounds.XMin + 1; x < Bounds.XMax; x++ ) { yield return new Vector3I( x, Bounds.YMin, Bounds.ZMin ); - if( Bounds.ZMin != Bounds.ZMax ) yield return new Vector3I( x, Bounds.YMin, Bounds.ZMax ); - if( Bounds.YMin != Bounds.YMax ) { + if ( Bounds.ZMin != Bounds.ZMax ) + yield return new Vector3I( x, Bounds.YMin, Bounds.ZMax ); + if ( Bounds.YMin != Bounds.YMax ) { yield return new Vector3I( x, Bounds.YMax, Bounds.ZMin ); - if( Bounds.ZMin != Bounds.ZMax ) yield return new Vector3I( x, Bounds.YMax, Bounds.ZMax ); + if ( Bounds.ZMin != Bounds.ZMax ) + yield return new Vector3I( x, Bounds.YMax, Bounds.ZMax ); } } } // Draw edges along the Y axis - if( Bounds.Length > 2 ) { - for( int y = Bounds.YMin + 1; y < Bounds.YMax; y++ ) { + if ( Bounds.Length > 2 ) { + for ( int y = Bounds.YMin + 1; y < Bounds.YMax; y++ ) { yield return new Vector3I( Bounds.XMin, y, Bounds.ZMin ); - if( Bounds.ZMin != Bounds.ZMax ) yield return new Vector3I( Bounds.XMin, y, Bounds.ZMax ); - if( Bounds.XMin != Bounds.XMax ) { + if ( Bounds.ZMin != Bounds.ZMax ) + yield return new Vector3I( Bounds.XMin, y, Bounds.ZMax ); + if ( Bounds.XMin != Bounds.XMax ) { yield return new Vector3I( Bounds.XMax, y, Bounds.ZMin ); - if( Bounds.ZMin != Bounds.ZMax ) yield return new Vector3I( Bounds.XMax, y, Bounds.ZMax ); + if ( Bounds.ZMin != Bounds.ZMax ) + yield return new Vector3I( Bounds.XMax, y, Bounds.ZMax ); } } } // Draw edges along the Z axis - if( Bounds.Height > 2 ) { - for( int z = Bounds.ZMin + 1; z < Bounds.ZMax; z++ ) { + if ( Bounds.Height > 2 ) { + for ( int z = Bounds.ZMin + 1; z < Bounds.ZMax; z++ ) { yield return new Vector3I( Bounds.XMin, Bounds.YMin, z ); - if( Bounds.YMin != Bounds.YMax ) yield return new Vector3I( Bounds.XMin, Bounds.YMax, z ); - if( Bounds.XMin != Bounds.XMax ) { + if ( Bounds.YMin != Bounds.YMax ) + yield return new Vector3I( Bounds.XMin, Bounds.YMax, z ); + if ( Bounds.XMin != Bounds.XMax ) { yield return new Vector3I( Bounds.XMax, Bounds.YMax, z ); - if( Bounds.YMin != Bounds.YMax ) yield return new Vector3I( Bounds.XMax, Bounds.YMin, z ); + if ( Bounds.YMin != Bounds.YMax ) + yield return new Vector3I( Bounds.XMax, Bounds.YMin, z ); } } } diff --git a/fCraft/Drawing/DrawOps/CutDrawOperation.cs b/fCraft/Drawing/DrawOps/CutDrawOperation.cs index 9ad9bd4..b8945de 100644 --- a/fCraft/Drawing/DrawOps/CutDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/CutDrawOperation.cs @@ -2,7 +2,9 @@ using System; namespace fCraft.Drawing { + public sealed class CutDrawOperation : DrawOperation { + public override string Name { get { return "Cut"; } } @@ -10,7 +12,7 @@ public override string Name { public override string Description { get { var normalBrush = Brush as NormalBrush; - if( normalBrush != null && normalBrush.Block != Block.Air ) { + if ( normalBrush != null && normalBrush.Block != Block.Air ) { return String.Format( "{0}/{1}", Name, normalBrush.Block ); } else { return Name; @@ -22,10 +24,11 @@ public CutDrawOperation( Player player ) : base( player ) { } - public override bool Prepare( Vector3I[] marks ) { - if( Player.World == null ) PlayerOpException.ThrowNoWorld( Player ); - if( !base.Prepare( marks ) ) return false; + if ( Player.World == null ) + PlayerOpException.ThrowNoWorld( Player ); + if ( !base.Prepare( marks ) ) + return false; BlocksTotalEstimate = Bounds.Volume; Coords = Bounds.MinVertex; @@ -33,9 +36,9 @@ public override bool Prepare( Vector3I[] marks ) { // remember dimensions and orientation CopyState copyInfo = new CopyState( marks[0], marks[1] ); - for( int x = Bounds.XMin; x <= Bounds.XMax; x++ ) { - for( int y = Bounds.YMin; y <= Bounds.YMax; y++ ) { - for( int z = Bounds.ZMin; z <= Bounds.ZMax; z++ ) { + for ( int x = Bounds.XMin; x <= Bounds.XMax; x++ ) { + for ( int y = Bounds.YMin; y <= Bounds.YMax; y++ ) { + for ( int z = Bounds.ZMin; z <= Bounds.ZMax; z++ ) { copyInfo.Buffer[x - Bounds.XMin, y - Bounds.YMin, z - Bounds.ZMin] = Map.GetBlock( x, y, z ); } } @@ -47,24 +50,23 @@ public override bool Prepare( Vector3I[] marks ) { Player.Message( "{0} blocks cut into slot #{1}. You can now &H/Paste", Bounds.Volume, Player.CopySlot + 1 ); Player.Message( "Origin at {0} {1}{2} corner.", - (copyInfo.Orientation.X == 1 ? "bottom" : "top"), - (copyInfo.Orientation.Y == 1 ? "south" : "north"), - (copyInfo.Orientation.Z == 1 ? "east" : "west") ); + ( copyInfo.Orientation.X == 1 ? "bottom" : "top" ), + ( copyInfo.Orientation.Y == 1 ? "south" : "north" ), + ( copyInfo.Orientation.Z == 1 ? "east" : "west" ) ); Context |= BlockChangeContext.Cut; return true; } - // lifted straight from CuboidDrawOp public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; - for( ; Coords.X <= Bounds.XMax; Coords.X++ ) { - for( ; Coords.Y <= Bounds.YMax; Coords.Y++ ) { - for( ; Coords.Z <= Bounds.ZMax; Coords.Z++ ) { - if( DrawOneBlock() ) { + for ( ; Coords.X <= Bounds.XMax; Coords.X++ ) { + for ( ; Coords.Y <= Bounds.YMax; Coords.Y++ ) { + for ( ; Coords.Z <= Bounds.ZMax; Coords.Z++ ) { + if ( DrawOneBlock() ) { blocksDone++; - if( blocksDone >= maxBlocksToDraw ) { + if ( blocksDone >= maxBlocksToDraw ) { Coords.Z++; return blocksDone; } @@ -73,7 +75,7 @@ public override int DrawBatch( int maxBlocksToDraw ) { Coords.Z = Bounds.ZMin; } Coords.Y = Bounds.YMin; - if( TimeToEndBatch ) { + if ( TimeToEndBatch ) { Coords.X++; return blocksDone; } diff --git a/fCraft/Drawing/DrawOps/CylinderDrawOperation.cs b/fCraft/Drawing/DrawOps/CylinderDrawOperation.cs index aca9cfe..1cc4ef2 100644 --- a/fCraft/Drawing/DrawOps/CylinderDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/CylinderDrawOperation.cs @@ -29,18 +29,20 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY using System; namespace fCraft.Drawing { + public class CylinderDrawOperation : DrawOperation { public override string Name { get { return "Cylinder"; } } - public CylinderDrawOperation ( Player player ) + public CylinderDrawOperation( Player player ) : base( player ) { } - public override bool Prepare ( Vector3I[] marks ) { - if ( !base.Prepare( marks ) ) return false; + public override bool Prepare( Vector3I[] marks ) { + if ( !base.Prepare( marks ) ) + return false; double r = Math.Sqrt( ( marks[0].X - marks[1].X ) * ( marks[0].X - marks[1].X ) + ( marks[0].Y - marks[1].Y ) * ( marks[0].Y - marks[1].Y ) + @@ -74,12 +76,12 @@ public override bool Prepare ( Vector3I[] marks ) { return true; } - State state; - Vector3F radius, center, delta; - bool fillInner; - int firstZ; + private State state; + private Vector3F radius, center, delta; + private bool fillInner; + private int firstZ; - public override int DrawBatch ( int maxBlocksToDraw ) { + public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; for ( ; Coords.X <= Bounds.XMax; Coords.X++ ) { for ( ; Coords.Y <= Bounds.YMax; Coords.Y++ ) { @@ -90,10 +92,10 @@ public override int DrawBatch ( int maxBlocksToDraw ) { delta.X = ( Coords.X - center.X ); delta.Y = ( Coords.Y - center.Y ); delta.Z = ( Coords.Z - center.Z ); - if ( delta.X2 * radius.X + delta.Y2 * radius.Y + delta.Z2 * radius.Z > 1 ) continue; + if ( delta.X2 * radius.X + delta.Y2 * radius.Y + delta.Z2 * radius.Z > 1 ) + continue; goto case State.OuterBlock1; - case State.OuterBlock1: state = State.OuterBlock1; firstZ = Coords.Z; @@ -102,10 +104,10 @@ public override int DrawBatch ( int maxBlocksToDraw ) { } goto case State.OuterBlock2; - case State.OuterBlock2: state = State.OuterBlock2; - if ( blocksDone >= maxBlocksToDraw ) return blocksDone; + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; int secondZ = ( int )( center.Z - delta.Z ); if ( secondZ != firstZ ) { int oldZ = Coords.Z; @@ -117,10 +119,10 @@ public override int DrawBatch ( int maxBlocksToDraw ) { } goto case State.AfterOuterBlock; - case State.AfterOuterBlock: state = State.AfterOuterBlock; - if ( blocksDone >= maxBlocksToDraw || TimeToEndBatch ) return blocksDone; + if ( blocksDone >= maxBlocksToDraw || TimeToEndBatch ) + return blocksDone; delta.Z = ( ++Coords.Z - center.Z ); if ( Coords.Z <= ( int )center.Z && ( ( delta.X + 1 ) * ( delta.X + 1 ) * radius.X + delta.Y2 * radius.Y + delta.Z2 * radius.Z > 1 || @@ -138,7 +140,6 @@ public override int DrawBatch ( int maxBlocksToDraw ) { UseAlternateBlock = true; goto case State.InnerBlock; - case State.InnerBlock: state = State.InnerBlock; if ( Coords.Z > ( int )( center.Z - delta.Z ) ) { @@ -167,8 +168,7 @@ public override int DrawBatch ( int maxBlocksToDraw ) { return blocksDone; } - - enum State { + private enum State { BeforeBlock = 0, OuterBlock1 = 1, OuterBlock2 = 2, diff --git a/fCraft/Drawing/DrawOps/DrawImageOperation.cs b/fCraft/Drawing/DrawOps/DrawImageOperation.cs index a46c902..bbc800a 100644 --- a/fCraft/Drawing/DrawOps/DrawImageOperation.cs +++ b/fCraft/Drawing/DrawOps/DrawImageOperation.cs @@ -1,23 +1,25 @@ using System; using System.Collections.Generic; using System.Drawing; -using System.Net; using System.IO; +using System.Net; using System.Threading; namespace fCraft.Drawing { + public class DrawImageOperation { + public int blocks = 0, //drawn blocks blocksDenied = 0; //denied blocks (zones, ect) - fCraft.Drawing.UndoState undoState; //undostate - #region Drawing + private fCraft.Drawing.UndoState undoState; //undostate - public DrawImageOperation () { + #region Drawing + public DrawImageOperation() { } - public void DrawImage ( byte popType, Direction direct, Vector3I cpos, Player player, string url ) { + public void DrawImage( byte popType, Direction direct, Vector3I cpos, Player player, string url ) { undoState = player.DrawBegin( null ); Bitmap myBitmap = null; HttpWebRequest request = ( HttpWebRequest )WebRequest.Create( url ); @@ -56,10 +58,14 @@ public void DrawImage ( byte popType, Direction direct, Vector3I cpos, Player pl myBitmap = resizeImage( myBitmap, myBitmap.Width, player.World.Map.Height ); } int direction = 0; - if ( direct == Direction.one ) direction = 0; - if ( direct == Direction.two ) direction = 1; - if ( direct == Direction.three ) direction = 2; - if ( direct == Direction.four ) direction = 3; + if ( direct == Direction.one ) + direction = 0; + if ( direct == Direction.two ) + direction = 1; + if ( direct == Direction.three ) + direction = 2; + if ( direct == Direction.four ) + direction = 3; List refCol = popRefCol( popType ); ColorBlock colblock; @@ -71,12 +77,16 @@ public void DrawImage ( byte popType, Direction direct, Vector3I cpos, Player pl for ( int i = 0; i < myBitmap.Height; i++ ) { colblock.z = ( ushort )( cpos.Z + i ); if ( direction <= 1 ) { - if ( direction == 0 ) colblock.x = ( ushort )( cpos.X + k ); - else colblock.x = ( ushort )( cpos.X - k ); + if ( direction == 0 ) + colblock.x = ( ushort )( cpos.X + k ); + else + colblock.x = ( ushort )( cpos.X - k ); colblock.y = cpos.Y; } else { - if ( direction == 2 ) colblock.y = ( ushort )( cpos.Y + k ); - else colblock.y = ( ushort )( cpos.Y - k ); + if ( direction == 2 ) + colblock.y = ( ushort )( cpos.Y + k ); + else + colblock.y = ( ushort )( cpos.Y - k ); colblock.x = cpos.X; } @@ -139,23 +149,25 @@ public void DrawImage ( byte popType, Direction direct, Vector3I cpos, Player pl } } } - if ( colblock.a < 20 ) colblock.type = ( byte )Block.Air; + if ( colblock.a < 20 ) + colblock.type = ( byte )Block.Air; DrawOneBlock( player, player.World.Map, ( Block )colblock.type, new Vector3I( colblock.x, colblock.y, colblock.z ), BlockChangeContext.Drawn, ref blocks, ref blocksDenied, undoState ); } } - } ) ); printThread.Start(); + } ) ); + printThread.Start(); } catch ( Exception e ) { player.Message( Color.Warning + "DrawImg: " + e.Message ); } } - #endregion + #endregion Drawing #region Helpers - Bitmap resizeImage ( Bitmap imgPhoto, int Width, int Height ) { + private Bitmap resizeImage( Bitmap imgPhoto, int Width, int Height ) { int sourceWidth = imgPhoto.Width; int sourceHeight = imgPhoto.Height; int sourceX = 0; @@ -196,7 +208,7 @@ Bitmap resizeImage ( Bitmap imgPhoto, int Width, int Height ) { } } - static List popRefCol ( byte popType ) { + private static List popRefCol( byte popType ) { ColorBlock tempref = new ColorBlock(); List refCol = new List(); refCol.Clear(); @@ -591,18 +603,23 @@ static List popRefCol ( byte popType ) { return refCol; } - struct ColorBlock { - public int x, y, z; public byte type, r, g, b, a; + private struct ColorBlock { + public int x, y, z; + public byte type, r, g, b, a; } - static void DrawOneBlock ( Player player, Map map, Block drawBlock, Vector3I coord, + private static void DrawOneBlock( Player player, Map map, Block drawBlock, Vector3I coord, BlockChangeContext context, ref int blocks, ref int blocksDenied, fCraft.Drawing.UndoState undoState ) { - if ( map == null ) return; - if ( player == null ) throw new ArgumentNullException( "player" ); + if ( map == null ) + return; + if ( player == null ) + throw new ArgumentNullException( "player" ); - if ( !map.InBounds( coord ) ) return; + if ( !map.InBounds( coord ) ) + return; Block block = map.GetBlock( coord ); - if ( block == drawBlock ) return; + if ( block == drawBlock ) + return; if ( player.CanPlace( map, coord, drawBlock, context ) != CanPlaceResult.Allowed ) { blocksDenied++; @@ -620,6 +637,7 @@ static void DrawOneBlock ( Player player, Map map, Block drawBlock, Vector3I coo } blocks++; } - #endregion + + #endregion Helpers } -} +} \ No newline at end of file diff --git a/fCraft/Drawing/DrawOps/EllipsoidDrawOperation.cs b/fCraft/Drawing/DrawOps/EllipsoidDrawOperation.cs index 3d4dec0..a2e6bef 100644 --- a/fCraft/Drawing/DrawOps/EllipsoidDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/EllipsoidDrawOperation.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; namespace fCraft.Drawing { + public class EllipsoidDrawOperation : DrawOperation { - Vector3F radius, center; + private Vector3F radius, center; public override string Name { get { return "Ellipsoid"; } @@ -14,56 +15,57 @@ public EllipsoidDrawOperation( Player player ) : base( player ) { } - public override bool Prepare( Vector3I[] marks ) { - if( !base.Prepare( marks ) ) return false; + if ( !base.Prepare( marks ) ) + return false; double rx = Bounds.Width / 2d; double ry = Bounds.Length / 2d; double rz = Bounds.Height / 2d; - radius.X = (float)(1 / (rx * rx)); - radius.Y = (float)(1 / (ry * ry)); - radius.Z = (float)(1 / (rz * rz)); + radius.X = ( float )( 1 / ( rx * rx ) ); + radius.Y = ( float )( 1 / ( ry * ry ) ); + radius.Z = ( float )( 1 / ( rz * rz ) ); // find center points - center.X = (float)((Bounds.XMin + Bounds.XMax) / 2d); - center.Y = (float)((Bounds.YMin + Bounds.YMax) / 2d); - center.Z = (float)((Bounds.ZMin + Bounds.ZMax) / 2d); + center.X = ( float )( ( Bounds.XMin + Bounds.XMax ) / 2d ); + center.Y = ( float )( ( Bounds.YMin + Bounds.YMax ) / 2d ); + center.Z = ( float )( ( Bounds.ZMin + Bounds.ZMax ) / 2d ); - BlocksTotalEstimate = (int)Math.Ceiling( 4 / 3d * Math.PI * rx * ry * rz ); + BlocksTotalEstimate = ( int )Math.Ceiling( 4 / 3d * Math.PI * rx * ry * rz ); coordEnumerator = BlockEnumerator().GetEnumerator(); return true; } + private IEnumerator coordEnumerator; - IEnumerator coordEnumerator; public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; - while( coordEnumerator.MoveNext() ) { + while ( coordEnumerator.MoveNext() ) { Coords = coordEnumerator.Current; - if( DrawOneBlock() ) { + if ( DrawOneBlock() ) { blocksDone++; - if( blocksDone >= maxBlocksToDraw ) return blocksDone; + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; } - if( TimeToEndBatch ) return blocksDone; + if ( TimeToEndBatch ) + return blocksDone; } IsDone = true; return blocksDone; } - - IEnumerable BlockEnumerator() { - for( int x = Bounds.XMin; x <= Bounds.XMax; x++ ) { - for( int y = Bounds.YMin; y <= Bounds.YMax; y++ ) { - for( int z = Bounds.ZMin; z <= Bounds.ZMax; z++ ) { - double dx = (x - center.X); - double dy = (y - center.Y); - double dz = (z - center.Z); + private IEnumerable BlockEnumerator() { + for ( int x = Bounds.XMin; x <= Bounds.XMax; x++ ) { + for ( int y = Bounds.YMin; y <= Bounds.YMax; y++ ) { + for ( int z = Bounds.ZMin; z <= Bounds.ZMax; z++ ) { + double dx = ( x - center.X ); + double dy = ( y - center.Y ); + double dz = ( z - center.Z ); // test if it's inside ellipse - if( (dx * dx) * radius.X + (dy * dy) * radius.Y + (dz * dz) * radius.Z <= 1 ) { + if ( ( dx * dx ) * radius.X + ( dy * dy ) * radius.Y + ( dz * dz ) * radius.Z <= 1 ) { yield return new Vector3I( x, y, z ); } } diff --git a/fCraft/Drawing/DrawOps/EllipsoidHollowDrawOperation.cs b/fCraft/Drawing/DrawOps/EllipsoidHollowDrawOperation.cs index 0705973..316a7d9 100644 --- a/fCraft/Drawing/DrawOps/EllipsoidHollowDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/EllipsoidHollowDrawOperation.cs @@ -2,6 +2,7 @@ using System; namespace fCraft.Drawing { + public class EllipsoidHollowDrawOperation : DrawOperation { public override string Name { @@ -12,21 +13,21 @@ public EllipsoidHollowDrawOperation( Player player ) : base( player ) { } - public override bool Prepare( Vector3I[] marks ) { - if( !base.Prepare( marks ) ) return false; + if ( !base.Prepare( marks ) ) + return false; double rx = Bounds.Width / 2d; double ry = Bounds.Length / 2d; double rz = Bounds.Height / 2d; - radius.X = (float)(1 / (rx * rx)); - radius.Y = (float)(1 / (ry * ry)); - radius.Z = (float)(1 / (rz * rz)); + radius.X = ( float )( 1 / ( rx * rx ) ); + radius.Y = ( float )( 1 / ( ry * ry ) ); + radius.Z = ( float )( 1 / ( rz * rz ) ); - center.X = (Bounds.XMin + Bounds.XMax) / 2f; - center.Y = (Bounds.YMin + Bounds.YMax) / 2f; - center.Z = (Bounds.ZMin + Bounds.ZMax) / 2f; + center.X = ( Bounds.XMin + Bounds.XMax ) / 2f; + center.Y = ( Bounds.YMin + Bounds.YMax ) / 2f; + center.Z = ( Bounds.ZMin + Bounds.ZMax ) / 2f; fillInner = Brush.HasAlternateBlock && Bounds.Width > 2 && @@ -35,74 +36,73 @@ public override bool Prepare( Vector3I[] marks ) { Coords = Bounds.MinVertex; - if( fillInner ) { - BlocksTotalEstimate = (int)(4 / 3d * Math.PI * rx * ry * rz); + if ( fillInner ) { + BlocksTotalEstimate = ( int )( 4 / 3d * Math.PI * rx * ry * rz ); } else { // rougher estimation than the non-hollow form, a voxelized surface is a bit funky - BlocksTotalEstimate = (int)(4 / 3d * Math.PI * ((rx + .5) * (ry + .5) * (rz + .5) - - (rx - .5) * (ry - .5) * (rz - .5)) * 0.85); + BlocksTotalEstimate = ( int )( 4 / 3d * Math.PI * ( ( rx + .5 ) * ( ry + .5 ) * ( rz + .5 ) - + ( rx - .5 ) * ( ry - .5 ) * ( rz - .5 ) ) * 0.85 ); } return true; } - - State state; - Vector3F radius, center, delta; - bool fillInner; - int firstZ; + private State state; + private Vector3F radius, center, delta; + private bool fillInner; + private int firstZ; public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; - for( ; Coords.X <= Bounds.XMax; Coords.X++ ) { - for( ; Coords.Y <= Bounds.YMax; Coords.Y++ ) { - for( ; Coords.Z <= Bounds.ZMax; Coords.Z++ ) { - switch( state ) { + for ( ; Coords.X <= Bounds.XMax; Coords.X++ ) { + for ( ; Coords.Y <= Bounds.YMax; Coords.Y++ ) { + for ( ; Coords.Z <= Bounds.ZMax; Coords.Z++ ) { + switch ( state ) { case State.BeforeBlock: state = State.BeforeBlock; - delta.X = (Coords.X - center.X); - delta.Y = (Coords.Y - center.Y); - delta.Z = (Coords.Z - center.Z); - if( delta.X2 * radius.X + delta.Y2 * radius.Y + delta.Z2 * radius.Z > 1 ) continue; + delta.X = ( Coords.X - center.X ); + delta.Y = ( Coords.Y - center.Y ); + delta.Z = ( Coords.Z - center.Z ); + if ( delta.X2 * radius.X + delta.Y2 * radius.Y + delta.Z2 * radius.Z > 1 ) + continue; goto case State.OuterBlock1; - case State.OuterBlock1: state = State.OuterBlock1; firstZ = Coords.Z; - if( DrawOneBlock() ) { + if ( DrawOneBlock() ) { blocksDone++; } goto case State.OuterBlock2; - case State.OuterBlock2: state = State.OuterBlock2; - if( blocksDone >= maxBlocksToDraw ) return blocksDone; - int secondZ = (int)(center.Z - delta.Z); - if( secondZ != firstZ ) { + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; + int secondZ = ( int )( center.Z - delta.Z ); + if ( secondZ != firstZ ) { int oldZ = Coords.Z; Coords.Z = secondZ; - if( DrawOneBlock() ) { + if ( DrawOneBlock() ) { blocksDone++; } Coords.Z = oldZ; } goto case State.AfterOuterBlock; - case State.AfterOuterBlock: state = State.AfterOuterBlock; - if( blocksDone >= maxBlocksToDraw || TimeToEndBatch ) return blocksDone; - delta.Z = (++Coords.Z - center.Z); - if( Coords.Z <= (int)center.Z && - ((delta.X + 1) * (delta.X + 1) * radius.X + delta.Y2 * radius.Y + delta.Z2 * radius.Z > 1 || - (delta.X - 1) * (delta.X - 1) * radius.X + delta.Y2 * radius.Y + delta.Z2 * radius.Z > 1 || - delta.X2 * radius.X + (delta.Y + 1) * (delta.Y + 1) * radius.Y + delta.Z2 * radius.Z > 1 || - delta.X2 * radius.X + (delta.Y - 1) * (delta.Y - 1) * radius.Y + delta.Z2 * radius.Z > 1) ) { + if ( blocksDone >= maxBlocksToDraw || TimeToEndBatch ) + return blocksDone; + delta.Z = ( ++Coords.Z - center.Z ); + if ( Coords.Z <= ( int )center.Z && + ( ( delta.X + 1 ) * ( delta.X + 1 ) * radius.X + delta.Y2 * radius.Y + delta.Z2 * radius.Z > 1 || + ( delta.X - 1 ) * ( delta.X - 1 ) * radius.X + delta.Y2 * radius.Y + delta.Z2 * radius.Z > 1 || + delta.X2 * radius.X + ( delta.Y + 1 ) * ( delta.Y + 1 ) * radius.Y + delta.Z2 * radius.Z > 1 || + delta.X2 * radius.X + ( delta.Y - 1 ) * ( delta.Y - 1 ) * radius.Y + delta.Z2 * radius.Z > 1 ) ) { goto case State.OuterBlock1; } - if( !fillInner ) { + if ( !fillInner ) { state = State.BeforeBlock; break; } @@ -110,18 +110,17 @@ public override int DrawBatch( int maxBlocksToDraw ) { UseAlternateBlock = true; goto case State.InnerBlock; - case State.InnerBlock: state = State.InnerBlock; - if( Coords.Z > (int)(center.Z - delta.Z) ) { + if ( Coords.Z > ( int )( center.Z - delta.Z ) ) { UseAlternateBlock = false; state = State.BeforeBlock; break; } - if( DrawOneBlock() ) { + if ( DrawOneBlock() ) { blocksDone++; Coords.Z++; - if( blocksDone >= maxBlocksToDraw || TimeToEndBatch ) { + if ( blocksDone >= maxBlocksToDraw || TimeToEndBatch ) { return blocksDone; } } else { @@ -139,8 +138,7 @@ public override int DrawBatch( int maxBlocksToDraw ) { return blocksDone; } - - enum State { + private enum State { BeforeBlock = 0, OuterBlock1 = 1, OuterBlock2 = 2, diff --git a/fCraft/Drawing/DrawOps/Fill2DDrawOperation.cs b/fCraft/Drawing/DrawOps/Fill2DDrawOperation.cs index 82dd624..7e8cdfd 100644 --- a/fCraft/Drawing/DrawOps/Fill2DDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/Fill2DDrawOperation.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; namespace fCraft.Drawing { + public sealed class Fill2DDrawOperation : DrawOpWithBrush { - int maxFillExtent; + private int maxFillExtent; public override string Name { get { return "Fill2D"; } @@ -16,8 +17,8 @@ public override int ExpectedMarks { public override string Description { get { - if( SourceBlock == Block.Undefined ) { - if( ReplacementBlock == Block.Undefined ) { + if ( SourceBlock == Block.Undefined ) { + if ( ReplacementBlock == Block.Undefined ) { return Name; } else { return String.Format( "{0}({1})", @@ -31,8 +32,11 @@ public override string Description { } public Block SourceBlock { get; private set; } + public Block ReplacementBlock { get; private set; } + public Axis Axis { get; private set; } + public Vector3I Origin { get; private set; } public Fill2DDrawOperation( Player player ) @@ -41,23 +45,24 @@ public Fill2DDrawOperation( Player player ) ReplacementBlock = Block.Undefined; } - public override bool ReadParams( Command cmd ) { - if( cmd.HasNext ) { + if ( cmd.HasNext ) { ReplacementBlock = cmd.NextBlock( Player ); - if( ReplacementBlock == Block.Undefined ) return false; + if ( ReplacementBlock == Block.Undefined ) + return false; } Brush = this; return true; } - public override bool Prepare( Vector3I[] marks ) { - if( marks == null ) throw new ArgumentNullException( "marks" ); - if( marks.Length < 1 ) throw new ArgumentException( "At least one mark needed.", "marks" ); + if ( marks == null ) + throw new ArgumentNullException( "marks" ); + if ( marks.Length < 1 ) + throw new ArgumentException( "At least one mark needed.", "marks" ); - if( ReplacementBlock == Block.Undefined ) { - if( Player.LastUsedBlockType == Block.Undefined ) { + if ( ReplacementBlock == Block.Undefined ) { + if ( Player.LastUsedBlockType == Block.Undefined ) { Player.Message( "Cannot deduce desired replacement block. Click a block or type out the block name." ); return false; } else { @@ -70,29 +75,32 @@ public override bool Prepare( Vector3I[] marks ) { SourceBlock = Map.GetBlock( Origin ); Vector3I playerCoords = Player.Position.ToBlockCoords(); - Vector3I lookVector = (Origin - playerCoords); + Vector3I lookVector = ( Origin - playerCoords ); Axis = lookVector.LongestAxis; Vector3I maxDelta; maxFillExtent = Player.Info.Rank.FillLimit; - if( maxFillExtent < 1 || maxFillExtent > 2048 ) maxFillExtent = 2048; + if ( maxFillExtent < 1 || maxFillExtent > 2048 ) + maxFillExtent = 2048; - switch( Axis ) { + switch ( Axis ) { case Axis.X: maxDelta = new Vector3I( 0, maxFillExtent, maxFillExtent ); coordEnumerator = BlockEnumeratorX().GetEnumerator(); break; + case Axis.Y: maxDelta = new Vector3I( maxFillExtent, 0, maxFillExtent ); coordEnumerator = BlockEnumeratorY().GetEnumerator(); break; + default: // Z maxDelta = new Vector3I( maxFillExtent, maxFillExtent, 0 ); coordEnumerator = BlockEnumeratorZ().GetEnumerator(); break; } - if( SourceBlock == ReplacementBlock ) { + if ( SourceBlock == ReplacementBlock ) { Bounds = new BoundingBox( Origin, Origin ); } else { Bounds = new BoundingBox( Origin - maxDelta, Origin + maxDelta ); @@ -112,63 +120,64 @@ public override bool Prepare( Vector3I[] marks ) { return true; } + private IEnumerator coordEnumerator; - IEnumerator coordEnumerator; public override int DrawBatch( int maxBlocksToDraw ) { - if( SourceBlock == ReplacementBlock ) { + if ( SourceBlock == ReplacementBlock ) { IsDone = true; return 0; } int blocksDone = 0; - while( coordEnumerator.MoveNext() ) { + while ( coordEnumerator.MoveNext() ) { Coords = coordEnumerator.Current; - if( DrawOneBlock() ) { + if ( DrawOneBlock() ) { blocksDone++; - if( blocksDone >= maxBlocksToDraw ) return blocksDone; + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; } - if( TimeToEndBatch ) return blocksDone; + if ( TimeToEndBatch ) + return blocksDone; } IsDone = true; return blocksDone; } - - bool CanPlace( Vector3I coords ) { - return (Map.GetBlock( coords ) == SourceBlock) && + private bool CanPlace( Vector3I coords ) { + return ( Map.GetBlock( coords ) == SourceBlock ) && Player.CanPlace( Map, coords, ReplacementBlock, Context ) == CanPlaceResult.Allowed; } - - IEnumerable BlockEnumeratorX() { + private IEnumerable BlockEnumeratorX() { Stack stack = new Stack(); stack.Push( Origin ); Vector3I coords; - while( stack.Count > 0 ) { + while ( stack.Count > 0 ) { coords = stack.Pop(); - while( coords.Y >= Bounds.YMin && CanPlace( coords ) ) coords.Y--; + while ( coords.Y >= Bounds.YMin && CanPlace( coords ) ) + coords.Y--; coords.Y++; bool spanLeft = false; bool spanRight = false; - while( coords.Y <= Bounds.YMax && CanPlace( coords ) ) { + while ( coords.Y <= Bounds.YMax && CanPlace( coords ) ) { yield return coords; - if( coords.Z > Bounds.ZMin ) { + if ( coords.Z > Bounds.ZMin ) { bool canPlace = CanPlace( new Vector3I( coords.X, coords.Y, coords.Z - 1 ) ); - if( !spanLeft && canPlace ) { + if ( !spanLeft && canPlace ) { stack.Push( new Vector3I( coords.X, coords.Y, coords.Z - 1 ) ); spanLeft = true; - } else if( spanLeft && !canPlace ) { + } else if ( spanLeft && !canPlace ) { spanLeft = false; } } - if( coords.Z < Bounds.ZMax ) { + if ( coords.Z < Bounds.ZMax ) { bool canPlace = CanPlace( new Vector3I( coords.X, coords.Y, coords.Z + 1 ) ); - if( !spanRight && canPlace ) { + if ( !spanRight && canPlace ) { stack.Push( new Vector3I( coords.X, coords.Y, coords.Z + 1 ) ); spanRight = true; - } else if( spanRight && !canPlace ) { + } else if ( spanRight && !canPlace ) { spanRight = false; } } @@ -177,37 +186,37 @@ IEnumerable BlockEnumeratorX() { } } - - IEnumerable BlockEnumeratorY() { + private IEnumerable BlockEnumeratorY() { Stack stack = new Stack(); stack.Push( Origin ); Vector3I coords; - while( stack.Count > 0 ) { + while ( stack.Count > 0 ) { coords = stack.Pop(); - while( coords.Z >= Bounds.ZMin && CanPlace( coords ) ) coords.Z--; + while ( coords.Z >= Bounds.ZMin && CanPlace( coords ) ) + coords.Z--; coords.Z++; bool spanLeft = false; bool spanRight = false; - while( coords.Z <= Bounds.ZMax && CanPlace( coords ) ) { + while ( coords.Z <= Bounds.ZMax && CanPlace( coords ) ) { yield return coords; - if( coords.X > Bounds.XMin ) { - bool canPlace = CanPlace( new Vector3I( coords.X -1, coords.Y, coords.Z ) ); - if( !spanLeft && canPlace ) { + if ( coords.X > Bounds.XMin ) { + bool canPlace = CanPlace( new Vector3I( coords.X - 1, coords.Y, coords.Z ) ); + if ( !spanLeft && canPlace ) { stack.Push( new Vector3I( coords.X - 1, coords.Y, coords.Z ) ); spanLeft = true; - } else if( spanLeft && !canPlace ) { + } else if ( spanLeft && !canPlace ) { spanLeft = false; } } - if( coords.X < Bounds.XMax ) { + if ( coords.X < Bounds.XMax ) { bool canPlace = CanPlace( new Vector3I( coords.X + 1, coords.Y, coords.Z ) ); - if( !spanRight && canPlace ) { + if ( !spanRight && canPlace ) { stack.Push( new Vector3I( coords.X + 1, coords.Y, coords.Z ) ); spanRight = true; - } else if( spanRight && !canPlace ) { + } else if ( spanRight && !canPlace ) { spanRight = false; } } @@ -216,37 +225,37 @@ IEnumerable BlockEnumeratorY() { } } - - IEnumerable BlockEnumeratorZ() { + private IEnumerable BlockEnumeratorZ() { Stack stack = new Stack(); stack.Push( Origin ); Vector3I coords; - while( stack.Count > 0 ) { + while ( stack.Count > 0 ) { coords = stack.Pop(); - while( coords.Y >= Bounds.YMin && CanPlace( coords ) ) coords.Y--; + while ( coords.Y >= Bounds.YMin && CanPlace( coords ) ) + coords.Y--; coords.Y++; bool spanLeft = false; bool spanRight = false; - while( coords.Y <= Bounds.YMax && CanPlace( coords ) ) { + while ( coords.Y <= Bounds.YMax && CanPlace( coords ) ) { yield return coords; - if( coords.X > Bounds.XMin ) { + if ( coords.X > Bounds.XMin ) { bool canPlace = CanPlace( new Vector3I( coords.X - 1, coords.Y, coords.Z ) ); - if( !spanLeft && canPlace ) { + if ( !spanLeft && canPlace ) { stack.Push( new Vector3I( coords.X - 1, coords.Y, coords.Z ) ); spanLeft = true; - } else if( spanLeft && !canPlace ) { + } else if ( spanLeft && !canPlace ) { spanLeft = false; } } - if( coords.X < Bounds.XMax ) { + if ( coords.X < Bounds.XMax ) { bool canPlace = CanPlace( new Vector3I( coords.X + 1, coords.Y, coords.Z ) ); - if( !spanRight && canPlace ) { + if ( !spanRight && canPlace ) { stack.Push( new Vector3I( coords.X + 1, coords.Y, coords.Z ) ); spanRight = true; - } else if( spanRight && !canPlace ) { + } else if ( spanRight && !canPlace ) { spanRight = false; } } @@ -255,7 +264,6 @@ IEnumerable BlockEnumeratorZ() { } } - protected override Block NextBlock() { return ReplacementBlock; } diff --git a/fCraft/Drawing/DrawOps/LineDrawOperation.cs b/fCraft/Drawing/DrawOps/LineDrawOperation.cs index dc8be37..8ab0e9a 100644 --- a/fCraft/Drawing/DrawOps/LineDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/LineDrawOperation.cs @@ -2,46 +2,41 @@ using System; using System.Collections.Generic; -namespace fCraft.Drawing -{ - public sealed class LineDrawOperation : DrawOperation - { +namespace fCraft.Drawing { - public override string Name - { + public sealed class LineDrawOperation : DrawOperation { + + public override string Name { get { return "Line"; } } - public LineDrawOperation(Player player) - : base(player) - { + public LineDrawOperation( Player player ) + : base( player ) { } + public override bool Prepare( Vector3I[] marks ) { + if ( !base.Prepare( marks ) ) + return false; - public override bool Prepare(Vector3I[] marks) - { - if (!base.Prepare(marks)) return false; - - BlocksTotalEstimate = Math.Max(Bounds.Width, Math.Max(Bounds.Height, Bounds.Length)); + BlocksTotalEstimate = Math.Max( Bounds.Width, Math.Max( Bounds.Height, Bounds.Length ) ); - coordEnumerator = LineEnumerator(marks[0], marks[1]).GetEnumerator(); + coordEnumerator = LineEnumerator( marks[0], marks[1] ).GetEnumerator(); return true; } + private IEnumerator coordEnumerator; - IEnumerator coordEnumerator; - public override int DrawBatch(int maxBlocksToDraw) - { + public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; - while (coordEnumerator.MoveNext()) - { + while ( coordEnumerator.MoveNext() ) { Coords = coordEnumerator.Current; - if (DrawOneBlock()) - { + if ( DrawOneBlock() ) { blocksDone++; - if (blocksDone >= maxBlocksToDraw) return blocksDone; + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; } - if (TimeToEndBatch) return blocksDone; + if ( TimeToEndBatch ) + return blocksDone; } IsDone = true; return blocksDone; diff --git a/fCraft/Drawing/DrawOps/Maze.cs b/fCraft/Drawing/DrawOps/Maze.cs index 1ddaa89..782b4fe 100644 --- a/fCraft/Drawing/DrawOps/Maze.cs +++ b/fCraft/Drawing/DrawOps/Maze.cs @@ -30,58 +30,50 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; +namespace RandomMaze { -namespace RandomMaze -{ - internal static class MazeUtil - { + internal static class MazeUtil { static private Random _r = new Random(); - public static void RndPermutate(this IList a) - { - for (int i = a.Count - 1; i > 0; --i) - { - int idx = _r.Next(i + 1); + + public static void RndPermutate( this IList a ) { + for ( int i = a.Count - 1; i > 0; --i ) { + int idx = _r.Next( i + 1 ); T t = a[idx]; a[idx] = a[i]; a[i] = t; } } } - internal struct Direction - { + + internal struct Direction { private int _d; - public int MoveX(int x) - { + public int MoveX( int x ) { return x + _dx[_d]; } - public int MoveY(int y) - { + + public int MoveY( int y ) { return y + _dy[_d]; } - public int MoveZ(int z) - { + + public int MoveZ( int z ) { return z + _dz[_d]; } - public Direction Invert() - { - return _d < 4 ? new Direction() { _d = (_d + 2) % 4 } : new Direction() { _d = 9 - _d }; + + public Direction Invert() { + return _d < 4 ? new Direction() { _d = ( _d + 2 ) % 4 } : new Direction() { _d = 9 - _d }; } - public static Direction[] GetRndPermutation() - { + public static Direction[] GetRndPermutation() { Direction[] a = new Direction[6]; - for (int i = 0; i < a.Length; ++i) + for ( int i = 0; i < a.Length; ++i ) a[i]._d = i; a.RndPermutate(); return a; } - public override string ToString() - { + public override string ToString() { return _names[_d]; } @@ -91,79 +83,88 @@ public override string ToString() private static int[] _dz = { 0, 0, 0, 0, -1, 1 }; public const int AllMask = 0x3F; - public static readonly Direction[] All = { new Direction() { _d = 0 }, new Direction() { _d = 1 }, - new Direction() { _d = 2 }, new Direction() { _d = 3 }, + + public static readonly Direction[] All = { new Direction() { _d = 0 }, new Direction() { _d = 1 }, + new Direction() { _d = 2 }, new Direction() { _d = 3 }, new Direction() { _d = 4 }, new Direction() { _d = 5 } }; - public int Mask() - { + + public int Mask() { return 0x1 << _d; } public delegate void WallCallbackDelegate( - ref int longSide1, ref int longSide2, int long1From, int long2From); + ref int longSide1, ref int longSide2, int long1From, int long2From ); - internal void ArrangeCoords(ref int x, ref int y, ref int z, int xFrom, int yFrom, int zFrom, int cellSize, WallCallbackDelegate fun) - { - switch (_d) - { + internal void ArrangeCoords( ref int x, ref int y, ref int z, int xFrom, int yFrom, int zFrom, int cellSize, WallCallbackDelegate fun ) { + switch ( _d ) { case 0: x = xFrom + cellSize; - fun(ref y, ref z, yFrom, zFrom); + fun( ref y, ref z, yFrom, zFrom ); break; + case 1: y = yFrom + cellSize; - fun(ref x, ref z, xFrom, zFrom); + fun( ref x, ref z, xFrom, zFrom ); break; + case 2: x = xFrom - 1; - fun(ref y, ref z, yFrom, zFrom); + fun( ref y, ref z, yFrom, zFrom ); break; + case 3: y = yFrom - 1; - fun(ref x, ref z, xFrom, zFrom); + fun( ref x, ref z, xFrom, zFrom ); break; + case 4: z = zFrom - 1; - fun(ref x, ref y, xFrom, yFrom); + fun( ref x, ref y, xFrom, yFrom ); break; + case 5: z = zFrom + cellSize; - fun(ref x, ref y, xFrom, yFrom); + fun( ref x, ref y, xFrom, yFrom ); break; } } + public delegate void StickCallbackDelegate( - ref int coord, int coordFrom); - internal void ArrangeCoords(ref int x, ref int y, ref int z, int xFrom, int yFrom, int zFrom, int cellSize, StickCallbackDelegate fun) - { - switch (_d) - { + ref int coord, int coordFrom ); + + internal void ArrangeCoords( ref int x, ref int y, ref int z, int xFrom, int yFrom, int zFrom, int cellSize, StickCallbackDelegate fun ) { + switch ( _d ) { case 0: case 2: y = yFrom - 1; z = zFrom - 1; - fun(ref x, xFrom); + fun( ref x, xFrom ); break; + case 1: case 3: x = xFrom - 1; z = zFrom - 1; - fun(ref y, yFrom); + fun( ref y, yFrom ); break; + case 4: case 5: x = xFrom - 1; y = yFrom - 1; - fun(ref z, zFrom); + fun( ref z, zFrom ); break; } } } - internal class Cell - { + internal class Cell { public Path Path = null; - public bool Used() { return null != Path; } + + public bool Used() { + return null != Path; + } + public int X; public int Y; public int Z; @@ -172,24 +173,20 @@ internal class Cell private int _walls = Direction.AllMask; - public void RemoveWall(Direction d) - { + public void RemoveWall( Direction d ) { _walls &= ~d.Mask(); } - public bool Wall(Direction d) - { - return (_walls & d.Mask()) != 0; + public bool Wall( Direction d ) { + return ( _walls & d.Mask() ) != 0; } - internal bool IsOnSolutionPath() - { - return (Path.ReachedDestination && IndexInPath<=Path.GoesToDestinationUpTo); - } - } + internal bool IsOnSolutionPath() { + return ( Path.ReachedDestination && IndexInPath <= Path.GoesToDestinationUpTo ); + } + } - internal class Path - { + internal class Path { private static int _counter = 0; private Maze _maze; @@ -203,24 +200,23 @@ internal class Path private Path _parent = null; private int _forkedAtParents = -1; - public Path(Maze maze, Cell start) - { + public Path( Maze maze, Cell start ) { _maze = maze; - Add(new Direction(), start); //direction doesnt matter if _cells is empty + Add( new Direction(), start ); //direction doesnt matter if _cells is empty Index = _counter++; } + public bool TryExtend() //returns true if a cell was added to the path { Cell last = _cells.Last(); Direction[] dir = Direction.GetRndPermutation(); - for (int i = 0; i < dir.Length; ++i) - { - Cell next = _maze.GetCell(dir[i].MoveX(last.X), dir[i].MoveY(last.Y), dir[i].MoveZ(last.Z)); - if (null == next) //outside + for ( int i = 0; i < dir.Length; ++i ) { + Cell next = _maze.GetCell( dir[i].MoveX( last.X ), dir[i].MoveY( last.Y ), dir[i].MoveZ( last.Z ) ); + if ( null == next ) //outside continue; - if (next.Used()) //taken already + if ( next.Used() ) //taken already continue; - Add(dir[i], next); + Add( dir[i], next ); return true; } //can not be extended @@ -228,48 +224,42 @@ public Path(Maze maze, Cell start) return false; } - public Path TryFork() - { - for (int j = _cells.Count - 2; j >= 0; --j) //try fork from the before the last to the very beginning + public Path TryFork() { + for ( int j = _cells.Count - 2; j >= 0; --j ) //try fork from the before the last to the very beginning { Cell cell = _cells[j]; Direction[] dir = Direction.GetRndPermutation(); - for (int i = 0; i < dir.Length; ++i) - { - Cell next = _maze.GetCell(dir[i].MoveX(cell.X), dir[i].MoveY(cell.Y), dir[i].MoveZ(cell.Z)); - if (null == next) //outside + for ( int i = 0; i < dir.Length; ++i ) { + Cell next = _maze.GetCell( dir[i].MoveX( cell.X ), dir[i].MoveY( cell.Y ), dir[i].MoveZ( cell.Z ) ); + if ( null == next ) //outside continue; - if (next.Used()) //taken already + if ( next.Used() ) //taken already continue; - ConnectCells(cell, next, dir[i]); - return new Path(_maze, next) { _parent = this, _forkedAtParents = j }; + ConnectCells( cell, next, dir[i] ); + return new Path( _maze, next ) { _parent = this, _forkedAtParents = j }; } } return null; } - private void Add(Direction d, Cell next) - { - if (_cells.Count > 0) - ConnectCells(_cells.Last(), next, d); + private void Add( Direction d, Cell next ) { + if ( _cells.Count > 0 ) + ConnectCells( _cells.Last(), next, d ); next.Path = this; next.IndexInPath = _cells.Count; - _cells.Add(next); + _cells.Add( next ); Extendable ^= next.IsDestination; //stop extending on reaching the destination ReachedDestination |= next.IsDestination; - if (ReachedDestination) - { + if ( ReachedDestination ) { GoesToDestinationUpTo = _cells.Count - 1; PropagateReachedDestination(); } } - private void PropagateReachedDestination() - { + private void PropagateReachedDestination() { Path me = this; Path parent = _parent; - while (null != parent) - { + while ( null != parent ) { parent.ReachedDestination = true; parent.GoesToDestinationUpTo = me._forkedAtParents; me = parent; @@ -277,32 +267,30 @@ private void PropagateReachedDestination() } } - private static void ConnectCells(Cell cell1, Cell cell2, Direction d) - { - cell1.RemoveWall(d); - cell2.RemoveWall(d.Invert()); + private static void ConnectCells( Cell cell1, Cell cell2, Direction d ) { + cell1.RemoveWall( d ); + cell2.RemoveWall( d.Invert() ); } private bool _wallAtEndRemoved = false; - public bool TryRemoveWallAtEnd() - { - if (_wallAtEndRemoved || _cells.Count < 5) //did already or too short + + public bool TryRemoveWallAtEnd() { + if ( _wallAtEndRemoved || _cells.Count < 5 ) //did already or too short return false; Cell last = _cells.Last(); Direction[] dir = Direction.GetRndPermutation(); - for (int i = 0; i < dir.Length; ++i) - { - if (!last.Wall(dir[i])) + for ( int i = 0; i < dir.Length; ++i ) { + if ( !last.Wall( dir[i] ) ) continue; - Cell next = _maze.GetCell(dir[i].MoveX(last.X), dir[i].MoveY(last.Y), dir[i].MoveY(last.Z)); - if (null == next) //outside + Cell next = _maze.GetCell( dir[i].MoveX( last.X ), dir[i].MoveY( last.Y ), dir[i].MoveY( last.Z ) ); + if ( null == next ) //outside continue; - if (ReferenceEquals(next.Path, this) && Math.Abs(last.IndexInPath - next.IndexInPath) < 10) //same path only if distance >=10 + if ( ReferenceEquals( next.Path, this ) && Math.Abs( last.IndexInPath - next.IndexInPath ) < 10 ) //same path only if distance >=10 continue; - if (next.IndexInPath + (null == next.Path._parent ? 0 : next.Path._forkedAtParents) < 5) //only take long paths, consider the immediate parent too + if ( next.IndexInPath + ( null == next.Path._parent ? 0 : next.Path._forkedAtParents ) < 5 ) //only take long paths, consider the immediate parent too continue; - ConnectCells(last, next, dir[i]); + ConnectCells( last, next, dir[i] ); _wallAtEndRemoved = true; return true; } @@ -311,8 +299,7 @@ public bool TryRemoveWallAtEnd() } } - internal class Maze - { + internal class Maze { private Cell[][][] _cells; private const double ForkProbability = 0.38; @@ -322,107 +309,96 @@ internal class Maze public List _allPaths = new List(); - public Maze(int xSize, int ySize, int zSize) //2d at the moment + public Maze( int xSize, int ySize, int zSize ) //2d at the moment { - if (xSize < 1 || ySize < 1 || zSize<1) - throw new ArgumentException("maze size must be at least 1x1x1"); + if ( xSize < 1 || ySize < 1 || zSize < 1 ) + throw new ArgumentException( "maze size must be at least 1x1x1" ); XSize = xSize; YSize = ySize; ZSize = zSize; _cells = new Cell[xSize][][]; - for (int i = 0; i < _cells.Length; ++i) - { + for ( int i = 0; i < _cells.Length; ++i ) { _cells[i] = new Cell[ySize][]; - for (int j = 0; j < _cells[i].Length; ++j) - { + for ( int j = 0; j < _cells[i].Length; ++j ) { _cells[i][j] = new Cell[zSize]; - for (int k = 0; k < _cells[i][j].Length; ++k) + for ( int k = 0; k < _cells[i][j].Length; ++k ) _cells[i][j][k] = new Cell() { X = i, Y = j, Z = k }; } } _cells[xSize - 1][ySize - 1][zSize - 1].IsDestination = true; - _cells[0][0][0].RemoveWall(Direction.All[3]); - _cells[xSize - 1][ySize - 1][zSize - 1].RemoveWall(Direction.All[1]); + _cells[0][0][0].RemoveWall( Direction.All[3] ); + _cells[xSize - 1][ySize - 1][zSize - 1].RemoveWall( Direction.All[1] ); Mazefy(); } - private void Mazefy() - { + private void Mazefy() { int count = XSize * YSize * ZSize - 1; //-1 accounts on the first path List extendible = new List(); List forkable = new List(); - Path initial = new Path(this, _cells[0][0][0]); - _allPaths.Add(initial); - extendible.Add(initial); - forkable.Add(initial); + Path initial = new Path( this, _cells[0][0][0] ); + _allPaths.Add( initial ); + extendible.Add( initial ); + forkable.Add( initial ); Random r = new Random(); - while (count > 0) - { + while ( count > 0 ) { //get a random extendible path and extend it - if (extendible.Count > 0) - { - int idx = r.Next(extendible.Count); + if ( extendible.Count > 0 ) { + int idx = r.Next( extendible.Count ); Path p = extendible[idx]; - if (p.TryExtend()) + if ( p.TryExtend() ) --count; - if (!p.Extendable) - extendible.RemoveAt(idx); + if ( !p.Extendable ) + extendible.RemoveAt( idx ); } - if (count <= 0) + if ( count <= 0 ) break; - if (extendible.Count == 0 || r.NextDouble() < ForkProbability / (forkable.Count + 1) && forkable.Count > 0)//fork when either we are totally entangled or just randomly + if ( extendible.Count == 0 || r.NextDouble() < ForkProbability / ( forkable.Count + 1 ) && forkable.Count > 0 )//fork when either we are totally entangled or just randomly { - int idx = r.Next(forkable.Count); + int idx = r.Next( forkable.Count ); Path p = forkable[idx]; Path fork = p.TryFork(); - if (null == fork) - { - if (!p.Extendable) - forkable.RemoveAt(idx); - } - else - { - _allPaths.Add(fork); - forkable.Add(fork); - if (fork.Extendable) - extendible.Add(fork); + if ( null == fork ) { + if ( !p.Extendable ) + forkable.RemoveAt( idx ); + } else { + _allPaths.Add( fork ); + forkable.Add( fork ); + if ( fork.Extendable ) + extendible.Add( fork ); --count; } } - if (count > 0 && extendible.Count == 0 && forkable.Count == 0)//algorithm failed :^( - should never ever happen - throw new Exception("failed to build the maze for reason unknown"); + if ( count > 0 && extendible.Count == 0 && forkable.Count == 0 )//algorithm failed :^( - should never ever happen + throw new Exception( "failed to build the maze for reason unknown" ); } //remove some walls to add cycles and alternative paths - if (XSize * YSize * ZSize > 90) + if ( XSize * YSize * ZSize > 90 ) AddCycles(); } - private void AddCycles() - { + private void AddCycles() { Random r = new Random(); - for (int i = 0; i < Math.Sqrt(XSize * YSize * ZSize) / 10.0 + 1; ++i) - { - for (int tries = 0; tries < 5; ++tries) //try some times to remove a wall somewhere, it may fail though + for ( int i = 0; i < Math.Sqrt( XSize * YSize * ZSize ) / 10.0 + 1; ++i ) { + for ( int tries = 0; tries < 5; ++tries ) //try some times to remove a wall somewhere, it may fail though { - Path p = _allPaths[r.Next(_allPaths.Count)]; - if (p.TryRemoveWallAtEnd()) + Path p = _allPaths[r.Next( _allPaths.Count )]; + if ( p.TryRemoveWallAtEnd() ) break; } } } - public Cell GetCell(int x, int y, int z) - { - if (x < 0 || x >= XSize || y < 0 || y >= YSize || z < 0 || z >= ZSize) + public Cell GetCell( int x, int y, int z ) { + if ( x < 0 || x >= XSize || y < 0 || y >= YSize || z < 0 || z >= ZSize ) return null; return _cells[x][y][z]; } } -} +} \ No newline at end of file diff --git a/fCraft/Drawing/DrawOps/MazeCuboidDrawOperation.cs b/fCraft/Drawing/DrawOps/MazeCuboidDrawOperation.cs index 7b239da..2736882 100644 --- a/fCraft/Drawing/DrawOps/MazeCuboidDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/MazeCuboidDrawOperation.cs @@ -27,87 +27,70 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) 2012 Lao Tszy (lao_tszy@yahoo.co.uk) -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using fCraft; using fCraft.Drawing; -namespace RandomMaze -{ - class MazeCuboidDrawOperation : DrawOperation - { - private Maze _maze; - private int _count = 0; +namespace RandomMaze { - public override string Name - { + internal class MazeCuboidDrawOperation : DrawOperation { + private Maze _maze; + private int _count = 0; + + public override string Name { get { return "MazeCuboid"; } } - public MazeCuboidDrawOperation(Player player) - : base( player ) - { + public MazeCuboidDrawOperation( Player player ) + : base( player ) { } + public override bool Prepare( Vector3I[] marks ) { + if ( !base.Prepare( marks ) ) + return false; + if ( Bounds.Width < 3 || Bounds.Length < 3 ) { + Player.Message( "Too small area marked (at least 3x3 blocks by X and Y)" ); + return false; + } + if ( Bounds.Width % 2 != 1 || Bounds.Length % 2 != 1 ) { + Player.Message( "Warning: bounding box X and Y dimensions must be uneven, current bounding box will be cropped!" ); + } + BlocksTotalEstimate = Bounds.Volume; - public override bool Prepare( Vector3I[] marks ) - { - if( !base.Prepare( marks ) ) - return false; - if (Bounds.Width < 3 || Bounds.Length < 3) - { - Player.Message("Too small area marked (at least 3x3 blocks by X and Y)"); - return false; - } - if (Bounds.Width % 2 != 1 || Bounds.Length % 2 != 1) - { - Player.Message("Warning: bounding box X and Y dimensions must be uneven, current bounding box will be cropped!"); - } - BlocksTotalEstimate = Bounds.Volume; - - _maze = new Maze((Bounds.Width - 1) / 2, (Bounds.Length - 1) / 2, 1); + _maze = new Maze( ( Bounds.Width - 1 ) / 2, ( Bounds.Length - 1 ) / 2, 1 ); return true; } + public override int DrawBatch( int maxBlocksToDraw ) { + for ( int j = 0; j < _maze.YSize; ++j ) { + for ( int i = 0; i < _maze.XSize; ++i ) { + DrawAtXY( i * 2, j * 2 ); + if ( _maze.GetCell( i, j, 0 ).Wall( Direction.All[3] ) ) + DrawAtXY( i * 2 + 1, j * 2 ); + if ( _maze.GetCell( i, j, 0 ).Wall( Direction.All[2] ) ) + DrawAtXY( i * 2, j * 2 + 1 ); + } + DrawAtXY( _maze.XSize * 2, j * 2 ); + if ( _maze.GetCell( _maze.XSize - 1, j, 0 ).Wall( Direction.All[0] ) ) + DrawAtXY( _maze.XSize * 2, j * 2 + 1 ); + } + for ( int i = 0; i < _maze.XSize; ++i ) { + DrawAtXY( i * 2, _maze.YSize * 2 ); + if ( _maze.GetCell( i, _maze.YSize - 1, 0 ).Wall( Direction.All[1] ) ) + DrawAtXY( i * 2 + 1, _maze.YSize * 2 ); + } + DrawAtXY( _maze.XSize * 2, _maze.YSize * 2 ); - public override int DrawBatch( int maxBlocksToDraw ) - { - for (int j = 0; j < _maze.YSize; ++j) - { - for (int i = 0; i < _maze.XSize; ++i) - { - DrawAtXY(i*2, j*2); - if (_maze.GetCell(i, j, 0).Wall(Direction.All[3])) - DrawAtXY(i*2 + 1, j*2); - if (_maze.GetCell(i, j, 0).Wall(Direction.All[2])) - DrawAtXY(i*2, j*2 + 1); - } - DrawAtXY(_maze.XSize * 2, j * 2); - if (_maze.GetCell(_maze.XSize - 1, j, 0).Wall(Direction.All[0])) - DrawAtXY(_maze.XSize*2, j*2 + 1); - } - for (int i = 0; i < _maze.XSize; ++i) - { - DrawAtXY(i * 2, _maze.YSize * 2); - if (_maze.GetCell(i, _maze.YSize - 1, 0).Wall(Direction.All[1])) - DrawAtXY(i*2 + 1, _maze.YSize*2); - } - DrawAtXY(_maze.XSize * 2, _maze.YSize * 2); - - IsDone = true; + IsDone = true; return _count; } - private void DrawAtXY(int x, int y) - { - Coords.X = x + Bounds.XMin; - Coords.Y = y + Bounds.YMin; - for (Coords.Z = Bounds.ZMin; Coords.Z <= Bounds.ZMax; ++Coords.Z) - if (DrawOneBlock()) - ++_count; - } + private void DrawAtXY( int x, int y ) { + Coords.X = x + Bounds.XMin; + Coords.Y = y + Bounds.YMin; + for ( Coords.Z = Bounds.ZMin; Coords.Z <= Bounds.ZMax; ++Coords.Z ) + if ( DrawOneBlock() ) + ++_count; + } } -} +} \ No newline at end of file diff --git a/fCraft/Drawing/DrawOps/PasteDrawOperation.cs b/fCraft/Drawing/DrawOps/PasteDrawOperation.cs index fe2a48d..fb82f6c 100644 --- a/fCraft/Drawing/DrawOps/PasteDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/PasteDrawOperation.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; namespace fCraft.Drawing { + public class PasteDrawOperation : DrawOpWithBrush { + public override string Name { get { return Not ? "PasteNotX" : "PasteX"; @@ -12,7 +14,7 @@ public override string Name { public override string Description { get { - if( Blocks == null ) { + if ( Blocks == null ) { return Name; } else { return String.Format( "{0}({1})", @@ -24,26 +26,28 @@ public override string Description { // ReSharper disable MemberCanBeProtected.Global public bool Not { get; private set; } + // ReSharper restore MemberCanBeProtected.Global public Block[] Blocks { get; private set; } + public Vector3I Start { get; private set; } public CopyState CopyInfo { get; private set; } - public PasteDrawOperation( Player player, bool not ) : base( player ) { Not = not; } - public override bool Prepare( Vector3I[] marks ) { - if( marks == null ) throw new ArgumentNullException( "marks" ); - if( marks.Length < 2 ) throw new ArgumentException( "At least two marks needed.", "marks" ); + if ( marks == null ) + throw new ArgumentNullException( "marks" ); + if ( marks.Length < 2 ) + throw new ArgumentException( "At least two marks needed.", "marks" ); // Make sure that we have something to paste CopyInfo = Player.GetCopyInformation(); - if( CopyInfo == null ) { + if ( CopyInfo == null ) { Player.Message( "Nothing to paste! Copy something first." ); return false; } @@ -51,26 +55,26 @@ public override bool Prepare( Vector3I[] marks ) { // Calculate the buffer orientation Vector3I delta = marks[1] - marks[0]; Vector3I orientation = new Vector3I { - X = (delta.X == 0 ? CopyInfo.Orientation.X : Math.Sign( delta.X )), - Y = (delta.Y == 0 ? CopyInfo.Orientation.Y : Math.Sign( delta.Y )), - Z = (delta.Z == 0 ? CopyInfo.Orientation.Z : Math.Sign( delta.Z )) + X = ( delta.X == 0 ? CopyInfo.Orientation.X : Math.Sign( delta.X ) ), + Y = ( delta.Y == 0 ? CopyInfo.Orientation.Y : Math.Sign( delta.Y ) ), + Z = ( delta.Z == 0 ? CopyInfo.Orientation.Z : Math.Sign( delta.Z ) ) }; // Calculate the start/end coordinates for pasting - marks[1] = marks[0] + new Vector3I( orientation.X * (CopyInfo.Dimensions.X - 1), - orientation.Y * (CopyInfo.Dimensions.Y - 1), - orientation.Z * (CopyInfo.Dimensions.Z - 1) ); + marks[1] = marks[0] + new Vector3I( orientation.X * ( CopyInfo.Dimensions.X - 1 ), + orientation.Y * ( CopyInfo.Dimensions.Y - 1 ), + orientation.Z * ( CopyInfo.Dimensions.Z - 1 ) ); Bounds = new BoundingBox( marks[0], marks[1] ); Marks = marks; // Warn if paste will be cut off - if( Bounds.XMin < 0 || Bounds.XMax > Map.Width - 1 ) { + if ( Bounds.XMin < 0 || Bounds.XMax > Map.Width - 1 ) { Player.Message( "Warning: Not enough room horizontally (X), paste cut off." ); } - if( Bounds.YMin < 0 || Bounds.YMax > Map.Length - 1 ) { + if ( Bounds.YMin < 0 || Bounds.YMax > Map.Length - 1 ) { Player.Message( "Warning: Not enough room horizontally (Y), paste cut off." ); } - if( Bounds.ZMin < 0 || Bounds.ZMax > Map.Height - 1 ) { + if ( Bounds.ZMin < 0 || Bounds.ZMax > Map.Height - 1 ) { Player.Message( "Warning: Not enough room vertically, paste cut off." ); } @@ -88,16 +92,16 @@ public override bool Prepare( Vector3I[] marks ) { return true; } - public override int DrawBatch( int maxBlocksToDraw ) { // basically same as CuboidDrawOp int blocksDone = 0; - for( ; Coords.X <= Bounds.XMax; Coords.X++ ) { - for( ; Coords.Y <= Bounds.YMax; Coords.Y++ ) { - for( ; Coords.Z <= Bounds.ZMax; Coords.Z++ ) { - if( !DrawOneBlock() ) continue; + for ( ; Coords.X <= Bounds.XMax; Coords.X++ ) { + for ( ; Coords.Y <= Bounds.YMax; Coords.Y++ ) { + for ( ; Coords.Z <= Bounds.ZMax; Coords.Z++ ) { + if ( !DrawOneBlock() ) + continue; blocksDone++; - if( blocksDone >= maxBlocksToDraw ) { + if ( blocksDone >= maxBlocksToDraw ) { Coords.Z++; return blocksDone; } @@ -105,7 +109,7 @@ public override int DrawBatch( int maxBlocksToDraw ) { Coords.Z = Bounds.ZMin; } Coords.Y = Bounds.YMin; - if( TimeToEndBatch ) { + if ( TimeToEndBatch ) { Coords.X++; return blocksDone; } @@ -114,21 +118,21 @@ public override int DrawBatch( int maxBlocksToDraw ) { return blocksDone; } - public override bool ReadParams( Command cmd ) { - if( Player.GetCopyInformation() == null ) { + if ( Player.GetCopyInformation() == null ) { Player.Message( "Nothing to paste! Copy something first." ); return false; } List blocks = new List(); - while( cmd.HasNext ) { + while ( cmd.HasNext ) { Block block = cmd.NextBlock( Player ); - if( block == Block.Undefined ) return false; + if ( block == Block.Undefined ) + return false; blocks.Add( block ); } - if( blocks.Count > 0 ) { + if ( blocks.Count > 0 ) { Blocks = blocks.ToArray(); - } else if( Not ) { + } else if ( Not ) { Player.Message( "PasteNot requires at least 1 block." ); return false; } @@ -136,19 +140,21 @@ public override bool ReadParams( Command cmd ) { return true; } - protected override Block NextBlock() { // ReSharper disable LoopCanBeConvertedToQuery Block block = CopyInfo.Buffer[Coords.X - Start.X, Coords.Y - Start.Y, Coords.Z - Start.Z]; - if( Blocks == null ) return block; - if( Not ) { - for( int i = 0; i < Blocks.Length; i++ ) { - if( block == Blocks[i] ) return Block.Undefined; + if ( Blocks == null ) + return block; + if ( Not ) { + for ( int i = 0; i < Blocks.Length; i++ ) { + if ( block == Blocks[i] ) + return Block.Undefined; } return block; } else { - for( int i = 0; i < Blocks.Length; i++ ) { - if( block == Blocks[i] ) return block; + for ( int i = 0; i < Blocks.Length; i++ ) { + if ( block == Blocks[i] ) + return block; } return Block.Undefined; } diff --git a/fCraft/Drawing/DrawOps/QuickPasteDrawOperation.cs b/fCraft/Drawing/DrawOps/QuickPasteDrawOperation.cs index ca27e51..ef0aaeb 100644 --- a/fCraft/Drawing/DrawOps/QuickPasteDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/QuickPasteDrawOperation.cs @@ -1,7 +1,9 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft.Drawing { - sealed class QuickPasteDrawOperation : PasteDrawOperation { + + internal sealed class QuickPasteDrawOperation : PasteDrawOperation { + public override string Name { get { return Not ? "PasteNot" : "Paste"; @@ -16,4 +18,4 @@ public override bool Prepare( Vector3I[] marks ) { return base.Prepare( new[] { marks[0], marks[0] } ); } } -} +} \ No newline at end of file diff --git a/fCraft/Drawing/DrawOps/RandomMazeDrawOperation.cs b/fCraft/Drawing/DrawOps/RandomMazeDrawOperation.cs index 78a6910..7dffe43 100644 --- a/fCraft/Drawing/DrawOps/RandomMazeDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/RandomMazeDrawOperation.cs @@ -28,29 +28,23 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) 2012 Lao Tszy (lao_tszy@yahoo.co.uk) using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using fCraft; using fCraft.Drawing; -namespace RandomMaze -{ - internal class RandomMazeDrawOperation : DrawOpWithBrush - { +namespace RandomMaze { + + internal class RandomMazeDrawOperation : DrawOpWithBrush { public const int DefaultXSize = 5; public const int DefaultYSize = 5; public const int DefaultZSize = 3; public const int DefaultCellSize = 3; - public const double HintProbability = 0.3; + public const double HintProbability = 0.3; - public override string Name - { + public override string Name { get { return "RandomMaze"; } } - public override string Description - { + public override string Description { get { return Name; } } @@ -66,83 +60,74 @@ public override string Description private int _patternIdx; private Random _r = new Random(); private IBrushInstance _playersBrush; - private bool _drawElevators = true; - private bool _drawHints = false; - private bool _needHint = false; - - public RandomMazeDrawOperation(Player player, Command cmd) - : base(player) - { - int xSize = CommandOrDefault(cmd, DefaultXSize); - int ySize = CommandOrDefault(cmd, DefaultYSize); - int zSize = CommandOrDefault(cmd, DefaultZSize); - ReadFlags(cmd); - _cellSize = DefaultCellSize; - _playersBrush = player.Brush.MakeInstance(player, cmd, this); - - _maze = new Maze(xSize, ySize, zSize); + private bool _drawElevators = true; + private bool _drawHints = false; + private bool _needHint = false; + + public RandomMazeDrawOperation( Player player, Command cmd ) + : base( player ) { + int xSize = CommandOrDefault( cmd, DefaultXSize ); + int ySize = CommandOrDefault( cmd, DefaultYSize ); + int zSize = CommandOrDefault( cmd, DefaultZSize ); + ReadFlags( cmd ); + _cellSize = DefaultCellSize; + _playersBrush = player.Brush.MakeInstance( player, cmd, this ); + + _maze = new Maze( xSize, ySize, zSize ); } - private static int CommandOrDefault(Command cmd, int defVal) - { + private static int CommandOrDefault( Command cmd, int defVal ) { string s = cmd.Next(); - if (!string.IsNullOrWhiteSpace(s)) - { + if ( !string.IsNullOrWhiteSpace( s ) ) { int n; - if (int.TryParse(s, out n)) + if ( int.TryParse( s, out n ) ) return n; } return defVal; } - private void ReadFlags(Command cmd) - { - for (;;) - { - string s = cmd.Next(); - if (null==s) - break; - s.ToLower(); - if (s=="noelevators" || s=="nolifts") - _drawElevators = false; - else if (s=="hint" || s=="hints") - _drawHints = true; - else - Player.Message("Unknown option: "+s+", ignored"); - } - } - - public override bool Prepare(Vector3I[] marks) - { - if (marks == null) - throw new ArgumentNullException("marks"); - if (marks.Length < 1) - throw new ArgumentException("At least one mark needed.", "marks"); - - Vector3I mark2 = new Vector3I((_cellSize + 1) * _maze.XSize + 1 + marks[0].X, - (_cellSize + 1) * _maze.YSize + 1 + marks[0].Y, - (_cellSize + 1) * _maze.ZSize + 1 + marks[0].Z); + private void ReadFlags( Command cmd ) { + for ( ; ; ) { + string s = cmd.Next(); + if ( null == s ) + break; + s.ToLower(); + if ( s == "noelevators" || s == "nolifts" ) + _drawElevators = false; + else if ( s == "hint" || s == "hints" ) + _drawHints = true; + else + Player.Message( "Unknown option: " + s + ", ignored" ); + } + } + + public override bool Prepare( Vector3I[] marks ) { + if ( marks == null ) + throw new ArgumentNullException( "marks" ); + if ( marks.Length < 1 ) + throw new ArgumentException( "At least one mark needed.", "marks" ); + + Vector3I mark2 = new Vector3I( ( _cellSize + 1 ) * _maze.XSize + 1 + marks[0].X, + ( _cellSize + 1 ) * _maze.YSize + 1 + marks[0].Y, + ( _cellSize + 1 ) * _maze.ZSize + 1 + marks[0].Z ); Marks = marks; // Warn if paste will be cut off - if (mark2.X >= Map.Width) - { - Player.Message("Error: Not enough room horizontally (X)"); + if ( mark2.X >= Map.Width ) { + Player.Message( "Error: Not enough room horizontally (X)" ); return false; } - if (mark2.Y >= Map.Length) - { - Player.Message("Error: Not enough room horizontally (Y)"); + if ( mark2.Y >= Map.Length ) { + Player.Message( "Error: Not enough room horizontally (Y)" ); return false; } - if (mark2.Z >= Map.Height) - { - Player.Message("Error: Not enough room vertically (Z)"); + if ( mark2.Z >= Map.Height ) { + Player.Message( "Error: Not enough room vertically (Z)" ); return false; } - Bounds = new BoundingBox(marks[0], mark2); + Bounds = new BoundingBox( marks[0], mark2 ); Brush = this; Coords = Bounds.MinVertex; @@ -153,132 +138,113 @@ public override bool Prepare(Vector3I[] marks) return true; } - - public override int DrawBatch(int maxBlocksToDraw) - { + public override int DrawBatch( int maxBlocksToDraw ) { //general drawing - for (int zCell = 0; zCell < _maze.ZSize; ++zCell) - { - for (int yCell = 0; yCell < _maze.YSize; ++yCell) - { - for (int xCell = 0; xCell < _maze.XSize; ++xCell) - { - DrawCell(xCell, yCell, zCell); + for ( int zCell = 0; zCell < _maze.ZSize; ++zCell ) { + for ( int yCell = 0; yCell < _maze.YSize; ++yCell ) { + for ( int xCell = 0; xCell < _maze.XSize; ++xCell ) { + DrawCell( xCell, yCell, zCell ); } //last cell in raw - DrawWall(_maze.XSize - 1, yCell, zCell, Direction.All[0]); - DrawColumn(_maze.XSize, yCell, zCell, Direction.All[4]); - DrawColumn(_maze.XSize, yCell, zCell, Direction.All[1]); + DrawWall( _maze.XSize - 1, yCell, zCell, Direction.All[0] ); + DrawColumn( _maze.XSize, yCell, zCell, Direction.All[4] ); + DrawColumn( _maze.XSize, yCell, zCell, Direction.All[1] ); } //side walls for the last raw - for (int xCell = 0; xCell < _maze.XSize; ++xCell) - { - DrawWall(xCell, _maze.YSize - 1, zCell, Direction.All[1]); - DrawColumn(xCell, _maze.YSize, zCell, Direction.All[4]); - DrawColumn(xCell, _maze.YSize, zCell, Direction.All[0]); + for ( int xCell = 0; xCell < _maze.XSize; ++xCell ) { + DrawWall( xCell, _maze.YSize - 1, zCell, Direction.All[1] ); + DrawColumn( xCell, _maze.YSize, zCell, Direction.All[4] ); + DrawColumn( xCell, _maze.YSize, zCell, Direction.All[0] ); } - DrawColumn(_maze.XSize, _maze.YSize, zCell, Direction.All[4]); + DrawColumn( _maze.XSize, _maze.YSize, zCell, Direction.All[4] ); } //roof //normal - for (int yCell = 0; yCell < _maze.YSize; ++yCell) - { - for (int xCell = 0; xCell < _maze.XSize; ++xCell) - { - DrawWall(xCell, yCell, _maze.ZSize - 1, Direction.All[5]); - DrawColumn(xCell, yCell, _maze.ZSize, Direction.All[0]); - DrawColumn(xCell, yCell, _maze.ZSize, Direction.All[1]); + for ( int yCell = 0; yCell < _maze.YSize; ++yCell ) { + for ( int xCell = 0; xCell < _maze.XSize; ++xCell ) { + DrawWall( xCell, yCell, _maze.ZSize - 1, Direction.All[5] ); + DrawColumn( xCell, yCell, _maze.ZSize, Direction.All[0] ); + DrawColumn( xCell, yCell, _maze.ZSize, Direction.All[1] ); } //last cell in raw - DrawColumn(_maze.XSize, yCell, _maze.ZSize, Direction.All[1]); + DrawColumn( _maze.XSize, yCell, _maze.ZSize, Direction.All[1] ); } //last raw - for (int xCell = 0; xCell < _maze.XSize; ++xCell) - { - DrawColumn(xCell, _maze.YSize, _maze.ZSize, Direction.All[0]); + for ( int xCell = 0; xCell < _maze.XSize; ++xCell ) { + DrawColumn( xCell, _maze.YSize, _maze.ZSize, Direction.All[0] ); } IsDone = true; return _count; } - private void DrawCell(int xCell, int yCell, int zCell) - { - DrawWall(xCell, yCell, zCell, Direction.All[2]); - DrawWall(xCell, yCell, zCell, Direction.All[3]); - //here we always request a hint, and in DrawWall we will correct it to the necessary probability - //only if we rally draw a wall there - if (_drawHints && _maze.GetCell(xCell, yCell, zCell).IsOnSolutionPath()) - _needHint = true; - DrawWall(xCell, yCell, zCell, Direction.All[4]); - _needHint = false; - DrawColumn(xCell, yCell, zCell, Direction.All[0]); - DrawColumn(xCell, yCell, zCell, Direction.All[1]); - DrawColumn(xCell, yCell, zCell, Direction.All[4]); - //special case: elevator - if (_drawElevators && !_maze.GetCell(xCell, yCell, zCell).Wall(Direction.All[5])) - DrawElevator(xCell, yCell, zCell); + private void DrawCell( int xCell, int yCell, int zCell ) { + DrawWall( xCell, yCell, zCell, Direction.All[2] ); + DrawWall( xCell, yCell, zCell, Direction.All[3] ); + //here we always request a hint, and in DrawWall we will correct it to the necessary probability + //only if we rally draw a wall there + if ( _drawHints && _maze.GetCell( xCell, yCell, zCell ).IsOnSolutionPath() ) + _needHint = true; + DrawWall( xCell, yCell, zCell, Direction.All[4] ); + _needHint = false; + DrawColumn( xCell, yCell, zCell, Direction.All[0] ); + DrawColumn( xCell, yCell, zCell, Direction.All[1] ); + DrawColumn( xCell, yCell, zCell, Direction.All[4] ); + //special case: elevator + if ( _drawElevators && !_maze.GetCell( xCell, yCell, zCell ).Wall( Direction.All[5] ) ) + DrawElevator( xCell, yCell, zCell ); } - private void DrawWall(int xCell, int yCell, int zCell, Direction d) - { - if (_maze.GetCell(xCell, yCell, zCell).Wall(d)) - { - //reduce the hint probability from 1.0 to required - if (_needHint && _r.NextDouble() >= HintProbability) - _needHint = false; - - d.ArrangeCoords(ref Coords.X, ref Coords.Y, ref Coords.Z, - xCell * (_cellSize + 1) + 1 + Marks[0].X, - yCell * (_cellSize + 1) + 1 + Marks[0].Y, - zCell * (_cellSize + 1) + 1 + Marks[0].Z, - _cellSize, WallCallback); + private void DrawWall( int xCell, int yCell, int zCell, Direction d ) { + if ( _maze.GetCell( xCell, yCell, zCell ).Wall( d ) ) { + //reduce the hint probability from 1.0 to required + if ( _needHint && _r.NextDouble() >= HintProbability ) + _needHint = false; + + d.ArrangeCoords( ref Coords.X, ref Coords.Y, ref Coords.Z, + xCell * ( _cellSize + 1 ) + 1 + Marks[0].X, + yCell * ( _cellSize + 1 ) + 1 + Marks[0].Y, + zCell * ( _cellSize + 1 ) + 1 + Marks[0].Z, + _cellSize, WallCallback ); } } - private void DrawColumn(int xCell, int yCell, int zCell, Direction d) - { - d.ArrangeCoords(ref Coords.X, ref Coords.Y, ref Coords.Z, - xCell * (_cellSize + 1) + 1 + Marks[0].X, - yCell * (_cellSize + 1) + 1 + Marks[0].Y, - zCell * (_cellSize + 1) + 1 + Marks[0].Z, - _cellSize, StickCallback); + private void DrawColumn( int xCell, int yCell, int zCell, Direction d ) { + d.ArrangeCoords( ref Coords.X, ref Coords.Y, ref Coords.Z, + xCell * ( _cellSize + 1 ) + 1 + Marks[0].X, + yCell * ( _cellSize + 1 ) + 1 + Marks[0].Y, + zCell * ( _cellSize + 1 ) + 1 + Marks[0].Z, + _cellSize, StickCallback ); } - private void StickCallback(ref int coord, int coordFrom) - { - for (coord = coordFrom; coord < coordFrom + _cellSize; ++coord) - { - if (DrawOneBlock()) + private void StickCallback( ref int coord, int coordFrom ) { + for ( coord = coordFrom; coord < coordFrom + _cellSize; ++coord ) { + if ( DrawOneBlock() ) ++_count; } } - private void WallCallback(ref int coord1, ref int coord2, int coord1From, int coord2From) - { + private void WallCallback( ref int coord1, ref int coord2, int coord1From, int coord2From ) { _drawingWall = true; ChoosePattern(); - for (coord1 = coord1From; coord1 < coord1From + _cellSize; ++coord1) - for (coord2 = coord2From; coord2 < coord2From + _cellSize; ++coord2) - { + for ( coord1 = coord1From; coord1 < coord1From + _cellSize; ++coord1 ) + for ( coord2 = coord2From; coord2 < coord2From + _cellSize; ++coord2 ) { _wallPatternCoordX = coord1 - coord1From; _wallPatternCoordY = coord2 - coord2From; - if (DrawOneBlock()) + if ( DrawOneBlock() ) ++_count; } _drawingWall = false; } - private void DrawElevator(int xCell, int yCell, int zCell) - { - Coords.X = xCell * (_cellSize + 1) + 1 + _cellSize / 2 + Marks[0].X; - Coords.Y = yCell * (_cellSize + 1) + 1 + _cellSize / 2 + Marks[0].Y; - int zFrom = zCell * (_cellSize + 1) + 1 + Marks[0].Z; + private void DrawElevator( int xCell, int yCell, int zCell ) { + Coords.X = xCell * ( _cellSize + 1 ) + 1 + _cellSize / 2 + Marks[0].X; + Coords.Y = yCell * ( _cellSize + 1 ) + 1 + _cellSize / 2 + Marks[0].Y; + int zFrom = zCell * ( _cellSize + 1 ) + 1 + Marks[0].Z; //water column _drawingElevator = true; - for (Coords.Z = zFrom; Coords.Z < zFrom + _cellSize + 1; ++Coords.Z) - { - if (DrawOneBlock()) + for ( Coords.Z = zFrom; Coords.Z < zFrom + _cellSize + 1; ++Coords.Z ) { + if ( DrawOneBlock() ) ++_count; } _drawingElevator = false; @@ -286,98 +252,91 @@ private void DrawElevator(int xCell, int yCell, int zCell) //partial floor above _drawingWall = true; ChoosePattern(); - Coords.Z = (zCell + 1) * (_cellSize + 1) + Marks[0].Z; + Coords.Z = ( zCell + 1 ) * ( _cellSize + 1 ) + Marks[0].Z; - Coords.Y = yCell * (_cellSize + 1) + 1 + _cellSize / 2 + Marks[0].Y; + Coords.Y = yCell * ( _cellSize + 1 ) + 1 + _cellSize / 2 + Marks[0].Y; _wallPatternCoordY = _cellSize / 2; - DrawPartOfPartialWall(ref Coords.X, xCell * (_cellSize + 1) + 1 + Marks[0].X, ref _wallPatternCoordX); + DrawPartOfPartialWall( ref Coords.X, xCell * ( _cellSize + 1 ) + 1 + Marks[0].X, ref _wallPatternCoordX ); - Coords.X = xCell * (_cellSize + 1) + 1 + _cellSize / 2 + Marks[0].X; + Coords.X = xCell * ( _cellSize + 1 ) + 1 + _cellSize / 2 + Marks[0].X; _wallPatternCoordX = _cellSize / 2; - DrawPartOfPartialWall(ref Coords.Y, yCell * (_cellSize + 1) + 1 + Marks[0].Y, ref _wallPatternCoordY); + DrawPartOfPartialWall( ref Coords.Y, yCell * ( _cellSize + 1 ) + 1 + Marks[0].Y, ref _wallPatternCoordY ); _drawingWall = false; } - private void DrawPartOfPartialWall(ref int coord, int coordFrom, ref int patternCoord) - { - for (coord = coordFrom; coord < coordFrom + _cellSize; ++coord) - { + private void DrawPartOfPartialWall( ref int coord, int coordFrom, ref int patternCoord ) { + for ( coord = coordFrom; coord < coordFrom + _cellSize; ++coord ) { patternCoord = coord - coordFrom; - if (patternCoord == _cellSize / 2) + if ( patternCoord == _cellSize / 2 ) continue; - if (DrawOneBlock()) + if ( DrawOneBlock() ) ++_count; } } - private void ChoosePattern() - { - _patternIdx = _r.NextDouble() < 0.24 ? _r.Next(_patterns.Length) : -1; + private void ChoosePattern() { + _patternIdx = _r.NextDouble() < 0.24 ? _r.Next( _patterns.Length ) : -1; } - public override bool ReadParams(Command cmd) - { + public override bool ReadParams( Command cmd ) { //Brush = this; return true; } - private Block[][][] _patterns = { new Block[][] - { new Block[]{ Block.Glass, Block.Glass, Block.Glass }, - new Block[]{ Block.Glass, Block.Glass, Block.Glass }, + { new Block[]{ Block.Glass, Block.Glass, Block.Glass }, + new Block[]{ Block.Glass, Block.Glass, Block.Glass }, new Block[]{ Block.Glass, Block.Glass, Block.Glass } }, new Block[][] - { new Block[]{ Block.Undefined, Block.Glass, Block.Undefined }, - new Block[]{ Block.Glass, Block.Glass, Block.Glass }, + { new Block[]{ Block.Undefined, Block.Glass, Block.Undefined }, + new Block[]{ Block.Glass, Block.Glass, Block.Glass }, new Block[]{ Block.Undefined, Block.Glass, Block.Undefined } }, new Block[][] - { new Block[]{ Block.Undefined, Block.Glass, Block.Undefined }, - new Block[]{ Block.Glass, Block.Undefined, Block.Glass }, + { new Block[]{ Block.Undefined, Block.Glass, Block.Undefined }, + new Block[]{ Block.Glass, Block.Undefined, Block.Glass }, new Block[]{ Block.Undefined, Block.Glass, Block.Undefined } }, new Block[][] - { new Block[]{ Block.Glass, Block.Undefined, Block.Glass }, - new Block[]{ Block.Undefined, Block.Glass, Block.Undefined }, + { new Block[]{ Block.Glass, Block.Undefined, Block.Glass }, + new Block[]{ Block.Undefined, Block.Glass, Block.Undefined }, new Block[]{ Block.Glass, Block.Undefined, Block.Glass } }, new Block[][] - { new Block[]{ Block.Leaves, Block.Leaves, Block.Leaves }, - new Block[]{ Block.Leaves, Block.Glass, Block.Leaves }, + { new Block[]{ Block.Leaves, Block.Leaves, Block.Leaves }, + new Block[]{ Block.Leaves, Block.Glass, Block.Leaves }, new Block[]{ Block.Leaves, Block.Leaves, Block.Leaves } }, new Block[][] - { new Block[]{ Block.Glass, Block.Leaves, Block.Glass }, - new Block[]{ Block.Leaves, Block.Glass, Block.Leaves }, + { new Block[]{ Block.Glass, Block.Leaves, Block.Glass }, + new Block[]{ Block.Leaves, Block.Glass, Block.Leaves }, new Block[]{ Block.Glass, Block.Leaves, Block.Glass } }, }; - private Block[] _randomBlocks = {Block.White, Block.Blue, Block.Gold, Block.Cyan, Block.Green, - Block.Indigo, Block.Magenta, Block.Obsidian, Block.Orange, + + private Block[] _randomBlocks = {Block.White, Block.Blue, Block.Gold, Block.Cyan, Block.Green, + Block.Indigo, Block.Magenta, Block.Obsidian, Block.Orange, Block.Pink,Block.Red, Block.Sponge, Block.Violet, Block.Yellow}; - private const Block HintBlock = Block.Log; + private const Block HintBlock = Block.Log; - protected override Block NextBlock() - { - if (_drawingElevator) + protected override Block NextBlock() { + if ( _drawingElevator ) return Block.Water; - if (!_drawingWall) + if ( !_drawingWall ) return Block.Wood;//_playersBrush.NextBlock(this); - if (_patternIdx < 0) - { - if (_needHint) - { - _needHint = false; - return HintBlock; - } - return _r.NextDouble() < 0.2 - ? Block.Wood /*_playersBrush.NextBlock(this)*/ - : _randomBlocks[_r.Next(_randomBlocks.Length)]; - } + if ( _patternIdx < 0 ) { + if ( _needHint ) { + _needHint = false; + return HintBlock; + } + return _r.NextDouble() < 0.2 + ? Block.Wood /*_playersBrush.NextBlock(this)*/ + : _randomBlocks[_r.Next( _randomBlocks.Length )]; + } Block b = _patterns[_patternIdx][_wallPatternCoordX][_wallPatternCoordY]; - if (b == Block.Undefined) + if ( b == Block.Undefined ) b = Block.Wood; //_playersBrush.NextBlock(this); - + return b; } } -} +} \ No newline at end of file diff --git a/fCraft/Drawing/DrawOps/SphereDrawOperation.cs b/fCraft/Drawing/DrawOps/SphereDrawOperation.cs index 9967d91..662ffa9 100644 --- a/fCraft/Drawing/DrawOps/SphereDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/SphereDrawOperation.cs @@ -2,7 +2,9 @@ using System; namespace fCraft.Drawing { + public sealed class SphereDrawOperation : EllipsoidDrawOperation { + public override string Name { get { return "Sphere"; } } @@ -12,17 +14,17 @@ public SphereDrawOperation( Player player ) } public override bool Prepare( Vector3I[] marks ) { - double radius = Math.Sqrt( (marks[0].X - marks[1].X) * (marks[0].X - marks[1].X) + - (marks[0].Y - marks[1].Y) * (marks[0].Y - marks[1].Y) + - (marks[0].Z - marks[1].Z) * (marks[0].Z - marks[1].Z) ); + double radius = Math.Sqrt( ( marks[0].X - marks[1].X ) * ( marks[0].X - marks[1].X ) + + ( marks[0].Y - marks[1].Y ) * ( marks[0].Y - marks[1].Y ) + + ( marks[0].Z - marks[1].Z ) * ( marks[0].Z - marks[1].Z ) ); - marks[1].X = (short)Math.Round( marks[0].X - radius ); - marks[1].Y = (short)Math.Round( marks[0].Y - radius ); - marks[1].Z = (short)Math.Round( marks[0].Z - radius ); + marks[1].X = ( short )Math.Round( marks[0].X - radius ); + marks[1].Y = ( short )Math.Round( marks[0].Y - radius ); + marks[1].Z = ( short )Math.Round( marks[0].Z - radius ); - marks[0].X = (short)Math.Round( marks[0].X + radius ); - marks[0].Y = (short)Math.Round( marks[0].Y + radius ); - marks[0].Z = (short)Math.Round( marks[0].Z + radius ); + marks[0].X = ( short )Math.Round( marks[0].X + radius ); + marks[0].Y = ( short )Math.Round( marks[0].Y + radius ); + marks[0].Z = ( short )Math.Round( marks[0].Z + radius ); return base.Prepare( marks ); } diff --git a/fCraft/Drawing/DrawOps/SphereHollowDrawOperation.cs b/fCraft/Drawing/DrawOps/SphereHollowDrawOperation.cs index 128d194..4bf7ddd 100644 --- a/fCraft/Drawing/DrawOps/SphereHollowDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/SphereHollowDrawOperation.cs @@ -2,7 +2,9 @@ using System; namespace fCraft.Drawing { + public sealed class SphereHollowDrawOperation : EllipsoidHollowDrawOperation { + public override string Name { get { return "SphereH"; } } @@ -12,17 +14,17 @@ public SphereHollowDrawOperation( Player player ) } public override bool Prepare( Vector3I[] marks ) { - double radius = Math.Sqrt( (marks[0].X - marks[1].X) * (marks[0].X - marks[1].X) + - (marks[0].Y - marks[1].Y) * (marks[0].Y - marks[1].Y) + - (marks[0].Z - marks[1].Z) * (marks[0].Z - marks[1].Z) ); + double radius = Math.Sqrt( ( marks[0].X - marks[1].X ) * ( marks[0].X - marks[1].X ) + + ( marks[0].Y - marks[1].Y ) * ( marks[0].Y - marks[1].Y ) + + ( marks[0].Z - marks[1].Z ) * ( marks[0].Z - marks[1].Z ) ); - marks[1].X = (short)Math.Round( marks[0].X - radius ); - marks[1].Y = (short)Math.Round( marks[0].Y - radius ); - marks[1].Z = (short)Math.Round( marks[0].Z - radius ); + marks[1].X = ( short )Math.Round( marks[0].X - radius ); + marks[1].Y = ( short )Math.Round( marks[0].Y - radius ); + marks[1].Z = ( short )Math.Round( marks[0].Z - radius ); - marks[0].X = (short)Math.Round( marks[0].X + radius ); - marks[0].Y = (short)Math.Round( marks[0].Y + radius ); - marks[0].Z = (short)Math.Round( marks[0].Z + radius ); + marks[0].X = ( short )Math.Round( marks[0].X + radius ); + marks[0].Y = ( short )Math.Round( marks[0].Y + radius ); + marks[0].Z = ( short )Math.Round( marks[0].Z + radius ); return base.Prepare( marks ); } diff --git a/fCraft/Drawing/DrawOps/TorusDrawOperation.cs b/fCraft/Drawing/DrawOps/TorusDrawOperation.cs index 7f31ec9..cf8c6b7 100644 --- a/fCraft/Drawing/DrawOps/TorusDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/TorusDrawOperation.cs @@ -4,13 +4,15 @@ using System.Collections.Generic; namespace fCraft.Drawing { + public sealed class TorusDrawOperation : DrawOperation { - const float Bias = 0.5f; + private const float Bias = 0.5f; + + private Vector3I center; - Vector3I center; + private int tubeR; + private double bigR; - int tubeR; - double bigR; public override string Name { get { return "Torus"; } } @@ -19,14 +21,14 @@ public TorusDrawOperation( Player player ) : base( player ) { } - public override bool Prepare( Vector3I[] marks ) { - if( !base.Prepare( marks ) ) return false; + if ( !base.Prepare( marks ) ) + return false; // center of the torus center = marks[0]; - Vector3I radiusVector = (marks[1] - center).Abs(); + Vector3I radiusVector = ( marks[1] - center ).Abs(); // tube radius is figured out from Z component of the mark vector tubeR = radiusVector.Z; @@ -36,7 +38,7 @@ public override bool Prepare( Vector3I[] marks ) { radiusVector.Y * radiusVector.Y + .5 ); // tube + torus radius, rounded up. This will be the maximum extend of the torus. - int combinedRadius = (int)Math.Ceiling( bigR + tubeR ); + int combinedRadius = ( int )Math.Ceiling( bigR + tubeR ); // vector from center of torus to the furthest-away point of the bounding box Vector3I combinedRadiusVector = new Vector3I( combinedRadius, combinedRadius, tubeR + 1 ); @@ -44,40 +46,41 @@ public override bool Prepare( Vector3I[] marks ) { // adjusted bounding box Bounds = new BoundingBox( center - combinedRadiusVector, center + combinedRadiusVector ); - BlocksTotalEstimate = (int)(2 * Math.PI * Math.PI * bigR * (tubeR * tubeR + Bias)); + BlocksTotalEstimate = ( int )( 2 * Math.PI * Math.PI * bigR * ( tubeR * tubeR + Bias ) ); coordEnumerator = BlockEnumerator().GetEnumerator(); return true; } + private IEnumerator coordEnumerator; - IEnumerator coordEnumerator; public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; - while( coordEnumerator.MoveNext() ) { + while ( coordEnumerator.MoveNext() ) { Coords = coordEnumerator.Current; - if( DrawOneBlock() ) { + if ( DrawOneBlock() ) { blocksDone++; - if( blocksDone >= maxBlocksToDraw ) return blocksDone; + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; } - if( TimeToEndBatch ) return blocksDone; + if ( TimeToEndBatch ) + return blocksDone; } IsDone = true; return blocksDone; } - - IEnumerable BlockEnumerator() { - for( int x = Bounds.XMin; x <= Bounds.XMax; x++ ) { - for( int y = Bounds.YMin; y <= Bounds.YMax; y++ ) { - for( int z = Bounds.ZMin; z <= Bounds.ZMax; z++ ) { - double dx = (x - center.X); - double dy = (y - center.Y); - double dz = (z - center.Z); + private IEnumerable BlockEnumerator() { + for ( int x = Bounds.XMin; x <= Bounds.XMax; x++ ) { + for ( int y = Bounds.YMin; y <= Bounds.YMax; y++ ) { + for ( int z = Bounds.ZMin; z <= Bounds.ZMax; z++ ) { + double dx = ( x - center.X ); + double dy = ( y - center.Y ); + double dz = ( z - center.Z ); // test if it's inside the torus double r1 = bigR - Math.Sqrt( dx * dx + dy * dy ); - if( r1 * r1 + dz * dz <= tubeR * tubeR + Bias ) { + if ( r1 * r1 + dz * dz <= tubeR * tubeR + Bias ) { yield return new Vector3I( x, y, z ); } } diff --git a/fCraft/Drawing/DrawOps/TriangleDrawOperation.cs b/fCraft/Drawing/DrawOps/TriangleDrawOperation.cs index 0a3d6d0..e17d1c6 100644 --- a/fCraft/Drawing/DrawOps/TriangleDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/TriangleDrawOperation.cs @@ -3,7 +3,9 @@ using System; namespace fCraft.Drawing { + public sealed class TriangleDrawOperation : DrawOperation { + public override string Name { get { return "Triangle"; } } @@ -17,22 +19,24 @@ public TriangleDrawOperation( Player player ) } // Triangle vertices. - Vector3I a, b, c; + private Vector3I a, b, c; + // Edge planes perpendicular to surface, pointing outwards. - Vector3F s1, s2, s3; + private Vector3F s1, s2, s3; - Vector3I normal; - Vector3F normalF; + private Vector3I normal; + private Vector3F normalF; - bool isLine; + private bool isLine; public override bool Prepare( Vector3I[] marks ) { a = marks[0]; b = marks[1]; c = marks[2]; - if( a == b || b == c || c == a ) { - if( a != c ) b = c; + if ( a == b || b == c || c == a ) { + if ( a != c ) + b = c; isLine = true; } @@ -47,9 +51,10 @@ public override bool Prepare( Vector3I[] marks ) { Coords = Bounds.MinVertex; - if( !base.Prepare( marks ) ) return false; + if ( !base.Prepare( marks ) ) + return false; - normal = (b - a).Cross( c - a ); + normal = ( b - a ).Cross( c - a ); normalF = normal.Normalize(); BlocksTotalEstimate = GetBlockTotalEstimate(); @@ -60,54 +65,60 @@ public override bool Prepare( Vector3I[] marks ) { return true; } - - int GetBlockTotalEstimate() { - if( isLine ) { + private int GetBlockTotalEstimate() { + if ( isLine ) { return Math.Max( Math.Max( Bounds.Width, Bounds.Height ), Bounds.Length ); } Vector3I nabs = normal.Abs(); return Math.Max( Math.Max( nabs.X, nabs.Y ), nabs.Z ) / 2; } - public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; - if( isLine ) { - foreach( var p in LineEnumerator( a, b) ) { + if ( isLine ) { + foreach ( var p in LineEnumerator( a, b ) ) { Coords = p; - if( DrawOneBlock() ) { + if ( DrawOneBlock() ) { blocksDone++; - if( blocksDone >= maxBlocksToDraw ) return blocksDone; + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; } - if( TimeToEndBatch ) return blocksDone; + if ( TimeToEndBatch ) + return blocksDone; } } else { - for( ; Coords.X <= Bounds.XMax; Coords.X++ ) { - for( ; Coords.Y <= Bounds.YMax; Coords.Y++ ) { - for( ; Coords.Z <= Bounds.ZMax; Coords.Z++ ) { - if( IsTriangleBlock() && DrawOneBlock() ) { + for ( ; Coords.X <= Bounds.XMax; Coords.X++ ) { + for ( ; Coords.Y <= Bounds.YMax; Coords.Y++ ) { + for ( ; Coords.Z <= Bounds.ZMax; Coords.Z++ ) { + if ( IsTriangleBlock() && DrawOneBlock() ) { blocksDone++; - if( blocksDone >= maxBlocksToDraw ) return blocksDone; + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; } - if( TimeToEndBatch ) return blocksDone; - } Coords.Z = Bounds.ZMin; - } Coords.Y = Bounds.YMin; + if ( TimeToEndBatch ) + return blocksDone; + } + Coords.Z = Bounds.ZMin; + } + Coords.Y = Bounds.YMin; } } IsDone = true; return blocksDone; } + private const float Extra = 0.5f; - const float Extra = 0.5f; - bool IsTriangleBlock() { + private bool IsTriangleBlock() { // Early out. - if( Math.Abs( normalF.Dot( Coords - a ) ) > 1 ) return false; + if ( Math.Abs( normalF.Dot( Coords - a ) ) > 1 ) + return false; // Check if within triangle region. - if( (Coords - a).Dot( s1 ) > Extra || - (Coords - b).Dot( s2 ) > Extra || - (Coords - c).Dot( s3 ) > Extra ) return false; + if ( ( Coords - a ).Dot( s1 ) > Extra || + ( Coords - b ).Dot( s2 ) > Extra || + ( Coords - c ).Dot( s3 ) > Extra ) + return false; // Check if minimal plane block. return TestAxis( 1, 0, 0 ) || @@ -116,13 +127,14 @@ bool IsTriangleBlock() { } // Checks distance to plane along axis. - bool TestAxis( int x, int y, int z ) { + private bool TestAxis( int x, int y, int z ) { Vector3I v = new Vector3I( x, y, z ); int numerator = normal.Dot( a - Coords ); int denominator = normal.Dot( v ); - if( denominator == 0 ) return numerator == 0; - double distance = (double)numerator / denominator; + if ( denominator == 0 ) + return numerator == 0; + double distance = ( double )numerator / denominator; return distance > -0.5 && distance <= 0.5; } } -} +} \ No newline at end of file diff --git a/fCraft/Drawing/DrawOps/TriangleWireframeDrawOperation.cs b/fCraft/Drawing/DrawOps/TriangleWireframeDrawOperation.cs index 6365817..8910a2e 100644 --- a/fCraft/Drawing/DrawOps/TriangleWireframeDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/TriangleWireframeDrawOperation.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; namespace fCraft.Drawing { + public sealed class TriangleWireframeDrawOperation : DrawOperation { public override int ExpectedMarks { @@ -17,7 +18,6 @@ public TriangleWireframeDrawOperation( Player player ) : base( player ) { } - public override bool Prepare( Vector3I[] marks ) { Vector3I minVector = new Vector3I( Math.Min( marks[0].X, Math.Min( marks[1].X, marks[2].X ) ), Math.Min( marks[0].Y, Math.Min( marks[1].Y, marks[2].Y ) ), @@ -27,7 +27,8 @@ public override bool Prepare( Vector3I[] marks ) { Math.Max( marks[0].Z, Math.Max( marks[1].Z, marks[2].Z ) ) ); Bounds = new BoundingBox( minVector, maxVector ); - if( !base.Prepare( marks ) ) return false; + if ( !base.Prepare( marks ) ) + return false; BlocksTotalEstimate = Math.Max( Bounds.Width, Math.Max( Bounds.Height, Bounds.Length ) ); @@ -37,45 +38,49 @@ public override bool Prepare( Vector3I[] marks ) { return true; } + private IEnumerator coordEnumerator1, coordEnumerator2, coordEnumerator3; - IEnumerator coordEnumerator1, coordEnumerator2, coordEnumerator3; public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; - while( coordEnumerator1.MoveNext() ) { + while ( coordEnumerator1.MoveNext() ) { Coords = coordEnumerator1.Current; - if( DrawOneBlockIfNotDuplicate() ) { + if ( DrawOneBlockIfNotDuplicate() ) { blocksDone++; - if( blocksDone >= maxBlocksToDraw ) return blocksDone; + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; } - if( TimeToEndBatch ) return blocksDone; + if ( TimeToEndBatch ) + return blocksDone; } - while( coordEnumerator2.MoveNext() ) { + while ( coordEnumerator2.MoveNext() ) { Coords = coordEnumerator2.Current; - if( DrawOneBlockIfNotDuplicate() ) { + if ( DrawOneBlockIfNotDuplicate() ) { blocksDone++; - if( blocksDone >= maxBlocksToDraw ) return blocksDone; + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; } - if( TimeToEndBatch ) return blocksDone; + if ( TimeToEndBatch ) + return blocksDone; } - while( coordEnumerator3.MoveNext() ) { + while ( coordEnumerator3.MoveNext() ) { Coords = coordEnumerator3.Current; - if( DrawOneBlockIfNotDuplicate() ) { + if ( DrawOneBlockIfNotDuplicate() ) { blocksDone++; - if( blocksDone >= maxBlocksToDraw ) return blocksDone; + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; } - if( TimeToEndBatch ) return blocksDone; + if ( TimeToEndBatch ) + return blocksDone; } IsDone = true; return blocksDone; } - - - readonly HashSet modifiedBlocks = new HashSet(); + private readonly HashSet modifiedBlocks = new HashSet(); - bool DrawOneBlockIfNotDuplicate() { + private bool DrawOneBlockIfNotDuplicate() { int index = Map.Index( Coords ); - if( modifiedBlocks.Contains( index ) ) { + if ( modifiedBlocks.Contains( index ) ) { return false; } else { modifiedBlocks.Add( index ); diff --git a/fCraft/Drawing/DrawOps/UndoDrawOperation.cs b/fCraft/Drawing/DrawOps/UndoDrawOperation.cs index 55b81ff..b5438a0 100644 --- a/fCraft/Drawing/DrawOps/UndoDrawOperation.cs +++ b/fCraft/Drawing/DrawOps/UndoDrawOperation.cs @@ -2,8 +2,9 @@ using System; namespace fCraft.Drawing { + public sealed class UndoDrawOperation : DrawOpWithBrush { - const BlockChangeContext UndoContext = BlockChangeContext.Drawn | BlockChangeContext.UndoneSelf; + private const BlockChangeContext UndoContext = BlockChangeContext.Drawn | BlockChangeContext.UndoneSelf; public UndoState State { get; private set; } @@ -19,7 +20,7 @@ public override string Description { public override string Name { get { - if( Redo ) { + if ( Redo ) { return "Redo"; } else { return "Undo"; @@ -27,17 +28,16 @@ public override string Name { } } - public UndoDrawOperation( Player player, UndoState state, bool redo ) : base( player ) { State = state; Redo = redo; } - public override bool Prepare( Vector3I[] marks ) { Brush = this; - if( !base.Prepare( marks ) ) return false; + if ( !base.Prepare( marks ) ) + return false; BlocksTotalEstimate = State.Buffer.Count; Context = UndoContext; Bounds = State.GetBounds(); @@ -45,8 +45,9 @@ public override bool Prepare( Vector3I[] marks ) { } public override bool Begin() { - if( !RaiseBeginningEvent( this ) ) return false; - if( Redo ) { + if ( !RaiseBeginningEvent( this ) ) + return false; + if ( Redo ) { UndoState = Player.RedoBegin( this ); } else { UndoState = Player.UndoBegin( this ); @@ -58,18 +59,18 @@ public override bool Begin() { return true; } - int undoBufferIndex; - Block block; + private int undoBufferIndex; + private Block block; public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; - for( ; undoBufferIndex < State.Buffer.Count; undoBufferIndex++ ) { + for ( ; undoBufferIndex < State.Buffer.Count; undoBufferIndex++ ) { UndoBlock blockUpdate = State.Get( undoBufferIndex ); Coords = new Vector3I( blockUpdate.X, blockUpdate.Y, blockUpdate.Z ); block = blockUpdate.Block; - if( DrawOneBlock() ) { + if ( DrawOneBlock() ) { blocksDone++; - if( blocksDone >= maxBlocksToDraw || TimeToEndBatch ) { + if ( blocksDone >= maxBlocksToDraw || TimeToEndBatch ) { undoBufferIndex++; return blocksDone; } @@ -79,7 +80,6 @@ public override int DrawBatch( int maxBlocksToDraw ) { return blocksDone; } - protected override Block NextBlock() { return block; } diff --git a/fCraft/Drawing/DrawOps/WallsOp.cs b/fCraft/Drawing/DrawOps/WallsOp.cs index a6480f6..8560703 100644 --- a/fCraft/Drawing/DrawOps/WallsOp.cs +++ b/fCraft/Drawing/DrawOps/WallsOp.cs @@ -30,8 +30,9 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY using System.Collections.Generic; namespace fCraft.Drawing { + public sealed class WallsDrawOperation : DrawOperation { - bool fillInner; + private bool fillInner; public override string Name { get { return "Walls"; } @@ -41,14 +42,13 @@ public override string Description { get { return Name; } } - public WallsDrawOperation ( Player player ) + public WallsDrawOperation( Player player ) : base( player ) { } - - public override bool Prepare ( Vector3I[] marks ) { - if ( !base.Prepare( marks ) ) return false; - + public override bool Prepare( Vector3I[] marks ) { + if ( !base.Prepare( marks ) ) + return false; fillInner = Brush.HasAlternateBlock && Bounds.Width > 2 && Bounds.Length > 2 && Bounds.Height > 2; @@ -61,15 +61,16 @@ public override bool Prepare ( Vector3I[] marks ) { return true; } + private IEnumerator coordEnumerator; - IEnumerator coordEnumerator; - public override int DrawBatch ( int maxBlocksToDraw ) { + public override int DrawBatch( int maxBlocksToDraw ) { int blocksDone = 0; while ( coordEnumerator.MoveNext() ) { Coords = coordEnumerator.Current; if ( DrawOneBlock() ) { blocksDone++; - if ( blocksDone >= maxBlocksToDraw ) return blocksDone; + if ( blocksDone >= maxBlocksToDraw ) + return blocksDone; } } IsDone = true; @@ -77,7 +78,7 @@ public override int DrawBatch ( int maxBlocksToDraw ) { } //all works. Maybe look at Block estimation. - IEnumerable BlockEnumerator () { + private IEnumerable BlockEnumerator() { for ( int x = Bounds.XMin; x <= Bounds.XMax; x++ ) { for ( int z = Bounds.ZMin - 1; z < Bounds.ZMax; z++ ) { yield return new Vector3I( x, Bounds.YMin, z + 1 ); @@ -107,4 +108,4 @@ IEnumerable BlockEnumerator () { } } } -} +} \ No newline at end of file diff --git a/fCraft/Drawing/IBrush.cs b/fCraft/Drawing/IBrush.cs index ca85f3c..d048cc4 100644 --- a/fCraft/Drawing/IBrush.cs +++ b/fCraft/Drawing/IBrush.cs @@ -7,6 +7,7 @@ namespace fCraft.Drawing { /// Class that desribes a type of brush in general, and allows creating new brushes with /Brush. /// One instance of IBrushFactory for each type of brush is kept by the BrushManager. public interface IBrushFactory { + [NotNull] string Name { get; } @@ -25,10 +26,10 @@ public interface IBrushFactory { IBrush MakeBrush( [NotNull] Player player, [NotNull] Command cmd ); } - /// Class that describes a configured brush, and allows creating instances for specific DrawOperations. /// Configuration-free brush types may combine IBrushFactory and IBrushType into one class. public interface IBrush { + /// IBrushFactory associated with this brush type. [NotNull] IBrushFactory Factory { get; } @@ -47,11 +48,11 @@ public interface IBrush { IBrushInstance MakeInstance( [NotNull] Player player, [NotNull] Command cmd, [NotNull] DrawOperation op ); } - /// Class that describes an individual instance of a configured brush. /// Each brush instance will only be used for one DrawOperation, so it can store state. /// Stateless brush types may combine IBrush and IBrushInstance into one class. public interface IBrushInstance { + /// Configured brush that created this instance. [NotNull] IBrush Brush { get; } diff --git a/fCraft/Drawing/UndoState.cs b/fCraft/Drawing/UndoState.cs index d509e1f..35ebce7 100644 --- a/fCraft/Drawing/UndoState.cs +++ b/fCraft/Drawing/UndoState.cs @@ -2,12 +2,11 @@ using System.Collections.Generic; using System.Runtime.InteropServices; -namespace fCraft.Drawing -{ - public sealed class UndoState - { - public UndoState(DrawOperation op) - { +namespace fCraft.Drawing { + + public sealed class UndoState { + + public UndoState( DrawOperation op ) { Op = op; Buffer = new List(); } @@ -17,17 +16,12 @@ public UndoState(DrawOperation op) public bool IsTooLargeToUndo; public readonly object SyncRoot = new object(); - public bool Add(Vector3I coord, Block block) - { - lock (SyncRoot) - { - if (BuildingCommands.MaxUndoCount < 1 || Buffer.Count <= BuildingCommands.MaxUndoCount) - { - Buffer.Add(new UndoBlock(coord, block)); + public bool Add( Vector3I coord, Block block ) { + lock ( SyncRoot ) { + if ( BuildingCommands.MaxUndoCount < 1 || Buffer.Count <= BuildingCommands.MaxUndoCount ) { + Buffer.Add( new UndoBlock( coord, block ) ); return true; - } - else if (!IsTooLargeToUndo) - { + } else if ( !IsTooLargeToUndo ) { IsTooLargeToUndo = true; Buffer.Clear(); } @@ -35,43 +29,44 @@ public bool Add(Vector3I coord, Block block) } } - public UndoBlock Get(int index) - { - lock (SyncRoot) - { + public UndoBlock Get( int index ) { + lock ( SyncRoot ) { return Buffer[index]; } } - public BoundingBox GetBounds() - { - lock (SyncRoot) - { - if (Buffer.Count == 0) return BoundingBox.Empty; - Vector3I min = new Vector3I(int.MaxValue, int.MaxValue, int.MaxValue); - Vector3I max = new Vector3I(int.MinValue, int.MinValue, int.MinValue); - for (int i = 0; i < Buffer.Count; i++) - { - if (Buffer[i].X < min.X) min.X = Buffer[i].X; - if (Buffer[i].Y < min.Y) min.Y = Buffer[i].Y; - if (Buffer[i].Z < min.Z) min.Z = Buffer[i].Z; - if (Buffer[i].X > max.X) max.X = Buffer[i].X; - if (Buffer[i].Y > max.Y) max.Y = Buffer[i].Y; - if (Buffer[i].Z > max.Z) max.Z = Buffer[i].Z; + public BoundingBox GetBounds() { + lock ( SyncRoot ) { + if ( Buffer.Count == 0 ) + return BoundingBox.Empty; + Vector3I min = new Vector3I( int.MaxValue, int.MaxValue, int.MaxValue ); + Vector3I max = new Vector3I( int.MinValue, int.MinValue, int.MinValue ); + for ( int i = 0; i < Buffer.Count; i++ ) { + if ( Buffer[i].X < min.X ) + min.X = Buffer[i].X; + if ( Buffer[i].Y < min.Y ) + min.Y = Buffer[i].Y; + if ( Buffer[i].Z < min.Z ) + min.Z = Buffer[i].Z; + if ( Buffer[i].X > max.X ) + max.X = Buffer[i].X; + if ( Buffer[i].Y > max.Y ) + max.Y = Buffer[i].Y; + if ( Buffer[i].Z > max.Z ) + max.Z = Buffer[i].Z; } - return new BoundingBox(min, max); + return new BoundingBox( min, max ); } } } - [StructLayout(LayoutKind.Sequential, Pack = 2)] - public struct UndoBlock - { - public UndoBlock(Vector3I coord, Block block) - { - X = (short)coord.X; - Y = (short)coord.Y; - Z = (short)coord.Z; + [StructLayout( LayoutKind.Sequential, Pack = 2 )] + public struct UndoBlock { + + public UndoBlock( Vector3I coord, Block block ) { + X = ( short )coord.X; + Y = ( short )coord.Y; + Z = ( short )coord.Z; Block = block; } diff --git a/fCraft/Games/Football.cs b/fCraft/Games/Football.cs index 295d9b3..831ca4d 100644 --- a/fCraft/Games/Football.cs +++ b/fCraft/Games/Football.cs @@ -27,24 +27,20 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) <2011 - 2013> Jon Baker(http://au70.net) using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft; using fCraft.Events; -using System.Collections.Concurrent; -using System.Threading; namespace fCraft { + public class Football { private World _world; private Vector3I _startPos; - public Football ( Player player, World world, Vector3I FootballPos ) { + + public Football( Player player, World world, Vector3I FootballPos ) { _world = world; Player.Clicked += ClickedFootball; } - public void ResetFootball () { + public void ResetFootball() { if ( _startPos == null ) { _startPos.X = _world.Map.Bounds.XMax - _world.Map.Bounds.XMin; _startPos.Y = _world.Map.Bounds.YMax - _world.Map.Bounds.YMin; @@ -59,7 +55,8 @@ public void ResetFootball () { } private FootballBehavior _footballBehavior = new FootballBehavior(); - public void ClickedFootball ( object sender, PlayerClickedEventArgs e ) { + + public void ClickedFootball( object sender, PlayerClickedEventArgs e ) { //replace e.coords with player.Pos.toblock() (moving event) if ( e.Coords == _world.footballPos ) { double ksi = 2.0 * Math.PI * ( -e.Player.Position.L ) / 256.0; @@ -70,4 +67,4 @@ public void ClickedFootball ( object sender, PlayerClickedEventArgs e ) { } } } -} +} \ No newline at end of file diff --git a/fCraft/Games/GameMode.cs b/fCraft/Games/GameMode.cs index b66e284..e345614 100644 --- a/fCraft/Games/GameMode.cs +++ b/fCraft/Games/GameMode.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +namespace fCraft { -namespace fCraft { public enum GameMode { NULL, FFA, @@ -15,4 +11,4 @@ public enum GameMode { Football, MineChallenge } -} +} \ No newline at end of file diff --git a/fCraft/Games/MineChallenge.cs b/fCraft/Games/MineChallenge.cs index 08424cf..1381e78 100644 --- a/fCraft/Games/MineChallenge.cs +++ b/fCraft/Games/MineChallenge.cs @@ -30,15 +30,16 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Text; -using fCraft; -using fCraft.Events; using System.Threading; +using fCraft.Events; namespace fCraft.Games { + public class MineChallenge { + //stuff public static Thread GameThread; + public static World world; public static int redRoundsWon; public static int blueRoundsWon; @@ -58,7 +59,7 @@ public enum GameMode { } //init - public static void Init ( World world_ ) { + public static void Init( World world_ ) { world = world_; Player.JoinedWorld += WorldChanging; Player.Clicked += playerClicking; @@ -70,7 +71,7 @@ public static void Init ( World world_ ) { //games - public static void math1 () { + public static void math1() { world.Games.Remove( math1 ); world.Players.Message( "&WKeyboards at the ready..." ); Thread.Sleep( 5000 ); @@ -88,7 +89,7 @@ public static void math1 () { gamePicker(); } - public static void math2 () { + public static void math2() { world.Games.Remove( math2 ); world.Players.Message( "&WKeyboards at the ready... stuff is about to happen!" ); Thread.Sleep( 5000 ); @@ -106,7 +107,7 @@ public static void math2 () { gamePicker(); } - public static void getOffGrass () { + public static void getOffGrass() { world.Games.Remove( getOffGrass ); mode = GameMode.getOffGrass; Map map = world.Map; @@ -132,7 +133,7 @@ public static void getOffGrass () { gamePicker(); } - public static void pinkPlatform () { + public static void pinkPlatform() { world.Games.Remove( pinkPlatform ); mode = GameMode.pinkplatform; Map map = world.Map; @@ -165,7 +166,7 @@ public static void pinkPlatform () { gamePicker(); } - public static void shootBlack () { + public static void shootBlack() { world.Games.Remove( shootBlack ); mode = GameMode.shootblack; GunModeOn(); @@ -194,7 +195,7 @@ public static void shootBlack () { } //events - public static void playerClicking ( object sender, PlayerClickedEventArgs e ) { + public static void playerClicking( object sender, PlayerClickedEventArgs e ) { if ( e.Player.World.GameOn ) { if ( Games.MineChallenge.mode == Games.MineChallenge.GameMode.NULL ) { if ( platform.Values.Count > 0 ) { @@ -209,7 +210,7 @@ public static void playerClicking ( object sender, PlayerClickedEventArgs e ) { } } - public static void PositionCheck () { + public static void PositionCheck() { foreach ( Player player in world.Players ) { foreach ( Vector3I platBlock in platform.Values ) { if ( ( player.Position.X / 32 ) == platBlock.X ) { @@ -230,9 +231,7 @@ public static void PositionCheck () { } } - - - public static void WorldChanging ( object sender, PlayerJoinedWorldEventArgs e ) { + public static void WorldChanging( object sender, PlayerJoinedWorldEventArgs e ) { if ( e.OldWorld != null ) { if ( e.OldWorld != e.NewWorld && e.NewWorld.GameOn ) { if ( !e.NewWorld.blueTeam.Contains( e.Player ) && !e.NewWorld.redTeam.Contains( e.Player ) ) { @@ -248,10 +247,9 @@ public static void WorldChanging ( object sender, PlayerJoinedWorldEventArgs e ) } } - //voids - public static void teamNotify () { + public static void teamNotify() { foreach ( Player player in world.Players ) { if ( world.blueTeam.Contains( player ) ) { player.Message( "&9You are on the Blue Team" ); @@ -261,7 +259,7 @@ public static void teamNotify () { } } - public static void GameAdder ( World world ) { + public static void GameAdder( World world ) { world.Games.Add( pinkPlatform ); world.Games.Add( shootBlack ); world.Games.Add( math1 ); @@ -269,34 +267,36 @@ public static void GameAdder ( World world ) { world.Games.Add( getOffGrass ); } - public static void scoreCounter () { + public static void scoreCounter() { if ( world.blueScore > world.redScore ) { blueRoundsWon++; world.Players.Message( "&SThe &9Blues&S won that round: &9{0} &S- &C{1}", world.blueScore, world.redScore ); - } if ( world.redScore > world.blueScore ) { + } + if ( world.redScore > world.blueScore ) { redRoundsWon++; world.Players.Message( "&SThe &CReds&S won that round: &9{0} &S- &C{1}", world.blueScore, world.redScore ); } else { world.Players.Message( "&SIt was a tie! Both teams get a point! &9{0} &S- &C{1}", world.blueScore, world.redScore ); - blueRoundsWon++; redRoundsWon++; + blueRoundsWon++; + redRoundsWon++; } } - public static void wait ( int time ) { + public static void wait( int time ) { Thread.Sleep( time ); if ( !world.GameOn ) { return; } } - public static void interval () { + public static void interval() { wait( 5000 ); world.Players.Message( "&SScores so far: &9Blues {0} &S- &CReds {1}", blueRoundsWon.ToString(), redRoundsWon.ToString() ); teamNotify(); wait( 5000 ); } - public static void TeamChooser ( Player player, World world ) { + public static void TeamChooser( Player player, World world ) { if ( !world.blueTeam.Contains( player ) && !world.redTeam.Contains( player ) ) { if ( world.blueTeam.Count() > world.redTeam.Count() ) { world.redTeam.Add( player ); @@ -311,7 +311,7 @@ public static void TeamChooser ( Player player, World world ) { } } - public static void teamRemover ( Player player, World world ) { + public static void teamRemover( Player player, World world ) { if ( world.blueTeam.Contains( player ) ) { world.blueTeam.Remove( player ); player.Message( "&SRemoving you from the game" ); @@ -320,26 +320,28 @@ public static void teamRemover ( Player player, World world ) { player.Message( "&SRemoving you from the game" ); } } - public static void Start ( Player player, World world ) { + + public static void Start( Player player, World world ) { GameThread = new Thread( new ThreadStart( delegate { - Init( world ); - world.GameOn = true; - Server.Players.Message( "{0}&S Started a game of MineChallenge on world {1}", - player.ClassyName, world.ClassyName ); - foreach ( Player p in world.Players ) { - TeamChooser( p, world ); - } - Server.Players.Message( "&SThe game will start in 60 Seconds." ); - GameAdder( world ); - // wait(60000); - world.Players.Message( "&SThe game has started!." ); - wait( 2000 ); - gamePicker(); - Scheduler.NewTask( t => PositionCheck() ).RunForever( TimeSpan.FromSeconds( 1 ) ); - } ) ); GameThread.Start(); + Init( world ); + world.GameOn = true; + Server.Players.Message( "{0}&S Started a game of MineChallenge on world {1}", + player.ClassyName, world.ClassyName ); + foreach ( Player p in world.Players ) { + TeamChooser( p, world ); + } + Server.Players.Message( "&SThe game will start in 60 Seconds." ); + GameAdder( world ); + // wait(60000); + world.Players.Message( "&SThe game has started!." ); + wait( 2000 ); + gamePicker(); + Scheduler.NewTask( t => PositionCheck() ).RunForever( TimeSpan.FromSeconds( 1 ) ); + } ) ); + GameThread.Start(); } - public static void gamePicker () { + public static void gamePicker() { if ( world.Games.Count() < 1 ) { Stop( Player.Console ); return; @@ -351,7 +353,7 @@ public static void gamePicker () { world.Games[i](); } - public static void Stop ( Player player ) { + public static void Stop( Player player ) { world.Players.Message( "&SThe game has ended! The scores are: \n&9Blue Team {0} &S- &CRed Team {1}", blueRoundsWon, redRoundsWon ); world.GameOn = false; Clear(); @@ -359,14 +361,14 @@ public static void Stop ( Player player ) { } //needs a rewrite for new gun code - public static void GunModeOn () { + public static void GunModeOn() { foreach ( Player player in world.Players ) { player.GunMode = true; player.Message( "GunMode Activated" ); } } - public static void GunModeOff () { + public static void GunModeOff() { foreach ( Player player in world.Players ) { player.GunMode = false; foreach ( Vector3I block in player.GunCache.Values ) { @@ -375,7 +377,7 @@ public static void GunModeOff () { } } - public static void Clear () { + public static void Clear() { world.blueTeam.Clear(); world.redTeam.Clear(); world.blueScore = 0; @@ -386,4 +388,4 @@ public static void Clear () { mode = GameMode.NULL; } } -} +} \ No newline at end of file diff --git a/fCraft/Games/MineField.cs b/fCraft/Games/MineField.cs index bfc0807..e4db390 100644 --- a/fCraft/Games/MineField.cs +++ b/fCraft/Games/MineField.cs @@ -27,15 +27,13 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) <2011 - 2013> Jon Baker(http://au70.net) using System; -using System.Collections.Generic; using System.Collections.Concurrent; -using System.Linq; -using System.Text; -using fCraft.MapConversion; +using System.Collections.Generic; using fCraft.Events; namespace fCraft { - class MineField { + + internal class MineField { private static World _world; private const int _ground = 1; private static Map _map; @@ -45,11 +43,11 @@ class MineField { private static bool _stopped; private static MineField instance; - private MineField () { + private MineField() { // Empty, singleton } - public static MineField GetInstance () { + public static MineField GetInstance() { if ( instance == null ) { instance = new MineField(); Failed = new List(); @@ -61,7 +59,8 @@ public static MineField GetInstance () { } return instance; } - public static void Start ( Player player ) { + + public static void Start( Player player ) { Map map = MapGenerator.GenerateEmpty( 64, 128, 16 ); map.Save( "maps/minefield.fcm" ); if ( _world != null ) { @@ -83,7 +82,7 @@ public static void Start ( Player player ) { Server.RequestGC(); } - public static void Stop ( Player player, bool Won ) { + public static void Stop( Player player, bool Won ) { if ( Failed != null && Mines != null ) { Failed.Clear(); @@ -104,7 +103,7 @@ public static void Stop ( Player player, bool Won ) { } } - private static void SetUpRed () { + private static void SetUpRed() { for ( int x = 0; x <= _map.Width; x++ ) { for ( int y = 0; y <= 10; y++ ) { _map.SetBlock( x, y, _ground, Block.Red ); @@ -113,7 +112,7 @@ private static void SetUpRed () { } } - private static void SetUpMiddleWater () { + private static void SetUpMiddleWater() { for ( int x = _map.Width; x >= 0; x-- ) { for ( int y = _map.Length - 50; y >= _map.Length - 56; y-- ) { _map.SetBlock( x, y, _ground, Block.Water ); @@ -122,7 +121,7 @@ private static void SetUpMiddleWater () { } } - private static void SetUpGreen () { + private static void SetUpGreen() { for ( int x = _map.Width; x >= 0; x-- ) { for ( int y = _map.Length; y >= _map.Length - 10; y-- ) { _map.SetBlock( x, y, _ground, Block.Green ); @@ -131,7 +130,7 @@ private static void SetUpGreen () { } } - private static void SetUpMines () { + private static void SetUpMines() { for ( short i = 0; i <= _map.Width; ++i ) { for ( short j = 0; j <= _map.Length; ++j ) { if ( _map.GetBlock( i, j, _ground ) != Block.Red && @@ -149,7 +148,7 @@ private static void SetUpMines () { } } - public static bool PlayerBlowUpCheck ( Player player ) { + public static bool PlayerBlowUpCheck( Player player ) { if ( !Failed.Contains( player ) ) { Failed.Add( player ); return true; @@ -157,14 +156,14 @@ public static bool PlayerBlowUpCheck ( Player player ) { return false; } - private static void PlayerPlacing ( object sender, PlayerPlacingBlockEventArgs e ) { + private static void PlayerPlacing( object sender, PlayerPlacingBlockEventArgs e ) { World world = e.Player.World; if ( world.gameMode == GameMode.MineField ) { e.Result = CanPlaceResult.Revert; } } - private static void PlayerMoving ( object sender, PlayerMovingEventArgs e ) { + private static void PlayerMoving( object sender, PlayerMovingEventArgs e ) { if ( _world != null && e.Player.World == _world ) { if ( _world.gameMode == GameMode.MineField && !Failed.Contains( e.Player ) ) { if ( e.NewPosition != null ) { @@ -202,4 +201,4 @@ private static void PlayerMoving ( object sender, PlayerMovingEventArgs e ) { } } } -} +} \ No newline at end of file diff --git a/fCraft/Games/PlayerProximityTracker.cs b/fCraft/Games/PlayerProximityTracker.cs index 2cdd6a7..2713ea8 100644 --- a/fCraft/Games/PlayerProximityTracker.cs +++ b/fCraft/Games/PlayerProximityTracker.cs @@ -29,231 +29,198 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using fCraft.Events; -namespace fCraft -{ - public class PlayersAtDistanceArgs : EventArgs - { - public Player FromPlayer; - public IEnumerable Others; - } - - class TrackerUsageExample - { - private World _world; - private PlayerProximityTracker _tracker = null; - private object _lock=new object(); - - public TrackerUsageExample(World world) - { - if (null==world) - throw new ArgumentNullException("world"); - lock (world.SyncRoot) - { - if (null==world.Map) - throw new ArgumentException("world.Map is null"); - _world = world; - lock (_lock) - { - PlayerProximityTracker tracker = new PlayerProximityTracker(world.Map.Width, world.Map.Length, world); - _tracker.OnPlayersAtDistance += OnPlayersAtDistance; - //_tracker.SetCallEvents(true, 1, (p1, p2) => p1.IsZombi != p2.IsZombi); - - Player.Moved += OnPlayerMoved; - Player.Disconnected += OnPlayerDisconnected; - Player.JoinedWorld += OnPlayerJoined; - } - } - } - - public void OnPlayerMoved(object sender, PlayerMovedEventArgs args) - { - lock (_lock) - { - if (args.Player.World!=_world) - {//he left....chicken - //_tracker.RemovePlayer(args.Player); remove will not work since the guy definitely has different position now - //he will be removed from book keeping later in PlayerProximityTracker.FindPlayersAtDistance - return; - } - _tracker.MovePlayer(args.OldPosition.ToBlockCoords(), args.NewPosition.ToBlockCoords(), args.Player); - } - } - - public void OnPlayerDisconnected(object sender, PlayerDisconnectedEventArgs args) - { - lock (_lock) - { - //try to - _tracker.RemovePlayer(args.Player); - } - } - - public void OnPlayerJoined(object sender, PlayerJoinedWorldEventArgs args) - { - lock (_lock) - { - if (args.NewWorld != args.OldWorld) - { - if (_world == args.NewWorld) - _tracker.AddPlayer(args.Player, args.Player.Position.ToBlockCoords()); - } - } - } - - public void OnPlayersAtDistance(object sender, PlayersAtDistanceArgs args) - { - //called from OnPlayerMoved/OnPlayerJoined under the lock - - //do smth with players from args and call - //FindPlayersAtDistance(Player p) for those whos status was changed - } - } - /// - /// Not thread safe. - /// - public class PlayerProximityTracker - { - private List[,] _players; - - public event EventHandler OnPlayersAtDistance; - - private bool _callEvents=false; - private double _distanceInBlocks; - private Func _takePair; - private World _world = null; //to be able to remove players left the game - - public PlayerProximityTracker(int xSize, int ySize, World world) - { - _players=new List[xSize, ySize]; - foreach (Player p in world.Players) - { - AddPlayer(p, p.Position.ToBlockCoords()); - } - } - - public void AddPlayer(Player p, Vector3I pos) - { - if (null == p) - { - Logger.Log(LogType.Trace, "PlayerProximityTracker.AddPlayer: Player is null"); - return; - } - CheckCoords(ref pos); - if (null == _players[pos.X, pos.Y]) - _players[pos.X, pos.Y] = new List(); - _players[pos.X, pos.Y].Add(p); - - if (_callEvents) - CallEvent(p); - } - - public void RemovePlayer(Player p) - { - if (null == p) - { - Logger.Log(LogType.Trace, "PlayerProximityTracker.RemovePlayer: Player is null"); - return; - } - Vector3I pos = p.Position.ToBlockCoords(); - CheckCoords(ref pos); - if (null == _players[pos.X, pos.Y] || !_players[pos.X, pos.Y].Remove(p)) - Logger.Log(LogType.Trace, "PlayerProximityTracker.RemovePlayer: Player " + p.Name + " is not found at its position"); - } - - public void MovePlayer(Vector3I oldPos, Vector3I newPos, Player p) - { - //the new pos is given as an argument (assumed from PlayerMoved event args) so that the new position would match the previous in the next moved event - CheckCoords(ref oldPos); - CheckCoords(ref newPos); - if (newPos.X == oldPos.X && newPos.Y == oldPos.Y) //nothing to do? - return; - - if (null == _players[oldPos.X, oldPos.Y] || !_players[oldPos.X,oldPos.Y].Remove(p)) - {//this is not a fatal error, the player, even when existing at some wrong position will not be returned by the find call looking around this wrong position - Logger.Log(LogType.Error, "PlayerProximityTracker.MovePlayer: Player " + p.Name + " is not found at its previous position"); - } - AddPlayer(p, newPos); - } - - //may return null - public IEnumerable FindPlayersAtDistance(Player p) - { - return FindPlayersAtDistance(p, _distanceInBlocks, _takePair); - } - //may return null - public IEnumerable FindPlayersAtDistance(Player p, double distInBlocks, Func takePair) - { - int d = (int)Math.Ceiling(distInBlocks); - d *= d*32*32; //squared distance in position coords - - List players=null; - - Vector3I pos = p.Position.ToBlockCoords(); - for (int x=Math.Max(0, pos.X-d); x<=Math.Min(_players.GetLength(0)-1, pos.X+d); ++x) - for (int y=Math.Max(0, pos.Y-d); y<=Math.Min(_players.GetLength(1)-1, pos.Y+d); ++y) - { - if (null==_players[x, y]) - continue; - for (int i = 0; i < _players[x, y].Count; ++i) - { - Player player = _players[x, y][i]; - if (ReferenceEquals(p, player)) //found THE player - continue; - if (!ReferenceEquals(_world, player.World)) //player has left the game world +namespace fCraft { + + public class PlayersAtDistanceArgs : EventArgs { + public Player FromPlayer; + public IEnumerable Others; + } + + internal class TrackerUsageExample { + private World _world; + private PlayerProximityTracker _tracker = null; + private object _lock = new object(); + + public TrackerUsageExample( World world ) { + if ( null == world ) + throw new ArgumentNullException( "world" ); + lock ( world.SyncRoot ) { + if ( null == world.Map ) + throw new ArgumentException( "world.Map is null" ); + _world = world; + lock ( _lock ) { + PlayerProximityTracker tracker = new PlayerProximityTracker( world.Map.Width, world.Map.Length, world ); + _tracker.OnPlayersAtDistance += OnPlayersAtDistance; + //_tracker.SetCallEvents(true, 1, (p1, p2) => p1.IsZombi != p2.IsZombi); + + Player.Moved += OnPlayerMoved; + Player.Disconnected += OnPlayerDisconnected; + Player.JoinedWorld += OnPlayerJoined; + } + } + } + + public void OnPlayerMoved( object sender, PlayerMovedEventArgs args ) { + lock ( _lock ) { + if ( args.Player.World != _world ) {//he left....chicken + //_tracker.RemovePlayer(args.Player); remove will not work since the guy definitely has different position now + //he will be removed from book keeping later in PlayerProximityTracker.FindPlayersAtDistance + return; + } + _tracker.MovePlayer( args.OldPosition.ToBlockCoords(), args.NewPosition.ToBlockCoords(), args.Player ); + } + } + + public void OnPlayerDisconnected( object sender, PlayerDisconnectedEventArgs args ) { + lock ( _lock ) { + //try to + _tracker.RemovePlayer( args.Player ); + } + } + + public void OnPlayerJoined( object sender, PlayerJoinedWorldEventArgs args ) { + lock ( _lock ) { + if ( args.NewWorld != args.OldWorld ) { + if ( _world == args.NewWorld ) + _tracker.AddPlayer( args.Player, args.Player.Position.ToBlockCoords() ); + } + } + } + + public void OnPlayersAtDistance( object sender, PlayersAtDistanceArgs args ) { + //called from OnPlayerMoved/OnPlayerJoined under the lock + + //do smth with players from args and call + //FindPlayersAtDistance(Player p) for those whos status was changed + } + } + + /// + /// Not thread safe. + /// + public class PlayerProximityTracker { + private List[,] _players; + + public event EventHandler OnPlayersAtDistance; + + private bool _callEvents = false; + private double _distanceInBlocks; + private Func _takePair; + private World _world = null; //to be able to remove players left the game + + public PlayerProximityTracker( int xSize, int ySize, World world ) { + _players = new List[xSize, ySize]; + foreach ( Player p in world.Players ) { + AddPlayer( p, p.Position.ToBlockCoords() ); + } + } + + public void AddPlayer( Player p, Vector3I pos ) { + if ( null == p ) { + Logger.Log( LogType.Trace, "PlayerProximityTracker.AddPlayer: Player is null" ); + return; + } + CheckCoords( ref pos ); + if ( null == _players[pos.X, pos.Y] ) + _players[pos.X, pos.Y] = new List(); + _players[pos.X, pos.Y].Add( p ); + + if ( _callEvents ) + CallEvent( p ); + } + + public void RemovePlayer( Player p ) { + if ( null == p ) { + Logger.Log( LogType.Trace, "PlayerProximityTracker.RemovePlayer: Player is null" ); + return; + } + Vector3I pos = p.Position.ToBlockCoords(); + CheckCoords( ref pos ); + if ( null == _players[pos.X, pos.Y] || !_players[pos.X, pos.Y].Remove( p ) ) + Logger.Log( LogType.Trace, "PlayerProximityTracker.RemovePlayer: Player " + p.Name + " is not found at its position" ); + } + + public void MovePlayer( Vector3I oldPos, Vector3I newPos, Player p ) { + //the new pos is given as an argument (assumed from PlayerMoved event args) so that the new position would match the previous in the next moved event + CheckCoords( ref oldPos ); + CheckCoords( ref newPos ); + if ( newPos.X == oldPos.X && newPos.Y == oldPos.Y ) //nothing to do? + return; + + if ( null == _players[oldPos.X, oldPos.Y] || !_players[oldPos.X, oldPos.Y].Remove( p ) ) {//this is not a fatal error, the player, even when existing at some wrong position will not be returned by the find call looking around this wrong position + Logger.Log( LogType.Error, "PlayerProximityTracker.MovePlayer: Player " + p.Name + " is not found at its previous position" ); + } + AddPlayer( p, newPos ); + } + + //may return null + public IEnumerable FindPlayersAtDistance( Player p ) { + return FindPlayersAtDistance( p, _distanceInBlocks, _takePair ); + } + + //may return null + public IEnumerable FindPlayersAtDistance( Player p, double distInBlocks, Func takePair ) { + int d = ( int )Math.Ceiling( distInBlocks ); + d *= d * 32 * 32; //squared distance in position coords + + List players = null; + + Vector3I pos = p.Position.ToBlockCoords(); + for ( int x = Math.Max( 0, pos.X - d ); x <= Math.Min( _players.GetLength( 0 ) - 1, pos.X + d ); ++x ) + for ( int y = Math.Max( 0, pos.Y - d ); y <= Math.Min( _players.GetLength( 1 ) - 1, pos.Y + d ); ++y ) { + if ( null == _players[x, y] ) + continue; + for ( int i = 0; i < _players[x, y].Count; ++i ) { + Player player = _players[x, y][i]; + if ( ReferenceEquals( p, player ) ) //found THE player + continue; + if ( !ReferenceEquals( _world, player.World ) ) //player has left the game world { - _players[x, y].RemoveAt(i); - --i; - continue; - } - if (null != takePair && !takePair(p, player)) - continue; - if ((p.Position.ToVector3I() - player.Position.ToVector3I()).LengthSquared > d) //too far away - continue; - if (null == players) //lasy instantiation - players = new List(); - players.Add(player); - } - } - - return players; - } - - public void SetCallEvents(bool call, double distanceInBlocks, Func takePair) - { - _callEvents = call; - _distanceInBlocks = distanceInBlocks; - _takePair = takePair; - } - - private void CallEvent(Player p) - { - IEnumerable players = FindPlayersAtDistance(p, _distanceInBlocks, _takePair); - if (null!=players) - { - EventHandler evt = OnPlayersAtDistance; - if (null!=evt) - { - evt(this, new PlayersAtDistanceArgs(){FromPlayer=p, Others=players}); - } - } - } - - private void CheckCoords(ref Vector3I pos) - { - CheckDim(ref pos.X, 0); - CheckDim(ref pos.Y, 1); - } - - private void CheckDim(ref int coord, int dim) - { - if (coord < 0) - coord = 0; - if (coord >= _players.GetLength(dim)) - coord = _players.GetLength(dim) - 1; - } - } -} + _players[x, y].RemoveAt( i ); + --i; + continue; + } + if ( null != takePair && !takePair( p, player ) ) + continue; + if ( ( p.Position.ToVector3I() - player.Position.ToVector3I() ).LengthSquared > d ) //too far away + continue; + if ( null == players ) //lasy instantiation + players = new List(); + players.Add( player ); + } + } + + return players; + } + + public void SetCallEvents( bool call, double distanceInBlocks, Func takePair ) { + _callEvents = call; + _distanceInBlocks = distanceInBlocks; + _takePair = takePair; + } + + private void CallEvent( Player p ) { + IEnumerable players = FindPlayersAtDistance( p, _distanceInBlocks, _takePair ); + if ( null != players ) { + EventHandler evt = OnPlayersAtDistance; + if ( null != evt ) { + evt( this, new PlayersAtDistanceArgs() { FromPlayer = p, Others = players } ); + } + } + } + + private void CheckCoords( ref Vector3I pos ) { + CheckDim( ref pos.X, 0 ); + CheckDim( ref pos.Y, 1 ); + } + + private void CheckDim( ref int coord, int dim ) { + if ( coord < 0 ) + coord = 0; + if ( coord >= _players.GetLength( dim ) ) + coord = _players.GetLength( dim ) - 1; + } + } +} \ No newline at end of file diff --git a/fCraft/Games/Spell.cs b/fCraft/Games/Spell.cs index aee58b8..e408653 100644 --- a/fCraft/Games/Spell.cs +++ b/fCraft/Games/Spell.cs @@ -24,13 +24,10 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; /// Spell enum, to be used with Spell Physics namespace fCraft { + public enum Spell : byte { Polymorph = 1, @@ -54,4 +51,4 @@ public enum Spell : byte { Freeze = 11, } -} +} \ No newline at end of file diff --git a/fCraft/Games/ZombieGame.cs b/fCraft/Games/ZombieGame.cs index 1dcef19..941651b 100644 --- a/fCraft/Games/ZombieGame.cs +++ b/fCraft/Games/ZombieGame.cs @@ -1,11 +1,10 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using fCraft.Events; namespace fCraft { - class ZombieGame { + + internal class ZombieGame { /// /// The name for the zombie skin @@ -42,12 +41,11 @@ class ZombieGame { /// private static bool _started = false; - /// /// Class instance /// /// Game world - public ZombieGame ( World world ) { + public ZombieGame( World world ) { _world = world; startTime = DateTime.UtcNow; _humanCount = _world.Players.Length; @@ -60,19 +58,18 @@ public ZombieGame ( World world ) { /// /// Method to start the game /// - public void Start () { + public void Start() { _world.gameMode = GameMode.ZombieSurvival; //set the game mode _humanCount = _world.Players.Where( p => p.iName != _zomb ).Count(); //count all players Scheduler.NewTask( t => _world.Players.Message( "&WThe game will be starting soon..." ) ) .RunRepeating( TimeSpan.FromSeconds( 0 ), TimeSpan.FromSeconds( 20 ), 2 ); } - /// /// Method to stop the game /// /// Player stopping the game. If null, presume game has finished by itself - public void Stop ( Player player ) { + public void Stop( Player player ) { if ( player != null ) { _world.Players.Message( "{0}&S stopped the game of Infection on world {1}", player.ClassyName, _world.ClassyName ); @@ -89,21 +86,22 @@ public void Stop ( Player player ) { /// /// Pick a random player and infect them /// - public void RandomPick () { + public void RandomPick() { Random rand = new Random(); int min = 0; - int max = _world.Players.Length; + int max = _world.Players.Length; int num = rand.Next( min, max ); Player p = _world.Players[num]; ToZombie( null, p ); } - Random rand = new Random(); + + private Random rand = new Random(); /// /// Repeating task, checks things /// /// Task in question - public void Interval ( SchedulerTask task ) { + public void Interval( SchedulerTask task ) { //check to stop Interval if ( _world.gameMode != GameMode.ZombieSurvival || _world == null ) { _world = null; @@ -149,18 +147,19 @@ public void Interval ( SchedulerTask task ) { if ( lastChecked != null && ( DateTime.UtcNow - lastChecked ).TotalSeconds >= 30 ) { _world.Players.Message( "&WThere are {0} humans", _humanCount.ToString() ); foreach ( Player p in _world.Players ) { - if ( p.iName == _zomb ) p.Message( "&8You are " + _zomb ); - else p.Message( "&8You are a Human" ); + if ( p.iName == _zomb ) + p.Message( "&8You are " + _zomb ); + else + p.Message( "&8You are a Human" ); } lastChecked = DateTime.UtcNow; } } - /// /// Event: Manages a player changing world /// - void OnChangedWorld ( object sender, PlayerJoinedWorldEventArgs e ) { + private void OnChangedWorld( object sender, PlayerJoinedWorldEventArgs e ) { if ( e.OldWorld != null ) { if ( e.OldWorld.gameMode == GameMode.ZombieSurvival && e.NewWorld != e.OldWorld ) { if ( e.Player.iName != null ) @@ -171,7 +170,7 @@ void OnChangedWorld ( object sender, PlayerJoinedWorldEventArgs e ) { e.Player.entityChanged = true; e.Player.Message( "&WYou arrived late, so you are " + _zomb ); } - if ( e.Player.IsUsingWoM ) + if ( e.Player.IsUsingWoM ) e.Player.Message( "&HUsing WoM? Be sure to turn off hacks" ); } } @@ -180,7 +179,7 @@ void OnChangedWorld ( object sender, PlayerJoinedWorldEventArgs e ) { /// /// Event: Manages a player's movement /// - void OnPlayerMoved ( object sender, PlayerMovedEventArgs e ) { + private void OnPlayerMoved( object sender, PlayerMovedEventArgs e ) { if ( e.Player.World.gameMode == GameMode.ZombieSurvival ) { if ( e.Player.World.Name == _world.Name && _world != null ) { if ( e.NewPosition != null ) { @@ -218,7 +217,7 @@ void OnPlayerMoved ( object sender, PlayerMovedEventArgs e ) { /// /// Used to spawn all players at a random position on the map /// - void ShufflePlayerPositions () { + private void ShufflePlayerPositions() { foreach ( Player p in _world.Players ) { int x = rand.Next( 2, _world.Map.Width ); int y = rand.Next( 2, _world.Map.Length ); @@ -238,7 +237,7 @@ void ShufflePlayerPositions () { /// /// Player infecting other /// Guy getting infected - public void ToZombie ( Player infector, Player target ) { + public void ToZombie( Player infector, Player target ) { if ( infector == null ) { _world.Players.Message( "{0}&S has been the first to get &cInfected. &9Panic!!!!!", target.ClassyName ); @@ -265,7 +264,7 @@ public void ToZombie ( Player infector, Player target ) { /// /// Reverts all names (disinfects all) /// - void RevertNames () { + private void RevertNames() { foreach ( Player p in _world.Players ) { RevertPlayerName( p ); } @@ -275,7 +274,7 @@ void RevertNames () { /// Disinfects one player /// /// Player in question - public void RevertPlayerName ( Player p ) { + public void RevertPlayerName( Player p ) { if ( p.iName == _zomb ) { p.iName = null; p.entityChanged = true; @@ -283,4 +282,4 @@ public void RevertPlayerName ( Player p ) { } } } -} +} \ No newline at end of file diff --git a/fCraft/MapConversion/IMapConverter.cs b/fCraft/MapConversion/IMapConverter.cs index 196a7ca..f889e1b 100644 --- a/fCraft/MapConversion/IMapConverter.cs +++ b/fCraft/MapConversion/IMapConverter.cs @@ -4,68 +4,66 @@ using JetBrains.Annotations; namespace fCraft.MapConversion { + public interface IMapConverter { + /// Returns name(s) of the server(s) that uses this format. [NotNull] string ServerName { get; } - /// Returns the map storage type (file-based or directory-based). MapStorageType StorageType { get; } - /// Returns the format name. MapFormat Format { get; } - /// Returns true if the filename (or directory name) matches this format's expectations. bool ClaimsName( [NotNull] string path ); - /// Allows validating the map format while using minimal resources. /// Returns true if specified file/directory is valid for this format. bool Claims( [NotNull] string path ); - /// Attempts to load map dimensions from specified location. /// Map object on success, or null on failure. Map LoadHeader( [NotNull] string path ); - /// Fully loads map from specified location. /// Map object on success, or null on failure. Map Load( [NotNull] string path ); - /// Saves given map at the given location. /// true if saving succeeded. bool Save( [NotNull] Map mapToSave, [NotNull] string path ); } - public interface IMapConverterEx : IMapConverter - { - //must return this to enable addin multiple extensions in one line: converter.AddExtension(e1).AddExtension(e2) - IMapConverterEx AddExtension(IConverterExtension ex); - void WriteMetadataEntry(string group, string key, string value, BinaryWriter writer); - } - - public interface IConverterExtension - { - /// - /// Returns groups procesed by this extension - /// - /// - IEnumerable AcceptedGroups { get; } - /// - /// Serializes the extended data as metadata and returns the number of written keys - /// - /// - /// The number of written keys - /// - int Serialize(Map map, Stream stream, IMapConverterEx converter); - /// - /// Instantiates the extended data for the given map from the group, key, and value - /// - void Deserialize(string group, string key, string value, Map map); - } -} + public interface IMapConverterEx : IMapConverter { + + //must return this to enable addin multiple extensions in one line: converter.AddExtension(e1).AddExtension(e2) + IMapConverterEx AddExtension( IConverterExtension ex ); + + void WriteMetadataEntry( string group, string key, string value, BinaryWriter writer ); + } + + public interface IConverterExtension { + + /// + /// Returns groups procesed by this extension + /// + /// + IEnumerable AcceptedGroups { get; } + + /// + /// Serializes the extended data as metadata and returns the number of written keys + /// + /// + /// The number of written keys + /// + int Serialize( Map map, Stream stream, IMapConverterEx converter ); + + /// + /// Instantiates the extended data for the given map from the group, key, and value + /// + void Deserialize( string group, string key, string value, Map map ); + } +} \ No newline at end of file diff --git a/fCraft/MapConversion/INIFile.cs b/fCraft/MapConversion/INIFile.cs index 6970ad8..348c920 100644 --- a/fCraft/MapConversion/INIFile.cs +++ b/fCraft/MapConversion/INIFile.cs @@ -6,22 +6,28 @@ using JetBrains.Annotations; namespace fCraft.MapConversion { + /// INI parser used by MapMyne. - sealed class INIFile { - const string Separator = "="; - readonly Dictionary> contents = new Dictionary>(); + internal sealed class INIFile { + private const string Separator = "="; + private readonly Dictionary> contents = new Dictionary>(); public string this[[NotNull] string section, [NotNull] string key] { get { - if( section == null ) throw new ArgumentNullException( "section" ); - if( key == null ) throw new ArgumentNullException( "key" ); + if ( section == null ) + throw new ArgumentNullException( "section" ); + if ( key == null ) + throw new ArgumentNullException( "key" ); return contents[section][key]; } set { - if( section == null ) throw new ArgumentNullException( "section" ); - if( key == null ) throw new ArgumentNullException( "key" ); - if( value == null ) throw new ArgumentNullException( "value" ); - if( !contents.ContainsKey( section ) ) { + if ( section == null ) + throw new ArgumentNullException( "section" ); + if ( key == null ) + throw new ArgumentNullException( "key" ); + if ( value == null ) + throw new ArgumentNullException( "value" ); + if ( !contents.ContainsKey( section ) ) { contents[section] = new Dictionary(); } contents[section][key] = value; @@ -29,20 +35,23 @@ sealed class INIFile { } public INIFile( [NotNull] Stream fileStream ) { - if( fileStream == null ) throw new ArgumentNullException( "fileStream" ); + if ( fileStream == null ) + throw new ArgumentNullException( "fileStream" ); StreamReader reader = new StreamReader( fileStream ); Dictionary section = null; - while( true ) { + while ( true ) { string line = reader.ReadLine(); - if( line == null ) break; + if ( line == null ) + break; line = line.Trim(); - if( line.StartsWith( "#" ) ) continue; - if( line.StartsWith( "[" ) ) { + if ( line.StartsWith( "#" ) ) + continue; + if ( line.StartsWith( "[" ) ) { string sectionName = line.Substring( 1, line.IndexOf( ']' ) - 1 ).Trim().ToLower(); section = new Dictionary(); contents.Add( sectionName, section ); - } else if( line.Contains( Separator ) && section != null ) { + } else if ( line.Contains( Separator ) && section != null ) { string keyName = line.Substring( 0, line.IndexOf( Separator ) ).TrimEnd().ToLower(); string valueName = line.Substring( line.IndexOf( Separator ) + 1 ).TrimStart(); section.Add( keyName, valueName ); @@ -50,16 +59,18 @@ public INIFile( [NotNull] Stream fileStream ) { } } - public bool ContainsSection( [NotNull] string section ) { - if( section == null ) throw new ArgumentNullException( "section" ); + if ( section == null ) + throw new ArgumentNullException( "section" ); return contents.ContainsKey( section.ToLower() ); } public bool Contains( [NotNull] string section, [NotNull] params string[] keys ) { - if( section == null ) throw new ArgumentNullException( "section" ); - if( keys == null ) throw new ArgumentNullException( "keys" ); - if( contents.ContainsKey( section.ToLower() ) ) { + if ( section == null ) + throw new ArgumentNullException( "section" ); + if ( keys == null ) + throw new ArgumentNullException( "keys" ); + if ( contents.ContainsKey( section.ToLower() ) ) { return keys.All( key => contents[section.ToLower()].ContainsKey( key.ToLower() ) ); } else { return false; @@ -68,8 +79,8 @@ public bool Contains( [NotNull] string section, [NotNull] params string[] keys ) public bool IsEmpty { get { - return (contents.Count == 0); + return ( contents.Count == 0 ); } } } -} +} \ No newline at end of file diff --git a/fCraft/MapConversion/MapD3.cs b/fCraft/MapConversion/MapD3.cs index 54e6ae5..6457e6c 100644 --- a/fCraft/MapConversion/MapD3.cs +++ b/fCraft/MapConversion/MapD3.cs @@ -6,121 +6,118 @@ using JetBrains.Annotations; namespace fCraft.MapConversion { - public sealed class MapD3 : IMapConverter { - static readonly byte[] Mapping = new byte[256]; + public sealed class MapD3 : IMapConverter { + private static readonly byte[] Mapping = new byte[256]; static MapD3() { // 0-49 default - Mapping[50] = (byte)Block.TNT; // Torch - Mapping[51] = (byte)Block.StillLava; // Fire - Mapping[52] = (byte)Block.Blue; // Water Source - Mapping[53] = (byte)Block.Red; // Lava Source - Mapping[54] = (byte)Block.TNT; // Chest - Mapping[55] = (byte)Block.TNT; // Gear - Mapping[56] = (byte)Block.Glass; // Diamond Ore - Mapping[57] = (byte)Block.Glass; // Diamond - Mapping[58] = (byte)Block.TNT; // Workbench - Mapping[59] = (byte)Block.Leaves; // Crops - Mapping[60] = (byte)Block.Obsidian; // Soil - Mapping[61] = (byte)Block.Cobblestone; // Furnace - Mapping[62] = (byte)Block.StillLava; // Burning Furnace + Mapping[50] = ( byte )Block.TNT; // Torch + Mapping[51] = ( byte )Block.StillLava; // Fire + Mapping[52] = ( byte )Block.Blue; // Water Source + Mapping[53] = ( byte )Block.Red; // Lava Source + Mapping[54] = ( byte )Block.TNT; // Chest + Mapping[55] = ( byte )Block.TNT; // Gear + Mapping[56] = ( byte )Block.Glass; // Diamond Ore + Mapping[57] = ( byte )Block.Glass; // Diamond + Mapping[58] = ( byte )Block.TNT; // Workbench + Mapping[59] = ( byte )Block.Leaves; // Crops + Mapping[60] = ( byte )Block.Obsidian; // Soil + Mapping[61] = ( byte )Block.Cobblestone; // Furnace + Mapping[62] = ( byte )Block.StillLava; // Burning Furnace // 63-199 unused - Mapping[200] = (byte)Block.Lava; // Kill Lava - Mapping[201] = (byte)Block.Stone; // Kill Lava + Mapping[200] = ( byte )Block.Lava; // Kill Lava + Mapping[201] = ( byte )Block.Stone; // Kill Lava // 202 unused - Mapping[203] = (byte)Block.Stair; // Still Stair + Mapping[203] = ( byte )Block.Stair; // Still Stair // 204-205 unused - Mapping[206] = (byte)Block.Water; // Original Water - Mapping[207] = (byte)Block.Lava; // Original Lava + Mapping[206] = ( byte )Block.Water; // Original Water + Mapping[207] = ( byte )Block.Lava; // Original Lava // 208 Invisible - Mapping[209] = (byte)Block.Water; // Acid - Mapping[210] = (byte)Block.Sand; // Still Sand - Mapping[211] = (byte)Block.Water; // Still Acid - Mapping[212] = (byte)Block.RedFlower; // Kill Rose - Mapping[213] = (byte)Block.Gravel; // Still Gravel + Mapping[209] = ( byte )Block.Water; // Acid + Mapping[210] = ( byte )Block.Sand; // Still Sand + Mapping[211] = ( byte )Block.Water; // Still Acid + Mapping[212] = ( byte )Block.RedFlower; // Kill Rose + Mapping[213] = ( byte )Block.Gravel; // Still Gravel // 214 No Entry - Mapping[215] = (byte)Block.White; // Snow - Mapping[216] = (byte)Block.Lava; // Fast Lava - Mapping[217] = (byte)Block.White; // Kill Glass + Mapping[215] = ( byte )Block.White; // Snow + Mapping[216] = ( byte )Block.Lava; // Fast Lava + Mapping[217] = ( byte )Block.White; // Kill Glass // 218 Invisible Sponge - Mapping[219] = (byte)Block.Sponge; // Drain Sponge - Mapping[220] = (byte)Block.Sponge; // Super Drain Sponge - Mapping[221] = (byte)Block.Gold; // Spark - Mapping[222] = (byte)Block.TNT; // Rocket - Mapping[223] = (byte)Block.Gold; // Short Spark - Mapping[224] = (byte)Block.TNT; // Mega Rocket - Mapping[225] = (byte)Block.Lava; // Red Spark - Mapping[226] = (byte)Block.TNT; // Fire Fountain - Mapping[227] = (byte)Block.TNT; // Admin TNT - Mapping[228] = (byte)Block.Iron; // Fan - Mapping[229] = (byte)Block.Iron; // Door - Mapping[230] = (byte)Block.Lava; // Campfire - Mapping[231] = (byte)Block.Red; // Laser - Mapping[232] = (byte)Block.Black; // Ash + Mapping[219] = ( byte )Block.Sponge; // Drain Sponge + Mapping[220] = ( byte )Block.Sponge; // Super Drain Sponge + Mapping[221] = ( byte )Block.Gold; // Spark + Mapping[222] = ( byte )Block.TNT; // Rocket + Mapping[223] = ( byte )Block.Gold; // Short Spark + Mapping[224] = ( byte )Block.TNT; // Mega Rocket + Mapping[225] = ( byte )Block.Lava; // Red Spark + Mapping[226] = ( byte )Block.TNT; // Fire Fountain + Mapping[227] = ( byte )Block.TNT; // Admin TNT + Mapping[228] = ( byte )Block.Iron; // Fan + Mapping[229] = ( byte )Block.Iron; // Door + Mapping[230] = ( byte )Block.Lava; // Campfire + Mapping[231] = ( byte )Block.Red; // Laser + Mapping[232] = ( byte )Block.Black; // Ash // 233-234 unused - Mapping[235] = (byte)Block.Water; // Sea - Mapping[236] = (byte)Block.White; // Flasher + Mapping[235] = ( byte )Block.Water; // Sea + Mapping[236] = ( byte )Block.White; // Flasher // 237-243 unused - Mapping[244] = (byte)Block.Leaves; // Vines - Mapping[245] = (byte)Block.Lava; // Flamethrower + Mapping[244] = ( byte )Block.Leaves; // Vines + Mapping[245] = ( byte )Block.Lava; // Flamethrower // 246 unused - Mapping[247] = (byte)Block.Iron; // Cannon - Mapping[248] = (byte)Block.Obsidian; // Blob + Mapping[247] = ( byte )Block.Iron; // Cannon + Mapping[248] = ( byte )Block.Obsidian; // Blob // all others default to 0/air } - public string ServerName { get { return "D3"; } } - public MapStorageType StorageType { get { return MapStorageType.SingleFile; } } - public MapFormat Format { get { return MapFormat.D3; } } - public bool ClaimsName( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); return fileName.EndsWith( ".map", StringComparison.OrdinalIgnoreCase ); } - public bool Claims( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); try { - using( FileStream mapStream = File.OpenRead( fileName ) ) { - using( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { + using ( FileStream mapStream = File.OpenRead( fileName ) ) { + using ( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { BinaryReader bs = new BinaryReader( gs ); int formatVersion = IPAddress.NetworkToHostOrder( bs.ReadInt32() ); - return (formatVersion == 1000 || formatVersion == 1010 || formatVersion == 1020 || - formatVersion == 1030 || formatVersion == 1040 || formatVersion == 1050); + return ( formatVersion == 1000 || formatVersion == 1010 || formatVersion == 1020 || + formatVersion == 1030 || formatVersion == 1040 || formatVersion == 1050 ); } } - } catch( Exception ) { + } catch ( Exception ) { return false; } } - public Map LoadHeader( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { return LoadHeaderInternal( mapStream ); } } - - static Map LoadHeaderInternal( Stream stream ) { - if( stream == null ) throw new ArgumentNullException( "stream" ); + private static Map LoadHeaderInternal( Stream stream ) { + if ( stream == null ) + throw new ArgumentNullException( "stream" ); // Setup a GZipStream to decompress and read the map file - using( GZipStream gs = new GZipStream( stream, CompressionMode.Decompress, true ) ) { + using ( GZipStream gs = new GZipStream( stream, CompressionMode.Decompress, true ) ) { BinaryReader bs = new BinaryReader( gs ); int formatVersion = IPAddress.NetworkToHostOrder( bs.ReadInt32() ); @@ -134,10 +131,11 @@ static Map LoadHeaderInternal( Stream stream ) { Position spawn = new Position(); - switch( formatVersion ) { + switch ( formatVersion ) { case 1000: case 1010: break; + case 1020: spawn.X = IPAddress.NetworkToHostOrder( bs.ReadInt16() ); spawn.Y = IPAddress.NetworkToHostOrder( bs.ReadInt16() ); @@ -151,8 +149,8 @@ static Map LoadHeaderInternal( Stream stream ) { spawn.X = IPAddress.NetworkToHostOrder( bs.ReadInt16() ); spawn.Y = IPAddress.NetworkToHostOrder( bs.ReadInt16() ); spawn.Z = IPAddress.NetworkToHostOrder( bs.ReadInt16() ); - spawn.R = (byte)IPAddress.NetworkToHostOrder( bs.ReadInt16() ); - spawn.L = (byte)IPAddress.NetworkToHostOrder( bs.ReadInt16() ); + spawn.R = ( byte )IPAddress.NetworkToHostOrder( bs.ReadInt16() ); + spawn.L = ( byte )IPAddress.NetworkToHostOrder( bs.ReadInt16() ); map.Spawn = spawn; break; } @@ -161,14 +159,13 @@ static Map LoadHeaderInternal( Stream stream ) { } } - public Map Load( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { - + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { Map map = LoadHeaderInternal( mapStream ); - if( !map.ValidateHeader() ) { + if ( !map.ValidateHeader() ) { throw new MapFormatException( "One or more of the map dimensions are invalid." ); } @@ -181,18 +178,19 @@ public Map Load( [NotNull] string fileName ) { } } - public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { - if( mapToSave == null ) throw new ArgumentNullException( "mapToSave" ); - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.Create( fileName ) ) { - using( GZipStream gs = new GZipStream( mapStream, CompressionMode.Compress ) ) { + if ( mapToSave == null ) + throw new ArgumentNullException( "mapToSave" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.Create( fileName ) ) { + using ( GZipStream gs = new GZipStream( mapStream, CompressionMode.Compress ) ) { BinaryWriter bs = new BinaryWriter( gs ); // Write the magic number bs.Write( IPAddress.HostToNetworkOrder( 1050 ) ); - bs.Write( (byte)0 ); - bs.Write( (byte)0 ); + bs.Write( ( byte )0 ); + bs.Write( ( byte )0 ); // Write the map dimensions bs.Write( IPAddress.NetworkToHostOrder( mapToSave.Width ) ); diff --git a/fCraft/MapConversion/MapDAT.cs b/fCraft/MapConversion/MapDAT.cs index 088f429..ca0ec28 100644 --- a/fCraft/MapConversion/MapDAT.cs +++ b/fCraft/MapConversion/MapDAT.cs @@ -7,125 +7,122 @@ using JetBrains.Annotations; namespace fCraft.MapConversion { - public sealed class MapDat : IMapConverter { - static readonly byte[] Mapping = new byte[256]; + public sealed class MapDat : IMapConverter { + private static readonly byte[] Mapping = new byte[256]; static MapDat() { - Mapping[50] = (byte)Block.Air; // torch - Mapping[51] = (byte)Block.Lava; // fire - Mapping[52] = (byte)Block.Glass; // spawner - Mapping[53] = (byte)Block.Stair; // wood stairs - Mapping[54] = (byte)Block.Wood; // chest - Mapping[55] = (byte)Block.Air; // redstone wire - Mapping[56] = (byte)Block.IronOre; // diamond ore - Mapping[57] = (byte)Block.Aqua; // diamond block - Mapping[58] = (byte)Block.Log; // workbench - Mapping[59] = (byte)Block.Leaves; // crops - Mapping[60] = (byte)Block.Dirt; // soil - Mapping[61] = (byte)Block.Stone; // furnace - Mapping[62] = (byte)Block.Stone; // burning furnance - Mapping[63] = (byte)Block.Air; // sign post - Mapping[64] = (byte)Block.Air; // wooden door - Mapping[65] = (byte)Block.Air; // ladder - Mapping[66] = (byte)Block.Air; // rails - Mapping[67] = (byte)Block.Stair; // cobblestone stairs - Mapping[68] = (byte)Block.Air; // wall sign - Mapping[69] = (byte)Block.Air; // lever - Mapping[70] = (byte)Block.Air; // pressure plate - Mapping[71] = (byte)Block.Air; // iron door - Mapping[72] = (byte)Block.Air; // wooden pressure plate - Mapping[73] = (byte)Block.IronOre; // redstone ore - Mapping[74] = (byte)Block.IronOre; // glowing redstone ore - Mapping[75] = (byte)Block.Air; // redstone torch (off) - Mapping[76] = (byte)Block.Air; // redstone torch (on) - Mapping[77] = (byte)Block.Air; // stone button - Mapping[78] = (byte)Block.Air; // snow - Mapping[79] = (byte)Block.Glass; // ice - Mapping[80] = (byte)Block.White; // snow block - Mapping[81] = (byte)Block.Leaves; // cactus - Mapping[82] = (byte)Block.Gray; // clay - Mapping[83] = (byte)Block.Leaves; // reed - Mapping[84] = (byte)Block.Log; // jukebox - Mapping[85] = (byte)Block.Wood; // fence - Mapping[86] = (byte)Block.Orange; // pumpkin - Mapping[87] = (byte)Block.Dirt; // netherstone - Mapping[88] = (byte)Block.Gravel; // slow sand - Mapping[89] = (byte)Block.Sand; // lightstone - Mapping[90] = (byte)Block.Violet; // portal - Mapping[91] = (byte)Block.Orange; // jack-o-lantern + Mapping[50] = ( byte )Block.Air; // torch + Mapping[51] = ( byte )Block.Lava; // fire + Mapping[52] = ( byte )Block.Glass; // spawner + Mapping[53] = ( byte )Block.Stair; // wood stairs + Mapping[54] = ( byte )Block.Wood; // chest + Mapping[55] = ( byte )Block.Air; // redstone wire + Mapping[56] = ( byte )Block.IronOre; // diamond ore + Mapping[57] = ( byte )Block.Aqua; // diamond block + Mapping[58] = ( byte )Block.Log; // workbench + Mapping[59] = ( byte )Block.Leaves; // crops + Mapping[60] = ( byte )Block.Dirt; // soil + Mapping[61] = ( byte )Block.Stone; // furnace + Mapping[62] = ( byte )Block.Stone; // burning furnance + Mapping[63] = ( byte )Block.Air; // sign post + Mapping[64] = ( byte )Block.Air; // wooden door + Mapping[65] = ( byte )Block.Air; // ladder + Mapping[66] = ( byte )Block.Air; // rails + Mapping[67] = ( byte )Block.Stair; // cobblestone stairs + Mapping[68] = ( byte )Block.Air; // wall sign + Mapping[69] = ( byte )Block.Air; // lever + Mapping[70] = ( byte )Block.Air; // pressure plate + Mapping[71] = ( byte )Block.Air; // iron door + Mapping[72] = ( byte )Block.Air; // wooden pressure plate + Mapping[73] = ( byte )Block.IronOre; // redstone ore + Mapping[74] = ( byte )Block.IronOre; // glowing redstone ore + Mapping[75] = ( byte )Block.Air; // redstone torch (off) + Mapping[76] = ( byte )Block.Air; // redstone torch (on) + Mapping[77] = ( byte )Block.Air; // stone button + Mapping[78] = ( byte )Block.Air; // snow + Mapping[79] = ( byte )Block.Glass; // ice + Mapping[80] = ( byte )Block.White; // snow block + Mapping[81] = ( byte )Block.Leaves; // cactus + Mapping[82] = ( byte )Block.Gray; // clay + Mapping[83] = ( byte )Block.Leaves; // reed + Mapping[84] = ( byte )Block.Log; // jukebox + Mapping[85] = ( byte )Block.Wood; // fence + Mapping[86] = ( byte )Block.Orange; // pumpkin + Mapping[87] = ( byte )Block.Dirt; // netherstone + Mapping[88] = ( byte )Block.Gravel; // slow sand + Mapping[89] = ( byte )Block.Sand; // lightstone + Mapping[90] = ( byte )Block.Violet; // portal + Mapping[91] = ( byte )Block.Orange; // jack-o-lantern // all others default to 0/air } - public string ServerName { get { return "Creative/Vanilla"; } } - public MapStorageType StorageType { get { return MapStorageType.SingleFile; } } - public MapFormat Format { get { return MapFormat.Creative; } } - public bool ClaimsName( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); return fileName.EndsWith( ".dat", StringComparison.OrdinalIgnoreCase ) || fileName.EndsWith( ".mine", StringComparison.OrdinalIgnoreCase ); } - public bool Claims( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); try { - using( FileStream mapStream = File.OpenRead( fileName ) ) { + using ( FileStream mapStream = File.OpenRead( fileName ) ) { byte[] temp = new byte[8]; mapStream.Seek( -4, SeekOrigin.End ); mapStream.Read( temp, 0, 4 ); mapStream.Seek( 0, SeekOrigin.Begin ); int length = BitConverter.ToInt32( temp, 0 ); byte[] data = new byte[length]; - using( GZipStream reader = new GZipStream( mapStream, CompressionMode.Decompress, true ) ) { + using ( GZipStream reader = new GZipStream( mapStream, CompressionMode.Decompress, true ) ) { reader.Read( data, 0, length ); } - for( int i = 0; i < length - 1; i++ ) { - if( data[i] == 0xAC && data[i + 1] == 0xED ) { + for ( int i = 0; i < length - 1; i++ ) { + if ( data[i] == 0xAC && data[i + 1] == 0xED ) { return true; } } return false; } - } catch( Exception ) { + } catch ( Exception ) { return false; } } - public Map LoadHeader( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); Map map = Load( fileName ); map.Blocks = null; return map; } - public static byte MapBlock( byte block ) { return Mapping[block]; } public static Block MapBlock( Block block ) { - return (Block)Mapping[(byte)block]; + return ( Block )Mapping[( byte )block]; } public Map Load( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { byte[] temp = new byte[8]; Map map = null; @@ -134,12 +131,13 @@ public Map Load( [NotNull] string fileName ) { mapStream.Seek( 0, SeekOrigin.Begin ); int uncompressedLength = BitConverter.ToInt32( temp, 0 ); byte[] data = new byte[uncompressedLength]; - using( GZipStream reader = new GZipStream( mapStream, CompressionMode.Decompress, true ) ) { + using ( GZipStream reader = new GZipStream( mapStream, CompressionMode.Decompress, true ) ) { reader.Read( data, 0, uncompressedLength ); } - for( int i = 0; i < uncompressedLength - 1; i++ ) { - if( data[i] != 0xAC || data[i + 1] != 0xED ) continue; + for ( int i = 0; i < uncompressedLength - 1; i++ ) { + if ( data[i] != 0xAC || data[i + 1] != 0xED ) + continue; // bypassing the header crap int pointer = i + 6; @@ -149,8 +147,8 @@ public Map Load( [NotNull] string fileName ) { int headerEnd; // find the end of serialization listing - for( headerEnd = pointer; headerEnd < data.Length - 1; headerEnd++ ) { - if( data[headerEnd] == 0x78 && data[headerEnd + 1] == 0x70 ) { + for ( headerEnd = pointer; headerEnd < data.Length - 1; headerEnd++ ) { + if ( data[headerEnd] == 0x78 && data[headerEnd + 1] == 0x70 ) { headerEnd += 2; break; } @@ -160,15 +158,17 @@ public Map Load( [NotNull] string fileName ) { int offset = 0; int width = 0, length = 0, height = 0; Position spawn = new Position(); - while( pointer < headerEnd ) { - switch( (char)data[pointer] ) { + while ( pointer < headerEnd ) { + switch ( ( char )data[pointer] ) { case 'Z': offset++; break; + case 'F': case 'I': offset += 4; break; + case 'J': offset += 8; break; @@ -181,18 +181,18 @@ public Map Load( [NotNull] string fileName ) { // look for relevant variables Array.Copy( data, headerEnd + offset - 4, temp, 0, 4 ); - if( MemCmp( data, pointer, "width" ) ) { - width = (ushort)IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) ); - } else if( MemCmp( data, pointer, "depth" ) ) { - height = (ushort)IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) ); - } else if( MemCmp( data, pointer, "height" ) ) { - length = (ushort)IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) ); - } else if( MemCmp( data, pointer, "xSpawn" ) ) { - spawn.X = (short)( IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) ) * 32 + 16 ); - } else if( MemCmp( data, pointer, "ySpawn" ) ) { - spawn.Z = (short)( IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) ) * 32 + 16 ); - } else if( MemCmp( data, pointer, "zSpawn" ) ) { - spawn.Y = (short)( IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) ) * 32 + 16 ); + if ( MemCmp( data, pointer, "width" ) ) { + width = ( ushort )IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) ); + } else if ( MemCmp( data, pointer, "depth" ) ) { + height = ( ushort )IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) ); + } else if ( MemCmp( data, pointer, "height" ) ) { + length = ( ushort )IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) ); + } else if ( MemCmp( data, pointer, "xSpawn" ) ) { + spawn.X = ( short )( IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) ) * 32 + 16 ); + } else if ( MemCmp( data, pointer, "ySpawn" ) ) { + spawn.Z = ( short )( IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) ) * 32 + 16 ); + } else if ( MemCmp( data, pointer, "zSpawn" ) ) { + spawn.Y = ( short )( IPAddress.HostToNetworkOrder( BitConverter.ToInt32( temp, 0 ) ) * 32 + 16 ); } pointer += skip; @@ -200,15 +200,15 @@ public Map Load( [NotNull] string fileName ) { map = new Map( null, width, length, height, false ) { Spawn = spawn }; - if( !map.ValidateHeader() ) { + if ( !map.ValidateHeader() ) { throw new MapFormatException( "One or more of the map dimensions are invalid." ); } // find the start of the block array bool foundBlockArray = false; offset = Array.IndexOf( data, 0x00, headerEnd ); - while( offset != -1 && offset < data.Length - 2 ) { - if( data[offset] == 0x00 && data[offset + 1] == 0x78 && data[offset + 2] == 0x70 ) { + while ( offset != -1 && offset < data.Length - 2 ) { + if ( data[offset] == 0x00 && data[offset + 1] == 0x78 && data[offset + 2] == 0x70 ) { foundBlockArray = true; pointer = offset + 7; } @@ -216,7 +216,7 @@ public Map Load( [NotNull] string fileName ) { } // copy the block array... or fail - if( foundBlockArray ) { + if ( foundBlockArray ) { map.Blocks = new byte[map.Volume]; Array.Copy( data, pointer, map.Blocks, 0, map.Blocks.Length ); map.ConvertBlockTypes( Mapping ); @@ -229,20 +229,23 @@ public Map Load( [NotNull] string fileName ) { } } - public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { - if( mapToSave == null ) throw new ArgumentNullException( "mapToSave" ); - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( mapToSave == null ) + throw new ArgumentNullException( "mapToSave" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); throw new NotImplementedException(); } - - static bool MemCmp( [NotNull] IList data, int offset, [NotNull] string value ) { - if( data == null ) throw new ArgumentNullException( "data" ); - if( value == null ) throw new ArgumentNullException( "value" ); + private static bool MemCmp( [NotNull] IList data, int offset, [NotNull] string value ) { + if ( data == null ) + throw new ArgumentNullException( "data" ); + if ( value == null ) + throw new ArgumentNullException( "value" ); // ReSharper disable LoopCanBeConvertedToQuery - for( int i = 0; i < value.Length; i++ ) { - if( offset + i >= data.Count || data[offset + i] != value[i] ) return false; + for ( int i = 0; i < value.Length; i++ ) { + if ( offset + i >= data.Count || data[offset + i] != value[i] ) + return false; } // ReSharper restore LoopCanBeConvertedToQuery return true; diff --git a/fCraft/MapConversion/MapFCMv2.cs b/fCraft/MapConversion/MapFCMv2.cs index 8bc772e..0512352 100644 --- a/fCraft/MapConversion/MapFCMv2.cs +++ b/fCraft/MapConversion/MapFCMv2.cs @@ -6,6 +6,7 @@ using JetBrains.Annotations; namespace fCraft.MapConversion { + /// fCraft map format converter, for obsolete format version #2 (2010). public sealed class MapFCMv2 : IMapConverter { public const uint Identifier = 0xfc000002; @@ -14,51 +15,48 @@ public string ServerName { get { return "fCraft"; } } - public MapStorageType StorageType { get { return MapStorageType.SingleFile; } } - public MapFormat Format { get { return MapFormat.FCMv2; } } - public bool ClaimsName( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); return fileName.EndsWith( ".fcm", StringComparison.OrdinalIgnoreCase ); } - public bool Claims( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); try { - using( FileStream mapStream = File.OpenRead( fileName ) ) { + using ( FileStream mapStream = File.OpenRead( fileName ) ) { BinaryReader reader = new BinaryReader( mapStream ); - return (reader.ReadUInt32() == Identifier); + return ( reader.ReadUInt32() == Identifier ); } - } catch( Exception ) { + } catch ( Exception ) { return false; } - } - public Map LoadHeader( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { return LoadHeaderInternal( mapStream ); } } - - static Map LoadHeaderInternal( [NotNull] Stream stream ) { - if( stream == null ) throw new ArgumentNullException( "stream" ); + private static Map LoadHeaderInternal( [NotNull] Stream stream ) { + if ( stream == null ) + throw new ArgumentNullException( "stream" ); BinaryReader reader = new BinaryReader( stream ); // Read in the magic number - if( reader.ReadUInt32() != Identifier ) { + if ( reader.ReadUInt32() != Identifier ) { throw new MapFormatException(); } @@ -83,14 +81,13 @@ static Map LoadHeaderInternal( [NotNull] Stream stream ) { return map; } - public Map Load( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { - + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { Map map = LoadHeaderInternal( mapStream ); - if( !map.ValidateHeader() ) { + if ( !map.ValidateHeader() ) { throw new MapFormatException( "One or more of the map dimensions are invalid." ); } @@ -99,13 +96,13 @@ public Map Load( [NotNull] string fileName ) { // Read the metadata int metaSize = reader.ReadUInt16(); - for( int i = 0; i < metaSize; i++ ) { + for ( int i = 0; i < metaSize; i++ ) { string key = ReadLengthPrefixedString( reader ); string value = ReadLengthPrefixedString( reader ); - if( key.StartsWith( "@zone", StringComparison.OrdinalIgnoreCase ) ) { + if ( key.StartsWith( "@zone", StringComparison.OrdinalIgnoreCase ) ) { try { map.Zones.Add( new Zone( value, map.World ) ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.Log( LogType.Error, "MapFCMv2.Load: Error importing zone definition: {0}", ex ); } @@ -118,7 +115,7 @@ public Map Load( [NotNull] string fileName ) { // Read in the map data map.Blocks = new Byte[map.Volume]; - using( GZipStream decompressor = new GZipStream( mapStream, CompressionMode.Decompress ) ) { + using ( GZipStream decompressor = new GZipStream( mapStream, CompressionMode.Decompress ) ) { decompressor.Read( map.Blocks, 0, map.Blocks.Length ); } @@ -128,16 +125,17 @@ public Map Load( [NotNull] string fileName ) { } } - public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { - if( mapToSave == null ) throw new ArgumentNullException( "mapToSave" ); - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( mapToSave == null ) + throw new ArgumentNullException( "mapToSave" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); throw new NotImplementedException(); } - - static string ReadLengthPrefixedString( [NotNull] BinaryReader reader ) { - if( reader == null ) throw new ArgumentNullException( "reader" ); + private static string ReadLengthPrefixedString( [NotNull] BinaryReader reader ) { + if ( reader == null ) + throw new ArgumentNullException( "reader" ); int length = reader.ReadInt32(); byte[] stringData = reader.ReadBytes( length ); return Encoding.ASCII.GetString( stringData ); diff --git a/fCraft/MapConversion/MapFCMv3.cs b/fCraft/MapConversion/MapFCMv3.cs index b08de61..26f0dba 100644 --- a/fCraft/MapConversion/MapFCMv3.cs +++ b/fCraft/MapConversion/MapFCMv3.cs @@ -8,53 +8,52 @@ using JetBrains.Annotations; namespace fCraft.MapConversion { + /// fCraft map format converter, for format version #3 (2011). /// Soon to be obsoleted by FCMv4. public sealed class MapFCMv3 : IMapConverterEx { public const int Identifier = 0x0FC2AF40; public const byte Revision = 13; - private Dictionary _extensions=new Dictionary(); + private Dictionary _extensions = new Dictionary(); public string ServerName { get { return "fCraft"; } } - public MapStorageType StorageType { get { return MapStorageType.SingleFile; } } - public MapFormat Format { get { return MapFormat.FCMv3; } } - public bool ClaimsName( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); return fileName.EndsWith( ".fcm", StringComparison.OrdinalIgnoreCase ); } - public bool Claims( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { try { BinaryReader reader = new BinaryReader( mapStream ); int id = reader.ReadInt32(); int rev = reader.ReadByte(); - return (id == Identifier && rev == Revision); - } catch( Exception ) { + return ( id == Identifier && rev == Revision ); + } catch ( Exception ) { return false; } } } - public Map LoadHeader( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { BinaryReader reader = new BinaryReader( mapStream ); Map map = LoadHeaderInternal( reader ); @@ -66,31 +65,27 @@ public Map LoadHeader( [NotNull] string fileName ) { // read metadata int metaCount = reader.ReadInt32(); - using( DeflateStream ds = new DeflateStream( mapStream, CompressionMode.Decompress ) ) { + using ( DeflateStream ds = new DeflateStream( mapStream, CompressionMode.Decompress ) ) { BinaryReader br = new BinaryReader( ds ); - for( int i = 0; i < metaCount; i++ ) { + for ( int i = 0; i < metaCount; i++ ) { string group = ReadLengthPrefixedString( br ).ToLowerInvariant(); string key = ReadLengthPrefixedString( br ).ToLowerInvariant(); string newValue = ReadLengthPrefixedString( br ); string oldValue; - - IConverterExtension ex; - if (_extensions.TryGetValue(group, out ex)) - { - ex.Deserialize(group, key, newValue, map); - } - else - { - if (map.Metadata.TryGetValue(key, group, out oldValue) && oldValue != newValue) - { - Logger.Log(LogType.Warning, - "MapFCMv3.LoadHeader: Duplicate metadata entry found for [{0}].[{1}]. " + - "Old value (overwritten): \"{2}\". New value: \"{3}\"", - group, key, oldValue, newValue); - } - map.Metadata[group, key] = newValue; - } + + IConverterExtension ex; + if ( _extensions.TryGetValue( group, out ex ) ) { + ex.Deserialize( group, key, newValue, map ); + } else { + if ( map.Metadata.TryGetValue( key, group, out oldValue ) && oldValue != newValue ) { + Logger.Log( LogType.Warning, + "MapFCMv3.LoadHeader: Duplicate metadata entry found for [{0}].[{1}]. " + + "Old value (overwritten): \"{2}\". New value: \"{3}\"", + group, key, oldValue, newValue ); + } + map.Metadata[group, key] = newValue; + } } } @@ -98,17 +93,17 @@ public Map LoadHeader( [NotNull] string fileName ) { } } - public Map Load( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { BinaryReader reader = new BinaryReader( mapStream ); Map map = LoadHeaderInternal( reader ); // read the layer index int layerCount = reader.ReadByte(); - if( layerCount < 1 ) { + if ( layerCount < 1 ) { throw new MapFormatException( "No data layers found." ); } mapStream.Seek( 25 * layerCount, SeekOrigin.Current ); @@ -116,32 +111,27 @@ public Map Load( [NotNull] string fileName ) { // read metadata int metaSize = reader.ReadInt32(); - using( DeflateStream ds = new DeflateStream( mapStream, CompressionMode.Decompress ) ) { + using ( DeflateStream ds = new DeflateStream( mapStream, CompressionMode.Decompress ) ) { BinaryReader br = new BinaryReader( ds ); - for( int i = 0; i < metaSize; i++ ) { + for ( int i = 0; i < metaSize; i++ ) { string group = ReadLengthPrefixedString( br ).ToLowerInvariant(); string key = ReadLengthPrefixedString( br ).ToLowerInvariant(); string newValue = ReadLengthPrefixedString( br ); string oldValue; - IConverterExtension ex; - if (_extensions.TryGetValue(group, out ex)) - { - ex.Deserialize(group, key, newValue, map); - } - else - { - if( map.Metadata.TryGetValue( key, group, out oldValue ) && oldValue != newValue ) - { - Logger.Log( LogType.Warning, + IConverterExtension ex; + if ( _extensions.TryGetValue( group, out ex ) ) { + ex.Deserialize( group, key, newValue, map ); + } else { + if ( map.Metadata.TryGetValue( key, group, out oldValue ) && oldValue != newValue ) { + Logger.Log( LogType.Warning, "MapFCMv3.LoadHeader: Duplicate metadata entry found for [{0}].[{1}]. " + "Old value (overwritten): \"{2}\". New value: \"{3}\"", group, key, oldValue, newValue ); - } - map.Metadata[group, key] = newValue; - } - + } + map.Metadata[group, key] = newValue; + } } map.Blocks = new byte[map.Volume]; ds.Read( map.Blocks, 0, map.Blocks.Length ); @@ -151,10 +141,10 @@ public Map Load( [NotNull] string fileName ) { } } - - static Map LoadHeaderInternal( [NotNull] BinaryReader reader ) { - if( reader == null ) throw new ArgumentNullException( "reader" ); - if( reader.ReadInt32() != Identifier || reader.ReadByte() != Revision ) { + private static Map LoadHeaderInternal( [NotNull] BinaryReader reader ) { + if ( reader == null ) + throw new ArgumentNullException( "reader" ); + if ( reader.ReadInt32() != Identifier || reader.ReadByte() != Revision ) { throw new MapFormatException(); } @@ -169,14 +159,13 @@ static Map LoadHeaderInternal( [NotNull] BinaryReader reader ) { // read spawn map.Spawn = new Position { - X = (short)reader.ReadInt32(), - Z = (short)reader.ReadInt32(), - Y = (short)reader.ReadInt32(), + X = ( short )reader.ReadInt32(), + Z = ( short )reader.ReadInt32(), + Y = ( short )reader.ReadInt32(), R = reader.ReadByte(), L = reader.ReadByte() }; - // read modification/creation times map.DateModified = DateTimeUtil.ToDateTimeLegacy( reader.ReadUInt32() ); map.DateCreated = DateTimeUtil.ToDateTimeLegacy( reader.ReadUInt32() ); @@ -186,34 +175,35 @@ static Map LoadHeaderInternal( [NotNull] BinaryReader reader ) { return map; } - public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { - if( mapToSave == null ) throw new ArgumentNullException( "mapToSave" ); - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.Create( fileName ) ) { + if ( mapToSave == null ) + throw new ArgumentNullException( "mapToSave" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.Create( fileName ) ) { BinaryWriter writer = new BinaryWriter( mapStream ); writer.Write( Identifier ); writer.Write( Revision ); - writer.Write( (short)mapToSave.Width ); - writer.Write( (short)mapToSave.Height ); - writer.Write( (short)mapToSave.Length ); + writer.Write( ( short )mapToSave.Width ); + writer.Write( ( short )mapToSave.Height ); + writer.Write( ( short )mapToSave.Length ); - writer.Write( (int)mapToSave.Spawn.X ); - writer.Write( (int)mapToSave.Spawn.Z ); - writer.Write( (int)mapToSave.Spawn.Y ); + writer.Write( ( int )mapToSave.Spawn.X ); + writer.Write( ( int )mapToSave.Spawn.Z ); + writer.Write( ( int )mapToSave.Spawn.Y ); writer.Write( mapToSave.Spawn.R ); writer.Write( mapToSave.Spawn.L ); mapToSave.DateModified = DateTime.UtcNow; - writer.Write( (uint)mapToSave.DateModified.ToUnixTimeLegacy() ); - writer.Write( (uint)mapToSave.DateCreated.ToUnixTimeLegacy() ); + writer.Write( ( uint )mapToSave.DateModified.ToUnixTimeLegacy() ); + writer.Write( ( uint )mapToSave.DateCreated.ToUnixTimeLegacy() ); writer.Write( mapToSave.Guid.ToByteArray() ); - writer.Write( (byte)1 ); // layer count + writer.Write( ( byte )1 ); // layer count // skip over index and metacount long indexOffset = mapStream.Position; @@ -222,20 +212,20 @@ public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { byte[] blocksCache = mapToSave.Blocks; int metaCount, compressedLength; long offset; - using( DeflateStream ds = new DeflateStream( mapStream, CompressionMode.Compress, true ) ) { - using( BufferedStream bs = new BufferedStream( ds ) ) { + using ( DeflateStream ds = new DeflateStream( mapStream, CompressionMode.Compress, true ) ) { + using ( BufferedStream bs = new BufferedStream( ds ) ) { // write metadata metaCount = WriteMetadata( bs, mapToSave ); offset = mapStream.Position; // inaccurate, but who cares bs.Write( blocksCache, 0, blocksCache.Length ); - compressedLength = (int)(mapStream.Position - offset); + compressedLength = ( int )( mapStream.Position - offset ); } } // come back to write the index writer.BaseStream.Seek( indexOffset, SeekOrigin.Begin ); - writer.Write( (byte)0 ); // data layer type (Blocks) + writer.Write( ( byte )0 ); // data layer type (Blocks) writer.Write( offset ); // offset, in bytes, from start of stream writer.Write( compressedLength ); // compressed length, in bytes writer.Write( 0 ); // general purpose field @@ -247,60 +237,58 @@ public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { } } - - static string ReadLengthPrefixedString( [NotNull] BinaryReader reader ) { - if( reader == null ) throw new ArgumentNullException( "reader" ); + private static string ReadLengthPrefixedString( [NotNull] BinaryReader reader ) { + if ( reader == null ) + throw new ArgumentNullException( "reader" ); int length = reader.ReadUInt16(); byte[] stringData = reader.ReadBytes( length ); return Encoding.ASCII.GetString( stringData ); } - private static void WriteLengthPrefixedString( [NotNull] BinaryWriter writer, [NotNull] string str ) { - if( writer == null ) throw new ArgumentNullException( "writer" ); - if( str == null ) throw new ArgumentNullException( "str" ); - if( str.Length > ushort.MaxValue ) throw new ArgumentException( "String is too long.", "str" ); + private static void WriteLengthPrefixedString( [NotNull] BinaryWriter writer, [NotNull] string str ) { + if ( writer == null ) + throw new ArgumentNullException( "writer" ); + if ( str == null ) + throw new ArgumentNullException( "str" ); + if ( str.Length > ushort.MaxValue ) + throw new ArgumentException( "String is too long.", "str" ); byte[] stringData = Encoding.ASCII.GetBytes( str ); - writer.Write( (ushort)stringData.Length ); + writer.Write( ( ushort )stringData.Length ); writer.Write( stringData ); } - private int WriteMetadata( [NotNull] Stream stream, [NotNull] Map map ) - { - if (stream == null) throw new ArgumentNullException("stream"); - if (map == null) throw new ArgumentNullException("map"); - BinaryWriter writer = new BinaryWriter(stream); - int metaCount = 0; - lock (map.Metadata.SyncRoot) - { - foreach (var entry in map.Metadata) - { - WriteMetadataEntry(entry.Group, entry.Key, entry.Value, writer); - metaCount++; - } - } - - //extensions - if (_extensions.Count > 0) - { - metaCount += _extensions.Values.Sum(ex => ex.Serialize(map, stream, this)); - } - return metaCount; + private int WriteMetadata( [NotNull] Stream stream, [NotNull] Map map ) { + if ( stream == null ) + throw new ArgumentNullException( "stream" ); + if ( map == null ) + throw new ArgumentNullException( "map" ); + BinaryWriter writer = new BinaryWriter( stream ); + int metaCount = 0; + lock ( map.Metadata.SyncRoot ) { + foreach ( var entry in map.Metadata ) { + WriteMetadataEntry( entry.Group, entry.Key, entry.Value, writer ); + metaCount++; + } + } + + //extensions + if ( _extensions.Count > 0 ) { + metaCount += _extensions.Values.Sum( ex => ex.Serialize( map, stream, this ) ); + } + return metaCount; } + public void WriteMetadataEntry( string group, string key, string value, BinaryWriter writer ) { + WriteLengthPrefixedString( writer, group ); + WriteLengthPrefixedString( writer, key ); + WriteLengthPrefixedString( writer, value ); + } - public void WriteMetadataEntry(string group, string key, string value, BinaryWriter writer) - { - WriteLengthPrefixedString(writer, group); - WriteLengthPrefixedString(writer, key); - WriteLengthPrefixedString(writer, value); - } - - public IMapConverterEx AddExtension(IConverterExtension ex) - { - //NullPtEx is not checked since this extensions are added once on runup and any exceptions here are programming errors - foreach (string s in ex.AcceptedGroups) - _extensions.Add(s, ex); - return this; //to be able to add multiple extensions in one line: converter.AddExtension(e1).AddExtension(e2); - } + public IMapConverterEx AddExtension( IConverterExtension ex ) { + //NullPtEx is not checked since this extensions are added once on runup and any exceptions here are programming errors + foreach ( string s in ex.AcceptedGroups ) + _extensions.Add( s, ex ); + return this; //to be able to add multiple extensions in one line: converter.AddExtension(e1).AddExtension(e2); + } } } \ No newline at end of file diff --git a/fCraft/MapConversion/MapFCMv4.cs b/fCraft/MapConversion/MapFCMv4.cs index 20e35c5..e2293e8 100644 --- a/fCraft/MapConversion/MapFCMv4.cs +++ b/fCraft/MapConversion/MapFCMv4.cs @@ -1,81 +1,81 @@ // Copyright 2009-2013 Matvei Stefarov using System; -using System.Text; using System.IO; using System.IO.Compression; +using System.Text; using System.Xml.Linq; using JetBrains.Annotations; namespace fCraft.MapConversion { + /// Next file format that fCraft shall use. public sealed class MapFCMv4 : IMapConverter { public const int FormatID = 0x00FC0004; - const string ZoneMetaGroupName = "fCraft.Zones", - BlockLayerName = "Blocks"; + private const string ZoneMetaGroupName = "fCraft.Zones", + BlockLayerName = "Blocks"; /// Returns name(s) of the server(s) that uses this format. public string ServerName { get { return "fCraft"; } } - /// Returns the format type (file-based or directory-based). public MapStorageType StorageType { get { return MapStorageType.SingleFile; } } - /// Returns the format name. public MapFormat Format { get { return MapFormat.FCMv4; } } - /// Returns true if the filename (or directory name) matches this format's expectations. public bool ClaimsName( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); return fileName.EndsWith( ".fcm", StringComparison.OrdinalIgnoreCase ); } - /// Allows validating the map format while using minimal resources. /// Returns true if specified file/directory is valid for this format. public bool Claims( [NotNull] string path ) { - if( path == null ) throw new ArgumentNullException( "path" ); - using( FileStream fs = File.OpenRead( path ) ) { + if ( path == null ) + throw new ArgumentNullException( "path" ); + using ( FileStream fs = File.OpenRead( path ) ) { BinaryReader reader = new BinaryReader( fs ); - return (reader.ReadInt32() == FormatID); + return ( reader.ReadInt32() == FormatID ); } } - /// Attempts to load map dimensions from specified location. /// Map object on success, or null on failure. public Map LoadHeader( string path ) { - if( path == null ) throw new ArgumentNullException( "path" ); - using( FileStream fs = File.OpenRead( path ) ) { + if ( path == null ) + throw new ArgumentNullException( "path" ); + using ( FileStream fs = File.OpenRead( path ) ) { return LoadInternal( fs, false ); } } - /// Fully loads map from specified location. /// Map object on success, or null on failure. public Map Load( [NotNull] string path ) { - if( path == null ) throw new ArgumentNullException( "path" ); - using( FileStream fs = File.OpenRead( path ) ) { + if ( path == null ) + throw new ArgumentNullException( "path" ); + using ( FileStream fs = File.OpenRead( path ) ) { return LoadInternal( fs, true ); } } - /// Saves given map at the given location. /// true if saving succeeded. public bool Save( [NotNull] Map map, [NotNull] string path ) { - if( map == null ) throw new ArgumentNullException( "map" ); - if( path == null ) throw new ArgumentNullException( "path" ); - using( FileStream mapStream = File.Create( path ) ) { + if ( map == null ) + throw new ArgumentNullException( "map" ); + if ( path == null ) + throw new ArgumentNullException( "path" ); + using ( FileStream mapStream = File.Create( path ) ) { BinaryWriter writer = new BinaryWriter( mapStream ); writer.Write( FormatID ); @@ -87,9 +87,9 @@ public bool Save( [NotNull] Map map, [NotNull] string path ) { // write out the spawn Position spawn = map.Spawn; - writer.Write( (int)spawn.X ); - writer.Write( (int)spawn.Z ); - writer.Write( (int)spawn.Y ); + writer.Write( ( int )spawn.X ); + writer.Write( ( int )spawn.Z ); + writer.Write( ( int )spawn.Y ); writer.Write( spawn.R ); writer.Write( spawn.L ); @@ -101,8 +101,8 @@ public bool Save( [NotNull] Map map, [NotNull] string path ) { writer.Write( modifiedTime ); // write out metadata - lock( map.Metadata.SyncRoot ) { - lock( map.Zones.SyncRoot ) { + lock ( map.Metadata.SyncRoot ) { + lock ( map.Zones.SyncRoot ) { int metaCount = map.Metadata.Count; metaCount += map.Zones.Count; @@ -111,14 +111,14 @@ public bool Save( [NotNull] Map map, [NotNull] string path ) { writer.Write( metaCount ); // write out metadata - foreach( var entry in map.Metadata ) { + foreach ( var entry in map.Metadata ) { WriteString( writer, entry.Group ); WriteString( writer, entry.Key ); WriteString( writer, entry.Value ); } // write out zones - foreach( var zone in map.Zones ) { + foreach ( var zone in map.Zones ) { WriteString( writer, ZoneMetaGroupName ); WriteString( writer, zone.Name ); WriteString( writer, zone.Serialize().ToString( SaveOptions.DisableFormatting ) ); @@ -138,13 +138,13 @@ public bool Save( [NotNull] Map map, [NotNull] string path ) { } } - - static Map LoadInternal( [NotNull] Stream stream, bool readLayers ) { - if( stream == null ) throw new ArgumentNullException( "stream" ); + private static Map LoadInternal( [NotNull] Stream stream, bool readLayers ) { + if ( stream == null ) + throw new ArgumentNullException( "stream" ); BinaryReader bs = new BinaryReader( stream ); // headers - if( bs.ReadInt32() != FormatID ) { + if ( bs.ReadInt32() != FormatID ) { throw new MapFormatException( "MapFCMv4: Invalid format ID." ); } @@ -159,9 +159,9 @@ static Map LoadInternal( [NotNull] Stream stream, bool readLayers ) { // spawn map.Spawn = new Position { - X = (short)bs.ReadInt32(), - Z = (short)bs.ReadInt32(), - Y = (short)bs.ReadInt32(), + X = ( short )bs.ReadInt32(), + Z = ( short )bs.ReadInt32(), + Y = ( short )bs.ReadInt32(), R = bs.ReadByte(), L = bs.ReadByte() }; @@ -173,30 +173,31 @@ static Map LoadInternal( [NotNull] Stream stream, bool readLayers ) { map.DateModified = modifiedTime.ToDateTime(); int metaEntryCount = bs.ReadInt32(); - if( metaEntryCount < 0 ) throw new MapFormatException( "Negative metadata entry count." ); + if ( metaEntryCount < 0 ) + throw new MapFormatException( "Negative metadata entry count." ); // metadata - for( int i = 0; i < metaEntryCount; i++ ) { + for ( int i = 0; i < metaEntryCount; i++ ) { string groupName = ReadString( bs ); string keyName = ReadString( bs ); string value = ReadString( bs ); // check for duplicate keys string oldValue; - if( map.Metadata.TryGetValue( groupName, keyName, out oldValue ) ) { + if ( map.Metadata.TryGetValue( groupName, keyName, out oldValue ) ) { Logger.Log( LogType.Warning, "MapFCMv4: Duplicate metadata entry \"{0}.{1}\". " + - "Old value: \"{2}\", new value \"{3}\"", + "Old value: \"{2}\", new value \"{3}\"", groupName, keyName, oldValue, value ); } // parse or store metadata - switch( groupName ) { + switch ( groupName ) { case ZoneMetaGroupName: try { Zone newZone = new Zone( XElement.Parse( value ) ); map.Zones.Add( newZone ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.Log( LogType.Error, "MapFCMv4: Error importing zone definition: {0}", ex ); @@ -210,20 +211,22 @@ static Map LoadInternal( [NotNull] Stream stream, bool readLayers ) { } int layerCount = bs.ReadInt32(); - if( layerCount < 0 ) throw new MapFormatException( "Negative layer count." ); + if ( layerCount < 0 ) + throw new MapFormatException( "Negative layer count." ); // layers - if( readLayers ) { - for( int l = 0; l < layerCount; l++ ) { + if ( readLayers ) { + for ( int l = 0; l < layerCount; l++ ) { string layerName = ReadString( bs ); int layerSize = bs.ReadInt32(); - if( layerSize < 0 ) throw new MapFormatException( "Invalid layer size." ); + if ( layerSize < 0 ) + throw new MapFormatException( "Invalid layer size." ); - switch( layerName ) { + switch ( layerName ) { case BlockLayerName: //long blockStart = stream.Position; map.Blocks = new byte[map.Volume]; - using( GZipStream gs = new GZipStream( stream, CompressionMode.Decompress ) ) { + using ( GZipStream gs = new GZipStream( stream, CompressionMode.Decompress ) ) { gs.Read( map.Blocks, 0, 4 ); // skip the 4-byte header gs.Read( map.Blocks, 0, layerSize ); } @@ -235,9 +238,9 @@ static Map LoadInternal( [NotNull] Stream stream, bool readLayers ) { break; default: - if( layerSize > 0 ) { + if ( layerSize > 0 ) { byte[] layerData = new byte[layerSize]; - using( GZipStream gs = new GZipStream( stream, CompressionMode.Decompress ) ) { + using ( GZipStream gs = new GZipStream( stream, CompressionMode.Decompress ) ) { gs.Read( layerData, 0, layerSize ); } } @@ -251,18 +254,20 @@ static Map LoadInternal( [NotNull] Stream stream, bool readLayers ) { return map; } - - static string ReadString( [NotNull] BinaryReader reader ) { - if( reader == null ) throw new ArgumentNullException( "reader" ); + private static string ReadString( [NotNull] BinaryReader reader ) { + if ( reader == null ) + throw new ArgumentNullException( "reader" ); int stringLength = reader.ReadInt32(); - if( stringLength < 0 ) throw new MapFormatException( "Negative string length." ); + if ( stringLength < 0 ) + throw new MapFormatException( "Negative string length." ); return Encoding.ASCII.GetString( reader.ReadBytes( stringLength ) ); } - - static void WriteString( [NotNull] BinaryWriter writer, [NotNull] string str ) { - if( writer == null ) throw new ArgumentNullException( "writer" ); - if( str == null ) throw new ArgumentNullException( "str" ); + private static void WriteString( [NotNull] BinaryWriter writer, [NotNull] string str ) { + if ( writer == null ) + throw new ArgumentNullException( "writer" ); + if ( str == null ) + throw new ArgumentNullException( "str" ); byte[] stringData = Encoding.ASCII.GetBytes( str ); writer.Write( stringData.Length ); writer.Write( stringData, 0, stringData.Length ); diff --git a/fCraft/MapConversion/MapFormat.cs b/fCraft/MapConversion/MapFormat.cs index ac7cb9d..0e2b4e4 100644 --- a/fCraft/MapConversion/MapFormat.cs +++ b/fCraft/MapConversion/MapFormat.cs @@ -1,8 +1,10 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft.MapConversion { + /// An enumeration of map formats supported by fCraft. public enum MapFormat { + /// Unidentified map. Unknown, @@ -40,10 +42,9 @@ public enum MapFormat { FCMv4 } - /// Type of map storage (file or folder-based). public enum MapStorageType { SingleFile, Directory } -} +} \ No newline at end of file diff --git a/fCraft/MapConversion/MapFormatException.cs b/fCraft/MapConversion/MapFormatException.cs index cce663a..7295338 100644 --- a/fCraft/MapConversion/MapFormatException.cs +++ b/fCraft/MapConversion/MapFormatException.cs @@ -3,9 +3,15 @@ using JetBrains.Annotations; namespace fCraft.MapConversion { + /// Exception caused by problems with the map file's incorrect format or structure. public sealed class MapFormatException : Exception { - public MapFormatException() { } - public MapFormatException( [NotNull] string message ) : base( message ) { } + + public MapFormatException() { + } + + public MapFormatException( [NotNull] string message ) + : base( message ) { + } } -} +} \ No newline at end of file diff --git a/fCraft/MapConversion/MapJTE.cs b/fCraft/MapConversion/MapJTE.cs index 18db922..2325630 100644 --- a/fCraft/MapConversion/MapJTE.cs +++ b/fCraft/MapConversion/MapJTE.cs @@ -6,95 +6,93 @@ using JetBrains.Annotations; namespace fCraft.MapConversion { - public sealed class MapJTE : IMapConverter { - static readonly byte[] Mapping = new byte[256]; + public sealed class MapJTE : IMapConverter { + private static readonly byte[] Mapping = new byte[256]; static MapJTE() { - Mapping[255] = (byte)Block.Sponge; // lava sponge - Mapping[254] = (byte)Block.TNT; // dynamite - Mapping[253] = (byte)Block.Sponge; // supersponge - Mapping[252] = (byte)Block.Water; // watervator - Mapping[251] = (byte)Block.White; // soccer - Mapping[250] = (byte)Block.Red; // fire - Mapping[249] = (byte)Block.Red; // badfire - Mapping[248] = (byte)Block.Red; // hellfire - Mapping[247] = (byte)Block.Black; // ashes - Mapping[246] = (byte)Block.Orange; // torch - Mapping[245] = (byte)Block.Orange; // safetorch - Mapping[244] = (byte)Block.Orange; // helltorch - Mapping[243] = (byte)Block.Red; // uberfire - Mapping[242] = (byte)Block.Red; // godfire - Mapping[241] = (byte)Block.TNT; // nuke - Mapping[240] = (byte)Block.Lava; // lavavator - Mapping[239] = (byte)Block.Admincrete; // instawall - Mapping[238] = (byte)Block.Admincrete; // spleef - Mapping[237] = (byte)Block.Green; // resetspleef - Mapping[236] = (byte)Block.Red; // deletespleef - Mapping[235] = (byte)Block.Sponge; // godsponge + Mapping[255] = ( byte )Block.Sponge; // lava sponge + Mapping[254] = ( byte )Block.TNT; // dynamite + Mapping[253] = ( byte )Block.Sponge; // supersponge + Mapping[252] = ( byte )Block.Water; // watervator + Mapping[251] = ( byte )Block.White; // soccer + Mapping[250] = ( byte )Block.Red; // fire + Mapping[249] = ( byte )Block.Red; // badfire + Mapping[248] = ( byte )Block.Red; // hellfire + Mapping[247] = ( byte )Block.Black; // ashes + Mapping[246] = ( byte )Block.Orange; // torch + Mapping[245] = ( byte )Block.Orange; // safetorch + Mapping[244] = ( byte )Block.Orange; // helltorch + Mapping[243] = ( byte )Block.Red; // uberfire + Mapping[242] = ( byte )Block.Red; // godfire + Mapping[241] = ( byte )Block.TNT; // nuke + Mapping[240] = ( byte )Block.Lava; // lavavator + Mapping[239] = ( byte )Block.Admincrete; // instawall + Mapping[238] = ( byte )Block.Admincrete; // spleef + Mapping[237] = ( byte )Block.Green; // resetspleef + Mapping[236] = ( byte )Block.Red; // deletespleef + Mapping[235] = ( byte )Block.Sponge; // godsponge // all others default to 0/air } - public string ServerName { get { return "JTE's"; } } - public MapStorageType StorageType { get { return MapStorageType.SingleFile; } } - public MapFormat Format { get { return MapFormat.JTE; } } - public bool ClaimsName( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); return fileName.EndsWith( ".gz", StringComparison.OrdinalIgnoreCase ); } - public bool Claims( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); try { - using( FileStream mapStream = File.OpenRead( fileName ) ) { - using( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { + using ( FileStream mapStream = File.OpenRead( fileName ) ) { + using ( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { BinaryReader bs = new BinaryReader( gs ); byte version = bs.ReadByte(); - return (version == 1 || version == 2); + return ( version == 1 || version == 2 ); } } - } catch( Exception ) { + } catch ( Exception ) { return false; } } - public Map LoadHeader( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { - using( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { + using ( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { return LoadHeaderInternal( gs ); } } } - - static Map LoadHeaderInternal( [NotNull] Stream stream ) { - if( stream == null ) throw new ArgumentNullException( "stream" ); + private static Map LoadHeaderInternal( [NotNull] Stream stream ) { + if ( stream == null ) + throw new ArgumentNullException( "stream" ); BinaryReader bs = new BinaryReader( stream ); byte version = bs.ReadByte(); - if( version != 1 && version != 2 ) throw new MapFormatException(); + if ( version != 1 && version != 2 ) + throw new MapFormatException(); // read spawn location and orientation Position spawn = new Position { - X = (short)( IPAddress.NetworkToHostOrder( bs.ReadInt16() ) * 32 ), - Z = (short)( IPAddress.NetworkToHostOrder( bs.ReadInt16() ) * 32 ), - Y = (short)( IPAddress.NetworkToHostOrder( bs.ReadInt16() ) * 32 ), + X = ( short )( IPAddress.NetworkToHostOrder( bs.ReadInt16() ) * 32 ), + Z = ( short )( IPAddress.NetworkToHostOrder( bs.ReadInt16() ) * 32 ), + Y = ( short )( IPAddress.NetworkToHostOrder( bs.ReadInt16() ) * 32 ), R = bs.ReadByte(), L = bs.ReadByte() }; @@ -107,16 +105,16 @@ static Map LoadHeaderInternal( [NotNull] Stream stream ) { return new Map( null, width, length, height, false ) { Spawn = spawn }; } - public Map Load( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { // Setup a GZipStream to decompress and read the map file GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ); Map map = LoadHeaderInternal( gs ); - if( !map.ValidateHeader() ) { + if ( !map.ValidateHeader() ) { throw new MapFormatException( "One or more of the map dimensions are invalid." ); } @@ -130,21 +128,22 @@ public Map Load( [NotNull] string fileName ) { } } - public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { - if( mapToSave == null ) throw new ArgumentNullException( "mapToSave" ); - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.Create( fileName ) ) { - using( GZipStream gs = new GZipStream( mapStream, CompressionMode.Compress ) ) { + if ( mapToSave == null ) + throw new ArgumentNullException( "mapToSave" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.Create( fileName ) ) { + using ( GZipStream gs = new GZipStream( mapStream, CompressionMode.Compress ) ) { BinaryWriter bs = new BinaryWriter( gs ); // Write the magic number - bs.Write( (byte)0x01 ); + bs.Write( ( byte )0x01 ); // Write the spawn location - bs.Write( IPAddress.NetworkToHostOrder( (short)(mapToSave.Spawn.X / 32) ) ); - bs.Write( IPAddress.NetworkToHostOrder( (short)(mapToSave.Spawn.Z / 32) ) ); - bs.Write( IPAddress.NetworkToHostOrder( (short)(mapToSave.Spawn.Y / 32) ) ); + bs.Write( IPAddress.NetworkToHostOrder( ( short )( mapToSave.Spawn.X / 32 ) ) ); + bs.Write( IPAddress.NetworkToHostOrder( ( short )( mapToSave.Spawn.Z / 32 ) ) ); + bs.Write( IPAddress.NetworkToHostOrder( ( short )( mapToSave.Spawn.Y / 32 ) ) ); //Write the spawn orientation bs.Write( mapToSave.Spawn.R ); diff --git a/fCraft/MapConversion/MapMCSharp.cs b/fCraft/MapConversion/MapMCSharp.cs index 5ba6157..78e4c5e 100644 --- a/fCraft/MapConversion/MapMCSharp.cs +++ b/fCraft/MapConversion/MapMCSharp.cs @@ -6,190 +6,187 @@ using JetBrains.Annotations; namespace fCraft.MapConversion { - public sealed class MapMCSharp : IMapConverter { - static readonly byte[] Mapping = new byte[256]; + public sealed class MapMCSharp : IMapConverter { + private static readonly byte[] Mapping = new byte[256]; static MapMCSharp() { - Mapping[100] = (byte)Block.Glass; // op_glass - Mapping[101] = (byte)Block.Obsidian; // opsidian - Mapping[102] = (byte)Block.Brick; // op_brick - Mapping[103] = (byte)Block.Stone; // op_stone - Mapping[104] = (byte)Block.Cobblestone; // op_cobblestone + Mapping[100] = ( byte )Block.Glass; // op_glass + Mapping[101] = ( byte )Block.Obsidian; // opsidian + Mapping[102] = ( byte )Block.Brick; // op_brick + Mapping[103] = ( byte )Block.Stone; // op_stone + Mapping[104] = ( byte )Block.Cobblestone; // op_cobblestone // 105 = op_air - Mapping[106] = (byte)Block.Water; // op_water + Mapping[106] = ( byte )Block.Water; // op_water // 107-109 unused - Mapping[110] = (byte)Block.Wood; // wood_float - Mapping[111] = (byte)Block.Log; // door - Mapping[112] = (byte)Block.Lava; // lava_fast - Mapping[113] = (byte)Block.Obsidian; // door2 - Mapping[114] = (byte)Block.Glass; // door3 - Mapping[115] = (byte)Block.Stone; // door4 - Mapping[116] = (byte)Block.Leaves; // door5 - Mapping[117] = (byte)Block.Sand; // door6 - Mapping[118] = (byte)Block.Wood; // door7 - Mapping[119] = (byte)Block.Green; // door8 - Mapping[120] = (byte)Block.TNT; // door9 - Mapping[121] = (byte)Block.Stair; // door10 - - Mapping[122] = (byte)Block.Log; // tdoor - Mapping[123] = (byte)Block.Obsidian; // tdoor2 - Mapping[124] = (byte)Block.Glass; // tdoor3 - Mapping[125] = (byte)Block.Stone; // tdoor4 - Mapping[126] = (byte)Block.Leaves; // tdoor5 - Mapping[127] = (byte)Block.Sand; // tdoor6 - Mapping[128] = (byte)Block.Wood; // tdoor7 - Mapping[129] = (byte)Block.Green; // tdoor8 - - Mapping[130] = (byte)Block.White; // MsgWhite - Mapping[131] = (byte)Block.Black; // MsgBlack - Mapping[132] = (byte)Block.Air; // MsgAir - Mapping[133] = (byte)Block.Water; // MsgWater - Mapping[134] = (byte)Block.Lava; // MsgLava - - Mapping[135] = (byte)Block.TNT; // tdoor9 - Mapping[136] = (byte)Block.Stair; // tdoor10 - Mapping[137] = (byte)Block.Air; // tdoor11 - Mapping[138] = (byte)Block.Water; // tdoor12 - Mapping[139] = (byte)Block.Lava; // tdoor13 - - Mapping[140] = (byte)Block.Water; // WaterDown - Mapping[141] = (byte)Block.Lava; // LavaDown - Mapping[143] = (byte)Block.Aqua; // WaterFaucet - Mapping[144] = (byte)Block.Orange; // LavaFaucet + Mapping[110] = ( byte )Block.Wood; // wood_float + Mapping[111] = ( byte )Block.Log; // door + Mapping[112] = ( byte )Block.Lava; // lava_fast + Mapping[113] = ( byte )Block.Obsidian; // door2 + Mapping[114] = ( byte )Block.Glass; // door3 + Mapping[115] = ( byte )Block.Stone; // door4 + Mapping[116] = ( byte )Block.Leaves; // door5 + Mapping[117] = ( byte )Block.Sand; // door6 + Mapping[118] = ( byte )Block.Wood; // door7 + Mapping[119] = ( byte )Block.Green; // door8 + Mapping[120] = ( byte )Block.TNT; // door9 + Mapping[121] = ( byte )Block.Stair; // door10 + + Mapping[122] = ( byte )Block.Log; // tdoor + Mapping[123] = ( byte )Block.Obsidian; // tdoor2 + Mapping[124] = ( byte )Block.Glass; // tdoor3 + Mapping[125] = ( byte )Block.Stone; // tdoor4 + Mapping[126] = ( byte )Block.Leaves; // tdoor5 + Mapping[127] = ( byte )Block.Sand; // tdoor6 + Mapping[128] = ( byte )Block.Wood; // tdoor7 + Mapping[129] = ( byte )Block.Green; // tdoor8 + + Mapping[130] = ( byte )Block.White; // MsgWhite + Mapping[131] = ( byte )Block.Black; // MsgBlack + Mapping[132] = ( byte )Block.Air; // MsgAir + Mapping[133] = ( byte )Block.Water; // MsgWater + Mapping[134] = ( byte )Block.Lava; // MsgLava + + Mapping[135] = ( byte )Block.TNT; // tdoor9 + Mapping[136] = ( byte )Block.Stair; // tdoor10 + Mapping[137] = ( byte )Block.Air; // tdoor11 + Mapping[138] = ( byte )Block.Water; // tdoor12 + Mapping[139] = ( byte )Block.Lava; // tdoor13 + + Mapping[140] = ( byte )Block.Water; // WaterDown + Mapping[141] = ( byte )Block.Lava; // LavaDown + Mapping[143] = ( byte )Block.Aqua; // WaterFaucet + Mapping[144] = ( byte )Block.Orange; // LavaFaucet // 143 unused - Mapping[145] = (byte)Block.Water; // finiteWater - Mapping[146] = (byte)Block.Lava; // finiteLava - Mapping[147] = (byte)Block.Cyan; // finiteFaucet - - Mapping[148] = (byte)Block.Log; // odoor1 - Mapping[149] = (byte)Block.Obsidian; // odoor2 - Mapping[150] = (byte)Block.Glass; // odoor3 - Mapping[151] = (byte)Block.Stone; // odoor4 - Mapping[152] = (byte)Block.Leaves; // odoor5 - Mapping[153] = (byte)Block.Sand; // odoor6 - Mapping[154] = (byte)Block.Wood; // odoor7 - Mapping[155] = (byte)Block.Green; // odoor8 - Mapping[156] = (byte)Block.TNT; // odoor9 - Mapping[157] = (byte)Block.Stair; // odoor10 - Mapping[158] = (byte)Block.Lava; // odoor11 - Mapping[159] = (byte)Block.Water; // odoor12 - - Mapping[160] = (byte)Block.Air; // air_portal - Mapping[161] = (byte)Block.Water; // water_portal - Mapping[162] = (byte)Block.Lava; // lava_portal + Mapping[145] = ( byte )Block.Water; // finiteWater + Mapping[146] = ( byte )Block.Lava; // finiteLava + Mapping[147] = ( byte )Block.Cyan; // finiteFaucet + + Mapping[148] = ( byte )Block.Log; // odoor1 + Mapping[149] = ( byte )Block.Obsidian; // odoor2 + Mapping[150] = ( byte )Block.Glass; // odoor3 + Mapping[151] = ( byte )Block.Stone; // odoor4 + Mapping[152] = ( byte )Block.Leaves; // odoor5 + Mapping[153] = ( byte )Block.Sand; // odoor6 + Mapping[154] = ( byte )Block.Wood; // odoor7 + Mapping[155] = ( byte )Block.Green; // odoor8 + Mapping[156] = ( byte )Block.TNT; // odoor9 + Mapping[157] = ( byte )Block.Stair; // odoor10 + Mapping[158] = ( byte )Block.Lava; // odoor11 + Mapping[159] = ( byte )Block.Water; // odoor12 + + Mapping[160] = ( byte )Block.Air; // air_portal + Mapping[161] = ( byte )Block.Water; // water_portal + Mapping[162] = ( byte )Block.Lava; // lava_portal // 163 unused - Mapping[164] = (byte)Block.Air; // air_door - Mapping[165] = (byte)Block.Air; // air_switch - Mapping[166] = (byte)Block.Water; // water_door - Mapping[167] = (byte)Block.Lava; // lava_door + Mapping[164] = ( byte )Block.Air; // air_door + Mapping[165] = ( byte )Block.Air; // air_switch + Mapping[166] = ( byte )Block.Water; // water_door + Mapping[167] = ( byte )Block.Lava; // lava_door // 168-174 = odoor*_air - Mapping[175] = (byte)Block.Cyan; // blue_portal - Mapping[176] = (byte)Block.Orange; // orange_portal + Mapping[175] = ( byte )Block.Cyan; // blue_portal + Mapping[176] = ( byte )Block.Orange; // orange_portal // 177-181 = odoor*_air - Mapping[182] = (byte)Block.TNT; // smalltnt - Mapping[183] = (byte)Block.TNT; // bigtnt - Mapping[184] = (byte)Block.Lava; // tntexplosion - Mapping[185] = (byte)Block.Lava; // fire + Mapping[182] = ( byte )Block.TNT; // smalltnt + Mapping[183] = ( byte )Block.TNT; // bigtnt + Mapping[184] = ( byte )Block.Lava; // tntexplosion + Mapping[185] = ( byte )Block.Lava; // fire // 186 unused - Mapping[187] = (byte)Block.Glass; // rocketstart - Mapping[188] = (byte)Block.Gold; // rockethead - Mapping[189] = (byte)Block.Iron; // firework + Mapping[187] = ( byte )Block.Glass; // rocketstart + Mapping[188] = ( byte )Block.Gold; // rockethead + Mapping[189] = ( byte )Block.Iron; // firework - Mapping[190] = (byte)Block.Lava; // deathlava - Mapping[191] = (byte)Block.Water; // deathwater - Mapping[192] = (byte)Block.Air; // deathair - Mapping[193] = (byte)Block.Water; // activedeathwater - Mapping[194] = (byte)Block.Lava; // activedeathlava + Mapping[190] = ( byte )Block.Lava; // deathlava + Mapping[191] = ( byte )Block.Water; // deathwater + Mapping[192] = ( byte )Block.Air; // deathair + Mapping[193] = ( byte )Block.Water; // activedeathwater + Mapping[194] = ( byte )Block.Lava; // activedeathlava - Mapping[195] = (byte)Block.Lava; // magma - Mapping[196] = (byte)Block.Water; // geyser + Mapping[195] = ( byte )Block.Lava; // magma + Mapping[196] = ( byte )Block.Water; // geyser // 197-210 = air - Mapping[211] = (byte)Block.Red; // door8_air - Mapping[212] = (byte)Block.Lava; // door9_air + Mapping[211] = ( byte )Block.Red; // door8_air + Mapping[212] = ( byte )Block.Lava; // door9_air // 213-229 = air - Mapping[230] = (byte)Block.Aqua; // train - Mapping[231] = (byte)Block.TNT; // creeper - Mapping[232] = (byte)Block.MossyRocks; // zombiebody - Mapping[233] = (byte)Block.Lime; // zombiehead + Mapping[230] = ( byte )Block.Aqua; // train + Mapping[231] = ( byte )Block.TNT; // creeper + Mapping[232] = ( byte )Block.MossyRocks; // zombiebody + Mapping[233] = ( byte )Block.Lime; // zombiehead // 234 unused - Mapping[235] = (byte)Block.White; // birdwhite - Mapping[236] = (byte)Block.Black; // birdblack - Mapping[237] = (byte)Block.Lava; // birdlava - Mapping[238] = (byte)Block.Red; // birdred - Mapping[239] = (byte)Block.Water; // birdwater - Mapping[240] = (byte)Block.Blue; // birdblue - Mapping[242] = (byte)Block.Lava; // birdkill - - Mapping[245] = (byte)Block.Gold; // fishgold - Mapping[246] = (byte)Block.Sponge; // fishsponge - Mapping[247] = (byte)Block.Gray; // fishshark - Mapping[248] = (byte)Block.Red; // fishsalmon - Mapping[249] = (byte)Block.Blue; // fishbetta + Mapping[235] = ( byte )Block.White; // birdwhite + Mapping[236] = ( byte )Block.Black; // birdblack + Mapping[237] = ( byte )Block.Lava; // birdlava + Mapping[238] = ( byte )Block.Red; // birdred + Mapping[239] = ( byte )Block.Water; // birdwater + Mapping[240] = ( byte )Block.Blue; // birdblue + Mapping[242] = ( byte )Block.Lava; // birdkill + + Mapping[245] = ( byte )Block.Gold; // fishgold + Mapping[246] = ( byte )Block.Sponge; // fishsponge + Mapping[247] = ( byte )Block.Gray; // fishshark + Mapping[248] = ( byte )Block.Red; // fishsalmon + Mapping[249] = ( byte )Block.Blue; // fishbetta } - public string ServerName { get { return "MCSharp/MCZall/MCLawl"; } } - public MapStorageType StorageType { get { return MapStorageType.SingleFile; } } - public MapFormat Format { get { return MapFormat.MCSharp; } } - public bool ClaimsName( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); return fileName.EndsWith( ".lvl", StringComparison.OrdinalIgnoreCase ); } - public bool Claims( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); try { - using( FileStream mapStream = File.OpenRead( fileName ) ) { - using( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { + using ( FileStream mapStream = File.OpenRead( fileName ) ) { + using ( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { BinaryReader bs = new BinaryReader( gs ); - return (bs.ReadUInt16() == 0x752); + return ( bs.ReadUInt16() == 0x752 ); } } - } catch( Exception ) { + } catch ( Exception ) { return false; } } - public Map LoadHeader( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { - using( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { + using ( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { return LoadHeaderInternal( gs ); } } } - - static Map LoadHeaderInternal( [NotNull] Stream stream ) { - if( stream == null ) throw new ArgumentNullException( "stream" ); + private static Map LoadHeaderInternal( [NotNull] Stream stream ) { + if ( stream == null ) + throw new ArgumentNullException( "stream" ); BinaryReader bs = new BinaryReader( stream ); // Read in the magic number - if( bs.ReadUInt16() != 0x752 ) { + if ( bs.ReadUInt16() != 0x752 ) { throw new MapFormatException(); } @@ -204,9 +201,9 @@ static Map LoadHeaderInternal( [NotNull] Stream stream ) { // Read in the spawn location map.Spawn = new Position { - X = (short)(bs.ReadInt16() * 32), - Z = (short)(bs.ReadInt16() * 32), - Y = (short)(bs.ReadInt16() * 32), + X = ( short )( bs.ReadInt16() * 32 ), + Z = ( short )( bs.ReadInt16() * 32 ), + Y = ( short )( bs.ReadInt16() * 32 ), R = bs.ReadByte(), L = bs.ReadByte(), }; @@ -216,15 +213,14 @@ static Map LoadHeaderInternal( [NotNull] Stream stream ) { return map; } - public Map Load( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { - using( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { - + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { + using ( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { Map map = LoadHeaderInternal( gs ); - if( !map.ValidateHeader() ) { + if ( !map.ValidateHeader() ) { throw new MapFormatException( "One or more of the map dimensions are invalid." ); } @@ -239,16 +235,17 @@ public Map Load( [NotNull] string fileName ) { } } - public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { - if( mapToSave == null ) throw new ArgumentNullException( "mapToSave" ); - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.Create( fileName ) ) { - using( GZipStream gs = new GZipStream( mapStream, CompressionMode.Compress ) ) { + if ( mapToSave == null ) + throw new ArgumentNullException( "mapToSave" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.Create( fileName ) ) { + using ( GZipStream gs = new GZipStream( mapStream, CompressionMode.Compress ) ) { BinaryWriter bs = new BinaryWriter( gs ); // Write the magic number - bs.Write( (ushort)0x752 ); + bs.Write( ( ushort )0x752 ); // Write the map dimensions bs.Write( mapToSave.Width ); @@ -265,8 +262,8 @@ public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { bs.Write( mapToSave.Spawn.L ); // Write the VistPermission and BuildPermission bytes - bs.Write( (byte)0 ); - bs.Write( (byte)0 ); + bs.Write( ( byte )0 ); + bs.Write( ( byte )0 ); // Write the map data bs.Write( mapToSave.Blocks, 0, mapToSave.Blocks.Length ); diff --git a/fCraft/MapConversion/MapMinerCPP.cs b/fCraft/MapConversion/MapMinerCPP.cs index 8bcdd18..8d42605 100644 --- a/fCraft/MapConversion/MapMinerCPP.cs +++ b/fCraft/MapConversion/MapMinerCPP.cs @@ -7,61 +7,60 @@ using JetBrains.Annotations; namespace fCraft.MapConversion { + public sealed class MapMinerCPP : IMapConverter { public string ServerName { get { return "MinerCPP/LuaCraft"; } } - public MapStorageType StorageType { get { return MapStorageType.SingleFile; } } - public MapFormat Format { get { return MapFormat.MinerCPP; } } - public bool ClaimsName( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); return fileName.EndsWith( ".dat", StringComparison.OrdinalIgnoreCase ); } - public bool Claims( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); try { - using( FileStream mapStream = File.OpenRead( fileName ) ) { - using( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { + using ( FileStream mapStream = File.OpenRead( fileName ) ) { + using ( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress ) ) { BinaryReader bs = new BinaryReader( gs ); - return (bs.ReadByte() == 0xbe && bs.ReadByte() == 0xee && bs.ReadByte() == 0xef); + return ( bs.ReadByte() == 0xbe && bs.ReadByte() == 0xee && bs.ReadByte() == 0xef ); } } - } catch( Exception ) { + } catch ( Exception ) { return false; } } - public Map LoadHeader( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { // Setup a GZipStream to decompress and read the map file - using( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress, true ) ) { + using ( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress, true ) ) { return LoadHeaderInternal( gs ); } } } - - static Map LoadHeaderInternal( [NotNull] Stream stream ) { - if( stream == null ) throw new ArgumentNullException( "stream" ); + private static Map LoadHeaderInternal( [NotNull] Stream stream ) { + if ( stream == null ) + throw new ArgumentNullException( "stream" ); BinaryReader bs = new BinaryReader( stream ); // Read in the magic number - if( bs.ReadByte() != 0xbe || bs.ReadByte() != 0xee || bs.ReadByte() != 0xef ) { + if ( bs.ReadByte() != 0xbe || bs.ReadByte() != 0xee || bs.ReadByte() != 0xef ) { throw new MapFormatException( "MinerCPP map header is incorrect." ); } @@ -92,16 +91,15 @@ static Map LoadHeaderInternal( [NotNull] Stream stream ) { return map; } - public Map Load( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { // Setup a GZipStream to decompress and read the map file - using( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress, true ) ) { - + using ( GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress, true ) ) { Map map = LoadHeaderInternal( gs ); - if( !map.ValidateHeader() ) { + if ( !map.ValidateHeader() ) { throw new MapFormatException( "One or more of the map dimensions are invalid." ); } @@ -114,12 +112,13 @@ public Map Load( [NotNull] string fileName ) { } } - public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { - if( mapToSave == null ) throw new ArgumentNullException( "mapToSave" ); - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.Create( fileName ) ) { - using( GZipStream gs = new GZipStream( mapStream, CompressionMode.Compress ) ) { + if ( mapToSave == null ) + throw new ArgumentNullException( "mapToSave" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.Create( fileName ) ) { + using ( GZipStream gs = new GZipStream( mapStream, CompressionMode.Compress ) ) { BinaryWriter bs = new BinaryWriter( gs ); // Write out the magic number @@ -127,9 +126,9 @@ public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { // Save the map dimensions // XYZ(?) - bs.Write( (ushort)IPAddress.HostToNetworkOrder( (short)mapToSave.Width ) ); - bs.Write( (ushort)IPAddress.HostToNetworkOrder( (short)mapToSave.Height ) ); - bs.Write( (ushort)IPAddress.HostToNetworkOrder( (short)mapToSave.Length ) ); + bs.Write( ( ushort )IPAddress.HostToNetworkOrder( ( short )mapToSave.Width ) ); + bs.Write( ( ushort )IPAddress.HostToNetworkOrder( ( short )mapToSave.Height ) ); + bs.Write( ( ushort )IPAddress.HostToNetworkOrder( ( short )mapToSave.Length ) ); // Save the spawn location bs.Write( IPAddress.HostToNetworkOrder( mapToSave.Spawn.X ) ); diff --git a/fCraft/MapConversion/MapMyne.cs b/fCraft/MapConversion/MapMyne.cs index acf3756..852d3f6 100644 --- a/fCraft/MapConversion/MapMyne.cs +++ b/fCraft/MapConversion/MapMyne.cs @@ -6,74 +6,70 @@ using JetBrains.Annotations; namespace fCraft.MapConversion { - public sealed class MapMyne : IMapConverter { - - const string BlockStoreFileName = "blocks.gz"; - const string MetaDataFileName = "world.meta"; + public sealed class MapMyne : IMapConverter { + private const string BlockStoreFileName = "blocks.gz"; + private const string MetaDataFileName = "world.meta"; public string ServerName { get { return "Myne/MyneCraft/HyveBuild/iCraft"; } } - public MapStorageType StorageType { get { return MapStorageType.Directory; } } - public MapFormat Format { get { return MapFormat.Myne; } } - public bool ClaimsName( [NotNull] string path ) { - if( path == null ) throw new ArgumentNullException( "path" ); + if ( path == null ) + throw new ArgumentNullException( "path" ); return Directory.Exists( path ) && File.Exists( Path.Combine( path, BlockStoreFileName ) ) && File.Exists( Path.Combine( path, MetaDataFileName ) ); } - public bool Claims( [NotNull] string path ) { - if( path == null ) throw new ArgumentNullException( "path" ); + if ( path == null ) + throw new ArgumentNullException( "path" ); return ClaimsName( path ); } - public Map LoadHeader( [NotNull] string path ) { - if( path == null ) throw new ArgumentNullException( "path" ); + if ( path == null ) + throw new ArgumentNullException( "path" ); string fullMetaDataFileName = Path.Combine( path, MetaDataFileName ); Map map; - using( Stream metaStream = File.OpenRead( fullMetaDataFileName ) ) { + using ( Stream metaStream = File.OpenRead( fullMetaDataFileName ) ) { map = LoadMeta( metaStream ); } return map; } - public Map Load( [NotNull] string path ) { - if( path == null ) throw new ArgumentNullException( "path" ); + if ( path == null ) + throw new ArgumentNullException( "path" ); string fullBlockStoreFileName = Path.Combine( path, BlockStoreFileName ); string fullMetaDataFileName = Path.Combine( path, MetaDataFileName ); - if( !File.Exists( fullBlockStoreFileName ) || !File.Exists( fullMetaDataFileName ) ) { + if ( !File.Exists( fullBlockStoreFileName ) || !File.Exists( fullMetaDataFileName ) ) { throw new FileNotFoundException( "When loading myne maps, both .gz and .meta files are required." ); } Map map; - using( Stream metaStream = File.OpenRead( fullMetaDataFileName ) ) { + using ( Stream metaStream = File.OpenRead( fullMetaDataFileName ) ) { map = LoadMeta( metaStream ); } - using( Stream dataStream = File.OpenRead( fullBlockStoreFileName ) ) { + using ( Stream dataStream = File.OpenRead( fullBlockStoreFileName ) ) { LoadBlocks( map, dataStream ); } return map; } - - static void LoadBlocks( [NotNull] Map map, [NotNull] Stream mapStream ) { + private static void LoadBlocks( [NotNull] Map map, [NotNull] Stream mapStream ) { mapStream.Seek( 0, SeekOrigin.Begin ); // Setup a GZipStream to decompress and read the map file @@ -81,7 +77,7 @@ static void LoadBlocks( [NotNull] Map map, [NotNull] Stream mapStream ) { BinaryReader bs = new BinaryReader( gs ); int blockCount = IPAddress.HostToNetworkOrder( bs.ReadInt32() ); - if( blockCount != map.Volume ) { + if ( blockCount != map.Volume ) { throw new Exception( "Map dimensions in the metadata do not match dimensions of the block array." ); } @@ -90,14 +86,14 @@ static void LoadBlocks( [NotNull] Map map, [NotNull] Stream mapStream ) { map.RemoveUnknownBlocktypes(); } - - static Map LoadMeta( [NotNull] Stream stream ) { - if( stream == null ) throw new ArgumentNullException( "stream" ); + private static Map LoadMeta( [NotNull] Stream stream ) { + if ( stream == null ) + throw new ArgumentNullException( "stream" ); INIFile metaFile = new INIFile( stream ); - if( metaFile.IsEmpty ) { + if ( metaFile.IsEmpty ) { throw new Exception( "Metadata file is empty or incorrectly formatted." ); } - if( !metaFile.Contains( "size", "x", "y", "z" ) ) { + if ( !metaFile.Contains( "size", "x", "y", "z" ) ) { throw new Exception( "Metadata file is missing map dimensions." ); } @@ -107,15 +103,15 @@ static Map LoadMeta( [NotNull] Stream stream ) { Map map = new Map( null, width, length, height, false ); - if( !map.ValidateHeader() ) { + if ( !map.ValidateHeader() ) { throw new MapFormatException( "One or more of the map dimensions are invalid." ); } - if( metaFile.Contains( "spawn", "x", "y", "z", "h" ) ) { + if ( metaFile.Contains( "spawn", "x", "y", "z", "h" ) ) { map.Spawn = new Position { - X = (short)(Int16.Parse( metaFile["spawn", "x"] ) * 32 + 16), - Y = (short)(Int16.Parse( metaFile["spawn", "z"] ) * 32 + 16), - Z = (short)(Int16.Parse( metaFile["spawn", "y"] ) * 32 + 16), + X = ( short )( Int16.Parse( metaFile["spawn", "x"] ) * 32 + 16 ), + Y = ( short )( Int16.Parse( metaFile["spawn", "z"] ) * 32 + 16 ), + Z = ( short )( Int16.Parse( metaFile["spawn", "y"] ) * 32 + 16 ), R = Byte.Parse( metaFile["spawn", "h"] ), L = 0 }; @@ -123,10 +119,11 @@ static Map LoadMeta( [NotNull] Stream stream ) { return map; } - public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { - if( mapToSave == null ) throw new ArgumentNullException( "mapToSave" ); - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( mapToSave == null ) + throw new ArgumentNullException( "mapToSave" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); throw new NotImplementedException(); } } diff --git a/fCraft/MapConversion/MapNBT.cs b/fCraft/MapConversion/MapNBT.cs index e2f40ce..b0e5988 100644 --- a/fCraft/MapConversion/MapNBT.cs +++ b/fCraft/MapConversion/MapNBT.cs @@ -5,58 +5,56 @@ using JetBrains.Annotations; namespace fCraft.MapConversion { + public sealed class MapNBT : IMapConverter { public string ServerName { get { return "InDev"; } } - public MapStorageType StorageType { get { return MapStorageType.SingleFile; } } - public MapFormat Format { get { return MapFormat.NBT; } } - public bool ClaimsName( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); return fileName.EndsWith( ".mclevel", StringComparison.OrdinalIgnoreCase ); } - public bool Claims( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); try { - using( FileStream mapStream = File.OpenRead( fileName ) ) { + using ( FileStream mapStream = File.OpenRead( fileName ) ) { GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress, true ); BinaryReader bs = new BinaryReader( gs ); - return (bs.ReadByte() == 10 && NBTag.ReadString( bs ) == "MinecraftLevel"); + return ( bs.ReadByte() == 10 && NBTag.ReadString( bs ) == "MinecraftLevel" ); } - } catch( Exception ) { + } catch ( Exception ) { return false; } } - public Map LoadHeader( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); Map map = Load( fileName ); map.Blocks = null; return map; } - public Map Load( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { GZipStream gs = new GZipStream( mapStream, CompressionMode.Decompress, true ); NBTag tag = NBTag.ReadStream( gs ); - NBTag mapTag = tag["Map"]; // ReSharper disable UseObjectOrCollectionInitializer Map map = new Map( null, @@ -73,7 +71,7 @@ public Map Load( [NotNull] string fileName ) { }; // ReSharper restore UseObjectOrCollectionInitializer - if( !map.ValidateHeader() ) { + if ( !map.ValidateHeader() ) { throw new MapFormatException( "One or more of the map dimensions are invalid." ); } @@ -84,10 +82,11 @@ public Map Load( [NotNull] string fileName ) { } } - public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { - if( mapToSave == null ) throw new ArgumentNullException( "mapToSave" ); - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( mapToSave == null ) + throw new ArgumentNullException( "mapToSave" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); throw new NotImplementedException(); } } diff --git a/fCraft/MapConversion/MapOpticraft.cs b/fCraft/MapConversion/MapOpticraft.cs index 078bd78..b59e863 100644 --- a/fCraft/MapConversion/MapOpticraft.cs +++ b/fCraft/MapConversion/MapOpticraft.cs @@ -7,74 +7,96 @@ using JetBrains.Annotations; namespace fCraft.MapConversion { + [DataContract] public sealed class OpticraftMetaData { + [DataMember] public int X { get; set; } + [DataMember] public int Y { get; set; } + [DataMember] public int Z { get; set; } + [DataMember] public int SpawnX { get; set; } + [DataMember] public int SpawnY { get; set; } + [DataMember] public int SpawnZ { get; set; } + [DataMember] public byte SpawnOrientation { get; set; } + [DataMember] public byte SpawnPitch { get; set; } + [DataMember] public string MinimumBuildRank { get; set; } + [DataMember] public string MinimumJoinRank { get; set; } + [DataMember] public bool Hidden { get; set; } + [DataMember] public int CreationDate { get; set; } } - public sealed class OpticraftDataStore { + [DataMember] public OpticraftZone[] Zones; - } - public sealed class OpticraftZone { + [DataMember] public string Name { get; set; } + [DataMember] public int X1 { get; set; } + [DataMember] public int X2 { get; set; } + [DataMember] public int Y1 { get; set; } + [DataMember] public int Y2 { get; set; } + [DataMember] public int Z1 { get; set; } + [DataMember] public int Z2 { get; set; } + [DataMember] public string MinimumRank { get; set; } + [DataMember] public string Owner { get; set; } + [DataMember] public string[] Builders; + [DataMember] public string[] Excluded; } - public sealed class MapOpticraft : IMapConverter { + public string ServerName { get { return "Opticraft"; } } - const short MapVersion = 2; + private const short MapVersion = 2; public MapFormat Format { get { return MapFormat.Opticraft; } @@ -84,36 +106,36 @@ public MapStorageType StorageType { get { return MapStorageType.SingleFile; } } - public bool ClaimsName( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); return fileName.EndsWith( ".save", StringComparison.Ordinal ); } - public bool Claims( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); try { - using( FileStream mapStream = File.OpenRead( fileName ) ) { + using ( FileStream mapStream = File.OpenRead( fileName ) ) { BinaryReader reader = new BinaryReader( mapStream ); return reader.ReadInt16() == MapVersion; } - } catch( Exception ) { + } catch ( Exception ) { return false; } } - public Map LoadHeader( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { return LoadMapMetadata( mapStream ); } } - - static Map LoadMapMetadata( [NotNull] Stream mapStream ) { - if( mapStream == null ) throw new ArgumentNullException( "mapStream" ); + private static Map LoadMapMetadata( [NotNull] Stream mapStream ) { + if ( mapStream == null ) + throw new ArgumentNullException( "mapStream" ); BinaryReader reader = new BinaryReader( mapStream ); reader.ReadInt16(); int metaDataSize = reader.ReadInt32(); @@ -123,24 +145,24 @@ static Map LoadMapMetadata( [NotNull] Stream mapStream ) { reader.Read( rawMetaData, 0, metaDataSize ); MemoryStream memStream = new MemoryStream( rawMetaData ); - OpticraftMetaData metaData = (OpticraftMetaData)serializer.ReadObject( memStream ); + OpticraftMetaData metaData = ( OpticraftMetaData )serializer.ReadObject( memStream ); // ReSharper disable UseObjectOrCollectionInitializer Map mapFile = new Map( null, metaData.X, metaData.Y, metaData.Z, false ); // ReSharper restore UseObjectOrCollectionInitializer mapFile.Spawn = new Position { - X = (short)(metaData.SpawnX), - Y = (short)(metaData.SpawnY), - Z = (short)(metaData.SpawnZ), + X = ( short )( metaData.SpawnX ), + Y = ( short )( metaData.SpawnY ), + Z = ( short )( metaData.SpawnZ ), R = metaData.SpawnOrientation, L = metaData.SpawnPitch }; return mapFile; } - public Map Load( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenRead( fileName ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenRead( fileName ) ) { BinaryReader reader = new BinaryReader( mapStream ); // Load MetaData Map mapFile = LoadMapMetadata( mapStream ); @@ -151,14 +173,14 @@ public Map Load( [NotNull] string fileName ) { reader.Read( jsonDataBlock, 0, dataBlockSize ); MemoryStream memStream = new MemoryStream( jsonDataBlock ); DataContractJsonSerializer serializer = new DataContractJsonSerializer( typeof( OpticraftDataStore ) ); - OpticraftDataStore dataStore = (OpticraftDataStore)serializer.ReadObject( memStream ); + OpticraftDataStore dataStore = ( OpticraftDataStore )serializer.ReadObject( memStream ); reader.ReadInt32(); // Load Zones LoadZones( mapFile, dataStore ); // Load the block store mapFile.Blocks = new Byte[mapFile.Volume]; - using( GZipStream decompressor = new GZipStream( mapStream, CompressionMode.Decompress ) ) { + using ( GZipStream decompressor = new GZipStream( mapStream, CompressionMode.Decompress ) ) { decompressor.Read( mapFile.Blocks, 0, mapFile.Blocks.Length ); } @@ -166,17 +188,18 @@ public Map Load( [NotNull] string fileName ) { } } - - static void LoadZones( [NotNull] Map mapFile, [NotNull] OpticraftDataStore dataStore ) { - if( mapFile == null ) throw new ArgumentNullException( "mapFile" ); - if( dataStore == null ) throw new ArgumentNullException( "dataStore" ); - if( dataStore.Zones.Length == 0 ) { + private static void LoadZones( [NotNull] Map mapFile, [NotNull] OpticraftDataStore dataStore ) { + if ( mapFile == null ) + throw new ArgumentNullException( "mapFile" ); + if ( dataStore == null ) + throw new ArgumentNullException( "dataStore" ); + if ( dataStore.Zones.Length == 0 ) { return; } // TODO: investigate side effects PlayerInfo conversionPlayer = new PlayerInfo( "OpticraftConversion", RankManager.HighestRank, true, RankChangeType.AutoPromoted ); - foreach( OpticraftZone optiZone in dataStore.Zones ) { + foreach ( OpticraftZone optiZone in dataStore.Zones ) { // Make zone Zone fZone = new Zone { Name = optiZone.Name, @@ -186,30 +209,30 @@ static void LoadZones( [NotNull] Map mapFile, [NotNull] OpticraftDataStore dataS // Min rank Rank minRank = Rank.Parse( optiZone.MinimumRank ); - if( minRank != null ) { + if ( minRank != null ) { fZone.Controller.MinRank = minRank; } - foreach( string playerName in optiZone.Builders ) { + foreach ( string playerName in optiZone.Builders ) { // These are all lower case names - if( !Player.IsValidName( playerName ) ) { + if ( !Player.IsValidName( playerName ) ) { continue; } PlayerInfo pInfo = PlayerDB.FindPlayerInfoExact( playerName ); - if( pInfo != null ) { + if ( pInfo != null ) { fZone.Controller.Include( pInfo ); } } // Excluded names are not as of yet implemented in opticraft, but will be soon // So add compatibility for them when they arrive. - if( optiZone.Excluded != null ) { - foreach( string playerName in optiZone.Excluded ) { + if ( optiZone.Excluded != null ) { + foreach ( string playerName in optiZone.Excluded ) { // These are all lower case names - if( !Player.IsValidName( playerName ) ) { + if ( !Player.IsValidName( playerName ) ) { continue; } PlayerInfo pInfo = PlayerDB.FindPlayerInfoExact( playerName ); - if( pInfo != null ) { + if ( pInfo != null ) { fZone.Controller.Exclude( pInfo ); } } @@ -218,11 +241,12 @@ static void LoadZones( [NotNull] Map mapFile, [NotNull] OpticraftDataStore dataS } } - public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { - if( mapToSave == null ) throw new ArgumentNullException( "mapToSave" ); - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream mapStream = File.OpenWrite( fileName ) ) { + if ( mapToSave == null ) + throw new ArgumentNullException( "mapToSave" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream mapStream = File.OpenWrite( fileName ) ) { BinaryWriter writer = new BinaryWriter( mapStream ); // Version writer.Write( MapVersion ); @@ -242,7 +266,7 @@ public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { SpawnPitch = mapToSave.Spawn.L }; // World related values. - if( mapToSave.World != null ) { + if ( mapToSave.World != null ) { oMetadate.Hidden = mapToSave.World.IsHidden; oMetadate.MinimumJoinRank = mapToSave.World.AccessSecurity.MinRank.Name; oMetadate.MinimumBuildRank = mapToSave.World.BuildSecurity.MinRank.Name; @@ -263,7 +287,7 @@ public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { Zones = new OpticraftZone[zoneCache.Length] }; int i = 0; - foreach( Zone zone in zoneCache ) { + foreach ( Zone zone in zoneCache ) { OpticraftZone oZone = new OpticraftZone { Name = zone.Name, MinimumRank = zone.Controller.MinRank.Name, @@ -281,14 +305,14 @@ public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { // Builders int j = 0; - foreach( PlayerInfo pInfo in zone.Controller.ExceptionList.Included ) { + foreach ( PlayerInfo pInfo in zone.Controller.ExceptionList.Included ) { oZone.Builders[j++] = pInfo.Name; } // Excluded players oZone.Excluded = new string[zone.Controller.ExceptionList.Excluded.Length]; j = 0; - foreach( PlayerInfo pInfo in zone.Controller.ExceptionList.Excluded ) { + foreach ( PlayerInfo pInfo in zone.Controller.ExceptionList.Excluded ) { oZone.Builders[j++] = pInfo.Name; } oDataStore.Zones[i++] = oZone; @@ -301,16 +325,14 @@ public bool Save( [NotNull] Map mapToSave, [NotNull] string fileName ) { writer.Write( jsonDataStore.Length ); writer.Write( jsonDataStore ); - // Blocks MemoryStream blockStream = new MemoryStream(); - using( GZipStream zipper = new GZipStream( blockStream, CompressionMode.Compress, true ) ) { + using ( GZipStream zipper = new GZipStream( blockStream, CompressionMode.Compress, true ) ) { zipper.Write( mapToSave.Blocks, 0, mapToSave.Blocks.Length ); } byte[] compressedBlocks = blockStream.ToArray(); writer.Write( compressedBlocks.Length ); writer.Write( compressedBlocks ); - } return true; } diff --git a/fCraft/MapConversion/MapUtility.cs b/fCraft/MapConversion/MapUtility.cs index 10029c7..7bcc552 100644 --- a/fCraft/MapConversion/MapUtility.cs +++ b/fCraft/MapConversion/MapUtility.cs @@ -7,11 +7,9 @@ namespace fCraft.MapConversion { public static class MapUtility { + private static readonly Dictionary AvailableConverters = new Dictionary(); - static readonly Dictionary AvailableConverters = new Dictionary(); - - - static MapUtility () { + static MapUtility() { AvailableConverters.Add( MapFormat.FCMv4, new MapFCMv4() ); AvailableConverters.Add( MapFormat.FCMv3, new MapFCMv3() .AddExtension( new ZoneConverterExtension() ) @@ -30,10 +28,10 @@ static MapUtility () { AvailableConverters.Add( MapFormat.Opticraft, new MapOpticraft() ); } - // ReSharper disable EmptyGeneralCatchClause - public static MapFormat Identify ( [NotNull] string fileName, bool tryFallbackConverters ) { - if ( fileName == null ) throw new ArgumentNullException( "fileName" ); + public static MapFormat Identify( [NotNull] string fileName, bool tryFallbackConverters ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); MapStorageType targetType = MapStorageType.SingleFile; if ( !File.Exists( fileName ) ) { if ( Directory.Exists( fileName ) ) { @@ -68,11 +66,12 @@ public static MapFormat Identify ( [NotNull] string fileName, bool tryFallbackCo return MapFormat.Unknown; } - // ReSharper restore EmptyGeneralCatchClause + // ReSharper restore EmptyGeneralCatchClause - public static bool TryLoadHeader ( [NotNull] string fileName, out Map map ) { - if ( fileName == null ) throw new ArgumentNullException( "fileName" ); + public static bool TryLoadHeader( [NotNull] string fileName, out Map map ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); try { map = LoadHeader( fileName ); return true; @@ -85,10 +84,10 @@ public static bool TryLoadHeader ( [NotNull] string fileName, out Map map ) { } } - - public static Map LoadHeader ( [NotNull] string fileName ) { + public static Map LoadHeader( [NotNull] string fileName ) { // ReSharper disable EmptyGeneralCatchClause - if ( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); MapStorageType targetType = MapStorageType.SingleFile; if ( !File.Exists( fileName ) ) { @@ -132,9 +131,9 @@ public static Map LoadHeader ( [NotNull] string fileName ) { // ReSharper restore EmptyGeneralCatchClause } - - public static bool TryLoad ( [NotNull] string fileName, out Map map ) { - if ( fileName == null ) throw new ArgumentNullException( "fileName" ); + public static bool TryLoad( [NotNull] string fileName, out Map map ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); try { map = Load( fileName ); return true; @@ -146,10 +145,10 @@ public static bool TryLoad ( [NotNull] string fileName, out Map map ) { } } - // ReSharper disable EmptyGeneralCatchClause - public static Map Load ( [NotNull] string fileName ) { - if ( fileName == null ) throw new ArgumentNullException( "fileName" ); + public static Map Load( [NotNull] string fileName ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); MapStorageType targetType = MapStorageType.SingleFile; if ( !File.Exists( fileName ) ) { if ( Directory.Exists( fileName ) ) { @@ -188,13 +187,16 @@ public static Map Load ( [NotNull] string fileName ) { throw new MapFormatException( "Unknown map format." ); } - // ReSharper restore EmptyGeneralCatchClause + // ReSharper restore EmptyGeneralCatchClause - public static bool TrySave ( [NotNull] Map mapToSave, [NotNull] string fileName, MapFormat format ) { - if ( mapToSave == null ) throw new ArgumentNullException( "mapToSave" ); - if ( fileName == null ) throw new ArgumentNullException( "fileName" ); - if ( format == MapFormat.Unknown ) throw new ArgumentException( "Format may not be \"Unknown\"", "format" ); + public static bool TrySave( [NotNull] Map mapToSave, [NotNull] string fileName, MapFormat format ) { + if ( mapToSave == null ) + throw new ArgumentNullException( "mapToSave" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + if ( format == MapFormat.Unknown ) + throw new ArgumentException( "Format may not be \"Unknown\"", "format" ); if ( AvailableConverters.ContainsKey( format ) ) { IMapConverter converter = AvailableConverters[format]; @@ -209,15 +211,17 @@ public static bool TrySave ( [NotNull] Map mapToSave, [NotNull] string fileName, throw new MapFormatException( "Unknown map format for saving." ); } - - internal static void ReadAll ( [NotNull] Stream source, [NotNull] byte[] destination ) { - if ( source == null ) throw new ArgumentNullException( "source" ); - if ( destination == null ) throw new ArgumentNullException( "destination" ); + internal static void ReadAll( [NotNull] Stream source, [NotNull] byte[] destination ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( destination == null ) + throw new ArgumentNullException( "destination" ); int bytesRead = 0; int bytesLeft = destination.Length; while ( bytesLeft > 0 ) { int readPass = source.Read( destination, bytesRead, bytesLeft ); - if ( readPass == 0 ) throw new EndOfStreamException(); + if ( readPass == 0 ) + throw new EndOfStreamException(); bytesRead += readPass; bytesLeft -= readPass; } diff --git a/fCraft/MapConversion/NBTag.cs b/fCraft/MapConversion/NBTag.cs index 22336ec..d4b727a 100644 --- a/fCraft/MapConversion/NBTag.cs +++ b/fCraft/MapConversion/NBTag.cs @@ -10,6 +10,7 @@ // ReSharper disable UnusedMember.Global namespace fCraft.MapConversion { + /// Standard NBT data types. public enum NBTType : byte { End, @@ -25,21 +26,25 @@ public enum NBTType : byte { Compound } - public class NBTag : IEnumerable { + // ReSharper disable MemberCanBeProtected.Global public NBTType Type { get; protected set; } + public string Name { get; set; } + public object Payload { get; set; } + public NBTag Parent { get; set; } - // ReSharper restore MemberCanBeProtected.Global + // ReSharper restore MemberCanBeProtected.Global #region Constructors - protected NBTag() { } + protected NBTag() { + } - NBTag( NBTType type, NBTag parent ) { + private NBTag( NBTType type, NBTag parent ) { Type = type; Parent = parent; } @@ -51,82 +56,92 @@ public NBTag( NBTType type, string name, object payload, NBTag parent ) { Payload = payload; Parent = parent; } - // ReSharper restore MemberCanBeProtected.Global - #endregion + // ReSharper restore MemberCanBeProtected.Global + #endregion Constructors #region Shorthand Contructors [CanBeNull] public NBTag Append( NBTag tag ) { - if( !(this is NBTCompound) ) { + if ( !( this is NBTCompound ) ) { return null; } tag.Parent = this; - (this)[tag.Name] = tag; + ( this )[tag.Name] = tag; return tag; } - public NBTag Append( string name, byte value ) { return Append( new NBTag( NBTType.Byte, name, value, this ) ); } + public NBTag Append( string name, short value ) { return Append( new NBTag( NBTType.Short, name, value, this ) ); } + public NBTag Append( string name, int value ) { return Append( new NBTag( NBTType.Int, name, value, this ) ); } + public NBTag Append( string name, long value ) { return Append( new NBTag( NBTType.Long, name, value, this ) ); } + public NBTag Append( string name, float value ) { return Append( new NBTag( NBTType.Float, name, value, this ) ); } + public NBTag Append( string name, double value ) { return Append( new NBTag( NBTType.Double, name, value, this ) ); } + public NBTag Append( string name, byte[] value ) { return Append( new NBTag( NBTType.Bytes, name, value, this ) ); } + public NBTag Append( string name, [NotNull] string value ) { - if( value == null ) throw new ArgumentNullException( "value" ); + if ( value == null ) + throw new ArgumentNullException( "value" ); return Append( new NBTag( NBTType.String, name, value, this ) ); } + public NBTag Append( string name, params NBTag[] tags ) { NBTCompound compound = new NBTCompound { Name = name }; - foreach( NBTag tag in tags ) { + foreach ( NBTag tag in tags ) { compound.Tags.Add( tag.Name, tag ); } return Append( compound ); } + public NBTag Append( params NBTag[] tags ) { - foreach( NBTag tag in tags ) { + foreach ( NBTag tag in tags ) { Append( tag ); } return this; } - #endregion - + #endregion Shorthand Contructors #region Child Tag Manipulation public bool Contains( [NotNull] string name ) { - if( name == null ) throw new ArgumentNullException( "name" ); - if( this is NBTCompound ) { - return ((NBTCompound)this).Tags.ContainsKey( name ); + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( this is NBTCompound ) { + return ( ( NBTCompound )this ).Tags.ContainsKey( name ); } else { return false; } } public NBTag Remove( [NotNull] string name ) { - if( name == null ) throw new ArgumentNullException( "name" ); - if( this is NBTCompound ) { - NBTag tag = (this)[name]; - ((NBTCompound)this).Tags.Remove( name ); + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( this is NBTCompound ) { + NBTag tag = ( this )[name]; + ( ( NBTCompound )this ).Tags.Remove( name ); return tag; } else { throw new NotSupportedException( "Can only Remove() from compound tags." ); @@ -134,7 +149,7 @@ public NBTag Remove( [NotNull] string name ) { } public NBTag Remove() { - if( Parent != null && Parent is NBTCompound ) { + if ( Parent != null && Parent is NBTCompound ) { Parent.Remove( Name ); return this; } else { @@ -142,32 +157,34 @@ public NBTag Remove() { } } - #endregion - + #endregion Child Tag Manipulation #region Loading public static NBTCompound ReadFile( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream fs = File.OpenRead( fileName ) ) { - using( GZipStream gs = new GZipStream( fs, CompressionMode.Decompress ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream fs = File.OpenRead( fileName ) ) { + using ( GZipStream gs = new GZipStream( fs, CompressionMode.Decompress ) ) { return ReadStream( gs ); } } } public static NBTCompound ReadStream( [NotNull] Stream stream ) { - if( stream == null ) throw new ArgumentNullException( "stream" ); + if ( stream == null ) + throw new ArgumentNullException( "stream" ); BinaryReader reader = new BinaryReader( stream ); - return (NBTCompound)ReadTag( reader, (NBTType)reader.ReadByte(), null, null ); + return ( NBTCompound )ReadTag( reader, ( NBTType )reader.ReadByte(), null, null ); } public static NBTag ReadTag( [NotNull] BinaryReader reader, NBTType type, string name, NBTag parent ) { - if( reader == null ) throw new ArgumentNullException( "reader" ); - if( name == null && type != NBTType.End ) { + if ( reader == null ) + throw new ArgumentNullException( "reader" ); + if ( name == null && type != NBTType.End ) { name = ReadString( reader ); } - switch( type ) { + switch ( type ) { case NBTType.End: return new NBTag( NBTType.End, parent ); @@ -196,17 +213,16 @@ public static NBTag ReadTag( [NotNull] BinaryReader reader, NBTType type, string case NBTType.String: return new NBTag( NBTType.String, name, ReadString( reader ), parent ); - case NBTType.List: NBTList list = new NBTList { Type = NBTType.List, Name = name, Parent = parent, - ListType = (NBTType)reader.ReadByte() + ListType = ( NBTType )reader.ReadByte() }; int listLength = IPAddress.NetworkToHostOrder( reader.ReadInt32() ); list.Tags = new NBTag[listLength]; - for( int i = 0; i < listLength; i++ ) { + for ( int i = 0; i < listLength; i++ ) { list.Tags[i] = ReadTag( reader, list.ListType, "", list ); } return list; @@ -218,12 +234,13 @@ public static NBTag ReadTag( [NotNull] BinaryReader reader, NBTType type, string Name = name, Parent = parent }; - while( true ) { - childTag = ReadTag( reader, (NBTType)reader.ReadByte(), null, compound ); - if( childTag.Type == NBTType.End ) break; - if( childTag.Name == null ) + while ( true ) { + childTag = ReadTag( reader, ( NBTType )reader.ReadByte(), null, compound ); + if ( childTag.Type == NBTType.End ) + break; + if ( childTag.Name == null ) continue; - if( compound.Tags.ContainsKey( childTag.Name ) ) { + if ( compound.Tags.ContainsKey( childTag.Name ) ) { throw new IOException( "NBT parsing error: null names and duplicate names are not allowed within a compound tags." ); } else { compound.Tags.Add( childTag.Name, childTag ); @@ -237,7 +254,8 @@ public static NBTag ReadTag( [NotNull] BinaryReader reader, NBTType type, string } public static string ReadString( [NotNull] BinaryReader reader ) { - if( reader == null ) throw new ArgumentNullException( "reader" ); + if ( reader == null ) + throw new ArgumentNullException( "reader" ); short stringLength = IPAddress.NetworkToHostOrder( reader.ReadInt16() ); return Encoding.UTF8.GetString( reader.ReadBytes( stringLength ) ); } @@ -246,7 +264,7 @@ public string FullName { get { string fullName = ToString(); NBTag tag = this; - while( tag.Parent != null ) { + while ( tag.Parent != null ) { tag = tag.Parent; fullName = tag + "." + fullName; } @@ -258,7 +276,7 @@ public string IndentedName { get { string fullName = ToString(); NBTag tag = this; - while( tag.Parent != null ) { + while ( tag.Parent != null ) { tag = tag.Parent; fullName = " " + fullName; } @@ -271,96 +289,102 @@ public override string ToString() { } public string ToString( bool recursive ) { - if( !recursive ) return ToString(); + if ( !recursive ) + return ToString(); StringBuilder sb = new StringBuilder( IndentedName ); sb.AppendLine(); - foreach( NBTag tag in this ) { + foreach ( NBTag tag in this ) { sb.Append( tag.ToString( true ) ); } return sb.ToString(); } - #endregion - + #endregion Loading #region Saving public void WriteTag( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - using( FileStream fs = File.OpenWrite( fileName ) ) { - using( GZipStream gs = new GZipStream( fs, CompressionMode.Compress ) ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + using ( FileStream fs = File.OpenWrite( fileName ) ) { + using ( GZipStream gs = new GZipStream( fs, CompressionMode.Compress ) ) { WriteTag( gs ); } } } public void WriteTag( [NotNull] Stream stream ) { - if( stream == null ) throw new ArgumentNullException( "stream" ); - using( BinaryWriter writer = new BinaryWriter( stream ) ) { + if ( stream == null ) + throw new ArgumentNullException( "stream" ); + using ( BinaryWriter writer = new BinaryWriter( stream ) ) { WriteTag( writer, true ); } } public void WriteTag( [NotNull] BinaryWriter writer ) { - if( writer == null ) throw new ArgumentNullException( "writer" ); + if ( writer == null ) + throw new ArgumentNullException( "writer" ); WriteTag( writer, true ); } public void WriteTag( [NotNull] BinaryWriter writer, bool writeType ) { - if( writer == null ) throw new ArgumentNullException( "writer" ); - if( writeType ) writer.Write( (byte)Type ); - if( Type == NBTType.End ) return; - if( writeType ) WriteString( Name, writer ); - switch( Type ) { + if ( writer == null ) + throw new ArgumentNullException( "writer" ); + if ( writeType ) + writer.Write( ( byte )Type ); + if ( Type == NBTType.End ) + return; + if ( writeType ) + WriteString( Name, writer ); + switch ( Type ) { case NBTType.Byte: - writer.Write( (byte)Payload ); + writer.Write( ( byte )Payload ); return; case NBTType.Short: - writer.Write( IPAddress.HostToNetworkOrder( (short)Payload ) ); + writer.Write( IPAddress.HostToNetworkOrder( ( short )Payload ) ); return; case NBTType.Int: - writer.Write( IPAddress.HostToNetworkOrder( (int)Payload ) ); + writer.Write( IPAddress.HostToNetworkOrder( ( int )Payload ) ); return; case NBTType.Long: - writer.Write( IPAddress.HostToNetworkOrder( (long)Payload ) ); + writer.Write( IPAddress.HostToNetworkOrder( ( long )Payload ) ); return; case NBTType.Float: - writer.Write( (float)Payload ); + writer.Write( ( float )Payload ); return; case NBTType.Double: - writer.Write( (double)Payload ); + writer.Write( ( double )Payload ); return; case NBTType.Bytes: - writer.Write( IPAddress.HostToNetworkOrder( ((byte[])Payload).Length ) ); - writer.Write( (byte[])Payload ); + writer.Write( IPAddress.HostToNetworkOrder( ( ( byte[] )Payload ).Length ) ); + writer.Write( ( byte[] )Payload ); return; case NBTType.String: - WriteString( (string)Payload, writer ); + WriteString( ( string )Payload, writer ); return; - case NBTType.List: - NBTList list = (NBTList)this; - writer.Write( (byte)list.ListType ); + NBTList list = ( NBTList )this; + writer.Write( ( byte )list.ListType ); writer.Write( IPAddress.HostToNetworkOrder( list.Tags.Length ) ); - for( int i = 0; i < list.Tags.Length; i++ ) { + for ( int i = 0; i < list.Tags.Length; i++ ) { list.Tags[i].WriteTag( writer, false ); } return; case NBTType.Compound: - foreach( NBTag tag in this ) { + foreach ( NBTag tag in this ) { tag.WriteTag( writer ); } - writer.Write( (byte)NBTType.End ); + writer.Write( ( byte )NBTType.End ); return; default: @@ -368,60 +392,107 @@ public void WriteTag( [NotNull] BinaryWriter writer, bool writeType ) { } } - static void WriteString( [NotNull] string str, [NotNull] BinaryWriter writer ) { - if( str == null ) throw new ArgumentNullException( "str" ); - if( writer == null ) throw new ArgumentNullException( "writer" ); + private static void WriteString( [NotNull] string str, [NotNull] BinaryWriter writer ) { + if ( str == null ) + throw new ArgumentNullException( "str" ); + if ( writer == null ) + throw new ArgumentNullException( "writer" ); byte[] stringBytes = Encoding.UTF8.GetBytes( str ); - writer.Write( IPAddress.NetworkToHostOrder( (short)stringBytes.Length ) ); + writer.Write( IPAddress.NetworkToHostOrder( ( short )stringBytes.Length ) ); writer.Write( stringBytes ); } - #endregion - + #endregion Saving #region Accessors - public void Set( object payload ) { Payload = payload; } + public void Set( object payload ) { + Payload = payload; + } + + public byte GetByte() { + return ( byte )Payload; + } + + public short GetShort() { + return ( short )Payload; + } + + public int GetInt() { + return ( int )Payload; + } - public byte GetByte() { return (byte)Payload; } - public short GetShort() { return (short)Payload; } - public int GetInt() { return (int)Payload; } - public long GetLong() { return (long)Payload; } - public float GetFloat() { return (float)Payload; } - public double GetDouble() { return (double)Payload; } - public byte[] GetBytes() { return (byte[])Payload; } - public string GetString() { return (string)Payload; } + public long GetLong() { + return ( long )Payload; + } + public float GetFloat() { + return ( float )Payload; + } + + public double GetDouble() { + return ( double )Payload; + } + + public byte[] GetBytes() { + return ( byte[] )Payload; + } + + public string GetString() { + return ( string )Payload; + } - object GetChild( string name, object defaultValue ) { + private object GetChild( string name, object defaultValue ) { return Contains( name ) ? this[name].Payload : defaultValue; } - public byte Get( string name, byte defaultValue ) { return (byte)GetChild( name, defaultValue ); } - public short Get( string name, short defaultValue ) { return (short)GetChild( name, defaultValue ); } - public int Get( string name, int defaultValue ) { return (int)GetChild( name, defaultValue ); } - public long Get( string name, long defaultValue ) { return (long)GetChild( name, defaultValue ); } - public float Get( string name, float defaultValue ) { return (float)GetChild( name, defaultValue ); } - public double Get( string name, double defaultValue ) { return (double)GetChild( name, defaultValue ); } - public byte[] Get( string name, byte[] defaultValue ) { return (byte[])GetChild( name, defaultValue ); } - public string Get( string name, string defaultValue ) { return (string)GetChild( name, defaultValue ); } + public byte Get( string name, byte defaultValue ) { + return ( byte )GetChild( name, defaultValue ); + } + + public short Get( string name, short defaultValue ) { + return ( short )GetChild( name, defaultValue ); + } + + public int Get( string name, int defaultValue ) { + return ( int )GetChild( name, defaultValue ); + } + + public long Get( string name, long defaultValue ) { + return ( long )GetChild( name, defaultValue ); + } + + public float Get( string name, float defaultValue ) { + return ( float )GetChild( name, defaultValue ); + } - #endregion + public double Get( string name, double defaultValue ) { + return ( double )GetChild( name, defaultValue ); + } + public byte[] Get( string name, byte[] defaultValue ) { + return ( byte[] )GetChild( name, defaultValue ); + } + + public string Get( string name, string defaultValue ) { + return ( string )GetChild( name, defaultValue ); + } + + #endregion Accessors #region Indexers public NBTag this[int index] { get { - if( this is NBTList ) { - return ((NBTList)this).Tags[index]; + if ( this is NBTList ) { + return ( ( NBTList )this ).Tags[index]; } else { throw new NotSupportedException(); } } set { - if( this is NBTList ) { - ((NBTList)this).Tags[index] = value; + if ( this is NBTList ) { + ( ( NBTList )this ).Tags[index] = value; } else { throw new NotSupportedException(); } @@ -430,23 +501,22 @@ public NBTag this[int index] { public NBTag this[string key] { get { - if( this is NBTCompound ) { - return ((NBTCompound)this).Tags[key]; + if ( this is NBTCompound ) { + return ( ( NBTCompound )this ).Tags[key]; } else { throw new NotSupportedException(); } } set { - if( this is NBTCompound ) { - ((NBTCompound)this).Tags[key] = value; + if ( this is NBTCompound ) { + ( ( NBTCompound )this ).Tags[key] = value; } else { throw new NotSupportedException(); } } } - #endregion - + #endregion Indexers #region Enumerators @@ -459,15 +529,15 @@ IEnumerator IEnumerable.GetEnumerator() { } public sealed class NBTEnumerator : IEnumerator { - readonly NBTag[] tags; - int index = -1; + private readonly NBTag[] tags; + private int index = -1; public NBTEnumerator( NBTag tag ) { - if( tag is NBTCompound ) { - tags = new NBTag[((NBTCompound)tag).Tags.Count]; - ((NBTCompound)tag).Tags.Values.CopyTo( tags, 0 ); - } else if( tag is NBTList ) { - tags = ((NBTList)tag).Tags; + if ( tag is NBTCompound ) { + tags = new NBTag[( ( NBTCompound )tag ).Tags.Count]; + ( ( NBTCompound )tag ).Tags.Values.CopyTo( tags, 0 ); + } else if ( tag is NBTList ) { + tags = ( ( NBTList )tag ).Tags; } else { tags = new NBTag[0]; } @@ -486,7 +556,8 @@ object IEnumerator.Current { } public bool MoveNext() { - if( index < tags.Length ) index++; + if ( index < tags.Length ) + index++; return index < tags.Length; } @@ -494,46 +565,52 @@ public void Reset() { index = -1; } - public void Dispose() { } + public void Dispose() { + } } - #endregion + #endregion Enumerators } - public sealed class NBTList : NBTag { + public NBTList() { Type = NBTType.List; } + public NBTList( string name, NBTType type, int count ) { Name = name; Type = NBTType.List; ListType = type; Tags = new NBTag[count]; } + public NBTList( string name, NBTType type, List payloads ) { Name = name; Type = NBTType.List; ListType = type; Tags = new NBTag[payloads.Count]; int i = 0; - foreach( object payload in payloads ) { + foreach ( object payload in payloads ) { Tags[i++] = new NBTag( ListType, null, payload, this ); } } + public NBTag[] Tags; public NBTType ListType; } - public sealed class NBTCompound : NBTag { + public NBTCompound() { Type = NBTType.Compound; } + public NBTCompound( string name ) { Name = name; Type = NBTType.Compound; } + public readonly Dictionary Tags = new Dictionary(); } } \ No newline at end of file diff --git a/fCraft/MessageBlocks/MessageBlock.cs b/fCraft/MessageBlocks/MessageBlock.cs index 304a79c..779958c 100644 --- a/fCraft/MessageBlocks/MessageBlock.cs +++ b/fCraft/MessageBlocks/MessageBlock.cs @@ -24,29 +24,33 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft.Drawing; -using System.Threading; using System.Runtime.Serialization; namespace fCraft { + public class MessageBlock { + public String Name { get; set; } + public String Creator { get; set; } + public DateTime Created { get; set; } + public String World { get; set; } + public Vector3I AffectedBlock { get; set; } + public MessageBlockRange Range { get; set; } + public String Message { get; set; } - public MessageBlock () { + public MessageBlock() { //empty } - public MessageBlock ( String world, Vector3I affectedBlock, String Name, String Creator, String Message ) { + public MessageBlock( String world, Vector3I affectedBlock, String Name, String Creator, String Message ) { this.World = world; this.AffectedBlock = affectedBlock; this.Range = MessageBlock.CalculateRange( this ); @@ -56,7 +60,7 @@ public MessageBlock ( String world, Vector3I affectedBlock, String Name, String this.Message = Message; } - public static MessageBlockRange CalculateRange ( MessageBlock MessageBlock ) { + public static MessageBlockRange CalculateRange( MessageBlock MessageBlock ) { MessageBlockRange range = new MessageBlockRange( 0, 0, 0, 0, 0, 0 ); range.Xmin = MessageBlock.AffectedBlock.X; range.Xmax = MessageBlock.AffectedBlock.X; @@ -67,7 +71,7 @@ public static MessageBlockRange CalculateRange ( MessageBlock MessageBlock ) { return range; } - public bool IsInRange ( Player player ) { + public bool IsInRange( Player player ) { if ( ( player.Position.X / 32 ) <= Range.Xmax + 1 && ( player.Position.X / 32 ) >= Range.Xmin - 1 ) { if ( ( player.Position.Y / 32 ) <= Range.Ymax + 1 && ( player.Position.Y / 32 ) >= Range.Ymin - 1 ) { if ( ( ( player.Position.Z / 32 ) - 1 ) <= Range.Zmax + 1 && ( ( player.Position.Z / 32 ) - 1 ) >= Range.Zmin - 1 ) { @@ -79,7 +83,7 @@ public bool IsInRange ( Player player ) { return false; } - public bool IsInRange ( Vector3I vector ) { + public bool IsInRange( Vector3I vector ) { if ( vector.X <= Range.Xmax && vector.X >= Range.Xmin ) { if ( vector.Y <= Range.Ymax && vector.Y >= Range.Ymin ) { if ( vector.Z <= Range.Zmax && vector.Z >= Range.Zmin ) { @@ -91,15 +95,17 @@ public bool IsInRange ( Vector3I vector ) { return false; } - public String GetMessage () { - if ( this.Message == null ) return ""; - if ( this.Message.Length < 1 ) return ""; + public String GetMessage() { + if ( this.Message == null ) + return ""; + if ( this.Message.Length < 1 ) + return ""; string SortedMessage = Color.ReplacePercentCodes( Message ); SortedMessage = Chat.ReplaceEmoteKeywords( SortedMessage ); return String.Format( "MessageBlock: {0}{1}", Color.Green, SortedMessage ); } - public static String GenerateName ( World world ) { + public static String GenerateName( World world ) { if ( world.Map.MessageBlocks != null ) { if ( world.Map.MessageBlocks.Count > 0 ) { bool found = false; @@ -128,7 +134,7 @@ public static String GenerateName ( World world ) { return "MB1"; } - public static bool DoesNameExist ( World world, String name ) { + public static bool DoesNameExist( World world, String name ) { if ( world.Map.MessageBlocks != null ) { if ( world.Map.MessageBlocks.Count > 0 ) { foreach ( MessageBlock MessageBlock in world.Map.MessageBlocks ) { @@ -142,13 +148,13 @@ public static bool DoesNameExist ( World world, String name ) { return false; } - public void Remove ( Player requester ) { + public void Remove( Player requester ) { lock ( requester.World.Map.MessageBlocks.SyncRoot ) { requester.World.Map.MessageBlocks.Remove( this ); } } - public string Serialize () { + public string Serialize() { SerializedData data = new SerializedData( this ); DataContractSerializer serializer = new DataContractSerializer( typeof( SerializedData ) ); System.IO.MemoryStream s = new System.IO.MemoryStream(); @@ -156,7 +162,7 @@ public string Serialize () { return Convert.ToBase64String( s.ToArray() ); } - public static MessageBlock Deserialize ( string name, string sdata, Map map ) { + public static MessageBlock Deserialize( string name, string sdata, Map map ) { byte[] bdata = Convert.FromBase64String( sdata ); MessageBlock MessageBlock = new MessageBlock(); DataContractSerializer serializer = new DataContractSerializer( typeof( SerializedData ) ); @@ -166,38 +172,53 @@ public static MessageBlock Deserialize ( string name, string sdata, Map map ) { data.UpdateMessageBlock( MessageBlock ); return MessageBlock; } + [DataContract] private class SerializedData { + [DataMember] public String Name; + [DataMember] public String Creator; + [DataMember] public DateTime Created; + [DataMember] public String World; + [DataMember] public int AffectedBlockX; + [DataMember] public int AffectedBlockY; + [DataMember] public int AffectedBlockZ; + [DataMember] public int XMin; + [DataMember] public int XMax; + [DataMember] public int YMin; + [DataMember] public int YMax; + [DataMember] public int ZMin; + [DataMember] public int ZMax; + [DataMember] public String Message; - public SerializedData ( MessageBlock MessageBlock ) { + public SerializedData( MessageBlock MessageBlock ) { lock ( MessageBlock ) { Name = MessageBlock.Name; Creator = MessageBlock.Creator; @@ -216,15 +237,15 @@ public SerializedData ( MessageBlock MessageBlock ) { } } - public void UpdateMessageBlock ( MessageBlock MessageBlock ) { + public void UpdateMessageBlock( MessageBlock MessageBlock ) { MessageBlock.Name = Name; MessageBlock.Creator = Creator; MessageBlock.Created = Created; MessageBlock.World = World; - MessageBlock.AffectedBlock = new Vector3I(AffectedBlockX, AffectedBlockY, AffectedBlockZ); + MessageBlock.AffectedBlock = new Vector3I( AffectedBlockX, AffectedBlockY, AffectedBlockZ ); MessageBlock.Range = new MessageBlockRange( XMin, XMax, YMin, YMax, ZMin, ZMax ); MessageBlock.Message = Message; } } } -} +} \ No newline at end of file diff --git a/fCraft/MessageBlocks/MessageBlockHandler.cs b/fCraft/MessageBlocks/MessageBlockHandler.cs index 6946e65..37f0fa5 100644 --- a/fCraft/MessageBlocks/MessageBlockHandler.cs +++ b/fCraft/MessageBlocks/MessageBlockHandler.cs @@ -24,22 +24,20 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Collections; namespace fCraft { - class MessageBlockHandler { + internal class MessageBlockHandler { private static MessageBlockHandler instance; - private MessageBlockHandler () { + private MessageBlockHandler() { // Empty, singleton } - public static MessageBlockHandler GetInstance () { + public static MessageBlockHandler GetInstance() { if ( instance == null ) { instance = new MessageBlockHandler(); Player.Moved += new EventHandler( Player_Moved ); @@ -48,7 +46,7 @@ public static MessageBlockHandler GetInstance () { return instance; } - static void Player_PlacingBlock ( object sender, Events.PlayerPlacingBlockEventArgs e ) { + private static void Player_PlacingBlock( object sender, Events.PlayerPlacingBlockEventArgs e ) { Map map = e.Map; if ( e.Map.MessageBlocks != null ) { if ( e.Map.MessageBlocks.Count > 0 ) { @@ -59,7 +57,8 @@ static void Player_PlacingBlock ( object sender, Events.PlayerPlacingBlockEventA if ( e.Context == BlockChangeContext.Manual ) { if ( mb.IsInRange( e.Coords ) ) { string M = mb.GetMessage(); - if ( M == "" ) return; + if ( M == "" ) + return; if ( e.Player.LastUsedMessageBlock == null ) { e.Player.LastUsedMessageBlock = DateTime.UtcNow; e.Player.Message( M ); @@ -78,18 +77,21 @@ static void Player_PlacingBlock ( object sender, Events.PlayerPlacingBlockEventA } } - static void Player_Moved ( object sender, Events.PlayerMovedEventArgs e ) { + private static void Player_Moved( object sender, Events.PlayerMovedEventArgs e ) { try { if ( ( e.OldPosition.X != e.NewPosition.X ) || ( e.OldPosition.Y != e.NewPosition.Y ) || ( e.OldPosition.Z != ( e.NewPosition.Z ) ) ) { lock ( e.Player.MessageBlockLock ) { - if ( e.Player.WorldMap == null ) return; + if ( e.Player.WorldMap == null ) + return; if ( e.Player.WorldMap.MessageBlocks != null ) { lock ( e.Player.WorldMap.MessageBlocks ) { foreach ( MessageBlock mb in e.Player.WorldMap.MessageBlocks ) { - if ( e.Player.WorldMap == null ) return; + if ( e.Player.WorldMap == null ) + return; if ( mb.IsInRange( e.Player ) ) { string M = mb.GetMessage(); - if ( M == "" ) return; + if ( M == "" ) + return; if ( e.Player.LastUsedMessageBlock == null ) { e.Player.LastUsedMessageBlock = DateTime.UtcNow; e.Player.Message( M ); @@ -108,7 +110,7 @@ static void Player_Moved ( object sender, Events.PlayerMovedEventArgs e ) { } catch ( Exception ex ) { Logger.Log( LogType.Error, "MessageBlock_Moving: " + ex ); }; } - public static MessageBlock GetMessageBlock ( World world, Vector3I block ) { + public static MessageBlock GetMessageBlock( World world, Vector3I block ) { MessageBlock MessageBlock = null; try { if ( world.Map.MessageBlocks != null && world.Map.MessageBlocks.Count > 0 ) { @@ -127,7 +129,7 @@ public static MessageBlock GetMessageBlock ( World world, Vector3I block ) { return MessageBlock; } - public static void CreateMessageBlock ( MessageBlock MessageBlock, World source ) { + public static void CreateMessageBlock( MessageBlock MessageBlock, World source ) { World world = WorldManager.FindWorldExact( MessageBlock.World ); if ( source.Map.MessageBlocks == null ) { @@ -139,7 +141,7 @@ public static void CreateMessageBlock ( MessageBlock MessageBlock, World source } } - public static bool IsInRangeOfSpawnpoint ( World world, Vector3I block ) { + public static bool IsInRangeOfSpawnpoint( World world, Vector3I block ) { try { int Xdistance = ( world.Map.Spawn.X / 32 ) - block.X; int Ydistance = ( world.Map.Spawn.Y / 32 ) - block.Y; @@ -159,4 +161,4 @@ public static bool IsInRangeOfSpawnpoint ( World world, Vector3I block ) { return false; } } -} +} \ No newline at end of file diff --git a/fCraft/MessageBlocks/MessageBlockRange.cs b/fCraft/MessageBlocks/MessageBlockRange.cs index 3743734..a47ef11 100644 --- a/fCraft/MessageBlocks/MessageBlockRange.cs +++ b/fCraft/MessageBlocks/MessageBlockRange.cs @@ -26,24 +26,27 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ----*/ //Copyright (C) <2011 - 2013> Glenn Mariën (http://project-vanilla.com) -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; namespace fCraft { + /// /// Class used for rapid check if user is in range of MessageBlock /// public class MessageBlockRange { + public int Xmin { get; set; } + public int Xmax { get; set; } + public int Ymin { get; set; } + public int Ymax { get; set; } + public int Zmin { get; set; } + public int Zmax { get; set; } - public MessageBlockRange ( int Xmin, int Xmax, int Ymin, int Ymax, int Zmin, int Zmax ) { + public MessageBlockRange( int Xmin, int Xmax, int Ymin, int Ymax, int Zmin, int Zmax ) { this.Xmin = Xmin; this.Xmax = Xmax; this.Ymin = Ymin; @@ -52,4 +55,4 @@ public MessageBlockRange ( int Xmin, int Xmax, int Ymin, int Ymax, int Zmin, int this.Zmax = Zmax; } } -} +} \ No newline at end of file diff --git a/fCraft/MessageBlocks/MessageBlockSerialization.cs b/fCraft/MessageBlocks/MessageBlockSerialization.cs index 033101b..af139ae 100644 --- a/fCraft/MessageBlocks/MessageBlockSerialization.cs +++ b/fCraft/MessageBlocks/MessageBlockSerialization.cs @@ -27,22 +27,20 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) <2011 - 2013> Glenn Mariën (http://project-vanilla.com) using System; +using System.Collections; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; using System.IO; -using System.Collections; -using System.Runtime.Serialization; using fCraft.MapConversion; namespace fCraft { + public class MessageBlockSerialization : IConverterExtension { private static readonly object SaveLoadLock = new object(); private static List _group = new List { "mblock" }; + public IEnumerable AcceptedGroups { get { return _group; } } - public int Serialize ( Map map, Stream stream, IMapConverterEx converter ) { + public int Serialize( Map map, Stream stream, IMapConverterEx converter ) { BinaryWriter writer = new BinaryWriter( stream ); int count = 0; if ( map.MessageBlocks != null ) { @@ -56,10 +54,11 @@ public int Serialize ( Map map, Stream stream, IMapConverterEx converter ) { return count; } - public void Deserialize ( string group, string key, string value, Map map ) { + public void Deserialize( string group, string key, string value, Map map ) { try { MessageBlock MessageBlock = MessageBlock.Deserialize( key, value, map ); - if ( map.MessageBlocks == null ) map.MessageBlocks = new ArrayList(); + if ( map.MessageBlocks == null ) + map.MessageBlocks = new ArrayList(); if ( map.MessageBlocks.Count >= 1 ) { if ( map.MessageBlocks.Contains( key ) ) { Logger.Log( LogType.Error, "Map loading warning: duplicate MessageBlock name found: " + key + ", ignored" ); @@ -72,4 +71,4 @@ public void Deserialize ( string group, string key, string value, Map map ) { } } } -} +} \ No newline at end of file diff --git a/fCraft/Network/Heartbeat.cs b/fCraft/Network/Heartbeat.cs index ee31cd6..39a9ec0 100644 --- a/fCraft/Network/Heartbeat.cs +++ b/fCraft/Network/Heartbeat.cs @@ -8,12 +8,11 @@ using fCraft.Events; using JetBrains.Annotations; -namespace fCraft -{ +namespace fCraft { + /// Static class responsible for sending heartbeats. - public static class Heartbeat - { - static readonly Uri MinecraftNetUri; + public static class Heartbeat { + private static readonly Uri MinecraftNetUri; /// Delay between sending heartbeats. Default: 25s public static TimeSpan Delay { get; set; } @@ -26,43 +25,33 @@ public static class Heartbeat /// Known only to this server and to heartbeat servers. public static string Salt { get; internal set; } - - static Heartbeat() - { - MinecraftNetUri = new Uri("https://minecraft.net/heartbeat.jsp"); - Delay = TimeSpan.FromSeconds(25); - Timeout = TimeSpan.FromSeconds(10); - Salt = Server.GetRandomString(32); + static Heartbeat() { + MinecraftNetUri = new Uri( "https://minecraft.net/heartbeat.jsp" ); + Delay = TimeSpan.FromSeconds( 25 ); + Timeout = TimeSpan.FromSeconds( 10 ); + Salt = Server.GetRandomString( 32 ); Server.ShutdownBegan += OnServerShutdown; } - static void OnServerShutdown(object sender, ShutdownEventArgs e) - { - if (minecraftNetRequest != null) - { + private static void OnServerShutdown( object sender, ShutdownEventArgs e ) { + if ( minecraftNetRequest != null ) { minecraftNetRequest.Abort(); } } - - internal static void Start() - { - Scheduler.NewBackgroundTask(Beat).RunForever(Delay); + internal static void Start() { + Scheduler.NewBackgroundTask( Beat ).RunForever( Delay ); } + private static void Beat( SchedulerTask scheduledTask ) { + if ( Server.IsShuttingDown ) + return; - static void Beat(SchedulerTask scheduledTask) - { - if (Server.IsShuttingDown) return; - - if (ConfigKey.HeartbeatEnabled.Enabled()) - { + if ( ConfigKey.HeartbeatEnabled.Enabled() ) { SendMinecraftNetBeat(); Send800CraftNetBeat(); HbSave(); - } - else - { + } else { // If heartbeats are disabled, the server data is written // to a text file instead (heartbeatdata.txt) string[] data = new[]{ @@ -75,28 +64,26 @@ static void Beat(SchedulerTask scheduledTask) ConfigKey.IsPublic.GetString() }; const string tempFile = Paths.HeartbeatDataFileName + ".tmp"; - File.WriteAllLines(tempFile, data, Encoding.ASCII); - Paths.MoveOrReplace(tempFile, Paths.HeartbeatDataFileName); + File.WriteAllLines( tempFile, data, Encoding.ASCII ); + Paths.MoveOrReplace( tempFile, Paths.HeartbeatDataFileName ); } } - static HttpWebRequest minecraftNetRequest; + private static HttpWebRequest minecraftNetRequest; - static void SendMinecraftNetBeat() - { - HeartbeatData data = new HeartbeatData(MinecraftNetUri); - if (!RaiseHeartbeatSendingEvent(data, MinecraftNetUri, true)) - { + private static void SendMinecraftNetBeat() { + HeartbeatData data = new HeartbeatData( MinecraftNetUri ); + if ( !RaiseHeartbeatSendingEvent( data, MinecraftNetUri, true ) ) { return; } - minecraftNetRequest = CreateRequest(data.CreateUri()); - var state = new HeartbeatRequestState(minecraftNetRequest, data, true); - minecraftNetRequest.BeginGetResponse(ResponseCallback, state); + minecraftNetRequest = CreateRequest( data.CreateUri() ); + var state = new HeartbeatRequestState( minecraftNetRequest, data, true ); + minecraftNetRequest.BeginGetResponse( ResponseCallback, state ); } - static void Send800CraftNetBeat() - { - if ( Server.Uri == null ) return; + private static void Send800CraftNetBeat() { + if ( Server.Uri == null ) + return; string uri = "http://800craft.webuda.com/Heartbeat.php"; // create a request try { @@ -136,106 +123,85 @@ static void Send800CraftNetBeat() } } - - // Creates an asynchrnous HTTP request to the given URL - static HttpWebRequest CreateRequest(Uri uri) - { - HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); - request.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint(Server.BindIPEndPointCallback); + private static HttpWebRequest CreateRequest( Uri uri ) { + HttpWebRequest request = ( HttpWebRequest )WebRequest.Create( uri ); + request.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint( Server.BindIPEndPointCallback ); request.Method = "GET"; - request.Timeout = (int)Timeout.TotalMilliseconds; - request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.BypassCache); + request.Timeout = ( int )Timeout.TotalMilliseconds; + request.CachePolicy = new HttpRequestCachePolicy( HttpRequestCacheLevel.BypassCache ); request.UserAgent = Updater.UserAgent; return request; } + public static string HbData; - public static void HbSave() - { - try - { + + public static void HbSave() { + try { const string SaverFile = "heartbeatsaver.txt"; - if (File.Exists(SaverFile)) - { - File.Delete(SaverFile); + if ( File.Exists( SaverFile ) ) { + File.Delete( SaverFile ); } - if (Salt == null) return; - if (Server.CountPlayers(false).ToString() == null) return; + if ( Salt == null ) + return; + if ( Server.CountPlayers( false ).ToString() == null ) + return; HbData = "port=" + Server.Port.ToString() + "&max=" + ConfigKey.MaxPlayers.GetString() + "&name=" + - Uri.EscapeDataString(ConfigKey.ServerName.GetString()) + - "&public=True" + "&salt=" + Salt + "&users=" + Server.CountPlayers(false).ToString(); - File.WriteAllText(SaverFile, HbData, Encoding.ASCII); - } - catch (Exception ex) { Logger.Log(LogType.Error, "" + ex); } + Uri.EscapeDataString( ConfigKey.ServerName.GetString() ) + + "&public=True" + "&salt=" + Salt + "&users=" + Server.CountPlayers( false ).ToString(); + File.WriteAllText( SaverFile, HbData, Encoding.ASCII ); + } catch ( Exception ex ) { Logger.Log( LogType.Error, "" + ex ); } } - // Called when the heartbeat server responds. - static void ResponseCallback(IAsyncResult result) - { - if (Server.IsShuttingDown) return; - HeartbeatRequestState state = (HeartbeatRequestState)result.AsyncState; - try - { + private static void ResponseCallback( IAsyncResult result ) { + if ( Server.IsShuttingDown ) + return; + HeartbeatRequestState state = ( HeartbeatRequestState )result.AsyncState; + try { string responseText; - using (HttpWebResponse response = (HttpWebResponse)state.Request.EndGetResponse(result)) - { + using ( HttpWebResponse response = ( HttpWebResponse )state.Request.EndGetResponse( result ) ) { // ReSharper disable AssignNullToNotNullAttribute - using (StreamReader responseReader = new StreamReader(response.GetResponseStream())) - { + using ( StreamReader responseReader = new StreamReader( response.GetResponseStream() ) ) { // ReSharper restore AssignNullToNotNullAttribute responseText = responseReader.ReadToEnd(); } - RaiseHeartbeatSentEvent(state.Data, response, responseText); + RaiseHeartbeatSentEvent( state.Data, response, responseText ); } // try parse response as server Uri, if needed - if (state.GetServerUri) - { + if ( state.GetServerUri ) { string replyString = responseText.Trim(); - if (replyString.StartsWith("bad heartbeat", StringComparison.OrdinalIgnoreCase)) - { - Logger.Log(LogType.Error, "Heartbeat: {0}", replyString); - } - else - { - try - { - Uri newUri = new Uri(replyString); + if ( replyString.StartsWith( "bad heartbeat", StringComparison.OrdinalIgnoreCase ) ) { + Logger.Log( LogType.Error, "Heartbeat: {0}", replyString ); + } else { + try { + Uri newUri = new Uri( replyString ); Uri oldUri = Server.Uri; - if (newUri != oldUri) - { + if ( newUri != oldUri ) { Server.Uri = newUri; - RaiseUriChangedEvent(oldUri, newUri); + RaiseUriChangedEvent( oldUri, newUri ); } - } - catch (UriFormatException) - { - Logger.Log(LogType.Error, + } catch ( UriFormatException ) { + Logger.Log( LogType.Error, "Heartbeat: Server replied with: {0}", - replyString); + replyString ); } } } - } - catch (Exception ex) - { - if (ex is WebException || ex is IOException) - { - Logger.Log(LogType.Warning, + } catch ( Exception ex ) { + if ( ex is WebException || ex is IOException ) { + Logger.Log( LogType.Warning, "Heartbeat: {0} is probably down ({1})", state.Request.RequestUri.Host, - ex.Message); - } - else - { - Logger.Log(LogType.Error, "Heartbeat: {0}", ex); + ex.Message ); + } else { + Logger.Log( LogType.Error, "Heartbeat: {0}", ex ); } } } - #region Events /// Occurs when a heartbeat is about to be sent (cancellable). @@ -247,62 +213,57 @@ static void ResponseCallback(IAsyncResult result) /// Occurs when the server Uri has been set or changed. public static event EventHandler UriChanged; - - static bool RaiseHeartbeatSendingEvent(HeartbeatData data, Uri uri, bool getServerUri) - { + private static bool RaiseHeartbeatSendingEvent( HeartbeatData data, Uri uri, bool getServerUri ) { var h = Sending; - if (h == null) return true; - var e = new HeartbeatSendingEventArgs(data, uri, getServerUri); - h(null, e); + if ( h == null ) + return true; + var e = new HeartbeatSendingEventArgs( data, uri, getServerUri ); + h( null, e ); return !e.Cancel; } - static void RaiseHeartbeatSentEvent(HeartbeatData heartbeatData, + private static void RaiseHeartbeatSentEvent( HeartbeatData heartbeatData, HttpWebResponse response, - string text) - { + string text ) { var h = Sent; - if (h != null) - { - h(null, new HeartbeatSentEventArgs(heartbeatData, + if ( h != null ) { + h( null, new HeartbeatSentEventArgs( heartbeatData, response.Headers, response.StatusCode, - text)); + text ) ); } } - static void RaiseUriChangedEvent(Uri oldUri, Uri newUri) - { + private static void RaiseUriChangedEvent( Uri oldUri, Uri newUri ) { var h = UriChanged; - if (h != null) h(null, new UriChangedEventArgs(oldUri, newUri)); + if ( h != null ) + h( null, new UriChangedEventArgs( oldUri, newUri ) ); } - #endregion + #endregion Events + private sealed class HeartbeatRequestState { - sealed class HeartbeatRequestState - { - public HeartbeatRequestState(HttpWebRequest request, HeartbeatData data, bool getServerUri) - { + public HeartbeatRequestState( HttpWebRequest request, HeartbeatData data, bool getServerUri ) { Request = request; Data = data; GetServerUri = getServerUri; } + public readonly HttpWebRequest Request; public readonly HeartbeatData Data; public readonly bool GetServerUri; } } + public sealed class HeartbeatData { - public sealed class HeartbeatData - { - internal HeartbeatData([NotNull] Uri heartbeatUri) - { - if (heartbeatUri == null) throw new ArgumentNullException("heartbeatUri"); + internal HeartbeatData( [NotNull] Uri heartbeatUri ) { + if ( heartbeatUri == null ) + throw new ArgumentNullException( "heartbeatUri" ); IsPublic = ConfigKey.IsPublic.Enabled(); MaxPlayers = ConfigKey.MaxPlayers.GetInt(); - PlayerCount = Server.CountPlayers(false); + PlayerCount = Server.CountPlayers( false ); ServerIP = Server.InternalIP; Port = Server.Port; ProtocolVersion = Config.ProtocolVersion; @@ -314,33 +275,40 @@ internal HeartbeatData([NotNull] Uri heartbeatUri) [NotNull] public Uri HeartbeatUri { get; private set; } + public string Salt { get; set; } + public IPAddress ServerIP { get; set; } + public int Port { get; set; } + public int PlayerCount { get; set; } + public int MaxPlayers { get; set; } + public string ServerName { get; set; } + public bool IsPublic { get; set; } + public int ProtocolVersion { get; set; } + public Dictionary CustomData { get; private set; } - public Uri CreateUri() - { - UriBuilder ub = new UriBuilder(HeartbeatUri); + public Uri CreateUri() { + UriBuilder ub = new UriBuilder( HeartbeatUri ); StringBuilder sb = new StringBuilder(); - sb.AppendFormat("public={0}&max={1}&users={2}&port={3}&version={4}&salt={5}&name={6}", + sb.AppendFormat( "public={0}&max={1}&users={2}&port={3}&version={4}&salt={5}&name={6}", IsPublic, MaxPlayers, PlayerCount, Port, ProtocolVersion, - Uri.EscapeDataString(Salt), - Uri.EscapeDataString(ServerName)); - foreach (var pair in CustomData) - { - sb.AppendFormat("&{0}={1}", - Uri.EscapeDataString(pair.Key), - Uri.EscapeDataString(pair.Value)); + Uri.EscapeDataString( Salt ), + Uri.EscapeDataString( ServerName ) ); + foreach ( var pair in CustomData ) { + sb.AppendFormat( "&{0}={1}", + Uri.EscapeDataString( pair.Key ), + Uri.EscapeDataString( pair.Value ) ); } ub.Query = sb.ToString(); return ub.Uri; @@ -348,16 +316,14 @@ public Uri CreateUri() } } +namespace fCraft.Events { + + public sealed class HeartbeatSentEventArgs : EventArgs { -namespace fCraft.Events -{ - public sealed class HeartbeatSentEventArgs : EventArgs - { - internal HeartbeatSentEventArgs(HeartbeatData heartbeatData, + internal HeartbeatSentEventArgs( HeartbeatData heartbeatData, WebHeaderCollection headers, HttpStatusCode status, - string text) - { + string text ) { HeartbeatData = heartbeatData; ResponseHeaders = headers; ResponseStatusCode = status; @@ -365,37 +331,40 @@ internal HeartbeatSentEventArgs(HeartbeatData heartbeatData, } public HeartbeatData HeartbeatData { get; private set; } + public WebHeaderCollection ResponseHeaders { get; private set; } + public HttpStatusCode ResponseStatusCode { get; private set; } + public string ResponseText { get; private set; } } + public sealed class HeartbeatSendingEventArgs : EventArgs, ICancellableEvent { - public sealed class HeartbeatSendingEventArgs : EventArgs, ICancellableEvent - { - internal HeartbeatSendingEventArgs(HeartbeatData data, Uri uri, bool getServerUri) - { + internal HeartbeatSendingEventArgs( HeartbeatData data, Uri uri, bool getServerUri ) { HeartbeatData = data; Uri = uri; GetServerUri = getServerUri; } public HeartbeatData HeartbeatData { get; private set; } + public Uri Uri { get; set; } + public bool GetServerUri { get; set; } + public bool Cancel { get; set; } } + public sealed class UriChangedEventArgs : EventArgs { - public sealed class UriChangedEventArgs : EventArgs - { - internal UriChangedEventArgs(Uri oldUri, Uri newUri) - { + internal UriChangedEventArgs( Uri oldUri, Uri newUri ) { OldUri = oldUri; NewUri = newUri; } public Uri OldUri { get; private set; } + public Uri NewUri { get; private set; } } } \ No newline at end of file diff --git a/fCraft/Network/IPBanInfo.cs b/fCraft/Network/IPBanInfo.cs index 6d14e6e..f9fd8ae 100644 --- a/fCraft/Network/IPBanInfo.cs +++ b/fCraft/Network/IPBanInfo.cs @@ -4,6 +4,7 @@ using JetBrains.Annotations; namespace fCraft { + /// IP ban record. public sealed class IPBanInfo { public const int FieldCount = 8; @@ -36,14 +37,15 @@ public sealed class IPBanInfo { /// Date/time (UTC) of the most recent login attempt. public DateTime LastAttemptDate; - - IPBanInfo() { } - + private IPBanInfo() { + } internal IPBanInfo( [NotNull] IPAddress address, [CanBeNull] string playerName, [NotNull] string bannedBy, [CanBeNull] string banReason ) { - if( address == null ) throw new ArgumentNullException( "address" ); - if( bannedBy == null ) throw new ArgumentNullException( "bannedBy" ); + if ( address == null ) + throw new ArgumentNullException( "address" ); + if ( bannedBy == null ) + throw new ArgumentNullException( "bannedBy" ); Address = address; BannedBy = bannedBy; BanDate = DateTime.UtcNow; @@ -53,20 +55,21 @@ internal IPBanInfo( [NotNull] IPAddress address, [CanBeNull] string playerName, LastAttemptDate = DateTime.MinValue; } - internal static IPBanInfo LoadFormat2( [NotNull] string[] fields ) { - if( fields == null ) throw new ArgumentNullException( "fields" ); - if( fields.Length != 8 ) throw new ArgumentException( "Unexpected field count", "fields" ); + if ( fields == null ) + throw new ArgumentNullException( "fields" ); + if ( fields.Length != 8 ) + throw new ArgumentException( "Unexpected field count", "fields" ); IPBanInfo info = new IPBanInfo { - Address = IPAddress.Parse( fields[0] ), - BannedBy = PlayerInfo.Unescape( fields[1] ) - }; + Address = IPAddress.Parse( fields[0] ), + BannedBy = PlayerInfo.Unescape( fields[1] ) + }; fields[2].ToDateTime( ref info.BanDate ); - if( fields[3].Length > 0 ) { + if ( fields[3].Length > 0 ) { info.BanReason = PlayerInfo.Unescape( fields[3] ); } - if( fields[4].Length > 0 ) { + if ( fields[4].Length > 0 ) { info.PlayerName = PlayerInfo.Unescape( fields[4] ); } @@ -77,20 +80,21 @@ internal static IPBanInfo LoadFormat2( [NotNull] string[] fields ) { return info; } - internal static IPBanInfo LoadFormat1( [NotNull] string[] fields ) { - if( fields == null ) throw new ArgumentNullException( "fields" ); - if( fields.Length != 8 ) throw new ArgumentException( "Unexpected field count", "fields" ); + if ( fields == null ) + throw new ArgumentNullException( "fields" ); + if ( fields.Length != 8 ) + throw new ArgumentException( "Unexpected field count", "fields" ); IPBanInfo info = new IPBanInfo { - Address = IPAddress.Parse( fields[0] ), - BannedBy = PlayerInfo.Unescape( fields[1] ) - }; + Address = IPAddress.Parse( fields[0] ), + BannedBy = PlayerInfo.Unescape( fields[1] ) + }; fields[2].ToDateTimeLegacy( ref info.BanDate ); - if( fields[3].Length > 0 ) { + if ( fields[3].Length > 0 ) { info.BanReason = PlayerInfo.Unescape( fields[3] ); } - if( fields[4].Length > 0 ) { + if ( fields[4].Length > 0 ) { info.PlayerName = PlayerInfo.Unescape( fields[4] ); } @@ -101,18 +105,19 @@ internal static IPBanInfo LoadFormat1( [NotNull] string[] fields ) { return info; } - internal static IPBanInfo LoadFormat0( [NotNull] string[] fields, bool convertDatesToUtc ) { - if( fields == null ) throw new ArgumentNullException( "fields" ); - if( fields.Length != 8 ) throw new ArgumentException( "Unexpected field count", "fields" ); + if ( fields == null ) + throw new ArgumentNullException( "fields" ); + if ( fields.Length != 8 ) + throw new ArgumentException( "Unexpected field count", "fields" ); IPBanInfo info = new IPBanInfo { - Address = IPAddress.Parse( fields[0] ), - BannedBy = PlayerInfo.UnescapeOldFormat( fields[1] ) - }; + Address = IPAddress.Parse( fields[0] ), + BannedBy = PlayerInfo.UnescapeOldFormat( fields[1] ) + }; DateTimeUtil.TryParseLocalDate( fields[2], out info.BanDate ); info.BanReason = PlayerInfo.UnescapeOldFormat( fields[3] ); - if( fields[4].Length > 1 ) { + if ( fields[4].Length > 1 ) { info.PlayerName = PlayerInfo.UnescapeOldFormat( fields[4] ); } @@ -120,15 +125,16 @@ internal static IPBanInfo LoadFormat0( [NotNull] string[] fields, bool convertDa info.LastAttemptName = PlayerInfo.UnescapeOldFormat( fields[6] ); DateTimeUtil.TryParseLocalDate( fields[7], out info.LastAttemptDate ); - if( convertDatesToUtc ) { - if( info.BanDate != DateTime.MinValue ) info.BanDate = info.BanDate.ToUniversalTime(); - if( info.LastAttemptDate != DateTime.MinValue ) info.LastAttemptDate = info.LastAttemptDate.ToUniversalTime(); + if ( convertDatesToUtc ) { + if ( info.BanDate != DateTime.MinValue ) + info.BanDate = info.BanDate.ToUniversalTime(); + if ( info.LastAttemptDate != DateTime.MinValue ) + info.LastAttemptDate = info.LastAttemptDate.ToUniversalTime(); } return info; } - internal string Serialize() { string[] fields = new string[FieldCount]; @@ -144,15 +150,14 @@ internal string Serialize() { return String.Join( ",", fields ); } - internal void ProcessAttempt( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Attempts++; LastAttemptDate = DateTime.UtcNow; LastAttemptName = player.Name; } - #region Shortcuts [NotNull] @@ -178,6 +183,6 @@ public TimeSpan TimeSinceLastAttempt { get { return DateTime.UtcNow.Subtract( LastAttemptDate ); } } - #endregion + #endregion Shortcuts } } \ No newline at end of file diff --git a/fCraft/Network/IPBanList.cs b/fCraft/Network/IPBanList.cs index 153d4d1..1a825c3 100644 --- a/fCraft/Network/IPBanList.cs +++ b/fCraft/Network/IPBanList.cs @@ -2,75 +2,79 @@ using System; using System.Collections.Generic; using System.IO; -using System.Net; using System.Linq; +using System.Net; using fCraft.Events; using JetBrains.Annotations; namespace fCraft { - public static class IPBanList { - static readonly SortedDictionary Bans = new SortedDictionary(); - static readonly object BanListLock = new object(); + public static class IPBanList { + private static readonly SortedDictionary Bans = new SortedDictionary(); + private static readonly object BanListLock = new object(); #region Loading/Saving - const string Header = "IP,bannedBy,banDate,banReason,playerName,attempts,lastAttemptName,lastAttemptDate"; - const int FormatVersion = 2; + private const string Header = "IP,bannedBy,banDate,banReason,playerName,attempts,lastAttemptName,lastAttemptDate"; + private const int FormatVersion = 2; + public static bool IsLoaded { get; private set; } internal static void Load() { - if( File.Exists( Paths.IPBanListFileName ) ) { - using( StreamReader reader = File.OpenText( Paths.IPBanListFileName ) ) { - + if ( File.Exists( Paths.IPBanListFileName ) ) { + using ( StreamReader reader = File.OpenText( Paths.IPBanListFileName ) ) { string headerText = reader.ReadLine(); - if( headerText == null ) { + if ( headerText == null ) { Logger.Log( LogType.Warning, "IPBanList.Load: IP ban file is empty." ); return; } int version = ParseHeader( headerText ); - if( version > FormatVersion ) { + if ( version > FormatVersion ) { Logger.Log( LogType.Warning, "IPBanList.Load: Attempting to load unsupported IPBanList format ({0}). Errors may occur.", version ); - } else if( version < FormatVersion ) { + } else if ( version < FormatVersion ) { Logger.Log( LogType.Warning, "IPBanList.Load: Converting IPBanList to a newer format (version {0} to {1}).", version, FormatVersion ); } - while( !reader.EndOfStream ) { + while ( !reader.EndOfStream ) { string line = reader.ReadLine(); - if( line == null ) break; + if ( line == null ) + break; string[] fields = line.Split( ',' ); - if( fields.Length == IPBanInfo.FieldCount ) { + if ( fields.Length == IPBanInfo.FieldCount ) { try { IPBanInfo ban; - switch( version ) { + switch ( version ) { case 0: ban = IPBanInfo.LoadFormat0( fields, true ); break; + case 1: ban = IPBanInfo.LoadFormat1( fields ); break; + case 2: ban = IPBanInfo.LoadFormat2( fields ); break; + default: return; } - if( ban.Address.Equals( IPAddress.Any ) || ban.Address.Equals( IPAddress.None ) ) { + if ( ban.Address.Equals( IPAddress.Any ) || ban.Address.Equals( IPAddress.None ) ) { Logger.Log( LogType.Warning, "IPBanList.Load: Invalid IP address skipped." ); } else { Bans.Add( ban.Address.ToString(), ban ); } - } catch( IOException ex ) { + } catch ( IOException ex ) { Logger.Log( LogType.Error, "IPBanList.Load: Error while trying to read from file: {0}", ex.Message ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.Log( LogType.Error, "IPBanList.Load: Could not parse a record: {0}", ex.Message ); } @@ -91,13 +95,13 @@ internal static void Load() { IsLoaded = true; } - - static int ParseHeader( [NotNull] string header ) { - if( header == null ) throw new ArgumentNullException( "header" ); - if( header.IndexOf( ' ' ) > 0 ) { + private static int ParseHeader( [NotNull] string header ) { + if ( header == null ) + throw new ArgumentNullException( "header" ); + if ( header.IndexOf( ' ' ) > 0 ) { string firstPart = header.Substring( 0, header.IndexOf( ' ' ) ); int version; - if( Int32.TryParse( firstPart, out version ) ) { + if ( Int32.TryParse( firstPart, out version ) ) { return version; } else { return 0; @@ -107,42 +111,44 @@ static int ParseHeader( [NotNull] string header ) { } } - internal static void Save() { - if( !IsLoaded ) return; + if ( !IsLoaded ) + return; Logger.Log( LogType.Debug, "IPBanList.Save: Saving IP ban list ({0} records).", Bans.Count ); const string tempFile = Paths.IPBanListFileName + ".temp"; - lock( BanListLock ) { - using( StreamWriter writer = File.CreateText( tempFile ) ) { + lock ( BanListLock ) { + using ( StreamWriter writer = File.CreateText( tempFile ) ) { writer.WriteLine( "{0} {1}", FormatVersion, Header ); - foreach( IPBanInfo entry in Bans.Values ) { + foreach ( IPBanInfo entry in Bans.Values ) { writer.WriteLine( entry.Serialize() ); } } } try { Paths.MoveOrReplace( tempFile, Paths.IPBanListFileName ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.Log( LogType.Error, "IPBanList.Save: An error occured while trying to save ban list file: {0}", ex ); } } - #endregion - + #endregion Loading/Saving /// Adds a new IP Ban. /// Ban information /// Whether AddingIPBan and AddedIPBan events should be raised. /// True if ban was added, false if it was already on the list public static bool Add( [NotNull] IPBanInfo ban, bool raiseEvent ) { - if( ban == null ) throw new ArgumentNullException( "ban" ); - lock( BanListLock ) { - if( Bans.ContainsKey( ban.Address.ToString() ) ) return false; - if( raiseEvent ) { - if( RaiseAddingIPBanEvent( ban ) ) return false; + if ( ban == null ) + throw new ArgumentNullException( "ban" ); + lock ( BanListLock ) { + if ( Bans.ContainsKey( ban.Address.ToString() ) ) + return false; + if ( raiseEvent ) { + if ( RaiseAddingIPBanEvent( ban ) ) + return false; Bans.Add( ban.Address.ToString(), ban ); RaiseAddedIPBanEvent( ban ); } else { @@ -153,16 +159,16 @@ public static bool Add( [NotNull] IPBanInfo ban, bool raiseEvent ) { } } - /// Retrieves ban information for a given IP address. /// IP address to check. /// IPBanInfo object if found, otherwise null. [CanBeNull] public static IPBanInfo Get( [NotNull] IPAddress address ) { - if( address == null ) throw new ArgumentNullException( "address" ); - lock( BanListLock ) { + if ( address == null ) + throw new ArgumentNullException( "address" ); + lock ( BanListLock ) { IPBanInfo info; - if( Bans.TryGetValue( address.ToString(), out info ) ) { + if ( Bans.TryGetValue( address.ToString(), out info ) ) { return info; } else { return null; @@ -170,34 +176,36 @@ public static IPBanInfo Get( [NotNull] IPAddress address ) { } } - /// Checks whether the given address is banned. /// Address to look for. public static bool Contains( [NotNull] IPAddress address ) { - if( address == null ) throw new ArgumentNullException( "address" ); - lock( BanListLock ) { + if ( address == null ) + throw new ArgumentNullException( "address" ); + lock ( BanListLock ) { return Bans.ContainsKey( address.ToString() ); } } - /// Removes a given IP address from the ban list (if present). /// Address to unban. /// Whether to raise RemovingIPBan and RemovedIPBan events. /// True if IP was unbanned. /// False if it was not banned in the first place, or if it was cancelled by an event. public static bool Remove( [NotNull] IPAddress address, bool raiseEvents ) { - if( address == null ) throw new ArgumentNullException( "address" ); - lock( BanListLock ) { - if( !Bans.ContainsKey( address.ToString() ) ) { + if ( address == null ) + throw new ArgumentNullException( "address" ); + lock ( BanListLock ) { + if ( !Bans.ContainsKey( address.ToString() ) ) { return false; } IPBanInfo info = Bans[address.ToString()]; - if( raiseEvents ) { - if( RaiseRemovingIPBanEvent( info ) ) return false; + if ( raiseEvents ) { + if ( RaiseRemovingIPBanEvent( info ) ) + return false; } - if( Bans.Remove( address.ToString() ) ) { - if( raiseEvents ) RaiseRemovedIPBanEvent( info ); + if ( Bans.Remove( address.ToString() ) ) { + if ( raiseEvents ) + RaiseRemovedIPBanEvent( info ); Save(); return true; } else { @@ -206,14 +214,12 @@ public static bool Remove( [NotNull] IPAddress address, bool raiseEvents ) { } } - public static int Count { get { return Bans.Count; } } - /// Bans given IP address. All players from IP are kicked. If an associated PlayerInfo is known, /// use a different overload of this method instead. Throws PlayerOpException on problems. /// IP address that is being banned. @@ -223,30 +229,33 @@ public static int Count { /// Whether AddingIPBan and AddedIPBan events should be raised. public static void BanIP( [NotNull] this IPAddress targetAddress, [NotNull] Player player, [CanBeNull] string reason, bool announce, bool raiseEvents ) { - if( targetAddress == null ) throw new ArgumentNullException( "targetAddress" ); - if( player == null ) throw new ArgumentNullException( "player" ); - if( reason != null && reason.Trim().Length == 0 ) reason = null; + if ( targetAddress == null ) + throw new ArgumentNullException( "targetAddress" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( reason != null && reason.Trim().Length == 0 ) + reason = null; // Check if player can ban IPs in general - if( !player.Can( Permission.Ban, Permission.BanIP ) ) { + if ( !player.Can( Permission.Ban, Permission.BanIP ) ) { PlayerOpException.ThrowPermissionMissing( player, null, "IP-ban", Permission.Ban, Permission.BanIP ); } // Check if a non-bannable address was given (0.0.0.0 or 255.255.255.255) - if( targetAddress.Equals( IPAddress.None ) || targetAddress.Equals( IPAddress.Any ) ) { + if ( targetAddress.Equals( IPAddress.None ) || targetAddress.Equals( IPAddress.Any ) ) { PlayerOpException.ThrowInvalidIP( player, null, targetAddress ); } // Check if player is trying to ban self - if( targetAddress.Equals( player.IP ) && !player.IsSuper ) { + if ( targetAddress.Equals( player.IP ) && !player.IsSuper ) { PlayerOpException.ThrowCannotTargetSelf( player, null, "IP-ban" ); } // Check if target is already banned IPBanInfo existingBan = Get( targetAddress ); - if( existingBan != null ) { + if ( existingBan != null ) { string msg; - if( player.Can( Permission.ViewPlayerIPs ) ) { + if ( player.Can( Permission.ViewPlayerIPs ) ) { msg = String.Format( "IP address {0} is already banned.", targetAddress ); } else { msg = String.Format( "Given IP address is already banned." ); @@ -258,7 +267,7 @@ public static void BanIP( [NotNull] this IPAddress targetAddress, [NotNull] Play // Check if any high-ranked players use this address PlayerInfo infoWhomPlayerCantBan = PlayerDB.FindPlayers( targetAddress ) .FirstOrDefault( info => !player.Can( Permission.Ban, info.Rank ) ); - if( infoWhomPlayerCantBan != null ) { + if ( infoWhomPlayerCantBan != null ) { PlayerOpException.ThrowPermissionLimitIP( player, infoWhomPlayerCantBan, targetAddress ); } @@ -268,38 +277,37 @@ public static void BanIP( [NotNull] this IPAddress targetAddress, [NotNull] Play IPBanInfo banInfo = new IPBanInfo( targetAddress, null, player.Name, reason ); bool result = Add( banInfo, raiseEvents ); - if( result ) { + if ( result ) { Logger.Log( LogType.UserActivity, "{0} banned {1} (BanIP {1}). Reason: {2}", player.Name, targetAddress, reason ?? "" ); - if( announce ) { + if ( announce ) { // Announce ban on the server var can = Server.Players.Can( Permission.ViewPlayerIPs ); can.Message( "&W{0} was banned by {1}", targetAddress, player.ClassyName ); var cant = Server.Players.Cant( Permission.ViewPlayerIPs ); cant.Message( "&WAn IP was banned by {0}", player.ClassyName ); - if( ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { + if ( ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { Server.Message( "&WBanIP reason: {0}", reason ); } } // Kick all players connected from address string kickReason; - if( reason != null ) { + if ( reason != null ) { kickReason = String.Format( "IP-Banned by {0}: {1}", player.Name, reason ); } else { kickReason = String.Format( "IP-Banned by {0}", player.Name ); } - foreach( Player other in Server.Players.FromIP( targetAddress ) ) { - if( other.Info.BanStatus != BanStatus.IPBanExempt ) { + foreach ( Player other in Server.Players.FromIP( targetAddress ) ) { + if ( other.Info.BanStatus != BanStatus.IPBanExempt ) { other.Kick( kickReason, LeaveReason.BanIP ); // TODO: check side effects of not using DoKick } } - } else { // address is already banned string msg; - if( player.Can( Permission.ViewPlayerIPs ) ) { + if ( player.Can( Permission.ViewPlayerIPs ) ) { msg = String.Format( "{0} is already banned.", targetAddress ); } else { msg = "Given IP address is already banned."; @@ -309,7 +317,6 @@ public static void BanIP( [NotNull] this IPAddress targetAddress, [NotNull] Play } } - /// Unbans an IP address. If an associated PlayerInfo is known, /// use a different overload of this method instead. Throws PlayerOpException on problems. /// IP address that is being unbanned. @@ -319,22 +326,25 @@ public static void BanIP( [NotNull] this IPAddress targetAddress, [NotNull] Play /// Whether RemovingIPBan and RemovedIPBan events should be raised. public static void UnbanIP( [NotNull] this IPAddress targetAddress, [NotNull] Player player, [CanBeNull] string reason, bool announce, bool raiseEvents ) { - if( targetAddress == null ) throw new ArgumentNullException( "targetAddress" ); - if( player == null ) throw new ArgumentNullException( "player" ); - if( reason != null && reason.Trim().Length == 0 ) reason = null; + if ( targetAddress == null ) + throw new ArgumentNullException( "targetAddress" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( reason != null && reason.Trim().Length == 0 ) + reason = null; // Check if player can unban IPs in general - if( !player.Can( Permission.Ban, Permission.BanIP ) ) { + if ( !player.Can( Permission.Ban, Permission.BanIP ) ) { PlayerOpException.ThrowPermissionMissing( player, null, "IP-unban", Permission.Ban, Permission.BanIP ); } // Check if a non-bannable address was given (0.0.0.0 or 255.255.255.255) - if( targetAddress.Equals( IPAddress.None ) || targetAddress.Equals( IPAddress.Any ) ) { + if ( targetAddress.Equals( IPAddress.None ) || targetAddress.Equals( IPAddress.Any ) ) { PlayerOpException.ThrowInvalidIP( player, null, targetAddress ); } // Check if player is trying to unban self - if( targetAddress.Equals( player.IP ) && !player.IsSuper ) { + if ( targetAddress.Equals( player.IP ) && !player.IsSuper ) { PlayerOpException.ThrowCannotTargetSelf( player, null, "IP-unban" ); } @@ -343,22 +353,22 @@ public static void UnbanIP( [NotNull] this IPAddress targetAddress, [NotNull] Pl // Actually unban bool result = Remove( targetAddress, raiseEvents ); - if( result ) { + if ( result ) { Logger.Log( LogType.UserActivity, "{0} unbanned {1} (UnbanIP {1}). Reason: {2}", player.Name, targetAddress, reason ?? "" ); - if( announce ) { + if ( announce ) { var can = Server.Players.Can( Permission.ViewPlayerIPs ); can.Message( "&W{0} was unbanned by {1}", targetAddress, player.ClassyName ); var cant = Server.Players.Cant( Permission.ViewPlayerIPs ); cant.Message( "&WAn IP was unbanned by {0}", player.ClassyName ); - if( ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { + if ( ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { Server.Message( "&WUnbanIP reason: {0}", reason ); } } } else { string msg; - if( player.Can( Permission.ViewPlayerIPs ) ) { + if ( player.Can( Permission.ViewPlayerIPs ) ) { msg = String.Format( "IP address {0} is not currently banned.", targetAddress ); } else { msg = String.Format( "Given IP address is not currently banned." ); @@ -368,7 +378,6 @@ public static void UnbanIP( [NotNull] this IPAddress targetAddress, [NotNull] Pl } } - /// Bans given IP address and all accounts on that IP. All players from IP are kicked. /// Throws PlayerOpException on problems. /// IP address that is being banned. @@ -378,29 +387,32 @@ public static void UnbanIP( [NotNull] this IPAddress targetAddress, [NotNull] Pl /// Whether AddingIPBan, AddedIPBan, BanChanging, and BanChanged events should be raised. public static void BanAll( [NotNull] this IPAddress targetAddress, [NotNull] Player player, [CanBeNull] string reason, bool announce, bool raiseEvents ) { - if( targetAddress == null ) throw new ArgumentNullException( "targetAddress" ); - if( player == null ) throw new ArgumentNullException( "player" ); - if( reason != null && reason.Trim().Length == 0 ) reason = null; - - if( !player.Can( Permission.Ban, Permission.BanIP, Permission.BanAll ) ) { + if ( targetAddress == null ) + throw new ArgumentNullException( "targetAddress" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( reason != null && reason.Trim().Length == 0 ) + reason = null; + + if ( !player.Can( Permission.Ban, Permission.BanIP, Permission.BanAll ) ) { PlayerOpException.ThrowPermissionMissing( player, null, "ban-all", Permission.Ban, Permission.BanIP, Permission.BanAll ); } // Check if player is trying to ban self - if( targetAddress.Equals( player.IP ) && !player.IsSuper ) { + if ( targetAddress.Equals( player.IP ) && !player.IsSuper ) { PlayerOpException.ThrowCannotTargetSelf( player, null, "ban-all" ); } // Check if a non-bannable address was given (0.0.0.0 or 255.255.255.255) - if( targetAddress.Equals( IPAddress.None ) || targetAddress.Equals( IPAddress.Any ) ) { + if ( targetAddress.Equals( IPAddress.None ) || targetAddress.Equals( IPAddress.Any ) ) { PlayerOpException.ThrowInvalidIP( player, null, targetAddress ); } // Check if any high-ranked players use this address PlayerInfo[] allPlayersOnIP = PlayerDB.FindPlayers( targetAddress ); PlayerInfo infoWhomPlayerCantBan = allPlayersOnIP.FirstOrDefault( info => !player.Can( Permission.Ban, info.Rank ) ); - if( infoWhomPlayerCantBan != null ) { + if ( infoWhomPlayerCantBan != null ) { PlayerOpException.ThrowPermissionLimitIP( player, infoWhomPlayerCantBan, targetAddress ); } @@ -408,15 +420,15 @@ public static void BanAll( [NotNull] this IPAddress targetAddress, [NotNull] Pla bool somethingGotBanned = false; // Ban the IP - if( !Contains( targetAddress ) ) { + if ( !Contains( targetAddress ) ) { IPBanInfo banInfo = new IPBanInfo( targetAddress, null, player.Name, reason ); - if( Add( banInfo, raiseEvents ) ) { + if ( Add( banInfo, raiseEvents ) ) { Logger.Log( LogType.UserActivity, "{0} banned {1} (BanAll {1}). Reason: {2}", player.Name, targetAddress, reason ?? "" ); // Announce ban on the server - if( announce ) { + if ( announce ) { var can = Server.Players.Can( Permission.ViewPlayerIPs ); can.Message( "&W{0} was banned by {1}", targetAddress, player.ClassyName ); var cant = Server.Players.Cant( Permission.ViewPlayerIPs ); @@ -427,20 +439,22 @@ public static void BanAll( [NotNull] this IPAddress targetAddress, [NotNull] Pla } // Ban individual players - foreach( PlayerInfo targetAlt in allPlayersOnIP ) { - if( targetAlt.BanStatus != BanStatus.NotBanned ) continue; + foreach ( PlayerInfo targetAlt in allPlayersOnIP ) { + if ( targetAlt.BanStatus != BanStatus.NotBanned ) + continue; // Raise PlayerInfo.BanChanging event PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs( targetAlt, player, false, reason, announce ); - if( raiseEvents ) { + if ( raiseEvents ) { PlayerInfo.RaiseBanChangingEvent( e ); - if( e.Cancel ) continue; + if ( e.Cancel ) + continue; reason = e.Reason; } // Do the ban - if( targetAlt.ProcessBan( player, player.Name, reason ) ) { - if( raiseEvents ) { + if ( targetAlt.ProcessBan( player, player.Name, reason ) ) { + if ( raiseEvents ) { PlayerInfo.RaiseBanChangedEvent( e ); } @@ -448,7 +462,7 @@ public static void BanAll( [NotNull] this IPAddress targetAddress, [NotNull] Pla Logger.Log( LogType.UserActivity, "{0} banned {1} (BanAll {2}). Reason: {3}", player.Name, targetAlt.Name, targetAddress, reason ?? "" ); - if( announce ) { + if ( announce ) { Server.Message( "&WPlayer {0}&W was banned by {1}&W (BanAll)", targetAlt.ClassyName, player.ClassyName ); } @@ -457,31 +471,30 @@ public static void BanAll( [NotNull] this IPAddress targetAddress, [NotNull] Pla } // If no one ended up getting banned, quit here - if( !somethingGotBanned ) { + if ( !somethingGotBanned ) { PlayerOpException.ThrowNoOneToBan( player, null, targetAddress ); } // Announce BanAll reason towards the end of all bans - if( announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { + if ( announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { Server.Message( "&WBanAll reason: {0}", reason ); } // Kick all players from IP Player[] targetsOnline = Server.Players.FromIP( targetAddress ).ToArray(); - if( targetsOnline.Length > 0 ) { + if ( targetsOnline.Length > 0 ) { string kickReason; - if( reason != null ) { + if ( reason != null ) { kickReason = String.Format( "Banned by {0}: {1}", player.Name, reason ); } else { kickReason = String.Format( "Banned by {0}", player.Name ); } - for( int i = 0; i < targetsOnline.Length; i++ ) { + for ( int i = 0; i < targetsOnline.Length; i++ ) { targetsOnline[i].Kick( kickReason, LeaveReason.BanAll ); } } } - /// Unbans given IP address and all accounts on that IP. Throws PlayerOpException on problems. /// IP address that is being unbanned. /// Player who is unbanning. @@ -490,22 +503,25 @@ public static void BanAll( [NotNull] this IPAddress targetAddress, [NotNull] Pla /// Whether RemovingIPBan, RemovedIPBan, BanChanging, and BanChanged events should be raised. public static void UnbanAll( [NotNull] this IPAddress targetAddress, [NotNull] Player player, [CanBeNull] string reason, bool announce, bool raiseEvents ) { - if( targetAddress == null ) throw new ArgumentNullException( "targetAddress" ); - if( player == null ) throw new ArgumentNullException( "player" ); - if( reason != null && reason.Trim().Length == 0 ) reason = null; - - if( !player.Can( Permission.Ban, Permission.BanIP, Permission.BanAll ) ) { + if ( targetAddress == null ) + throw new ArgumentNullException( "targetAddress" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( reason != null && reason.Trim().Length == 0 ) + reason = null; + + if ( !player.Can( Permission.Ban, Permission.BanIP, Permission.BanAll ) ) { PlayerOpException.ThrowPermissionMissing( player, null, "unban-all", Permission.Ban, Permission.BanIP, Permission.BanAll ); } // Check if player is trying to unban self - if( targetAddress.Equals( player.IP ) && !player.IsSuper ) { + if ( targetAddress.Equals( player.IP ) && !player.IsSuper ) { PlayerOpException.ThrowCannotTargetSelf( player, null, "unban-all" ); } // Check if a non-bannable address was given (0.0.0.0 or 255.255.255.255) - if( targetAddress.Equals( IPAddress.None ) || targetAddress.Equals( IPAddress.Any ) ) { + if ( targetAddress.Equals( IPAddress.None ) || targetAddress.Equals( IPAddress.Any ) ) { PlayerOpException.ThrowInvalidIP( player, null, targetAddress ); } @@ -513,14 +529,14 @@ public static void UnbanAll( [NotNull] this IPAddress targetAddress, [NotNull] P bool somethingGotUnbanned = false; // Unban the IP - if( Contains( targetAddress ) ) { - if( Remove( targetAddress, raiseEvents ) ) { + if ( Contains( targetAddress ) ) { + if ( Remove( targetAddress, raiseEvents ) ) { Logger.Log( LogType.UserActivity, "{0} unbanned {1} (UnbanAll {1}). Reason: {2}", player.Name, targetAddress, reason ?? "" ); // Announce unban on the server - if( announce ) { + if ( announce ) { var can = Server.Players.Can( Permission.ViewPlayerIPs ); can.Message( "&W{0} was unbanned by {1}", targetAddress, player.ClassyName ); var cant = Server.Players.Cant( Permission.ViewPlayerIPs ); @@ -533,20 +549,22 @@ public static void UnbanAll( [NotNull] this IPAddress targetAddress, [NotNull] P // Unban individual players PlayerInfo[] allPlayersOnIP = PlayerDB.FindPlayers( targetAddress ); - foreach( PlayerInfo targetAlt in allPlayersOnIP ) { - if( targetAlt.BanStatus != BanStatus.Banned ) continue; + foreach ( PlayerInfo targetAlt in allPlayersOnIP ) { + if ( targetAlt.BanStatus != BanStatus.Banned ) + continue; // Raise PlayerInfo.BanChanging event PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs( targetAlt, player, true, reason, announce ); - if( raiseEvents ) { + if ( raiseEvents ) { PlayerInfo.RaiseBanChangingEvent( e ); - if( e.Cancel ) continue; + if ( e.Cancel ) + continue; reason = e.Reason; } // Do the ban - if( targetAlt.ProcessUnban( player.Name, reason ) ) { - if( raiseEvents ) { + if ( targetAlt.ProcessUnban( player.Name, reason ) ) { + if ( raiseEvents ) { PlayerInfo.RaiseBanChangedEvent( e ); } @@ -554,7 +572,7 @@ public static void UnbanAll( [NotNull] this IPAddress targetAddress, [NotNull] P Logger.Log( LogType.UserActivity, "{0} unbanned {1} (UnbanAll {2}). Reason: {3}", player.Name, targetAlt.Name, targetAddress, reason ?? "" ); - if( announce ) { + if ( announce ) { Server.Message( "&WPlayer {0}&W was unbanned by {1}&W (UnbanAll)", targetAlt.ClassyName, player.ClassyName ); } @@ -563,75 +581,79 @@ public static void UnbanAll( [NotNull] this IPAddress targetAddress, [NotNull] P } // If no one ended up getting unbanned, quit here - if( !somethingGotUnbanned ) { + if ( !somethingGotUnbanned ) { PlayerOpException.ThrowNoOneToUnban( player, null, targetAddress ); } // Announce UnbanAll reason towards the end of all unbans - if( announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { + if ( announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { Server.Message( "&WUnbanAll reason: {0}", reason ); } } - #region Events /// Occurs when a new IP ban is about to be added (cancellable). public static event EventHandler AddingIPBan; - /// Occurs when a new IP ban has been added. public static event EventHandler AddedIPBan; - /// Occurs when an existing IP ban is about to be removed (cancellable). public static event EventHandler RemovingIPBan; - /// Occurs after an existing IP ban has been removed. public static event EventHandler RemovedIPBan; - - static bool RaiseAddingIPBanEvent( [NotNull] IPBanInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); + private static bool RaiseAddingIPBanEvent( [NotNull] IPBanInfo info ) { + if ( info == null ) + throw new ArgumentNullException( "info" ); var h = AddingIPBan; - if( h == null ) return false; + if ( h == null ) + return false; var e = new IPBanCancellableEventArgs( info ); h( null, e ); return e.Cancel; } - static void RaiseAddedIPBanEvent( [NotNull] IPBanInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); + private static void RaiseAddedIPBanEvent( [NotNull] IPBanInfo info ) { + if ( info == null ) + throw new ArgumentNullException( "info" ); var h = AddedIPBan; - if( h != null ) h( null, new IPBanEventArgs( info ) ); + if ( h != null ) + h( null, new IPBanEventArgs( info ) ); } - static bool RaiseRemovingIPBanEvent( [NotNull] IPBanInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); + private static bool RaiseRemovingIPBanEvent( [NotNull] IPBanInfo info ) { + if ( info == null ) + throw new ArgumentNullException( "info" ); var h = RemovingIPBan; - if( h == null ) return false; + if ( h == null ) + return false; var e = new IPBanCancellableEventArgs( info ); h( null, e ); return e.Cancel; } - static void RaiseRemovedIPBanEvent( [NotNull] IPBanInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); + private static void RaiseRemovedIPBanEvent( [NotNull] IPBanInfo info ) { + if ( info == null ) + throw new ArgumentNullException( "info" ); var h = RemovedIPBan; - if( h != null ) h( null, new IPBanEventArgs( info ) ); + if ( h != null ) + h( null, new IPBanEventArgs( info ) ); } - #endregion + #endregion Events } } - namespace fCraft.Events { public class IPBanEventArgs : EventArgs { + internal IPBanEventArgs( [NotNull] IPBanInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); + if ( info == null ) + throw new ArgumentNullException( "info" ); BanInfo = info; } @@ -639,13 +661,12 @@ internal IPBanEventArgs( [NotNull] IPBanInfo info ) { public IPBanInfo BanInfo { get; private set; } } - public sealed class IPBanCancellableEventArgs : IPBanEventArgs, ICancellableEvent { + internal IPBanCancellableEventArgs( IPBanInfo info ) : base( info ) { } public bool Cancel { get; set; } } - } \ No newline at end of file diff --git a/fCraft/Network/IRC.cs b/fCraft/Network/IRC.cs index 773f718..262d39b 100644 --- a/fCraft/Network/IRC.cs +++ b/fCraft/Network/IRC.cs @@ -1,7 +1,7 @@ /* Copyright 2009-2012 Matvei Stefarov - * + * * Based, in part, on SmartIrc4net code. Original license is reproduced below. - * + * * * * SmartIrc4net - the IRC library for .NET/C# @@ -42,38 +42,42 @@ namespace fCraft { /// IRC control class. public static class IRC { - const string ResetReplacement = "\u0003\u000F", + + private const string ResetReplacement = "\u0003\u000F", BoldReplacement = "\u0002"; + public const string ResetCode = "\u211C", BoldCode = "\u212C"; - static readonly Regex IrcNickRegex = new Regex( @"\A[a-z_\-\[\]\\^{}|`][a-z0-9_\-\[\]\\^{}|`]*\z", RegexOptions.IgnoreCase ), + + private static readonly Regex IrcNickRegex = new Regex( @"\A[a-z_\-\[\]\\^{}|`][a-z0-9_\-\[\]\\^{}|`]*\z", RegexOptions.IgnoreCase ), UserHostRegex = new Regex( @"^[a-z0-9_\-\[\]\\^{}|`]+\*?=[+-]?(.+@.+)$", RegexOptions.IgnoreCase ), MaxNickLengthRegex = new Regex( @"NICKLEN=(\d+)" ); - static int userHostLength = 60, maxNickLength = 30; + + private static int userHostLength = 60, maxNickLength = 30; /// Class represents an IRC connection/thread. /// There is an undocumented option (IRCThreads) to "load balance" the outgoing /// messages between multiple bots. If that's the case, several IRCThread objects /// are created. The bots grab messages from IRC.outputQueue whenever they are /// not on cooldown (a bit of an intentional race condition). - sealed class IRCThread : IDisposable { - TcpClient client; - StreamReader reader; - StreamWriter writer; - Thread thread; - bool isConnected; + private sealed class IRCThread : IDisposable { + private TcpClient client; + private StreamReader reader; + private StreamWriter writer; + private Thread thread; + private bool isConnected; public bool IsReady; - bool reconnect; + private bool reconnect; public bool ResponsibleForInputParsing; public string ActualBotNick; - string desiredBotNick; - DateTime lastMessageSent; - int nickTry; - readonly ConcurrentQueue localQueue = new ConcurrentQueue(); - - - public bool Start ( [NotNull] string botNick, bool parseInput ) { - if ( botNick == null ) throw new ArgumentNullException( "botNick" ); + private string desiredBotNick; + private DateTime lastMessageSent; + private int nickTry; + private readonly ConcurrentQueue localQueue = new ConcurrentQueue(); + + public bool Start( [NotNull] string botNick, bool parseInput ) { + if ( botNick == null ) + throw new ArgumentNullException( "botNick" ); desiredBotNick = botNick; ResponsibleForInputParsing = parseInput; try { @@ -92,8 +96,7 @@ public bool Start ( [NotNull] string botNick, bool parseInput ) { } } - - void Connect () { + private void Connect() { // initialize the client IPAddress ipToBindTo = IPAddress.Parse( ConfigKey.IP.GetString() ); IPEndPoint localEndPoint = new IPEndPoint( ipToBindTo, 0 ); @@ -113,15 +116,14 @@ void Connect () { isConnected = true; } - - void Send ( [NotNull] string msg ) { - if ( msg == null ) throw new ArgumentNullException( "msg" ); + private void Send( [NotNull] string msg ) { + if ( msg == null ) + throw new ArgumentNullException( "msg" ); localQueue.Enqueue( msg ); } - // runs in its own thread, started from Connect() - void IoThread () { + private void IoThread() { lastMessageSent = DateTime.UtcNow; do { @@ -171,12 +173,10 @@ void IoThread () { HandleMessage( line ); } } - } catch ( SocketException ) { Logger.Log( LogType.Warning, "IRC: Disconnected. Will retry in {0} seconds.", ReconnectDelay / 1000 ); reconnect = true; - } catch ( IOException ) { Logger.Log( LogType.Warning, "IRC: Disconnected. Will retry in {0} seconds.", ReconnectDelay / 1000 ); @@ -188,13 +188,14 @@ void IoThread () { #endif } - if ( reconnect ) Thread.Sleep( ReconnectDelay ); + if ( reconnect ) + Thread.Sleep( ReconnectDelay ); } while ( reconnect ); } - - void HandleMessage ( [NotNull] string message ) { - if ( message == null ) throw new ArgumentNullException( "message" ); + private void HandleMessage( [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); IRCMessage msg = MessageParser( message, ActualBotNick ); #if DEBUG_IRC @@ -225,17 +226,16 @@ void HandleMessage ( [NotNull] string message ) { } return; - case IRCMessageType.Ping: // ping-pong Send( IRCCommands.Pong( msg.RawMessageArray[1].Substring( 1 ) ) ); return; - case IRCMessageType.ChannelAction: case IRCMessageType.ChannelMessage: // channel chat - if ( !ResponsibleForInputParsing ) return; + if ( !ResponsibleForInputParsing ) + return; if ( !IsBotNick( msg.Nick ) ) { string processedMessage = msg.Message; if ( msg.Type == IRCMessageType.ChannelAction ) { @@ -265,40 +265,39 @@ void HandleMessage ( [NotNull] string message ) { } return; - case IRCMessageType.Join: - if ( !ResponsibleForInputParsing ) return; + if ( !ResponsibleForInputParsing ) + return; if ( ConfigKey.IRCBotAnnounceIRCJoins.Enabled() ) { Server.Message( "&i(IRC) {0} joined {1}", msg.Nick, msg.Channel ); } return; - case IRCMessageType.Kick: string kicked = msg.RawMessageArray[3]; if ( kicked == ActualBotNick ) { Thread.Sleep( ReconnectDelay ); Send( IRCCommands.Join( msg.Channel ) ); } else { - if ( !ResponsibleForInputParsing ) return; + if ( !ResponsibleForInputParsing ) + return; string kickMessage = ProcessMessageFromIRC( msg.Message ); Server.Message( "&i(IRC) {0} kicked {1} from {2} ({3})", msg.Nick, kicked, msg.Channel, kickMessage ); } return; - case IRCMessageType.Part: case IRCMessageType.Quit: - if ( !ResponsibleForInputParsing ) return; + if ( !ResponsibleForInputParsing ) + return; if ( ConfigKey.IRCBotAnnounceIRCJoins.Enabled() ) { Server.Message( "&i(IRC) {0} left {1}", msg.Nick, msg.Channel ); } return; - case IRCMessageType.NickChange: if ( msg.Nick == ActualBotNick ) { ActualBotNick = msg.Message; @@ -307,7 +306,8 @@ void HandleMessage ( [NotNull] string message ) { "Bot was forcefully renamed from {0} to {1}", msg.Nick, msg.Message ); } else { - if ( !ResponsibleForInputParsing ) return; + if ( !ResponsibleForInputParsing ) + return; Server.Message( "&i(IRC) {0} is now known as {1}", msg.Nick, msg.Message ); } @@ -367,14 +367,12 @@ void HandleMessage ( [NotNull] string message ) { return; - case IRCMessageType.QueryAction: // TODO: PMs Logger.Log( LogType.IRC, "Query: {0}", msg.RawMessage ); break; - case IRCMessageType.Kill: Logger.Log( LogType.IRC, "Bot was killed from {0} by {1} ({2}), reconnecting.", @@ -394,8 +392,7 @@ void HandleMessage ( [NotNull] string message ) { } } - - public void DisconnectThread () { + public void DisconnectThread() { IsReady = false; AssignBotForInputParsing(); isConnected = false; @@ -406,26 +403,30 @@ public void DisconnectThread () { } } try { - if ( reader != null ) reader.Close(); + if ( reader != null ) + reader.Close(); } catch ( ObjectDisposedException ) { } try { - if ( writer != null ) writer.Close(); + if ( writer != null ) + writer.Close(); } catch ( ObjectDisposedException ) { } try { - if ( client != null ) client.Close(); + if ( client != null ) + client.Close(); } catch ( ObjectDisposedException ) { } } - #region IDisposable members - public void Dispose () { + public void Dispose() { try { - if ( reader != null ) reader.Dispose(); + if ( reader != null ) + reader.Dispose(); } catch ( ObjectDisposedException ) { } try { - if ( reader != null ) writer.Dispose(); + if ( reader != null ) + writer.Dispose(); } catch ( ObjectDisposedException ) { } try { @@ -435,25 +436,23 @@ public void Dispose () { } catch ( ObjectDisposedException ) { } } - #endregion + #endregion IDisposable members } + private static IRCThread[] threads; - static IRCThread[] threads; - - const int Timeout = 10000; // socket timeout (ms) + private const int Timeout = 10000; // socket timeout (ms) internal static int SendDelay; // set by ApplyConfig - const int ReconnectDelay = 15000; - - static string hostName; - static int port; - static string[] channelNames; - static string botNick; + private const int ReconnectDelay = 15000; - static readonly ConcurrentQueue OutputQueue = new ConcurrentQueue(); + private static string hostName; + private static int port; + private static string[] channelNames; + private static string botNick; + private static readonly ConcurrentQueue OutputQueue = new ConcurrentQueue(); - static void AssignBotForInputParsing () { + private static void AssignBotForInputParsing() { bool needReassignment = false; for ( int i = 0; i < threads.Length; i++ ) { if ( threads[i].ResponsibleForInputParsing && !threads[i].IsReady ) { @@ -475,8 +474,9 @@ static void AssignBotForInputParsing () { } } - public static void Init () { - if ( !ConfigKey.IRCBotEnabled.Enabled() ) return; + public static void Init() { + if ( !ConfigKey.IRCBotEnabled.Enabled() ) + return; hostName = ConfigKey.IRCBotNetwork.GetString(); port = ConfigKey.IRCBotPort.GetInt(); @@ -490,8 +490,7 @@ public static void Init () { botNick = ConfigKey.IRCBotNick.GetString(); } - - public static bool Start () { + public static bool Start() { if ( !IrcNickRegex.IsMatch( botNick ) ) { Logger.Log( LogType.Error, "IRC: Unacceptable bot nick." ); return false; @@ -504,7 +503,6 @@ public static bool Start () { if ( thread.Start( botNick, true ) ) { threads = new[] { thread }; } - } else { List threadTemp = new List(); for ( int i = 0; i < threadCount; i++ ) { @@ -525,30 +523,33 @@ public static bool Start () { } } - - public static void SendChannelMessage ( [NotNull] string line ) { - if ( line == null ) throw new ArgumentNullException( "line" ); - if ( channelNames == null ) return; // in case IRC bot is disabled. + public static void SendChannelMessage( [NotNull] string line ) { + if ( line == null ) + throw new ArgumentNullException( "line" ); + if ( channelNames == null ) + return; // in case IRC bot is disabled. line = ProcessMessageToIRC( line ); for ( int i = 0; i < channelNames.Length; i++ ) { SendRawMessage( IRCCommands.Privmsg( channelNames[i], "" ), line, "" ); } } - - public static void SendAction ( [NotNull] string line ) { - if ( line == null ) throw new ArgumentNullException( "line" ); - if ( channelNames == null ) return; // in case IRC bot is disabled. + public static void SendAction( [NotNull] string line ) { + if ( line == null ) + throw new ArgumentNullException( "line" ); + if ( channelNames == null ) + return; // in case IRC bot is disabled. line = ProcessMessageToIRC( line ); for ( int i = 0; i < channelNames.Length; i++ ) { SendRawMessage( IRCCommands.Privmsg( channelNames[i], "\u0001ACTION " ), line, "\u0001" ); } } + private const int MaxMessageSize = 510; // +2 bytes for CR-LF - const int MaxMessageSize = 510; // +2 bytes for CR-LF - public static void SendRawMessage ( string prefix, [NotNull] string line, string suffix ) { - if ( line == null ) throw new ArgumentNullException( "line" ); + public static void SendRawMessage( string prefix, [NotNull] string line, string suffix ) { + if ( line == null ) + throw new ArgumentNullException( "line" ); // handle newlines if ( line.Contains( '\n' ) ) { string[] segments = line.Split( '\n' ); @@ -576,14 +577,13 @@ public static void SendRawMessage ( string prefix, [NotNull] string line, string OutputQueue.Enqueue( prefix + line + suffix ); } - - static bool IsBotNick ( [NotNull] string str ) { - if ( str == null ) throw new ArgumentNullException( "str" ); + private static bool IsBotNick( [NotNull] string str ) { + if ( str == null ) + throw new ArgumentNullException( "str" ); return threads.Any( t => t.ActualBotNick == str ); } - - internal static void Disconnect () { + internal static void Disconnect() { if ( threads != null && threads.Length > 0 ) { foreach ( IRCThread thread in threads ) { thread.DisconnectThread(); @@ -591,14 +591,14 @@ internal static void Disconnect () { } } - // includes IRC color codes and non-printable ASCII - static readonly Regex + private static readonly Regex IRCColorsAndNonStandardChars = new Regex( "\x03\\d{1,2}(,\\d{1,2})?|[^\x0A\x20-\x7E]" ), IRCColorsAndNonStandardCharsExceptEmotes = new Regex( "\x03\\d{1,2}(,\\d{1,2})?|[^\x0A\x20-\x7F☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼⌂]" ); - static string ProcessMessageFromIRC ( [NotNull] string message ) { - if ( message == null ) throw new ArgumentNullException( "message" ); + private static string ProcessMessageFromIRC( [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); bool useColor = ConfigKey.IRCUseColor.Enabled(); bool useEmotes = true; @@ -630,9 +630,9 @@ static string ProcessMessageFromIRC ( [NotNull] string message ) { return message.Trim(); } - - static string ProcessMessageToIRC ( [NotNull] string message ) { - if ( message == null ) throw new ArgumentNullException( "message" ); + private static string ProcessMessageToIRC( [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); bool useColor = ConfigKey.IRCUseColor.Enabled(); bool useEmotes = true; @@ -658,10 +658,9 @@ static string ProcessMessageToIRC ( [NotNull] string message ) { return message.Trim(); } - #region Server Event Handlers - static void HookUpHandlers () { + private static void HookUpHandlers() { Chat.Sent += ChatSentHandler; Player.Ready += PlayerReadyHandler; Player.Disconnected += PlayerDisconnectedHandler; @@ -670,7 +669,7 @@ static void HookUpHandlers () { PlayerInfo.RankChanged += PlayerInfoRankChangedHandler; } - static void ChatSentHandler ( object sender, ChatSentEventArgs args ) { + private static void ChatSentHandler( object sender, ChatSentEventArgs args ) { bool enabled = ConfigKey.IRCBotForwardFromServer.Enabled(); switch ( args.MessageType ) { case ChatMessageType.Global: @@ -698,8 +697,7 @@ static void ChatSentHandler ( object sender, ChatSentEventArgs args ) { } } - - public static void PlayerReadyHandler ( object sender, IPlayerEvent e ) { + public static void PlayerReadyHandler( object sender, IPlayerEvent e ) { if ( ConfigKey.IRCBotAnnounceServerJoins.Enabled() && !e.Player.Info.IsHidden ) { string message = String.Format( "{0}&S* {1}&S connected.", BoldCode, e.Player.ClassyName ); @@ -707,15 +705,13 @@ public static void PlayerReadyHandler ( object sender, IPlayerEvent e ) { } } - - public static void PlayerDisconnectedHandler ( object sender, PlayerDisconnectedEventArgs e ) { + public static void PlayerDisconnectedHandler( object sender, PlayerDisconnectedEventArgs e ) { if ( e.Player.HasFullyConnected && ConfigKey.IRCBotAnnounceServerJoins.Enabled() && !e.Player.Info.IsHidden ) { ShowPlayerDisconnectedMsg( e.Player, e.LeaveReason ); } } - - static void ShowPlayerDisconnectedMsg ( Player player, LeaveReason leaveReason ) { + private static void ShowPlayerDisconnectedMsg( Player player, LeaveReason leaveReason ) { string message = String.Format( "{0}&S* {1}&S left the server ({2})", BoldCode, player.ClassyName, @@ -723,15 +719,13 @@ static void ShowPlayerDisconnectedMsg ( Player player, LeaveReason leaveReason ) SendAction( message ); } - - static void PlayerKickedHandler ( object sender, PlayerKickedEventArgs e ) { + private static void PlayerKickedHandler( object sender, PlayerKickedEventArgs e ) { if ( e.Announce && e.Context == LeaveReason.Kick ) { PlayerSomethingMessage( e.Kicker, "kicked", e.Player.Info, e.Reason ); } } - - static void PlayerInfoBanChangedHandler ( object sender, PlayerInfoBanChangedEventArgs e ) { + private static void PlayerInfoBanChangedHandler( object sender, PlayerInfoBanChangedEventArgs e ) { if ( e.Announce ) { if ( e.IsBeingUnbanned ) { PlayerSomethingMessage( e.Banner, "unbanned", e.PlayerInfo, e.Reason ); @@ -741,8 +735,7 @@ static void PlayerInfoBanChangedHandler ( object sender, PlayerInfoBanChangedEve } } - - static void PlayerInfoRankChangedHandler ( object sender, PlayerInfoRankChangedEventArgs e ) { + private static void PlayerInfoRankChangedHandler( object sender, PlayerInfoRankChangedEventArgs e ) { if ( e.Announce ) { string actionString = String.Format( "{0} from {1}&W to {2}&W", e.RankChangeType, @@ -752,12 +745,15 @@ static void PlayerInfoRankChangedHandler ( object sender, PlayerInfoRankChangedE } } - - public static void PlayerSomethingMessage ( [NotNull] IClassy player, [NotNull] string action, [NotNull] IClassy target, [CanBeNull] string reason ) { - if ( player == null ) throw new ArgumentNullException( "player" ); - if ( action == null ) throw new ArgumentNullException( "action" ); - if ( target == null ) throw new ArgumentNullException( "target" ); - if ( !ConfigKey.IRCBotAnnounceServerEvents.Enabled() ) return; + public static void PlayerSomethingMessage( [NotNull] IClassy player, [NotNull] string action, [NotNull] IClassy target, [CanBeNull] string reason ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( action == null ) + throw new ArgumentNullException( "action" ); + if ( target == null ) + throw new ArgumentNullException( "target" ); + if ( !ConfigKey.IRCBotAnnounceServerEvents.Enabled() ) + return; string message = String.Format( "{0}&W* {1}&W was {2} by {3}&W", BoldCode, target.ClassyName, @@ -769,17 +765,17 @@ public static void PlayerSomethingMessage ( [NotNull] IClassy player, [NotNull] SendAction( message ); } - #endregion - + #endregion Server Event Handlers #region Parsing - static readonly IRCReplyCode[] ReplyCodes = ( IRCReplyCode[] )Enum.GetValues( typeof( IRCReplyCode ) ); + private static readonly IRCReplyCode[] ReplyCodes = ( IRCReplyCode[] )Enum.GetValues( typeof( IRCReplyCode ) ); - - static IRCMessageType GetMessageType ( [NotNull] string rawline, [NotNull] string actualBotNick ) { - if ( rawline == null ) throw new ArgumentNullException( "rawline" ); - if ( actualBotNick == null ) throw new ArgumentNullException( "actualBotNick" ); + private static IRCMessageType GetMessageType( [NotNull] string rawline, [NotNull] string actualBotNick ) { + if ( rawline == null ) + throw new ArgumentNullException( "rawline" ); + if ( actualBotNick == null ) + throw new ArgumentNullException( "actualBotNick" ); Match found = ReplyCodeRegex.Match( rawline ); if ( found.Success ) { @@ -959,10 +955,11 @@ static IRCMessageType GetMessageType ( [NotNull] string rawline, [NotNull] strin return found.Success ? IRCMessageType.Kill : IRCMessageType.Unknown; } - - static IRCMessage MessageParser ( [NotNull] string rawline, [NotNull] string actualBotNick ) { - if ( rawline == null ) throw new ArgumentNullException( "rawline" ); - if ( actualBotNick == null ) throw new ArgumentNullException( "actualBotNick" ); + private static IRCMessage MessageParser( [NotNull] string rawline, [NotNull] string actualBotNick ) { + if ( rawline == null ) + throw new ArgumentNullException( "rawline" ); + if ( actualBotNick == null ) + throw new ArgumentNullException( "actualBotNick" ); string line; string nick = null; @@ -1022,6 +1019,7 @@ static IRCMessage MessageParser ( [NotNull] string rawline, [NotNull] string act case IRCMessageType.ChannelNotice: channel = linear[2]; break; + case IRCMessageType.Who: case IRCMessageType.Topic: case IRCMessageType.Invite: @@ -1029,6 +1027,7 @@ static IRCMessage MessageParser ( [NotNull] string rawline, [NotNull] string act case IRCMessageType.ChannelMode: channel = linear[3]; break; + case IRCMessageType.Name: channel = linear[4]; break; @@ -1042,30 +1041,29 @@ static IRCMessage MessageParser ( [NotNull] string rawline, [NotNull] string act return new IRCMessage( from, nick, ident, host, channel, message, rawline, type, replycode ); } - - static readonly Regex ReplyCodeRegex = new Regex( "^:[^ ]+? ([0-9]{3}) .+$", RegexOptions.Compiled ); - static readonly Regex PingRegex = new Regex( "^PING :.*", RegexOptions.Compiled ); - static readonly Regex ErrorRegex = new Regex( "^ERROR :.*", RegexOptions.Compiled ); - static readonly Regex ActionRegex = new Regex( "^:.*? PRIVMSG (.).* :" + "\x1" + "ACTION .*" + "\x1" + "$", RegexOptions.Compiled ); - static readonly Regex CtcpRequestRegex = new Regex( "^:.*? PRIVMSG .* :" + "\x1" + ".*" + "\x1" + "$", RegexOptions.Compiled ); - static readonly Regex MessageRegex = new Regex( "^:.*? PRIVMSG (.).* :.*$", RegexOptions.Compiled ); - static readonly Regex CtcpReplyRegex = new Regex( "^:.*? NOTICE .* :" + "\x1" + ".*" + "\x1" + "$", RegexOptions.Compiled ); - static readonly Regex NoticeRegex = new Regex( "^:.*? NOTICE (.).* :.*$", RegexOptions.Compiled ); - static readonly Regex InviteRegex = new Regex( "^:.*? INVITE .* .*$", RegexOptions.Compiled ); - static readonly Regex JoinRegex = new Regex( "^:.*? JOIN .*$", RegexOptions.Compiled ); - static readonly Regex TopicRegex = new Regex( "^:.*? TOPIC .* :.*$", RegexOptions.Compiled ); - static readonly Regex NickRegex = new Regex( "^:.*? NICK .*$", RegexOptions.Compiled ); - static readonly Regex KickRegex = new Regex( "^:.*? KICK .* .*$", RegexOptions.Compiled ); - static readonly Regex PartRegex = new Regex( "^:.*? PART .*$", RegexOptions.Compiled ); - static readonly Regex ModeRegex = new Regex( "^:.*? MODE (.*) .*$", RegexOptions.Compiled ); - static readonly Regex QuitRegex = new Regex( "^:.*? QUIT :.*$", RegexOptions.Compiled ); - static readonly Regex KillRegex = new Regex( "^:.*? KILL (.*) :.*$", RegexOptions.Compiled ); - - #endregion + private static readonly Regex ReplyCodeRegex = new Regex( "^:[^ ]+? ([0-9]{3}) .+$", RegexOptions.Compiled ); + private static readonly Regex PingRegex = new Regex( "^PING :.*", RegexOptions.Compiled ); + private static readonly Regex ErrorRegex = new Regex( "^ERROR :.*", RegexOptions.Compiled ); + private static readonly Regex ActionRegex = new Regex( "^:.*? PRIVMSG (.).* :" + "\x1" + "ACTION .*" + "\x1" + "$", RegexOptions.Compiled ); + private static readonly Regex CtcpRequestRegex = new Regex( "^:.*? PRIVMSG .* :" + "\x1" + ".*" + "\x1" + "$", RegexOptions.Compiled ); + private static readonly Regex MessageRegex = new Regex( "^:.*? PRIVMSG (.).* :.*$", RegexOptions.Compiled ); + private static readonly Regex CtcpReplyRegex = new Regex( "^:.*? NOTICE .* :" + "\x1" + ".*" + "\x1" + "$", RegexOptions.Compiled ); + private static readonly Regex NoticeRegex = new Regex( "^:.*? NOTICE (.).* :.*$", RegexOptions.Compiled ); + private static readonly Regex InviteRegex = new Regex( "^:.*? INVITE .* .*$", RegexOptions.Compiled ); + private static readonly Regex JoinRegex = new Regex( "^:.*? JOIN .*$", RegexOptions.Compiled ); + private static readonly Regex TopicRegex = new Regex( "^:.*? TOPIC .* :.*$", RegexOptions.Compiled ); + private static readonly Regex NickRegex = new Regex( "^:.*? NICK .*$", RegexOptions.Compiled ); + private static readonly Regex KickRegex = new Regex( "^:.*? KICK .* .*$", RegexOptions.Compiled ); + private static readonly Regex PartRegex = new Regex( "^:.*? PART .*$", RegexOptions.Compiled ); + private static readonly Regex ModeRegex = new Regex( "^:.*? MODE (.*) .*$", RegexOptions.Compiled ); + private static readonly Regex QuitRegex = new Regex( "^:.*? QUIT :.*$", RegexOptions.Compiled ); + private static readonly Regex KillRegex = new Regex( "^:.*? KILL (.*) :.*$", RegexOptions.Compiled ); + + #endregion Parsing } - #pragma warning disable 1591 + /// IRC protocol reply codes. public enum IRCReplyCode { Null = 000, @@ -1212,7 +1210,6 @@ public enum IRCReplyCode { ErrorUsersDoNotMatch = 502 } - /// IRC message types. public enum IRCMessageType { Ping, @@ -1250,5 +1247,6 @@ public enum IRCMessageType { ErrorMessage, Unknown } + #pragma warning restore 1591 } \ No newline at end of file diff --git a/fCraft/Network/IRCCommands.cs b/fCraft/Network/IRCCommands.cs index b2579c6..3640587 100644 --- a/fCraft/Network/IRCCommands.cs +++ b/fCraft/Network/IRCCommands.cs @@ -1,7 +1,7 @@ /* Copyright 2009-2012 Matvei Stefarov - * + * * Based, in part, on SmartIrc4net code. Original license is reproduced below. - * + * * * * SmartIrc4net - the IRC library for .NET/C# @@ -28,8 +28,10 @@ using System; namespace fCraft { + // ReSharper disable UnusedMember.Global public static class IRCCommands { + public static string Pass( string password ) { return "PASS " + password; } @@ -316,7 +318,7 @@ public static string Who( string mask ) { } public static string Who( string mask, bool ircop ) { - if( ircop ) { + if ( ircop ) { return "WHO " + mask + " o"; } else { return "WHO " + mask; @@ -466,4 +468,4 @@ public static string Squit( string server, string comment ) { return "SQUIT " + server + " :" + comment; } } -} +} \ No newline at end of file diff --git a/fCraft/Network/IRCMessage.cs b/fCraft/Network/IRCMessage.cs index 1cde104..b98dd82 100644 --- a/fCraft/Network/IRCMessage.cs +++ b/fCraft/Network/IRCMessage.cs @@ -1,7 +1,7 @@ /* Copyright 2009-2012 Matvei Stefarov - * + * * Based, in part, on SmartIrc4net code. Original license is reproduced below. - * + * * * * SmartIrc4net - the IRC library for .NET/C# @@ -26,18 +26,30 @@ */ namespace fCraft { + // ReSharper disable FieldCanBeMadeReadOnly.Global public sealed class IRCMessage { + public string From { get; private set; } + public string Nick { get; private set; } + public string Ident { get; private set; } + public string Host { get; private set; } + public string Channel { get; private set; } + public string Message { get; private set; } + public string[] MessageArray { get; private set; } + public string RawMessage { get; private set; } + public string[] RawMessageArray { get; private set; } + public IRCMessageType Type { get; private set; } + public IRCReplyCode ReplyCode { get; private set; } public IRCMessage( string from, string nick, string ident, string host, string channel, string message, string rawMessage, IRCMessageType type, IRCReplyCode replycode ) { @@ -50,11 +62,11 @@ public IRCMessage( string from, string nick, string ident, string host, string c Ident = ident; Host = host; Channel = channel; - if( message != null ) { + if ( message != null ) { // message is optional Message = message; MessageArray = message.Split( new[] { ' ' } ); } } } -} +} \ No newline at end of file diff --git a/fCraft/Network/LineWrapper.cs b/fCraft/Network/LineWrapper.cs index 2408a54..6672137 100644 --- a/fCraft/Network/LineWrapper.cs +++ b/fCraft/Network/LineWrapper.cs @@ -6,81 +6,78 @@ using System.Text; using JetBrains.Annotations; -namespace fCraft -{ +namespace fCraft { + /// Intelligent line-wrapper for Minecraft protocol. /// Splits long messages into 64-character chunks of ASCII. /// Maintains colors between lines. Wraps at word boundaries and hyphens. /// Removes invalid characters and color sequences. /// Supports optional line prefixes for second and consequent lines. /// This class is implemented as IEnumerable of Packets, so it's usable with foreach() and Linq. - public sealed class LineWrapper : IEnumerable, IEnumerator - { - const string DefaultPrefixString = "> "; - static readonly byte[] DefaultPrefix; - + public sealed class LineWrapper : IEnumerable, IEnumerator { + private const string DefaultPrefixString = "> "; + private static readonly byte[] DefaultPrefix; - static LineWrapper() - { - DefaultPrefix = Encoding.ASCII.GetBytes(DefaultPrefixString); + static LineWrapper() { + DefaultPrefix = Encoding.ASCII.GetBytes( DefaultPrefixString ); } - - const int MaxPrefixSize = 48; - const int PacketSize = 66; // opcode + id + 64 - const byte DefaultColor = (byte)'f'; + private const int MaxPrefixSize = 48; + private const int PacketSize = 66; // opcode + id + 64 + private const byte DefaultColor = ( byte )'f'; public Packet Current { get; private set; } - bool expectingColor;// whether next input character is expected to be a color code - byte color, // color that the next inserted character should be + private bool expectingColor;// whether next input character is expected to be a color code + + private byte color, // color that the next inserted character should be lastColor; // used to detect duplicate color codes - bool endsWithSymbol; // used to guarantee suffixes for symbols ("emotes") + private bool endsWithSymbol; // used to guarantee suffixes for symbols ("emotes") - bool hadColor, // used to see if white (&f) colorcodes should be inserted + private bool hadColor, // used to see if white (&f) colorcodes should be inserted canWrap; // used to see if a word needs to be forcefully wrapped (i.e. doesnt fit in one line) - int spaceCount, // used to track spacing between words + private int spaceCount, // used to track spacing between words wordLength; // used to see whether to wrap at hyphens - readonly byte[] prefix; + private readonly byte[] prefix; - readonly byte[] input; - int inputIndex; + private readonly byte[] input; + private int inputIndex; - byte[] output; - int outputStart, + private byte[] output; + + private int outputStart, outputIndex; - int wrapInputIndex, // index of the nearest line-wrapping opportunity in the input buffer + private int wrapInputIndex, // index of the nearest line-wrapping opportunity in the input buffer wrapOutputIndex; // corresponding index in the output buffer - byte wrapColor; // value of "color" field at the wrapping point - bool wrapEndsWithSymbol; // value of "endsWithSymbol" field at the wrapping point + private byte wrapColor; // value of "color" field at the wrapping point + private bool wrapEndsWithSymbol; // value of "endsWithSymbol" field at the wrapping point - LineWrapper([NotNull] string message) - { - if (message == null) throw new ArgumentNullException("message"); - input = Encoding.ASCII.GetBytes(message); + private LineWrapper( [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + input = Encoding.ASCII.GetBytes( message ); prefix = DefaultPrefix; Reset(); } - - LineWrapper([NotNull] string prefixString, [NotNull] string message) - { - if (prefixString == null) throw new ArgumentNullException("prefixString"); - prefix = Encoding.ASCII.GetBytes(prefixString); - if (prefix.Length > MaxPrefixSize) throw new ArgumentException("Prefix too long", "prefixString"); - if (message == null) throw new ArgumentNullException("message"); - input = Encoding.ASCII.GetBytes(message); + private LineWrapper( [NotNull] string prefixString, [NotNull] string message ) { + if ( prefixString == null ) + throw new ArgumentNullException( "prefixString" ); + prefix = Encoding.ASCII.GetBytes( prefixString ); + if ( prefix.Length > MaxPrefixSize ) + throw new ArgumentException( "Prefix too long", "prefixString" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); + input = Encoding.ASCII.GetBytes( message ); Reset(); } - - public void Reset() - { + public void Reset() { color = DefaultColor; wordLength = 0; inputIndex = 0; @@ -88,17 +85,14 @@ public void Reset() wrapOutputIndex = 0; } - - public bool MoveNext() - { - if (inputIndex >= input.Length) - { + public bool MoveNext() { + if ( inputIndex >= input.Length ) { return false; } output = new byte[PacketSize]; - output[0] = (byte)OpCode.Message; - Current = new Packet(output); + output[0] = ( byte )OpCode.Message; + Current = new Packet( output ); hadColor = false; canWrap = false; @@ -116,21 +110,18 @@ public bool MoveNext() wrapEndsWithSymbol = false; // Prepend line prefix, if needed - if (inputIndex > 0 && prefix.Length > 0) - { + if ( inputIndex > 0 && prefix.Length > 0 ) { int preBufferInputIndex = inputIndex; byte preBufferColor = color; color = DefaultColor; inputIndex = 0; wrapInputIndex = 0; wordLength = 0; - while (inputIndex < prefix.Length) - { + while ( inputIndex < prefix.Length ) { byte ch = prefix[inputIndex]; - if (ProcessChar(ch)) - { + if ( ProcessChar( ch ) ) { // Should never happen, since prefix is under 48 chars - throw new Exception("Prefix required wrapping."); + throw new Exception( "Prefix required wrapping." ); } inputIndex++; } @@ -144,11 +135,9 @@ public bool MoveNext() canWrap = false; // to prevent linewrapping at prefix // Append as much of the remaining input as possible - while (inputIndex < input.Length) - { + while ( inputIndex < input.Length ) { byte ch = input[inputIndex]; - if (ProcessChar(ch)) - { + if ( ProcessChar( ch ) ) { // Line wrap is needed PrepareOutput(); return true; @@ -161,16 +150,12 @@ public bool MoveNext() return true; } - - bool ProcessChar(byte ch) - { - switch (ch) - { - case (byte)' ': + private bool ProcessChar( byte ch ) { + switch ( ch ) { + case ( byte )' ': canWrap = true; expectingColor = false; - if (spaceCount == 0) - { + if ( spaceCount == 0 ) { // first space after a word, set wrapping point wrapInputIndex = inputIndex; wrapOutputIndex = outputIndex; @@ -180,24 +165,21 @@ bool ProcessChar(byte ch) spaceCount++; break; - case (byte)'&': + case ( byte )'&': // skip double ampersands expectingColor = !expectingColor; break; - case (byte)'-': - if (spaceCount > 0) - { + case ( byte )'-': + if ( spaceCount > 0 ) { // set wrapping point, if at beginning of a word wrapInputIndex = inputIndex; wrapColor = color; wrapEndsWithSymbol = endsWithSymbol; } expectingColor = false; - if (!Append(ch)) - { - if (canWrap) - { + if ( !Append( ch ) ) { + if ( canWrap ) { // word doesn't fit in line, backtrack to wrapping point inputIndex = wrapInputIndex; outputIndex = wrapOutputIndex; @@ -207,8 +189,7 @@ bool ProcessChar(byte ch) return true; } spaceCount = 0; - if (wordLength > 2) - { + if ( wordLength > 2 ) { // allow wrapping after hyphen, if at least 2 word characters precede this hyphen wrapInputIndex = inputIndex + 1; wrapOutputIndex = outputIndex; @@ -219,46 +200,36 @@ bool ProcessChar(byte ch) } break; - case (byte)'\n': + case ( byte )'\n': // break the line early inputIndex++; return true; default: - if (expectingColor) - { + if ( expectingColor ) { expectingColor = false; - if (ch == 'N' || ch == 'n') - { + if ( ch == 'N' || ch == 'n' ) { // newline inputIndex++; return true; - } - else if (ProcessColor(ref ch)) - { + } else if ( ProcessColor( ref ch ) ) { // valid colorcode color = ch; hadColor = true; } // else colorcode is invalid, skip - } - else - { - if (spaceCount > 0) - { + } else { + if ( spaceCount > 0 ) { // set wrapping point, if at beginning of a word wrapInputIndex = inputIndex; wrapColor = color; wrapEndsWithSymbol = endsWithSymbol; } - if (ch == 0 || ch > 127) - { + if ( ch == 0 || ch > 127 ) { // replace unprintable chars with '?' - ch = (byte)'?'; + ch = ( byte )'?'; } - if (!Append(ch)) - { - if (canWrap) - { + if ( !Append( ch ) ) { + if ( canWrap ) { inputIndex = wrapInputIndex; outputIndex = wrapOutputIndex; color = wrapColor; @@ -272,17 +243,13 @@ bool ProcessChar(byte ch) return false; } - - void PrepareOutput() - { + private void PrepareOutput() { // pad the packet with spaces - for (int i = outputIndex; i < PacketSize; i++) - { - output[i] = (byte)' '; + for ( int i = outputIndex; i < PacketSize; i++ ) { + output[i] = ( byte )' '; } - if (endsWithSymbol) - { - output[65] = (byte)'.'; + if ( endsWithSymbol ) { + output[65] = ( byte )'.'; } #if DEBUG_LINE_WRAPPER Console.WriteLine( "\"" + Encoding.ASCII.GetString( output, outputStart, outputIndex - outputStart ) + "\"" ); @@ -290,46 +257,45 @@ void PrepareOutput() #endif } - - bool Append(byte ch) - { + private bool Append( byte ch ) { bool prependColor = // color changed since last inserted character lastColor != color || // no characters have been inserted, but color codes have been encountered - (color == DefaultColor && hadColor && outputIndex == outputStart); + ( color == DefaultColor && hadColor && outputIndex == outputStart ); // calculate the number of characters to insert int bytesToInsert = 1 + spaceCount; - if (prependColor) bytesToInsert += 2; + if ( prependColor ) + bytesToInsert += 2; // calculating requirements for the next symbol - if (ch < ' ') - { - switch (ch) - { + if ( ch < ' ' ) { + switch ( ch ) { case 7: case 25: bytesToInsert += 3; // 2 spaces pad AND 1-char terminator break; + case 9: case 22: case 24: bytesToInsert += 2; // 2 spaces pad OR 1-char terminator break; + case 12: case 18: case 19: bytesToInsert += 2; // 2 spaces pad OR 2-char terminator break; + default: bytesToInsert += 1; // 1-char terminator break; } } - if (outputIndex + bytesToInsert > PacketSize) - { + if ( outputIndex + bytesToInsert > PacketSize ) { #if DEBUG_LINE_WRAPPER Console.WriteLine( "X ii={0} ({1}+{2}+{3}={4}) wl={5} wi={6} woi={7}", inputIndex, @@ -340,9 +306,8 @@ bool Append(byte ch) } // append color, if changed since last inserted character - if (prependColor) - { - output[outputIndex++] = (byte)'&'; + if ( prependColor ) { + output[outputIndex++] = ( byte )'&'; output[outputIndex++] = color; lastColor = color; } @@ -351,12 +316,10 @@ bool Append(byte ch) int spacesToAppend = spaceCount; #endif - if (spaceCount > 0 && outputIndex > outputStart) - { + if ( spaceCount > 0 && outputIndex > outputStart ) { // append spaces that accumulated since last word - while (spaceCount > 0) - { - output[outputIndex++] = (byte)' '; + while ( spaceCount > 0 ) { + output[outputIndex++] = ( byte )' '; spaceCount--; } wordLength = 0; @@ -372,140 +335,131 @@ bool Append(byte ch) output[outputIndex++] = ch; // padding for symbols - switch (ch) - { + switch ( ch ) { case 9: - output[outputIndex++] = (byte)' '; - output[outputIndex++] = (byte)'.'; + output[outputIndex++] = ( byte )' '; + output[outputIndex++] = ( byte )'.'; endsWithSymbol = false; break; + case 12: - output[outputIndex++] = (byte)' '; - output[outputIndex++] = (byte)'`'; + output[outputIndex++] = ( byte )' '; + output[outputIndex++] = ( byte )'`'; endsWithSymbol = false; break; + case 18: - output[outputIndex++] = (byte)' '; - output[outputIndex++] = (byte)'.'; + output[outputIndex++] = ( byte )' '; + output[outputIndex++] = ( byte )'.'; endsWithSymbol = false; break; + case 19: - output[outputIndex++] = (byte)' '; - output[outputIndex++] = (byte)'!'; + output[outputIndex++] = ( byte )' '; + output[outputIndex++] = ( byte )'!'; endsWithSymbol = false; break; + case 22: - output[outputIndex++] = (byte)'.'; - output[outputIndex++] = (byte)' '; + output[outputIndex++] = ( byte )'.'; + output[outputIndex++] = ( byte )' '; endsWithSymbol = false; break; + case 24: - output[outputIndex++] = (byte)'^'; - output[outputIndex++] = (byte)' '; + output[outputIndex++] = ( byte )'^'; + output[outputIndex++] = ( byte )' '; endsWithSymbol = false; break; + case 7: case 25: - output[outputIndex++] = (byte)' '; - output[outputIndex++] = (byte)' '; + output[outputIndex++] = ( byte )' '; + output[outputIndex++] = ( byte )' '; endsWithSymbol = true; break; + default: - endsWithSymbol = (ch < ' '); + endsWithSymbol = ( ch < ' ' ); break; } return true; } - - static bool ProcessColor(ref byte ch) - { - if (ch >= (byte)'A' && ch <= (byte)'Z') - { + private static bool ProcessColor( ref byte ch ) { + if ( ch >= ( byte )'A' && ch <= ( byte )'Z' ) { ch += 32; } - if (ch >= (byte)'a' && ch <= (byte)'f' || - ch >= (byte)'0' && ch <= (byte)'9') - { + if ( ch >= ( byte )'a' && ch <= ( byte )'f' || + ch >= ( byte )'0' && ch <= ( byte )'9' ) { return true; } - switch (ch) - { - case (byte)'s': - ch = (byte)Color.Sys[1]; + switch ( ch ) { + case ( byte )'s': + ch = ( byte )Color.Sys[1]; return true; - case (byte)'y': - ch = (byte)Color.Say[1]; + case ( byte )'y': + ch = ( byte )Color.Say[1]; return true; - case (byte)'p': - ch = (byte)Color.PM[1]; + case ( byte )'p': + ch = ( byte )Color.PM[1]; return true; - case (byte)'r': - ch = (byte)Color.Announcement[1]; + case ( byte )'r': + ch = ( byte )Color.Announcement[1]; return true; - case (byte)'h': - ch = (byte)Color.Help[1]; + case ( byte )'h': + ch = ( byte )Color.Help[1]; return true; - case (byte)'w': - ch = (byte)Color.Warning[1]; + case ( byte )'w': + ch = ( byte )Color.Warning[1]; return true; - case (byte)'m': - ch = (byte)Color.Me[1]; + case ( byte )'m': + ch = ( byte )Color.Me[1]; return true; - case (byte)'i': - ch = (byte)Color.IRC[1]; + case ( byte )'i': + ch = ( byte )Color.IRC[1]; return true; } return false; } - - object IEnumerator.Current - { + object IEnumerator.Current { get { return Current; } } - - void IDisposable.Dispose() { } - + void IDisposable.Dispose() { + } #region IEnumerable Members - public IEnumerator GetEnumerator() - { + public IEnumerator GetEnumerator() { return this; } - - IEnumerator IEnumerable.GetEnumerator() - { + IEnumerator IEnumerable.GetEnumerator() { return this; } - #endregion - + #endregion IEnumerable Members /// Creates a new line wrapper for a given raw string. /// message is null. - public static LineWrapper Wrap(string message) - { - return new LineWrapper(message); + public static LineWrapper Wrap( string message ) { + return new LineWrapper( message ); } - /// Creates a new line wrapper for a given raw string. /// prefix or message is null. /// prefix length exceeds maximum allowed value (48 characters). - public static LineWrapper WrapPrefixed(string prefix, string message) - { - return new LineWrapper(prefix, message); + public static LineWrapper WrapPrefixed( string prefix, string message ) { + return new LineWrapper( prefix, message ); } } } \ No newline at end of file diff --git a/fCraft/Network/OpCode.cs b/fCraft/Network/OpCode.cs index c3cb9ef..4d83c80 100644 --- a/fCraft/Network/OpCode.cs +++ b/fCraft/Network/OpCode.cs @@ -1,6 +1,7 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft { + /// Minecraft protocol's opcodes. public enum OpCode { Handshake = 0, diff --git a/fCraft/Network/Packet.cs b/fCraft/Network/Packet.cs index efbcf13..44e39e7 100644 --- a/fCraft/Network/Packet.cs +++ b/fCraft/Network/Packet.cs @@ -9,31 +9,29 @@ public struct Packet { public readonly byte[] Data; public OpCode OpCode { - get { return (OpCode)Data[0]; } + get { return ( OpCode )Data[0]; } } public Packet( [NotNull] byte[] data ) { - if( data == null ) throw new ArgumentNullException( "data" ); + if ( data == null ) + throw new ArgumentNullException( "data" ); Data = data; } - /// Creates a packet of correct size for a given opcode, /// and sets the first (opcode) byte. public Packet( OpCode opcode ) { - Data = new byte[PacketSizes[(int)opcode]]; - Data[0] = (byte)opcode; + Data = new byte[PacketSizes[( int )opcode]]; + Data[0] = ( byte )opcode; } - /// Returns packet size (in bytes) for a given opcode. /// Size includes the opcode byte itself. public static int GetSize( OpCode opcode ) { - return PacketSizes[(int)opcode]; + return PacketSizes[( int )opcode]; } - - static readonly int[] PacketSizes = { + private static readonly int[] PacketSizes = { 131, // Handshake 1, // Ping 1, // MapBegin diff --git a/fCraft/Network/PacketWriter.cs b/fCraft/Network/PacketWriter.cs index 3936832..f38755d 100644 --- a/fCraft/Network/PacketWriter.cs +++ b/fCraft/Network/PacketWriter.cs @@ -6,16 +6,18 @@ using JetBrains.Annotations; namespace fCraft { + // Protocol encoder for outgoing packets public sealed class PacketWriter : BinaryWriter { - public PacketWriter( Stream stream ) : base( stream ) { } - + public PacketWriter( Stream stream ) + : base( stream ) { + } #region Direct Writing public void Write( OpCode opcode ) { - Write( (byte)opcode ); + Write( ( byte )opcode ); } /// Writes a 16-bit short integer in Big-Endian order. @@ -31,13 +33,14 @@ public override void Write( int data ) { /// Writes a string in Minecraft protocol format. /// Maximum length: 64 characters. public override void Write( [NotNull] string str ) { - if( str == null ) throw new ArgumentNullException( "str" ); - if( str.Length > 64 ) throw new ArgumentException( "String is too long (>64).", "str" ); + if ( str == null ) + throw new ArgumentNullException( "str" ); + if ( str.Length > 64 ) + throw new ArgumentException( "String is too long (>64).", "str" ); Write( Encoding.ASCII.GetBytes( str.PadRight( 64 ) ) ); } - #endregion - + #endregion Direct Writing #region Direct Writing Whole Packets @@ -50,23 +53,26 @@ public void WriteMapBegin() { } public void WriteMapChunk( [NotNull] byte[] chunk, int chunkSize, byte progress ) { - if( chunk == null ) throw new ArgumentNullException( "chunk" ); + if ( chunk == null ) + throw new ArgumentNullException( "chunk" ); Write( OpCode.MapChunk ); - Write( (short)chunkSize ); + Write( ( short )chunkSize ); Write( chunk, 0, 1024 ); Write( progress ); } internal void WriteMapEnd( [NotNull] Map map ) { - if( map == null ) throw new ArgumentNullException( "map" ); + if ( map == null ) + throw new ArgumentNullException( "map" ); Write( OpCode.MapEnd ); - Write( (short)map.Width ); - Write( (short)map.Height ); - Write( (short)map.Length ); + Write( ( short )map.Width ); + Write( ( short )map.Height ); + Write( ( short )map.Length ); } public void WriteAddEntity( byte id, [NotNull] Player player, Position pos ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Write( OpCode.AddEntity ); Write( id ); Write( player.ListName ); @@ -87,27 +93,29 @@ public void WriteTeleport( byte id, Position pos ) { Write( pos.L ); } - #endregion - + #endregion Direct Writing Whole Packets #region Packet Making internal static Packet MakeHandshake( [NotNull] Player player, [NotNull] string serverName, [NotNull] string motd ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( serverName == null ) throw new ArgumentNullException( "serverName" ); - if( motd == null ) throw new ArgumentNullException( "motd" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( serverName == null ) + throw new ArgumentNullException( "serverName" ); + if ( motd == null ) + throw new ArgumentNullException( "motd" ); Packet packet = new Packet( OpCode.Handshake ); packet.Data[1] = Config.ProtocolVersion; Encoding.ASCII.GetBytes( serverName.PadRight( 64 ), 0, 64, packet.Data, 2 ); Encoding.ASCII.GetBytes( motd.PadRight( 64 ), 0, 64, packet.Data, 66 ); - packet.Data[130] = (byte)(player.Can( Permission.DeleteAdmincrete ) ? 100 : 0); + packet.Data[130] = ( byte )( player.Can( Permission.DeleteAdmincrete ) ? 100 : 0 ); return packet; } - internal static Packet MakeMessage( [NotNull] string message ) { - if( message == null ) throw new ArgumentNullException( "message" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); Packet packet = new Packet( OpCode.Message ); packet.Data[1] = 0; // unused @@ -115,12 +123,12 @@ internal static Packet MakeMessage( [NotNull] string message ) { return packet; } - internal static Packet MakeAddEntity( int id, [NotNull] string name, Position pos ) { - if( name == null ) throw new ArgumentNullException( "name" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); Packet packet = new Packet( OpCode.AddEntity ); - packet.Data[1] = (byte)id; + packet.Data[1] = ( byte )id; Encoding.ASCII.GetBytes( name.PadRight( 64 ), 0, 64, packet.Data, 2 ); ToNetOrder( pos.X, packet.Data, 66 ); ToNetOrder( pos.Z, packet.Data, 68 ); @@ -130,26 +138,24 @@ internal static Packet MakeAddEntity( int id, [NotNull] string name, Position po return packet; } - internal static Packet MakeDisconnect( [NotNull] string reason ) { - if( reason == null ) throw new ArgumentNullException( "reason" ); + if ( reason == null ) + throw new ArgumentNullException( "reason" ); Packet packet = new Packet( OpCode.Kick ); Encoding.ASCII.GetBytes( reason.PadRight( 64 ), 0, 64, packet.Data, 1 ); return packet; } - internal static Packet MakeRemoveEntity( int id ) { Packet packet = new Packet( OpCode.RemoveEntity ); - packet.Data[1] = (byte)id; + packet.Data[1] = ( byte )id; return packet; } - internal static Packet MakeTeleport( int id, Position pos ) { Packet packet = new Packet( OpCode.Teleport ); - packet.Data[1] = (byte)id; + packet.Data[1] = ( byte )id; ToNetOrder( pos.X, packet.Data, 2 ); ToNetOrder( pos.Z, packet.Data, 4 ); ToNetOrder( pos.Y, packet.Data, 6 ); @@ -158,77 +164,70 @@ internal static Packet MakeTeleport( int id, Position pos ) { return packet; } - internal static Packet MakeSelfTeleport( Position pos ) { return MakeTeleport( 255, pos.GetFixed() ); } - internal static Packet MakeMoveRotate( int id, Position pos ) { Packet packet = new Packet( OpCode.MoveRotate ); - packet.Data[1] = (byte)id; - packet.Data[2] = (byte)(pos.X & 0xFF); - packet.Data[3] = (byte)(pos.Z & 0xFF); - packet.Data[4] = (byte)(pos.Y & 0xFF); + packet.Data[1] = ( byte )id; + packet.Data[2] = ( byte )( pos.X & 0xFF ); + packet.Data[3] = ( byte )( pos.Z & 0xFF ); + packet.Data[4] = ( byte )( pos.Y & 0xFF ); packet.Data[5] = pos.R; packet.Data[6] = pos.L; return packet; } - internal static Packet MakeMove( int id, Position pos ) { Packet packet = new Packet( OpCode.Move ); - packet.Data[1] = (byte)id; - packet.Data[2] = (byte)pos.X; - packet.Data[3] = (byte)pos.Z; - packet.Data[4] = (byte)pos.Y; + packet.Data[1] = ( byte )id; + packet.Data[2] = ( byte )pos.X; + packet.Data[3] = ( byte )pos.Z; + packet.Data[4] = ( byte )pos.Y; return packet; } - internal static Packet MakeRotate( int id, Position pos ) { Packet packet = new Packet( OpCode.Rotate ); - packet.Data[1] = (byte)id; + packet.Data[1] = ( byte )id; packet.Data[2] = pos.R; packet.Data[3] = pos.L; return packet; } - public static Packet MakeSetBlock( int x, int y, int z, Block type ) { Packet packet = new Packet( OpCode.SetBlockServer ); ToNetOrder( x, packet.Data, 1 ); ToNetOrder( z, packet.Data, 3 ); ToNetOrder( y, packet.Data, 5 ); - packet.Data[7] = (byte)type; + packet.Data[7] = ( byte )type; return packet; } - internal static Packet MakeSetBlock( Vector3I coords, Block type ) { Packet packet = new Packet( OpCode.SetBlockServer ); ToNetOrder( coords.X, packet.Data, 1 ); ToNetOrder( coords.Z, packet.Data, 3 ); ToNetOrder( coords.Y, packet.Data, 5 ); - packet.Data[7] = (byte)type; + packet.Data[7] = ( byte )type; return packet; } - internal static Packet MakeSetPermission( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Packet packet = new Packet( OpCode.SetPermission ); - packet.Data[1] = (byte)(player.Can( Permission.DeleteAdmincrete ) ? 100 : 0); + packet.Data[1] = ( byte )( player.Can( Permission.DeleteAdmincrete ) ? 100 : 0 ); return packet; } - #endregion - + #endregion Packet Making internal static void ToNetOrder( int number, byte[] arr, int offset ) { - arr[offset] = (byte)((number & 0xff00) >> 8); - arr[offset + 1] = (byte)(number & 0x00ff); + arr[offset] = ( byte )( ( number & 0xff00 ) >> 8 ); + arr[offset + 1] = ( byte )( number & 0x00ff ); } } } \ No newline at end of file diff --git a/fCraft/Network/Player.Networking.cs b/fCraft/Network/Player.Networking.cs index 8f8e980..26dd7c1 100644 --- a/fCraft/Network/Player.Networking.cs +++ b/fCraft/Network/Player.Networking.cs @@ -1,62 +1,66 @@ // Copyright 2009-2013 Matvei Stefarov using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; +using System.Text.RegularExpressions; using System.Threading; using fCraft.AutoRank; using fCraft.Drawing; using fCraft.Events; using fCraft.MapConversion; using JetBrains.Annotations; -using System.Text.RegularExpressions; -using System.Collections.Concurrent; namespace fCraft { + /// Represents a connection to a Minecraft client. Handles low-level interactions (e.g. networking). public sealed partial class Player { + public static int SocketTimeout { get; set; } + public static bool RelayAllUpdates { get; set; } - const int SleepDelay = 5; // milliseconds - const int SocketPollInterval = 200; // multiples of SleepDelay, approx. 1 second - const int PingInterval = 3; // multiples of SocketPollInterval, approx. 3 seconds - const string NoSmpMessage = "This server is for Minecraft Classic only."; + private const int SleepDelay = 5; // milliseconds + private const int SocketPollInterval = 200; // multiples of SleepDelay, approx. 1 second + private const int PingInterval = 3; // multiples of SocketPollInterval, approx. 3 seconds + + private const string NoSmpMessage = "This server is for Minecraft Classic only."; - static Player () { + static Player() { MaxBlockPlacementRange = 7 * 32; SocketTimeout = 10000; } - public LeaveReason LeaveReason { get; private set; } public IPAddress IP { get; private set; } - - bool canReceive = true, + private bool canReceive = true, canSend = true, canQueue = true; - Thread ioThread; - TcpClient client; - readonly NetworkStream stream; - BinaryReader reader; - PacketWriter writer; - ConcurrentQueue outputQueue = new ConcurrentQueue(), - priorityOutputQueue = new ConcurrentQueue(); + private Thread ioThread; + private TcpClient client; + private readonly NetworkStream stream; + private BinaryReader reader; + private PacketWriter writer; + private ConcurrentQueue outputQueue = new ConcurrentQueue(), + priorityOutputQueue = new ConcurrentQueue(); - public static void StartSession ( [NotNull] TcpClient tcpClient ) { - if ( tcpClient == null ) throw new ArgumentNullException( "tcpClient" ); + public static void StartSession( [NotNull] TcpClient tcpClient ) { + if ( tcpClient == null ) + throw new ArgumentNullException( "tcpClient" ); new Player( tcpClient ); } - Player ( [NotNull] TcpClient tcpClient ) { - if ( tcpClient == null ) throw new ArgumentNullException( "tcpClient" ); + private Player( [NotNull] TcpClient tcpClient ) { + if ( tcpClient == null ) + throw new ArgumentNullException( "tcpClient" ); State = SessionState.Connecting; LoginTime = DateTime.UtcNow; LastActiveTime = DateTime.UtcNow; @@ -73,7 +77,8 @@ public static void StartSession ( [NotNull] TcpClient tcpClient ) { try { IP = ( ( IPEndPoint )( client.Client.RemoteEndPoint ) ).Address; - if ( Server.RaiseSessionConnectingEvent( IP ) ) return; + if ( Server.RaiseSessionConnectingEvent( IP ) ) + return; stream = client.GetStream(); reader = new BinaryReader( stream ); @@ -84,26 +89,24 @@ public static void StartSession ( [NotNull] TcpClient tcpClient ) { IsBackground = true }; ioThread.Start(); - } catch ( SocketException ) { // Mono throws SocketException when accessing Client.RemoteEndPoint on disconnected sockets Disconnect(); - } catch ( Exception ex ) { Logger.LogAndReportCrash( "Session failed to start", "800Craft", ex, false ); Disconnect(); } } - #region I/O Loop - void IoLoop () { + private void IoLoop() { try { Server.RaiseSessionConnectedEvent( this ); // try to log the player in, otherwise die. - if ( !LoginSequence() ) return; + if ( !LoginSequence() ) + return; BandwidthUseMode = Info.BandwidthUseMode; @@ -153,9 +156,11 @@ void IoLoop () { // send output to player while ( canSend && packetsSent < Server.MaxSessionPacketsPerTick ) { if ( !priorityOutputQueue.TryDequeue( out packet ) ) - if ( !outputQueue.TryDequeue( out packet ) ) break; + if ( !outputQueue.TryDequeue( out packet ) ) + break; - if ( IsDeaf && packet.OpCode == OpCode.Message ) continue; + if ( IsDeaf && packet.OpCode == OpCode.Message ) + continue; writer.Write( packet.Data ); BytesSent += packet.Data.Length; @@ -163,7 +168,8 @@ void IoLoop () { if ( packet.OpCode == OpCode.Kick ) { writer.Flush(); - if ( LeaveReason == LeaveReason.Unknown ) LeaveReason = LeaveReason.Kick; + if ( LeaveReason == LeaveReason.Unknown ) + LeaveReason = LeaveReason.Kick; return; } @@ -183,7 +189,8 @@ void IoLoop () { packetsSent++; if ( packet.OpCode == OpCode.Kick ) { writer.Flush(); - if ( LeaveReason == LeaveReason.Unknown ) LeaveReason = LeaveReason.Kick; + if ( LeaveReason == LeaveReason.Unknown ) + LeaveReason = LeaveReason.Kick; return; } } @@ -202,14 +209,13 @@ void IoLoop () { } } - // get input from player while ( canReceive && stream.DataAvailable ) { byte opcode = reader.ReadByte(); switch ( ( OpCode )opcode ) { - case OpCode.Message: - if ( !ProcessMessagePacket() ) return; + if ( !ProcessMessagePacket() ) + return; break; case OpCode.Teleport: @@ -241,10 +247,8 @@ void IoLoop () { Thread.Sleep( SleepDelay ); } - } catch ( IOException ) { LeaveReason = LeaveReason.ClientQuit; - } catch ( SocketException ) { LeaveReason = LeaveReason.ClientQuit; #if !DEBUG @@ -259,8 +263,7 @@ void IoLoop () { } } - - bool ProcessMessagePacket () { + private bool ProcessMessagePacket() { BytesReceived += 66; ResetIdleTimer(); reader.ReadByte(); @@ -298,8 +301,7 @@ bool ProcessMessagePacket () { return true; } - - void ProcessMovementPacket () { + private void ProcessMovementPacket() { BytesReceived += 10; reader.ReadByte(); Position newPos = new Position { @@ -322,13 +324,15 @@ void ProcessMovementPacket () { }; // skip everything if player hasn't moved - if ( delta.IsZero ) return; + if ( delta.IsZero ) + return; bool rotChanged = ( delta.R != 0 ) || ( delta.L != 0 ); // only reset the timer if player rotated // if player is just pushed around, rotation does not change (and timer should not reset) - if ( rotChanged ) ResetIdleTimer(); + if ( rotChanged ) + ResetIdleTimer(); if ( Info.IsFrozen ) { // special handling for frozen players @@ -344,7 +348,6 @@ void ProcessMovementPacket () { delta.X = 0; delta.Y = 0; delta.Z = 0; - } if ( IsFlying ) { Vector3I oldPosi = new Vector3I( oldPos.X / 32, oldPos.Y / 32, oldPos.Z / 32 ); @@ -374,7 +377,6 @@ void ProcessMovementPacket () { } } - // Remove old blocks foreach ( Vector3I block in FlyCache.Values ) { if ( fCraft.Utils.FlyHandler.CanRemoveBlock( this, block, newPosi ) ) { @@ -389,10 +391,8 @@ void ProcessMovementPacket () { // speedhack detection if ( DetectMovementPacketSpam() ) { return; - } else if ( ( distSquared - delta.Z * delta.Z > AntiSpeedMaxDistanceSquared || delta.Z > AntiSpeedMaxJumpDelta ) && speedHackDetectionCounter >= 0 ) { - if ( speedHackDetectionCounter == 0 ) { lastValidPosition = Position; } else if ( speedHackDetectionCounter > 1 ) { @@ -401,7 +401,6 @@ void ProcessMovementPacket () { return; } speedHackDetectionCounter++; - } else { speedHackDetectionCounter = 0; } @@ -416,10 +415,10 @@ void ProcessMovementPacket () { RaisePlayerMovedEvent( this, oldPos ); } - - void ProcessSetBlockPacket () { + private void ProcessSetBlockPacket() { BytesReceived += 9; - if ( World == null || World.Map == null ) return; + if ( World == null || World.Map == null ) + return; ResetIdleTimer(); short x = IPAddress.NetworkToHostOrder( reader.ReadInt16() ); short z = IPAddress.NetworkToHostOrder( reader.ReadInt16() ); @@ -450,10 +449,9 @@ void ProcessSetBlockPacket () { } } - #endregion + #endregion I/O Loop - - void Disconnect () { + private void Disconnect() { State = SessionState.Disconnected; Server.UnregisterSession( this ); Server.RaiseSessionDisconnectedEvent( this, LeaveReason ); @@ -481,8 +479,7 @@ void Disconnect () { ioThread = null; } - - bool LoginSequence () { + private bool LoginSequence() { byte opcode = reader.ReadByte(); switch ( opcode ) { @@ -534,7 +531,8 @@ bool LoginSequence () { Logger.Log( LogType.SystemActivity, "Email account " + givenName + " connected, attemping to create unique new name" ); int nameAppend = PlayerDB.PlayerInfoList.Where( p => p.MojangAccount != null ).Count() + 1; string trimmedName = givenName.Split( '@' )[0].Replace( "@", "" ); //this should be the first part of the name ("Jonty800"@email.com) - if ( trimmedName == null ) throw new ArgumentNullException( "trimmedName" ); + if ( trimmedName == null ) + throw new ArgumentNullException( "trimmedName" ); if ( trimmedName.Length > 16 ) { trimmedName = trimmedName.Substring( 0, 15 - ( nameAppend.ToString().Length ) ); //shorten name } @@ -579,7 +577,6 @@ bool LoginSequence () { Info = PlayerDB.FindOrCreateInfoForPlayer( givenName, IP ); ResetAllBinds(); - if ( Server.VerifyName( packetPlayerName, verificationCode, Heartbeat.Salt ) ) { IsVerified = true; // update capitalization of player's name @@ -599,13 +596,11 @@ bool LoginSequence () { "{0} Player was identified as connecting from localhost and allowed in.", standardMessage ); IsVerified = true; - } else if ( IP.IsLAN() && ConfigKey.AllowUnverifiedLAN.Enabled() ) { Logger.Log( LogType.SuspiciousActivity, "{0} Player was identified as connecting from LAN and allowed in.", standardMessage ); IsVerified = true; - } else if ( Info.TimesVisited > 1 && Info.LastIP.Equals( IP ) ) { switch ( nameVerificationMode ) { case NameVerificationMode.Always: @@ -625,7 +620,6 @@ bool LoginSequence () { IsVerified = true; break; } - } else { switch ( nameVerificationMode ) { case NameVerificationMode.Always: @@ -685,7 +679,6 @@ bool LoginSequence () { return false; } - // Check if player's IP is banned IPBanInfo ipBanInfo = IPBanList.Get( IP ); if ( ipBanInfo != null && Info.BanStatus != BanStatus.IPBanExempt ) { @@ -701,7 +694,6 @@ bool LoginSequence () { return false; } - // Check if max number of connections is reached for IP if ( !Server.RegisterSession( this ) ) { Info.ProcessFailedLogin( this ); @@ -712,7 +704,6 @@ bool LoginSequence () { return false; } - // Check if player is paid (if required) if ( ConfigKey.PaidPlayersOnly.Enabled() ) { SendNow( PacketWriter.MakeHandshake( this, @@ -721,10 +712,9 @@ bool LoginSequence () { writer.Flush(); } - // Any additional security checks should be done right here - if ( RaisePlayerConnectingEvent( this ) ) return false; - + if ( RaisePlayerConnectingEvent( this ) ) + return false; // ----==== beyond this point, player is considered connecting (allowed to join) ====---- @@ -740,11 +730,9 @@ bool LoginSequence () { Info.ProcessLogin( this ); State = SessionState.LoadingMain; - // ----==== Beyond this point, player is considered connected (authenticated and registered) ====---- Logger.Log( LogType.UserActivity, "Player {0} connected from {1}.", Name, IP ); - // Figure out what the starting world should be World startingWorld = Info.Rank.MainWorld ?? WorldManager.MainWorld; startingWorld = RaisePlayerConnectedEvent( this, startingWorld ); @@ -787,7 +775,6 @@ bool LoginSequence () { return false; } - // ==== Beyond this point, player is considered ready (has a world) ==== var canSee = Server.Players.CanSee( this ); @@ -883,8 +870,7 @@ bool LoginSequence () { return true; } - - void GentlyKickBetaClients () { + private void GentlyKickBetaClients() { // This may be someone connecting with an SMP client int strLen = IPAddress.NetworkToHostOrder( reader.ReadInt16() ); @@ -903,7 +889,6 @@ void GentlyKickBetaClients () { writer.Write( stringData ); BytesSent += ( 1 + stringData.Length ); writer.Flush(); - } else { // Not SMP client (invalid player name length) Logger.Log( LogType.Error, @@ -912,9 +897,9 @@ void GentlyKickBetaClients () { } } + private static readonly Regex HttpFirstLine = new Regex( "GET /([a-zA-Z0-9_]{1,16})(~motd)? .+", RegexOptions.Compiled ); - static readonly Regex HttpFirstLine = new Regex( "GET /([a-zA-Z0-9_]{1,16})(~motd)? .+", RegexOptions.Compiled ); - void ServeCfg () { + private void ServeCfg() { using ( StreamReader textReader = new StreamReader( stream ) ) { using ( StreamWriter textWriter = new StreamWriter( stream ) ) { string firstLine = "G" + textReader.ReadLine(); @@ -942,19 +927,20 @@ void ServeCfg () { } } - #region Joining Worlds - readonly object joinWorldLock = new object(); + private readonly object joinWorldLock = new object(); [CanBeNull] - World forcedWorldToJoin; - WorldChangeReason worldChangeReason; - Position postJoinPosition; - bool useWorldSpawn; + private World forcedWorldToJoin; + + private WorldChangeReason worldChangeReason; + private Position postJoinPosition; + private bool useWorldSpawn; - public void JoinWorld ( [NotNull] World newWorld, WorldChangeReason reason ) { - if ( newWorld == null ) throw new ArgumentNullException( "newWorld" ); + public void JoinWorld( [NotNull] World newWorld, WorldChangeReason reason ) { + if ( newWorld == null ) + throw new ArgumentNullException( "newWorld" ); lock ( joinWorldLock ) { useWorldSpawn = true; postJoinPosition = Position.Zero; @@ -963,9 +949,9 @@ public void JoinWorld ( [NotNull] World newWorld, WorldChangeReason reason ) { } } - - public void JoinWorld ( [NotNull] World newWorld, WorldChangeReason reason, Position position ) { - if ( newWorld == null ) throw new ArgumentNullException( "newWorld" ); + public void JoinWorld( [NotNull] World newWorld, WorldChangeReason reason, Position position ) { + if ( newWorld == null ) + throw new ArgumentNullException( "newWorld" ); if ( !Enum.IsDefined( typeof( WorldChangeReason ), reason ) ) { throw new ArgumentOutOfRangeException( "reason" ); } @@ -977,9 +963,9 @@ public void JoinWorld ( [NotNull] World newWorld, WorldChangeReason reason, Posi } } - - internal bool JoinWorldNow ( [NotNull] World newWorld, bool doUseWorldSpawn, WorldChangeReason reason ) { - if ( newWorld == null ) throw new ArgumentNullException( "newWorld" ); + internal bool JoinWorldNow( [NotNull] World newWorld, bool doUseWorldSpawn, WorldChangeReason reason ) { + if ( newWorld == null ) + throw new ArgumentNullException( "newWorld" ); if ( !Enum.IsDefined( typeof( WorldChangeReason ), reason ) ) { throw new ArgumentOutOfRangeException( "reason" ); } @@ -1134,15 +1120,14 @@ internal bool JoinWorldNow ( [NotNull] World newWorld, bool doUseWorldSpawn, Wor return true; } - #endregion - + #endregion Joining Worlds #region Sending /// Send packet to player (not thread safe, sync, immediate). /// Should NEVER be used from any thread other than this session's ioThread. /// Not thread-safe (for performance reason). - public void SendNow ( Packet packet ) { + public void SendNow( Packet packet ) { if ( Thread.CurrentThread != ioThread ) { throw new InvalidOperationException( "SendNow may only be called from player's own thread." ); } @@ -1150,46 +1135,43 @@ public void SendNow ( Packet packet ) { BytesSent += packet.Data.Length; } - /// Send packet (thread-safe, async, priority queue). /// This is used for most packets (movement, chat, etc). - public void Send ( Packet packet ) { - if ( canQueue ) priorityOutputQueue.Enqueue( packet ); + public void Send( Packet packet ) { + if ( canQueue ) + priorityOutputQueue.Enqueue( packet ); } - /// Send packet (thread-safe, asynchronous, delayed queue). /// This is currently only used for block updates. - public void SendLowPriority ( Packet packet ) { - if ( canQueue ) outputQueue.Enqueue( packet ); + public void SendLowPriority( Packet packet ) { + if ( canQueue ) + outputQueue.Enqueue( packet ); } - #endregion - + #endregion Sending - string ReadString () { + private string ReadString() { return Encoding.ASCII.GetString( reader.ReadBytes( 64 ) ).TrimEnd(); } - /// Clears the low priority player queue. - void ClearLowPriotityOutputQueue () { + private void ClearLowPriotityOutputQueue() { outputQueue = new ConcurrentQueue(); } - /// Clears the priority player queue. - void ClearPriorityOutputQueue () { + private void ClearPriorityOutputQueue() { priorityOutputQueue = new ConcurrentQueue(); } - #region Kicking /// Kick (asynchronous). Immediately blocks all client input, but waits /// until client thread has sent the kick packet. - public void Kick ( [NotNull] string message, LeaveReason leaveReason ) { - if ( message == null ) throw new ArgumentNullException( "message" ); + public void Kick( [NotNull] string message, LeaveReason leaveReason ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); if ( !Enum.IsDefined( typeof( LeaveReason ), leaveReason ) ) { throw new ArgumentOutOfRangeException( "leaveReason" ); } @@ -1207,11 +1189,11 @@ public void Kick ( [NotNull] string message, LeaveReason leaveReason ) { priorityOutputQueue.Enqueue( PacketWriter.MakeDisconnect( message ) ); } - /// Kick (synchronous). Immediately sends the kick packet. /// Can only be used from IoThread (this is not thread-safe). - void KickNow ( [NotNull] string message, LeaveReason leaveReason ) { - if ( message == null ) throw new ArgumentNullException( "message" ); + private void KickNow( [NotNull] string message, LeaveReason leaveReason ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); if ( !Enum.IsDefined( typeof( LeaveReason ), leaveReason ) ) { throw new ArgumentOutOfRangeException( "leaveReason" ); } @@ -1228,9 +1210,8 @@ void KickNow ( [NotNull] string message, LeaveReason leaveReason ) { writer.Flush(); } - /// Blocks the calling thread until this session disconnects. - public void WaitForDisconnect () { + public void WaitForDisconnect() { if ( Thread.CurrentThread == ioThread ) { throw new InvalidOperationException( "Cannot call WaitForDisconnect from IoThread." ); } @@ -1242,36 +1223,39 @@ public void WaitForDisconnect () { } } - #endregion - + #endregion Kicking #region Movement // visible entities - readonly Dictionary entities = new Dictionary(); - readonly Stack playersToRemove = new Stack( 127 ); - readonly Stack freePlayerIDs = new Stack( 127 ); + private readonly Dictionary entities = new Dictionary(); + + private readonly Stack playersToRemove = new Stack( 127 ); + private readonly Stack freePlayerIDs = new Stack( 127 ); // movement optimization - int fullUpdateCounter; + private int fullUpdateCounter; + public const int FullPositionUpdateIntervalDefault = 20; public static int FullPositionUpdateInterval = FullPositionUpdateIntervalDefault; - const int SkipMovementThresholdSquared = 64, + + private const int SkipMovementThresholdSquared = 64, SkipRotationThresholdSquared = 1500; // anti-speedhack vars - int speedHackDetectionCounter; - const int AntiSpeedMaxJumpDelta = 25, // 16 for normal client, 25 for WoM + private int speedHackDetectionCounter; + + private const int AntiSpeedMaxJumpDelta = 25, // 16 for normal client, 25 for WoM AntiSpeedMaxDistanceSquared = 1024, // 32 * 32 AntiSpeedMaxPacketCount = 200, AntiSpeedMaxPacketInterval = 6; // anti-speedhack vars: packet spam - readonly Queue antiSpeedPacketLog = new Queue(); - DateTime antiSpeedLastNotification = DateTime.UtcNow; + private readonly Queue antiSpeedPacketLog = new Queue(); + private DateTime antiSpeedLastNotification = DateTime.UtcNow; - void ResetVisibleEntities () { + private void ResetVisibleEntities() { foreach ( var pos in entities.Values ) { SendNow( PacketWriter.MakeRemoveEntity( pos.Id ) ); } @@ -1283,9 +1267,9 @@ void ResetVisibleEntities () { entities.Clear(); } - - void UpdateVisibleEntities () { - if ( World == null ) PlayerOpException.ThrowNoWorld( this ); + private void UpdateVisibleEntities() { + if ( World == null ) + PlayerOpException.ThrowNoWorld( this ); if ( possessionPlayer != null ) { if ( !possessionPlayer.IsOnline || possessionPlayer.IsSpectating ) { Message( "You have been released from possession" ); @@ -1349,7 +1333,8 @@ void UpdateVisibleEntities () { Player otherPlayer = worldPlayerList[i]; if ( otherPlayer == this || !CanSeeMoving( otherPlayer ) || - spectatedPlayer == otherPlayer || possessionPlayer != null ) continue; + spectatedPlayer == otherPlayer || possessionPlayer != null ) + continue; Position otherPos = otherPlayer.Position; int distance = pos.DistanceSquaredTo( otherPos ); @@ -1366,16 +1351,13 @@ void UpdateVisibleEntities () { if ( otherPlayer.entityChanged ) { ReAddEntity( entity, otherPlayer, otherPos ); otherPlayer.entityChanged = false; - } else if ( entity.Hidden ) { if ( distance < entityShowingThreshold ) { ShowEntity( entity, otherPos ); } - } else { if ( distance > entityHidingThreshold ) { HideEntity( entity ); - } else if ( entity.LastKnownPosition != otherPos ) { MoveEntity( entity, otherPos ); } @@ -1385,7 +1367,6 @@ void UpdateVisibleEntities () { } } - // Find entities to remove (not marked for retention). foreach ( var pair in entities ) { if ( pair.Value.MarkedForRetention ) { @@ -1406,9 +1387,9 @@ void UpdateVisibleEntities () { } } - - void AddEntity ( [NotNull] Player player, Position newPos ) { - if ( player == null ) throw new ArgumentNullException( "player" ); + private void AddEntity( [NotNull] Player player, Position newPos ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); if ( freePlayerIDs.Count > 0 ) { var pos = new VisibleEntity( newPos, freePlayerIDs.Pop(), player.Info.Rank ); entities.Add( player, pos ); @@ -1416,42 +1397,43 @@ void AddEntity ( [NotNull] Player player, Position newPos ) { } } - - void HideEntity ( [NotNull] VisibleEntity entity ) { - if ( entity == null ) throw new ArgumentNullException( "entity" ); + private void HideEntity( [NotNull] VisibleEntity entity ) { + if ( entity == null ) + throw new ArgumentNullException( "entity" ); entity.Hidden = true; entity.LastKnownPosition = VisibleEntity.HiddenPosition; SendNow( PacketWriter.MakeTeleport( entity.Id, VisibleEntity.HiddenPosition ) ); } - - void ShowEntity ( [NotNull] VisibleEntity entity, Position newPos ) { - if ( entity == null ) throw new ArgumentNullException( "entity" ); + private void ShowEntity( [NotNull] VisibleEntity entity, Position newPos ) { + if ( entity == null ) + throw new ArgumentNullException( "entity" ); entity.Hidden = false; entity.LastKnownPosition = newPos; SendNow( PacketWriter.MakeTeleport( entity.Id, newPos ) ); } - - void ReAddEntity ( [NotNull] VisibleEntity entity, [NotNull] Player player, Position newPos ) { - if ( entity == null ) throw new ArgumentNullException( "entity" ); - if ( player == null ) throw new ArgumentNullException( "player" ); + private void ReAddEntity( [NotNull] VisibleEntity entity, [NotNull] Player player, Position newPos ) { + if ( entity == null ) + throw new ArgumentNullException( "entity" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); SendNow( PacketWriter.MakeRemoveEntity( entity.Id ) ); SendNow( PacketWriter.MakeAddEntity( entity.Id, player.ListName, newPos ) ); entity.LastKnownPosition = newPos; } - - void RemoveEntity ( [NotNull] Player player ) { - if ( player == null ) throw new ArgumentNullException( "player" ); + private void RemoveEntity( [NotNull] Player player ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); SendNow( PacketWriter.MakeRemoveEntity( entities[player].Id ) ); freePlayerIDs.Push( entities[player].Id ); entities.Remove( player ); } - - void MoveEntity ( [NotNull] VisibleEntity entity, Position newPos ) { - if ( entity == null ) throw new ArgumentNullException( "entity" ); + private void MoveEntity( [NotNull] VisibleEntity entity, Position newPos ) { + if ( entity == null ) + throw new ArgumentNullException( "entity" ); Position oldPos = entity.LastKnownPosition; // calculate difference between old and new positions @@ -1472,7 +1454,6 @@ void MoveEntity ( [NotNull] VisibleEntity entity, Position newPos ) { if ( distSquared < SkipMovementThresholdSquared && ( delta.R * delta.R + delta.L * delta.L ) < SkipRotationThresholdSquared && !entity.SkippedLastMove ) { - entity.SkippedLastMove = true; return; } @@ -1491,18 +1472,15 @@ void MoveEntity ( [NotNull] VisibleEntity entity, Position newPos ) { R = newPos.R, L = newPos.L } ); - } else if ( posChanged ) { // incremental position update packet = PacketWriter.MakeMove( entity.Id, delta ); - } else if ( rotChanged ) { // absolute rotation update packet = PacketWriter.MakeRotate( entity.Id, newPos ); } else { return; } - } else { // full (absolute position + rotation) update packet = PacketWriter.MakeTeleport( entity.Id, newPos ); @@ -1512,11 +1490,10 @@ void MoveEntity ( [NotNull] VisibleEntity entity, Position newPos ) { SendNow( packet ); } - - sealed class VisibleEntity { + private sealed class VisibleEntity { public static readonly Position HiddenPosition = new Position( 0, 0, short.MinValue ); - public VisibleEntity ( Position newPos, sbyte newId, Rank newRank ) { + public VisibleEntity( Position newPos, sbyte newId, Rank newRank ) { Id = newId; LastKnownPosition = newPos; MarkedForRetention = true; @@ -1532,10 +1509,9 @@ public VisibleEntity ( Position newPos, sbyte newId, Rank newRank ) { public bool SkippedLastMove; } + private Position lastValidPosition; // used in speedhack detection - Position lastValidPosition; // used in speedhack detection - - bool DetectMovementPacketSpam () { + private bool DetectMovementPacketSpam() { if ( antiSpeedPacketLog.Count >= AntiSpeedMaxPacketCount ) { DateTime oldestTime = antiSpeedPacketLog.Dequeue(); double spamTimer = DateTime.UtcNow.Subtract( oldestTime ).TotalSeconds; @@ -1548,8 +1524,7 @@ bool DetectMovementPacketSpam () { return false; } - - void DenyMovement () { + private void DenyMovement() { SendNow( PacketWriter.MakeSelfTeleport( lastValidPosition ) ); if ( DateTime.UtcNow.Subtract( antiSpeedLastNotification ).Seconds > 1 ) { Message( "&WYou are not allowed to speedhack." ); @@ -1557,18 +1532,16 @@ void DenyMovement () { } } - #endregion - + #endregion Movement #region Bandwidth Use Tweaks - BandwidthUseMode bandwidthUseMode; - int entityShowingThreshold, entityHidingThreshold; - bool partialUpdates, skipUpdates; - - DateTime lastMovementUpdate; - TimeSpan movementUpdateInterval; + private BandwidthUseMode bandwidthUseMode; + private int entityShowingThreshold, entityHidingThreshold; + private bool partialUpdates, skipUpdates; + private DateTime lastMovementUpdate; + private TimeSpan movementUpdateInterval; public BandwidthUseMode BandwidthUseMode { get { @@ -1625,14 +1598,12 @@ public BandwidthUseMode BandwidthUseMode { } } - #endregion - + #endregion Bandwidth Use Tweaks #region Bandwidth Use Metering - DateTime lastMeasurementDate = DateTime.UtcNow; - int lastBytesSent, lastBytesReceived; - + private DateTime lastMeasurementDate = DateTime.UtcNow; + private int lastBytesSent, lastBytesReceived; /// Total bytes sent (to the client) this session. public int BytesSent { get; private set; } @@ -1646,8 +1617,7 @@ public BandwidthUseMode BandwidthUseMode { /// Bytes received (from the client) per second, averaged over the last several seconds. public double BytesReceivedRate { get; private set; } - - void MeasureBandwidthUseRates () { + private void MeasureBandwidthUseRates() { int sentDelta = BytesSent - lastBytesSent; int receivedDelta = BytesReceived - lastBytesReceived; TimeSpan timeDelta = DateTime.UtcNow.Subtract( lastMeasurementDate ); @@ -1658,6 +1628,6 @@ void MeasureBandwidthUseRates () { lastMeasurementDate = DateTime.UtcNow; } - #endregion + #endregion Bandwidth Use Metering } } \ No newline at end of file diff --git a/fCraft/Physics/ExplodingPhysics.cs b/fCraft/Physics/ExplodingPhysics.cs index ae25a83..abbc9e5 100644 --- a/fCraft/Physics/ExplodingPhysics.cs +++ b/fCraft/Physics/ExplodingPhysics.cs @@ -24,23 +24,20 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Linq; -using System.Text; -using fCraft.Events; using Util = RandomMaze.MazeUtil; -namespace fCraft -{ - public class TNTTask : PhysicsTask - { - private struct BData - { +namespace fCraft { + + public class TNTTask : PhysicsTask { + + private struct BData { public int X, Y, Z; public Block PrevBlock; } + public const int ExplosionDelay = 3000; private const int StepDelay = 100; private static ExplosionParticleBehavior _particleBehavior = new ExplosionParticleBehavior(); @@ -54,8 +51,7 @@ private struct BData private Random _r = new Random(); private List _explosion; - private enum Stage - { + private enum Stage { Waiting, Exploding, } @@ -64,9 +60,8 @@ private enum Stage private int _currentR = 0; private bool _particles; - public TNTTask(World world, Vector3I position, Player owner, bool gun, bool particles) - : base(world) - { + public TNTTask( World world, Vector3I position, Player owner, bool gun, bool particles ) + : base( world ) { _particles = particles; _gun = gun; _pos = position; @@ -74,24 +69,19 @@ public TNTTask(World world, Vector3I position, Player owner, bool gun, bool part _stage = Stage.Waiting; } - protected override int PerformInternal() - { - lock (_world.SyncRoot) - { - switch (_stage) - { + protected override int PerformInternal() { + lock ( _world.SyncRoot ) { + switch ( _stage ) { case Stage.Waiting: - if (!_gun) - { - if (!_world.tntPhysics)// || _map.GetBlock(_pos) != Block.TNT) //TNT was removed for some reason, forget the xplosion + if ( !_gun ) { + if ( !_world.tntPhysics )// || _map.GetBlock(_pos) != Block.TNT) //TNT was removed for some reason, forget the xplosion return 0; //remove task } - UpdateMap(new BlockUpdate(null, _pos, Block.Air)); + UpdateMap( new BlockUpdate( null, _pos, Block.Air ) ); _stage = Stage.Exploding; //switch to expansion stage - if (_particles) - { + if ( _particles ) { CreateParticles(); } Explosion(); @@ -99,60 +89,47 @@ protected override int PerformInternal() case Stage.Exploding: return Explosion() ? StepDelay : 0;//when done remove task default: - throw new Exception("State machine ist kaputt! tnt panic!"); + throw new Exception( "State machine ist kaputt! tnt panic!" ); } } } - private void CreateParticles() - { - int n = _r.Next(1, 4); - for (int i = 0; i < n; ++i) - { + private void CreateParticles() { + int n = _r.Next( 1, 4 ); + for ( int i = 0; i < n; ++i ) { double phi = _r.NextDouble() * 2 * Math.PI; double ksi = _r.NextDouble() * Math.PI - Math.PI / 2.0; - Vector3F direction = (new Vector3F((float)(Math.Cos(phi) * Math.Cos(ksi)), (float)(Math.Sin(phi) * Math.Cos(ksi)), (float)Math.Sin(ksi))).Normalize(); - if (_owner.CanPlace(_map, (_pos + 2 * direction).Round(), Block.Obsidian, BlockChangeContext.Manual) == CanPlaceResult.Allowed) - { - if (_map.GetBlock((_pos + 2 * direction).Round()) != Block.Obsidian) - { - _world.AddPhysicsTask(new Particle(_world, (_pos + 2 * direction).Round(), direction, _owner, Block.Obsidian, _particleBehavior), 0); + Vector3F direction = ( new Vector3F( ( float )( Math.Cos( phi ) * Math.Cos( ksi ) ), ( float )( Math.Sin( phi ) * Math.Cos( ksi ) ), ( float )Math.Sin( ksi ) ) ).Normalize(); + if ( _owner.CanPlace( _map, ( _pos + 2 * direction ).Round(), Block.Obsidian, BlockChangeContext.Manual ) == CanPlaceResult.Allowed ) { + if ( _map.GetBlock( ( _pos + 2 * direction ).Round() ) != Block.Obsidian ) { + _world.AddPhysicsTask( new Particle( _world, ( _pos + 2 * direction ).Round(), direction, _owner, Block.Obsidian, _particleBehavior ), 0 ); } } } } - private bool Explosion() - { + private bool Explosion() { List toClean = _explosion; - if (++_currentR <= R) - { + if ( ++_currentR <= R ) { _explosion = new List(); - int rPrev = 0; - for (int z = _currentR; z >= 0; --z) - { + int rPrev = 0; + for ( int z = _currentR; z >= 0; --z ) { double r2 = _currentR * _currentR - z * z; - double r = Math.Sqrt(r2); - double yPrev = r; - for (double x = 0; x <= Math.Round(r); ++x) - { - if (x > r) - x = r; - double y = Math.Sqrt(r2 - x * x); - int ix = (int)Math.Round(x); - for (int iy = ix > rPrev ? 0 : (int)Math.Round(y); iy < Math.Max(Math.Round(y) + 1, Math.Round(yPrev)); ++iy) - { - for (int mx = -1; mx < 2; mx += 2) - { - for (int my = -1; my < 2; my += 2) - { - for (int mz = -1; mz < 2; mz += 2) - { - if (_owner.CanPlace(_map, new Vector3I(mx * ix + _pos.X, my * iy + _pos.Y, mz * z + _pos.Z), Block.Wood, BlockChangeContext.Manual) == CanPlaceResult.Allowed) - { - TryAddPoint(mx * ix + _pos.X, my * iy + _pos.Y, mz * z + _pos.Z); + double r = Math.Sqrt( r2 ); + double yPrev = r; + for ( double x = 0; x <= Math.Round( r ); ++x ) { + if ( x > r ) + x = r; + double y = Math.Sqrt( r2 - x * x ); + int ix = ( int )Math.Round( x ); + for ( int iy = ix > rPrev ? 0 : ( int )Math.Round( y ); iy < Math.Max( Math.Round( y ) + 1, Math.Round( yPrev ) ); ++iy ) { + for ( int mx = -1; mx < 2; mx += 2 ) { + for ( int my = -1; my < 2; my += 2 ) { + for ( int mz = -1; mz < 2; mz += 2 ) { + if ( _owner.CanPlace( _map, new Vector3I( mx * ix + _pos.X, my * iy + _pos.Y, mz * z + _pos.Z ), Block.Wood, BlockChangeContext.Manual ) == CanPlaceResult.Allowed ) { + TryAddPoint( mx * ix + _pos.X, my * iy + _pos.Y, mz * z + _pos.Z ); } yPrev = y; } @@ -160,35 +137,29 @@ private bool Explosion() } } } - rPrev = (int) Math.Round(r); + rPrev = ( int )Math.Round( r ); } - Util.RndPermutate(_explosion); - foreach (BData pt in _explosion) - { - if (_owner.CanPlace(_map, new Vector3I(pt.X, pt.Y, pt.Z), Block.Wood, BlockChangeContext.Manual) == CanPlaceResult.Allowed) - { - if (_map.GetBlock(pt.X, pt.Y, pt.Z) != Block.Lava) //if another tnt hasnt already caused lava here + Util.RndPermutate( _explosion ); + foreach ( BData pt in _explosion ) { + if ( _owner.CanPlace( _map, new Vector3I( pt.X, pt.Y, pt.Z ), Block.Wood, BlockChangeContext.Manual ) == CanPlaceResult.Allowed ) { + if ( _map.GetBlock( pt.X, pt.Y, pt.Z ) != Block.Lava ) //if another tnt hasnt already caused lava here { - UpdateMap(new BlockUpdate(null, (short)pt.X, (short)pt.Y, (short)pt.Z, Block.Lava)); - foreach (Player p in _world.Players) - { - if (p.CanBeKilled() && p.Position.DistanceSquaredTo((new Vector3I(pt.X, pt.Y, pt.Z)).ToPlayerCoords()) <= 64 * 64) //less or equal than 2 blocks - HitPlayer(_world, p, _owner); + UpdateMap( new BlockUpdate( null, ( short )pt.X, ( short )pt.Y, ( short )pt.Z, Block.Lava ) ); + foreach ( Player p in _world.Players ) { + if ( p.CanBeKilled() && p.Position.DistanceSquaredTo( ( new Vector3I( pt.X, pt.Y, pt.Z ) ).ToPlayerCoords() ) <= 64 * 64 ) //less or equal than 2 blocks + HitPlayer( _world, p, _owner ); } } } } } - if (null != toClean) - { - foreach (BData pt in toClean) - { - if (_owner.CanPlace(_map, new Vector3I(pt.X, pt.Y, pt.Z), Block.Wood, BlockChangeContext.Manual) == CanPlaceResult.Allowed) - { - UpdateMap(new BlockUpdate(null, (short)pt.X, (short)pt.Y, (short)pt.Z, - pt.PrevBlock == Block.Water ? Block.Water : Block.Air)); + if ( null != toClean ) { + foreach ( BData pt in toClean ) { + if ( _owner.CanPlace( _map, new Vector3I( pt.X, pt.Y, pt.Z ), Block.Wood, BlockChangeContext.Manual ) == CanPlaceResult.Allowed ) { + UpdateMap( new BlockUpdate( null, ( short )pt.X, ( short )pt.Y, ( short )pt.Z, + pt.PrevBlock == Block.Water ? Block.Water : Block.Air ) ); } } toClean.Clear(); @@ -196,95 +167,76 @@ private bool Explosion() return _currentR <= R; } - private void TryAddPoint(int x, int y, int z) - { - if (x < 0 || x >= _map.Width + private void TryAddPoint( int x, int y, int z ) { + if ( x < 0 || x >= _map.Width || y < 0 || y >= _map.Length - || z < 0 || z >= _map.Height) + || z < 0 || z >= _map.Height ) return; - Block prevBlock = _map.GetBlock(x, y, z); - if (Block.Lava != prevBlock) - { + Block prevBlock = _map.GetBlock( x, y, z ); + if ( Block.Lava != prevBlock ) { //chain explosion - if (Block.TNT == prevBlock) - { - _world.AddPhysicsTask(new TNTTask(_world, new Vector3I(x, y, z), _owner, false, _particles), _r.Next(150, 300)); - UpdateMap(new BlockUpdate(null, (short)x, (short)y, (short)z, Block.Air)); + if ( Block.TNT == prevBlock ) { + _world.AddPhysicsTask( new TNTTask( _world, new Vector3I( x, y, z ), _owner, false, _particles ), _r.Next( 150, 300 ) ); + UpdateMap( new BlockUpdate( null, ( short )x, ( short )y, ( short )z, Block.Air ) ); } - if ((0.2 + 0.75 * (R - _currentR) / R) * 0.65 > _r.NextDouble()) - _explosion.Add(new BData() { X = x, Y = y, Z = z, PrevBlock = _map.GetBlock(x, y, z) }); + if ( ( 0.2 + 0.75 * ( R - _currentR ) / R ) * 0.65 > _r.NextDouble() ) + _explosion.Add( new BData() { X = x, Y = y, Z = z, PrevBlock = _map.GetBlock( x, y, z ) } ); } } - public void HitPlayer(World world, Player hitted, Player by) - { - if (by == null) - { - if (MineField.Failed != null && !MineField.Failed.Contains(hitted)) - { - hitted.Kill(world, String.Format("{0}&S was torn to pieces and lost the game!", hitted.ClassyName)); - if (MineField.PlayerBlowUpCheck(hitted)) - { - hitted.Message("&WYou lost the game! You are now unable to win."); + public void HitPlayer( World world, Player hitted, Player by ) { + if ( by == null ) { + if ( MineField.Failed != null && !MineField.Failed.Contains( hitted ) ) { + hitted.Kill( world, String.Format( "{0}&S was torn to pieces and lost the game!", hitted.ClassyName ) ); + if ( MineField.PlayerBlowUpCheck( hitted ) ) { + hitted.Message( "&WYou lost the game! You are now unable to win." ); } return; - } - else return; + } else + return; } - hitted.Kill(world, String.Format("{0}&S was torn to pieces by {1}", hitted.ClassyName, hitted.ClassyName==by.ClassyName?"theirself":by.ClassyName)); + hitted.Kill( world, String.Format( "{0}&S was torn to pieces by {1}", hitted.ClassyName, hitted.ClassyName == by.ClassyName ? "theirself" : by.ClassyName ) ); } } - public class Firework : PhysicsTask - { + public class Firework : PhysicsTask { private const int Delay = 150; private Vector3I _pos; private int _z; private bool _notSent = true; - private int _height = new Random().Next(13, 20); + private int _height = new Random().Next( 13, 20 ); private int _count = 0; - public Firework(World world, Vector3I position) - : base(world) - { + public Firework( World world, Vector3I position ) + : base( world ) { _pos = position; _z = position.Z + 1; } - protected override int PerformInternal() - { - lock (_world.SyncRoot) - { - if (_world.fireworkPhysics) - { - if (_world.Map.GetBlock(_pos.X, _pos.Y, _z) != Block.Air || _count >= _height) - { - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)(_z - 1), Block.Air)); - if (_world.Map.GetBlock(_pos.X, _pos.Y, _z - 2) == Block.Lava) - { - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)(_z - 2), Block.Air)); + + protected override int PerformInternal() { + lock ( _world.SyncRoot ) { + if ( _world.fireworkPhysics ) { + if ( _world.Map.GetBlock( _pos.X, _pos.Y, _z ) != Block.Air || _count >= _height ) { + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )( _z - 1 ), Block.Air ) ); + if ( _world.Map.GetBlock( _pos.X, _pos.Y, _z - 2 ) == Block.Lava ) { + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )( _z - 2 ), Block.Air ) ); } Random rand = new Random(); - int blockId = new Random().Next(1, 9); + int blockId = new Random().Next( 1, 9 ); Block fBlock = new Block(); - if (blockId <= 6) - { - fBlock = (Block)rand.Next(21, 33); + if ( blockId <= 6 ) { + fBlock = ( Block )rand.Next( 21, 33 ); } - for (int X2 = _pos.X - 5; X2 <= _pos.X + 5; X2++) - { - for (int Y2 = (_pos.Y - 5); Y2 <= (_pos.Y + 5); Y2++) - { - for (int Z2 = (_z - 5); Z2 <= (_z + 5); Z2++) - { - if (blockId >= 7) - { - fBlock = (Block)rand.Next(21, 33); + for ( int X2 = _pos.X - 5; X2 <= _pos.X + 5; X2++ ) { + for ( int Y2 = ( _pos.Y - 5 ); Y2 <= ( _pos.Y + 5 ); Y2++ ) { + for ( int Z2 = ( _z - 5 ); Z2 <= ( _z + 5 ); Z2++ ) { + if ( blockId >= 7 ) { + fBlock = ( Block )rand.Next( 21, 33 ); } - if (rand.Next(1, 50) < 3) - { - _world.AddPhysicsTask(new FireworkParticle(_world, new Vector3I(X2, Y2, Z2), fBlock), rand.Next(1, 100)); + if ( rand.Next( 1, 50 ) < 3 ) { + _world.AddPhysicsTask( new FireworkParticle( _world, new Vector3I( X2, Y2, Z2 ), fBlock ), rand.Next( 1, 100 ) ); } } } @@ -292,22 +244,20 @@ protected override int PerformInternal() _world.FireworkCount--; return 0; } - if (_notSent) - { - if (_world.Map.GetBlock(_pos) != Block.Gold) - { + if ( _notSent ) { + if ( _world.Map.GetBlock( _pos ) != Block.Gold ) { _world.FireworkCount--; return 0; } } _notSent = false; - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)_z, Block.Gold)); - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)(_z - 1), Block.Lava)); - if (_world.Map.GetBlock(_pos.X, _pos.Y, _z - 2) == Block.Lava) - { - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)(_z - 2), Block.Air)); + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )_z, Block.Gold ) ); + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )( _z - 1 ), Block.Lava ) ); + if ( _world.Map.GetBlock( _pos.X, _pos.Y, _z - 2 ) == Block.Lava ) { + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )( _z - 2 ), Block.Air ) ); } - _z++; _count++; + _z++; + _count++; return Delay; } } diff --git a/fCraft/Physics/Life/Life2DZone.cs b/fCraft/Physics/Life/Life2DZone.cs index 0c35986..ea924d8 100644 --- a/fCraft/Physics/Life/Life2DZone.cs +++ b/fCraft/Physics/Life/Life2DZone.cs @@ -24,508 +24,507 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; using System.Runtime.Serialization; -namespace fCraft -{ - public class CircularBuffer where T:IEquatable - { - private T[] _a; - private int _current; - private bool _full = false; - - public CircularBuffer(int size) - { - _a=new T[size]; - _current = 0; - } - - public bool Contains(T t) - { - for (int i=0; i<(_full?_a.Length:_current); ++i) - if (t.Equals(_a[i])) - return true; - return false; - } - - public void Add(T t) - { - _a[_current] = t; - if (++_current>=_a.Length) - { - _current = 0; - _full = true; - } - } - - public void Clear() - { - _full = false; - _current = 0; - } - } - - public enum AutoResetMethod - { - None, - ToInitial, - ToRandom, - } - - public class Life2DZone - { - public int MaxSize = 2500; - - public static readonly Block[] DefaultBlocks = {Block.Air,Block.Red,Block.Black,Block.Brick}; - public const int EmptyIdx = 0; - public const int NormalIdx = 1; - public const int DeadIdx = 2; - public const int NewbornIdx = 3; - - public const int DefaultDelay = 200; - public const int DefaultHalfStepDelay = 50; - - public const int LongDelay = 1000; - - private const int LastStateHashesSize = 10; - - public string Name { get; private set; } - - private enum Orientation - { - X, Y, Z, - } - private enum State - { - Starting, HalfStep, FinalizedStep, Stopped, Resetting, Reinit, - } - - private Map _map; - private BoundingBox _bounds; - private Orientation _orientation; - private Life2d _life2d; - private Vector3I _coords=new Vector3I(); //used for remapping of axes, see XXXByOrientation methods below - - private Block _normal; - private Block _empty; - private Block _dead; - private Block _newborn; - - private State _state=State.Stopped; - - private int _halfStepDelay; - private int _delay; - private AutoResetMethod _autoReset; - private byte[,] _initialState; - private CircularBuffer _stateHashes = new CircularBuffer(LastStateHashesSize); - - public bool Stopped { get { lock (_life2d) { return State.Stopped == _state; } } } - - public Block Normal { get { lock (_life2d) { return _normal; } } set { lock (_life2d) { _normal = value; } } } - public Block Empty { get { lock (_life2d) { return _empty; } } set { lock (_life2d) { _empty = value; } } } - public Block Dead { get { lock (_life2d) { return _dead; } } set { lock (_life2d) { _dead = value; } } } - public Block Newborn { get { lock (_life2d) { return _newborn; } } set { lock (_life2d) { _newborn = value; } } } - public int HalfStepDelay { get { lock (_life2d) { return _halfStepDelay; } } set { lock (_life2d) { _halfStepDelay = value; } } } - public int Delay { get { lock (_life2d) { return _delay; } } set { lock (_life2d) { _delay = value; } } } - public bool Torus { get { lock (_life2d) { return _life2d.Torus; } } set { lock (_life2d) { _life2d.Torus = value; } } } - public AutoResetMethod AutoReset { get { lock (_life2d) { return _autoReset; } } set { lock (_life2d) { _autoReset = value; } } } - - public string CreatorName { get; set; } - public string MinRankToChange { get; set; } - - public Life2DZone(string name, Map map, Vector3I[] marks, Player creator, string minRankToChange) - { - _map = map; - _bounds=new BoundingBox(marks[0], marks[1]); - if (_bounds.Dimensions.X == 1 && _bounds.Dimensions.Y > 1 && _bounds.Dimensions.Z > 1) - { - _orientation = Orientation.X; - _life2d = new Life2d(_bounds.Dimensions.Y, _bounds.Dimensions.Z); - _coords.X = _bounds.XMin; - } - else if (_bounds.Dimensions.X > 1 && _bounds.Dimensions.Y == 1 && _bounds.Dimensions.Z > 1) - { - _orientation = Orientation.Y; - _life2d = new Life2d(_bounds.Dimensions.X, _bounds.Dimensions.Z); - _coords.Y = _bounds.YMin; - } - else if (_bounds.Dimensions.X > 1 && _bounds.Dimensions.Y > 1 && _bounds.Dimensions.Z == 1) - { - _orientation = Orientation.Z; - _life2d = new Life2d(_bounds.Dimensions.X, _bounds.Dimensions.Y); - _coords.Z = _bounds.ZMin; - } - else - throw new ArgumentException("bounds must be a 2d rectangle"); - - if (_bounds.Dimensions.X*_bounds.Dimensions.Y*_bounds.Dimensions.Z>MaxSize) - throw new ArgumentException("The life if too large. Width*Length must be less or equal than "+MaxSize); - - CheckPermissionsToDraw(creator); - - Name = name; - CreatorName = creator.Name; - MinRankToChange = minRankToChange; - _normal = DefaultBlocks[NormalIdx]; - _empty = DefaultBlocks[EmptyIdx]; - _dead = DefaultBlocks[DeadIdx]; - _newborn = DefaultBlocks[NewbornIdx]; - - _halfStepDelay = DefaultHalfStepDelay; - _delay = DefaultDelay; - Torus = false; - _autoReset = AutoResetMethod.ToRandom; +namespace fCraft { + + public class CircularBuffer where T : IEquatable { + private T[] _a; + private int _current; + private bool _full = false; + + public CircularBuffer( int size ) { + _a = new T[size]; + _current = 0; + } + + public bool Contains( T t ) { + for ( int i = 0; i < ( _full ? _a.Length : _current ); ++i ) + if ( t.Equals( _a[i] ) ) + return true; + return false; + } + + public void Add( T t ) { + _a[_current] = t; + if ( ++_current >= _a.Length ) { + _current = 0; + _full = true; + } + } + + public void Clear() { + _full = false; + _current = 0; + } + } + + public enum AutoResetMethod { + None, + ToInitial, + ToRandom, + } + + public class Life2DZone { + public int MaxSize = 2500; + + public static readonly Block[] DefaultBlocks = { Block.Air, Block.Red, Block.Black, Block.Brick }; + public const int EmptyIdx = 0; + public const int NormalIdx = 1; + public const int DeadIdx = 2; + public const int NewbornIdx = 3; + + public const int DefaultDelay = 200; + public const int DefaultHalfStepDelay = 50; + + public const int LongDelay = 1000; + + private const int LastStateHashesSize = 10; + + public string Name { get; private set; } + + private enum Orientation { + X, + Y, + Z, + } + + private enum State { + Starting, + HalfStep, + FinalizedStep, + Stopped, + Resetting, + Reinit, + } + + private Map _map; + private BoundingBox _bounds; + private Orientation _orientation; + private Life2d _life2d; + private Vector3I _coords = new Vector3I(); //used for remapping of axes, see XXXByOrientation methods below + + private Block _normal; + private Block _empty; + private Block _dead; + private Block _newborn; + + private State _state = State.Stopped; + + private int _halfStepDelay; + private int _delay; + private AutoResetMethod _autoReset; + private byte[,] _initialState; + private CircularBuffer _stateHashes = new CircularBuffer( LastStateHashesSize ); + + public bool Stopped { get { lock ( _life2d ) { return State.Stopped == _state; } } } + + public Block Normal { get { lock ( _life2d ) { return _normal; } } set { lock ( _life2d ) { _normal = value; } } } + + public Block Empty { get { lock ( _life2d ) { return _empty; } } set { lock ( _life2d ) { _empty = value; } } } + + public Block Dead { get { lock ( _life2d ) { return _dead; } } set { lock ( _life2d ) { _dead = value; } } } + + public Block Newborn { get { lock ( _life2d ) { return _newborn; } } set { lock ( _life2d ) { _newborn = value; } } } + + public int HalfStepDelay { get { lock ( _life2d ) { return _halfStepDelay; } } set { lock ( _life2d ) { _halfStepDelay = value; } } } + + public int Delay { get { lock ( _life2d ) { return _delay; } } set { lock ( _life2d ) { _delay = value; } } } + + public bool Torus { get { lock ( _life2d ) { return _life2d.Torus; } } set { lock ( _life2d ) { _life2d.Torus = value; } } } + + public AutoResetMethod AutoReset { get { lock ( _life2d ) { return _autoReset; } } set { lock ( _life2d ) { _autoReset = value; } } } + + public string CreatorName { get; set; } + + public string MinRankToChange { get; set; } + + public Life2DZone( string name, Map map, Vector3I[] marks, Player creator, string minRankToChange ) { + _map = map; + _bounds = new BoundingBox( marks[0], marks[1] ); + if ( _bounds.Dimensions.X == 1 && _bounds.Dimensions.Y > 1 && _bounds.Dimensions.Z > 1 ) { + _orientation = Orientation.X; + _life2d = new Life2d( _bounds.Dimensions.Y, _bounds.Dimensions.Z ); + _coords.X = _bounds.XMin; + } else if ( _bounds.Dimensions.X > 1 && _bounds.Dimensions.Y == 1 && _bounds.Dimensions.Z > 1 ) { + _orientation = Orientation.Y; + _life2d = new Life2d( _bounds.Dimensions.X, _bounds.Dimensions.Z ); + _coords.Y = _bounds.YMin; + } else if ( _bounds.Dimensions.X > 1 && _bounds.Dimensions.Y > 1 && _bounds.Dimensions.Z == 1 ) { + _orientation = Orientation.Z; + _life2d = new Life2d( _bounds.Dimensions.X, _bounds.Dimensions.Y ); + _coords.Z = _bounds.ZMin; + } else + throw new ArgumentException( "bounds must be a 2d rectangle" ); + + if ( _bounds.Dimensions.X * _bounds.Dimensions.Y * _bounds.Dimensions.Z > MaxSize ) + throw new ArgumentException( "The life if too large. Width*Length must be less or equal than " + MaxSize ); + + CheckPermissionsToDraw( creator ); + + Name = name; + CreatorName = creator.Name; + MinRankToChange = minRankToChange; + _normal = DefaultBlocks[NormalIdx]; + _empty = DefaultBlocks[EmptyIdx]; + _dead = DefaultBlocks[DeadIdx]; + _newborn = DefaultBlocks[NewbornIdx]; + + _halfStepDelay = DefaultHalfStepDelay; + _delay = DefaultDelay; + Torus = false; + _autoReset = AutoResetMethod.ToRandom; _initialState = _life2d.GetArrayCopy(); - } - - private void CheckPermissionsToDraw(Player creator) - { - for (int i=_bounds.XMin; i<=_bounds.XMax; ++i) - for (int j=_bounds.YMin; j<=_bounds.YMax; ++j) - for (int k=_bounds.ZMin; k<=_bounds.ZMax; ++k) - if (creator.CanPlace(_map, new Vector3I(i, j, k), DefaultBlocks[EmptyIdx], BlockChangeContext.Physics)!=CanPlaceResult.Allowed) - throw new ArgumentException("This life intersects with prohibited zones/blocks. Creation denied."); - } - - public void Stop() - { - lock (_life2d) - { - if (!Stopped) - { - _state = State.Stopped; - } - } - } - - public void Start() - { - lock (_life2d) - { - if (!Stopped) - return; - _state = State.Starting; - } - - World w = _map.World; - if (null == w) - { - Logger.Log(LogType.Error, "Life: cant start life in a map without a world"); - return; - } - w.AddTask(TaskCategory.Life, new Task(w, this), 0); - } - - public void Resume() //the map with this life was just loaded from the file - { - lock (_life2d) - { - if (Stopped) - return; - } - World w = _map.World; - if (null == w) - { - Logger.Log(LogType.Error, "Life: cant resume life in a map without a world"); - return; - } - w.AddTask(TaskCategory.Life, new Task(w, this), 0); - } - - private class Task : PhysicsTask - { - private Life2DZone _life; - public Task(World w, Life2DZone life) : base(w) {_life = life;} - protected override int PerformInternal() - { - return _life.PerformInternal(); - } - } - - private void ReadToArray(ref int i, ref int j, int minI, int maxI, int minJ, int maxJ) - { - _life2d.Clear(); - for (i = minI; i <= maxI; ++i) - for (j = minJ; j <= maxJ; ++j) - { - if (_empty != _map.GetBlock(_coords)) - _life2d.Set(i - minI, j - minJ); - } - } - - private void Draw(ref int i, ref int j, int minI, int maxI, int minJ, int maxJ) - { - for (i = minI; i <= maxI; ++i) - for (j = minJ; j <= maxJ; ++j) - { - switch (_life2d.Get(i-minI, j-minJ)) - { - case Life2d.Nothing: - SetBlock(_empty); - break; - case Life2d.Normal: - SetBlock(_normal); - break; - case Life2d.Newborn: - SetBlock(_newborn); - break; - case Life2d.Dead: - SetBlock(_dead); - break; - } - } - } - - private void SetBlock(Block b) - { - if (_map.GetBlock(_coords)!=b) - _map.QueueUpdate(new BlockUpdate(null, _coords, b)); - } - - private void ReadToArrayByOrientation() - { - switch (_orientation) - { - case Orientation.X: - ReadToArray(ref _coords.Y, ref _coords.Z, _bounds.YMin, _bounds.YMax, _bounds.ZMin, _bounds.ZMax); - return; - case Orientation.Y: - ReadToArray(ref _coords.X, ref _coords.Z, _bounds.XMin, _bounds.XMax, _bounds.ZMin, _bounds.ZMax); - return; - case Orientation.Z: - ReadToArray(ref _coords.X, ref _coords.Y, _bounds.XMin, _bounds.XMax, _bounds.YMin, _bounds.YMax); - return; - } - } - private void DrawByOrientation() - { - switch (_orientation) - { - case Orientation.X: - Draw(ref _coords.Y, ref _coords.Z, _bounds.YMin, _bounds.YMax, _bounds.ZMin, _bounds.ZMax); - return; - case Orientation.Y: - Draw(ref _coords.X, ref _coords.Z, _bounds.XMin, _bounds.XMax, _bounds.ZMin, _bounds.ZMax); - return; - case Orientation.Z: - Draw(ref _coords.X, ref _coords.Y, _bounds.XMin, _bounds.XMax, _bounds.YMin, _bounds.YMax); - return; - } - } - - private int PerformInternal() - { - lock (_life2d) - { - switch (_state) - { - case State.Stopped: - return 0; - case State.Starting: - - ReadToArrayByOrientation(); - _initialState = _life2d.GetArrayCopy(); - _stateHashes.Clear(); - - _state = State.HalfStep; - goto case State.HalfStep; //fall through c# stile - case State.HalfStep: - _life2d.HalfStep(); - _state = State.FinalizedStep; - if (_halfStepDelay > 0) - { - DrawByOrientation(); - return _halfStepDelay; - } - goto case State.FinalizedStep; //fall through c# stile - case State.FinalizedStep: - _state = _life2d.FinalizeStep() ? State.HalfStep : (_autoReset!=AutoResetMethod.None ? State.Resetting : State.Stopped); - if (_autoReset!=AutoResetMethod.None && State.HalfStep==_state) - {//check short periodical repetition - if (_stateHashes.Contains(_life2d.Hash)) - _state = State.Resetting; - else - _stateHashes.Add(_life2d.Hash); - } - DrawByOrientation(); - return _delay; - - case State.Resetting: - if (_autoReset==AutoResetMethod.None) //has been just changed? + } + + private void CheckPermissionsToDraw( Player creator ) { + for ( int i = _bounds.XMin; i <= _bounds.XMax; ++i ) + for ( int j = _bounds.YMin; j <= _bounds.YMax; ++j ) + for ( int k = _bounds.ZMin; k <= _bounds.ZMax; ++k ) + if ( creator.CanPlace( _map, new Vector3I( i, j, k ), DefaultBlocks[EmptyIdx], BlockChangeContext.Physics ) != CanPlaceResult.Allowed ) + throw new ArgumentException( "This life intersects with prohibited zones/blocks. Creation denied." ); + } + + public void Stop() { + lock ( _life2d ) { + if ( !Stopped ) { + _state = State.Stopped; + } + } + } + + public void Start() { + lock ( _life2d ) { + if ( !Stopped ) + return; + _state = State.Starting; + } + + World w = _map.World; + if ( null == w ) { + Logger.Log( LogType.Error, "Life: cant start life in a map without a world" ); + return; + } + w.AddTask( TaskCategory.Life, new Task( w, this ), 0 ); + } + + public void Resume() //the map with this life was just loaded from the file + { + lock ( _life2d ) { + if ( Stopped ) + return; + } + World w = _map.World; + if ( null == w ) { + Logger.Log( LogType.Error, "Life: cant resume life in a map without a world" ); + return; + } + w.AddTask( TaskCategory.Life, new Task( w, this ), 0 ); + } + + private class Task : PhysicsTask { + private Life2DZone _life; + + public Task( World w, Life2DZone life ) + : base( w ) { + _life = life; + } + + protected override int PerformInternal() { + return _life.PerformInternal(); + } + } + + private void ReadToArray( ref int i, ref int j, int minI, int maxI, int minJ, int maxJ ) { + _life2d.Clear(); + for ( i = minI; i <= maxI; ++i ) + for ( j = minJ; j <= maxJ; ++j ) { + if ( _empty != _map.GetBlock( _coords ) ) + _life2d.Set( i - minI, j - minJ ); + } + } + + private void Draw( ref int i, ref int j, int minI, int maxI, int minJ, int maxJ ) { + for ( i = minI; i <= maxI; ++i ) + for ( j = minJ; j <= maxJ; ++j ) { + switch ( _life2d.Get( i - minI, j - minJ ) ) { + case Life2d.Nothing: + SetBlock( _empty ); + break; + + case Life2d.Normal: + SetBlock( _normal ); + break; + + case Life2d.Newborn: + SetBlock( _newborn ); + break; + + case Life2d.Dead: + SetBlock( _dead ); + break; + } + } + } + + private void SetBlock( Block b ) { + if ( _map.GetBlock( _coords ) != b ) + _map.QueueUpdate( new BlockUpdate( null, _coords, b ) ); + } + + private void ReadToArrayByOrientation() { + switch ( _orientation ) { + case Orientation.X: + ReadToArray( ref _coords.Y, ref _coords.Z, _bounds.YMin, _bounds.YMax, _bounds.ZMin, _bounds.ZMax ); + return; + + case Orientation.Y: + ReadToArray( ref _coords.X, ref _coords.Z, _bounds.XMin, _bounds.XMax, _bounds.ZMin, _bounds.ZMax ); + return; + + case Orientation.Z: + ReadToArray( ref _coords.X, ref _coords.Y, _bounds.XMin, _bounds.XMax, _bounds.YMin, _bounds.YMax ); + return; + } + } + + private void DrawByOrientation() { + switch ( _orientation ) { + case Orientation.X: + Draw( ref _coords.Y, ref _coords.Z, _bounds.YMin, _bounds.YMax, _bounds.ZMin, _bounds.ZMax ); + return; + + case Orientation.Y: + Draw( ref _coords.X, ref _coords.Z, _bounds.XMin, _bounds.XMax, _bounds.ZMin, _bounds.ZMax ); + return; + + case Orientation.Z: + Draw( ref _coords.X, ref _coords.Y, _bounds.XMin, _bounds.XMax, _bounds.YMin, _bounds.YMax ); + return; + } + } + + private int PerformInternal() { + lock ( _life2d ) { + switch ( _state ) { + case State.Stopped: + return 0; + case State.Starting: + + ReadToArrayByOrientation(); + _initialState = _life2d.GetArrayCopy(); + _stateHashes.Clear(); + + _state = State.HalfStep; + goto case State.HalfStep; //fall through c# stile + case State.HalfStep: + _life2d.HalfStep(); + _state = State.FinalizedStep; + if ( _halfStepDelay > 0 ) { + DrawByOrientation(); + return _halfStepDelay; + } + goto case State.FinalizedStep; //fall through c# stile + case State.FinalizedStep: + _state = _life2d.FinalizeStep() ? State.HalfStep : ( _autoReset != AutoResetMethod.None ? State.Resetting : State.Stopped ); + if ( _autoReset != AutoResetMethod.None && State.HalfStep == _state ) {//check short periodical repetition + if ( _stateHashes.Contains( _life2d.Hash ) ) + _state = State.Resetting; + else + _stateHashes.Add( _life2d.Hash ); + } + DrawByOrientation(); + return _delay; + + case State.Resetting: + if ( _autoReset == AutoResetMethod.None ) //has been just changed? { - _state = State.Stopped; - return 0; - } - _life2d.Clear(); - _stateHashes.Clear(); - DrawByOrientation(); - _state = State.Reinit; - return LongDelay; - - case State.Reinit: - if (_autoReset == AutoResetMethod.None) //has been just changed? + _state = State.Stopped; + return 0; + } + _life2d.Clear(); + _stateHashes.Clear(); + DrawByOrientation(); + _state = State.Reinit; + return LongDelay; + + case State.Reinit: + if ( _autoReset == AutoResetMethod.None ) //has been just changed? { - _state = State.Stopped; - return 0; - } - Reinit(); - _state = State.HalfStep; - DrawByOrientation(); - return _delay; - } - } - return 0; - } - - private void Reinit() - { - switch (_autoReset) - { - case AutoResetMethod.ToInitial: - if (null == _initialState) - goto case AutoResetMethod.ToRandom; - _life2d.SetState(_initialState); - return; - case AutoResetMethod.ToRandom: - _life2d.SetStateToRandom(); - return; - } - } - - public string Serialize() - { - SerializedData data=new SerializedData(this); - DataContractSerializer serializer = new DataContractSerializer(typeof(SerializedData)); - MemoryStream s = new MemoryStream(); - serializer.WriteObject(s, data); - return Convert.ToBase64String(s.ToArray()); - } - - private Life2DZone(string name, Map map) - { - _map = map; - Name = name; - } - - public static Life2DZone Deserialize(string name, string sdata, Map map) - { - Life2DZone life=new Life2DZone(name, map); - - byte[] bdata = Convert.FromBase64String(sdata); - DataContractSerializer serializer = new DataContractSerializer(typeof(SerializedData)); - MemoryStream s=new MemoryStream(bdata); - SerializedData data = (SerializedData)serializer.ReadObject(s); - - data.UpdateLife2DZone(life); - return life; - } - - [DataContract] - private class SerializedData - { - [DataMember] public BoundingBox Bounds; - [DataMember] public Orientation Orient; - - [DataMember] public Block Normal; - [DataMember] public Block Empty; - [DataMember] public Block Dead; - [DataMember] public Block Newborn; - - [DataMember] public State RuntimeState; - - [DataMember] public int HalfStepDelay; - [DataMember] public int Delay; - [DataMember] public AutoResetMethod AutoReset; - [DataMember] public byte[] CurrentState; - [DataMember] public byte[] InitialState; - - [DataMember] public int Dim0, Dim1; - - [DataMember] public string CreatorName; - [DataMember] public string MinRankToChange; - - public SerializedData(Life2DZone life) - { - lock (life._life2d) - { - Bounds = life._bounds; - Orient = life._orientation; - - Normal = life._normal; - Empty = life._empty; - Dead = life._dead; - Newborn = life._newborn; - - RuntimeState = life._state; - HalfStepDelay = life._halfStepDelay; - Delay = life._delay; - AutoReset = life._autoReset; - - CreatorName = life.CreatorName; - MinRankToChange = life.MinRankToChange; - - CurrentState = To1DArray(life._life2d.GetArrayCopy(), out Dim0, out Dim1); - InitialState = To1DArray((byte[,])life._initialState.Clone(), out Dim0, out Dim1); - } - } - - public void UpdateLife2DZone(Life2DZone life) - { - //the life is not running, no locks needed - life._bounds = Bounds; - //we only will be needed one assignment depending on the orientation (see the public life constructor) - //but it doesnt hurt to assign all variables, which is shorter than a switch statement - life._coords.X = Bounds.XMin; - life._coords.Y = Bounds.YMin; - life._coords.Z = Bounds.ZMin; - life._orientation = Orient; - - life._normal = Normal; - life._empty = Empty; - life._dead = Dead; - life._newborn = Newborn; - - life._state = RuntimeState; - life._halfStepDelay = HalfStepDelay; - life._delay = Delay; - life._autoReset = AutoReset; - - life.CreatorName = CreatorName; - life.MinRankToChange = MinRankToChange; - - life._life2d=new Life2d(Dim0, Dim1); - life._life2d.SetState(To2DArray(CurrentState, Dim0, Dim1)); - life._initialState = To2DArray(InitialState, Dim0, Dim1); - } - - private static byte[] To1DArray(byte[,] a, out int dim0, out int dim1) - { - byte[] aa=new byte[a.GetLength(0)*a.GetLength(1)]; - int idx = 0; - dim0 = a.GetLength(0); - dim1 = a.GetLength(1); - for (int i = 0; i < dim0; ++i) - for (int j = 0; j < dim1; ++j) - aa[idx++] = a[i, j]; - return aa; - } - - private static byte[,] To2DArray(byte[] a, int dim0, int dim1) - { - if (a.Length!=dim0*dim1) - throw new ArgumentException("wrong dimensions"); - byte[,] aa=new byte[dim0, dim1]; - int idx = 0; - for (int i = 0; i < dim0; ++i) - for (int j = 0; j < dim1; ++j) - a[idx++] = aa[i, j]; - return aa; - } - } - } -} + _state = State.Stopped; + return 0; + } + Reinit(); + _state = State.HalfStep; + DrawByOrientation(); + return _delay; + } + } + return 0; + } + + private void Reinit() { + switch ( _autoReset ) { + case AutoResetMethod.ToInitial: + if ( null == _initialState ) + goto case AutoResetMethod.ToRandom; + _life2d.SetState( _initialState ); + return; + + case AutoResetMethod.ToRandom: + _life2d.SetStateToRandom(); + return; + } + } + + public string Serialize() { + SerializedData data = new SerializedData( this ); + DataContractSerializer serializer = new DataContractSerializer( typeof( SerializedData ) ); + MemoryStream s = new MemoryStream(); + serializer.WriteObject( s, data ); + return Convert.ToBase64String( s.ToArray() ); + } + + private Life2DZone( string name, Map map ) { + _map = map; + Name = name; + } + + public static Life2DZone Deserialize( string name, string sdata, Map map ) { + Life2DZone life = new Life2DZone( name, map ); + + byte[] bdata = Convert.FromBase64String( sdata ); + DataContractSerializer serializer = new DataContractSerializer( typeof( SerializedData ) ); + MemoryStream s = new MemoryStream( bdata ); + SerializedData data = ( SerializedData )serializer.ReadObject( s ); + + data.UpdateLife2DZone( life ); + return life; + } + + [DataContract] + private class SerializedData { + + [DataMember] + public BoundingBox Bounds; + + [DataMember] + public Orientation Orient; + + [DataMember] + public Block Normal; + + [DataMember] + public Block Empty; + + [DataMember] + public Block Dead; + + [DataMember] + public Block Newborn; + + [DataMember] + public State RuntimeState; + + [DataMember] + public int HalfStepDelay; + + [DataMember] + public int Delay; + + [DataMember] + public AutoResetMethod AutoReset; + + [DataMember] + public byte[] CurrentState; + + [DataMember] + public byte[] InitialState; + + [DataMember] + public int Dim0, Dim1; + + [DataMember] + public string CreatorName; + + [DataMember] + public string MinRankToChange; + + public SerializedData( Life2DZone life ) { + lock ( life._life2d ) { + Bounds = life._bounds; + Orient = life._orientation; + + Normal = life._normal; + Empty = life._empty; + Dead = life._dead; + Newborn = life._newborn; + + RuntimeState = life._state; + HalfStepDelay = life._halfStepDelay; + Delay = life._delay; + AutoReset = life._autoReset; + + CreatorName = life.CreatorName; + MinRankToChange = life.MinRankToChange; + + CurrentState = To1DArray( life._life2d.GetArrayCopy(), out Dim0, out Dim1 ); + InitialState = To1DArray( ( byte[,] )life._initialState.Clone(), out Dim0, out Dim1 ); + } + } + + public void UpdateLife2DZone( Life2DZone life ) { + //the life is not running, no locks needed + life._bounds = Bounds; + //we only will be needed one assignment depending on the orientation (see the public life constructor) + //but it doesnt hurt to assign all variables, which is shorter than a switch statement + life._coords.X = Bounds.XMin; + life._coords.Y = Bounds.YMin; + life._coords.Z = Bounds.ZMin; + life._orientation = Orient; + + life._normal = Normal; + life._empty = Empty; + life._dead = Dead; + life._newborn = Newborn; + + life._state = RuntimeState; + life._halfStepDelay = HalfStepDelay; + life._delay = Delay; + life._autoReset = AutoReset; + + life.CreatorName = CreatorName; + life.MinRankToChange = MinRankToChange; + + life._life2d = new Life2d( Dim0, Dim1 ); + life._life2d.SetState( To2DArray( CurrentState, Dim0, Dim1 ) ); + life._initialState = To2DArray( InitialState, Dim0, Dim1 ); + } + + private static byte[] To1DArray( byte[,] a, out int dim0, out int dim1 ) { + byte[] aa = new byte[a.GetLength( 0 ) * a.GetLength( 1 )]; + int idx = 0; + dim0 = a.GetLength( 0 ); + dim1 = a.GetLength( 1 ); + for ( int i = 0; i < dim0; ++i ) + for ( int j = 0; j < dim1; ++j ) + aa[idx++] = a[i, j]; + return aa; + } + + private static byte[,] To2DArray( byte[] a, int dim0, int dim1 ) { + if ( a.Length != dim0 * dim1 ) + throw new ArgumentException( "wrong dimensions" ); + byte[,] aa = new byte[dim0, dim1]; + int idx = 0; + for ( int i = 0; i < dim0; ++i ) + for ( int j = 0; j < dim1; ++j ) + a[idx++] = aa[i, j]; + return aa; + } + } + } +} \ No newline at end of file diff --git a/fCraft/Physics/Life/Life2d.cs b/fCraft/Physics/Life/Life2d.cs index aa244fe..e0de1c8 100644 --- a/fCraft/Physics/Life/Life2d.cs +++ b/fCraft/Physics/Life/Life2d.cs @@ -24,161 +24,138 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace fCraft -{ - public class Life2d - { - public const byte Newborn = 2; - public const byte Normal = 1; - public const byte Dead = 0xff; - public const byte Nothing = 0; - - private byte[,] _a; - public bool Torus=false; - private int _hash=0; - public int Hash { get { return _hash; } } - - public Life2d(int xSize, int ySize) - { - _a=new byte[xSize, ySize]; - } - public void Clear() - { - Array.Clear(_a, 0, _a.Length); - } - public void Set(int x, int y) - { - _a[x, y]=Normal; - } - public byte Get(int x, int y) - { - return _a[x, y]; - } - - public void HalfStep() - { - for (int i=0; i<_a.GetLength(0); ++i) - for (int j=0; j<_a.GetLength(1); ++j) - { - if (Empty(i, j) && Neighbors(i, j)==3) - _a[i, j]=Newborn; - } - - for (int i = 0; i < _a.GetLength(0); ++i) - for (int j = 0; j < _a.GetLength(1); ++j) - { - if (Alive(i, j)) - { - int n = Neighbors(i, j); - - if (n > 3 || n < 2) - _a[i, j]=Dead; - } - } - } - - private bool Empty(int x, int y) - { - return _a[x, y] == Nothing; - } - private bool Alive(int x, int y) - { - return _a[x, y] == Normal; - } - - private int Neighbors(int x, int y) - { - int s = 0; - - for (int i = x - 1; i <= x + 1; ++i) - { - int ii = i; - if (!ContinueWithCoord(ref ii, _a.GetLength(0))) - continue; - for (int j = y - 1; j <= y + 1; ++j) - if (i != x || j != y) - { - int jj = j; - if (!ContinueWithCoord(ref jj, _a.GetLength(1))) - continue; - byte b = _a[ii, jj]; - if (b == Normal || b == Dead) - ++s; - } - } - return s; - } - - private bool ContinueWithCoord(ref int c, int max) - { - if (c < 0) - { - if (Torus) - c = max - 1; - else - return false; - } - else if (c >= max) - { - if (Torus) - c = 0; - else - return false; - } - return true; - } - - public bool FinalizeStep() - { - bool changed = Replace(Dead, Nothing, false); - changed |= Replace(Newborn, Normal, true); - return changed; - } - - private bool Replace(byte from, byte to, bool computeHash) - { - bool changed = false; - if (computeHash) - _hash = (int)216713671; - for (int i = 0; i < _a.GetLength(0); ++i) - for (int j = 0; j < _a.GetLength(1); ++j) - { - if (_a[i, j]==from) - { - _a[i, j] = to; - changed = true; - } - if (computeHash && _a[i, j]==Normal) - { - const int p = 16777619; - int h = i | (j << 16); - _hash ^= h*p; - } - } - return changed; - } - - public byte[,] GetArrayCopy() - { - return (byte[,])_a.Clone(); - } - - public void SetState(byte[,] a) - { - _a = (byte[,]) a.Clone(); - } - - public void SetStateToRandom() - { - Random r=new Random(); - for (int i=0; i<_a.GetLength(0); ++i) - for (int j=0; j<_a.GetLength(1); ++j) - _a[i, j] = r.NextDouble() < 0.3 ? Normal : Nothing; - } - } -} + +namespace fCraft { + + public class Life2d { + public const byte Newborn = 2; + public const byte Normal = 1; + public const byte Dead = 0xff; + public const byte Nothing = 0; + + private byte[,] _a; + public bool Torus = false; + private int _hash = 0; + + public int Hash { get { return _hash; } } + + public Life2d( int xSize, int ySize ) { + _a = new byte[xSize, ySize]; + } + + public void Clear() { + Array.Clear( _a, 0, _a.Length ); + } + + public void Set( int x, int y ) { + _a[x, y] = Normal; + } + + public byte Get( int x, int y ) { + return _a[x, y]; + } + + public void HalfStep() { + for ( int i = 0; i < _a.GetLength( 0 ); ++i ) + for ( int j = 0; j < _a.GetLength( 1 ); ++j ) { + if ( Empty( i, j ) && Neighbors( i, j ) == 3 ) + _a[i, j] = Newborn; + } + + for ( int i = 0; i < _a.GetLength( 0 ); ++i ) + for ( int j = 0; j < _a.GetLength( 1 ); ++j ) { + if ( Alive( i, j ) ) { + int n = Neighbors( i, j ); + + if ( n > 3 || n < 2 ) + _a[i, j] = Dead; + } + } + } + + private bool Empty( int x, int y ) { + return _a[x, y] == Nothing; + } + + private bool Alive( int x, int y ) { + return _a[x, y] == Normal; + } + + private int Neighbors( int x, int y ) { + int s = 0; + + for ( int i = x - 1; i <= x + 1; ++i ) { + int ii = i; + if ( !ContinueWithCoord( ref ii, _a.GetLength( 0 ) ) ) + continue; + for ( int j = y - 1; j <= y + 1; ++j ) + if ( i != x || j != y ) { + int jj = j; + if ( !ContinueWithCoord( ref jj, _a.GetLength( 1 ) ) ) + continue; + byte b = _a[ii, jj]; + if ( b == Normal || b == Dead ) + ++s; + } + } + return s; + } + + private bool ContinueWithCoord( ref int c, int max ) { + if ( c < 0 ) { + if ( Torus ) + c = max - 1; + else + return false; + } else if ( c >= max ) { + if ( Torus ) + c = 0; + else + return false; + } + return true; + } + + public bool FinalizeStep() { + bool changed = Replace( Dead, Nothing, false ); + changed |= Replace( Newborn, Normal, true ); + return changed; + } + + private bool Replace( byte from, byte to, bool computeHash ) { + bool changed = false; + if ( computeHash ) + _hash = ( int )216713671; + for ( int i = 0; i < _a.GetLength( 0 ); ++i ) + for ( int j = 0; j < _a.GetLength( 1 ); ++j ) { + if ( _a[i, j] == from ) { + _a[i, j] = to; + changed = true; + } + if ( computeHash && _a[i, j] == Normal ) { + const int p = 16777619; + int h = i | ( j << 16 ); + _hash ^= h * p; + } + } + return changed; + } + + public byte[,] GetArrayCopy() { + return ( byte[,] )_a.Clone(); + } + + public void SetState( byte[,] a ) { + _a = ( byte[,] )a.Clone(); + } + + public void SetStateToRandom() { + Random r = new Random(); + for ( int i = 0; i < _a.GetLength( 0 ); ++i ) + for ( int j = 0; j < _a.GetLength( 1 ); ++j ) + _a[i, j] = r.NextDouble() < 0.3 ? Normal : Nothing; + } + } +} \ No newline at end of file diff --git a/fCraft/Physics/Life/LifeSerialization.cs b/fCraft/Physics/Life/LifeSerialization.cs index 00c371e..b640ca3 100644 --- a/fCraft/Physics/Life/LifeSerialization.cs +++ b/fCraft/Physics/Life/LifeSerialization.cs @@ -2,52 +2,43 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using fCraft.MapConversion; -namespace fCraft -{ - public class LifeSerialization : IConverterExtension - { - private static List _group = new List { "life" }; - public IEnumerable AcceptedGroups { get { return _group; } } - - public int Serialize(Map map, Stream stream, IMapConverterEx converter) - { - BinaryWriter writer = new BinaryWriter(stream); - int count = 0; - World w = map.World; - Object lockObj = null == w ? new object() : w.SyncRoot; +namespace fCraft { - IEnumerable lifes; - lock (lockObj) - { - lifes = map.LifeZones.Values.ToList(); //copies the current life list under a lock - } - foreach (Life2DZone life in lifes) - { - converter.WriteMetadataEntry(_group[0], life.Name, life.Serialize(), writer); - ++count; - } - return count; - } + public class LifeSerialization : IConverterExtension { + private static List _group = new List { "life" }; - public void Deserialize(string group, string key, string value, Map map) - { - try - { - Life2DZone life = Life2DZone.Deserialize(key, value, map); - if (map.LifeZones.ContainsKey(key.ToLower())) - { - Logger.Log(LogType.Error, "Map loading warning: duplicate life name found: " + key+", ignored"); - return; - } - map.LifeZones.Add(key.ToLower(), life); - } - catch (Exception ex) - { - Logger.Log(LogType.Error, "LifeSerialization.Deserialize: Error deserializing life {0}: {1}", key, ex); - } - } - } -} + public IEnumerable AcceptedGroups { get { return _group; } } + + public int Serialize( Map map, Stream stream, IMapConverterEx converter ) { + BinaryWriter writer = new BinaryWriter( stream ); + int count = 0; + World w = map.World; + Object lockObj = null == w ? new object() : w.SyncRoot; + + IEnumerable lifes; + lock ( lockObj ) { + lifes = map.LifeZones.Values.ToList(); //copies the current life list under a lock + } + foreach ( Life2DZone life in lifes ) { + converter.WriteMetadataEntry( _group[0], life.Name, life.Serialize(), writer ); + ++count; + } + return count; + } + + public void Deserialize( string group, string key, string value, Map map ) { + try { + Life2DZone life = Life2DZone.Deserialize( key, value, map ); + if ( map.LifeZones.ContainsKey( key.ToLower() ) ) { + Logger.Log( LogType.Error, "Map loading warning: duplicate life name found: " + key + ", ignored" ); + return; + } + map.LifeZones.Add( key.ToLower(), life ); + } catch ( Exception ex ) { + Logger.Log( LogType.Error, "LifeSerialization.Deserialize: Error deserializing life {0}: {1}", key, ex ); + } + } + } +} \ No newline at end of file diff --git a/fCraft/Physics/ParticleSystem.cs b/fCraft/Physics/ParticleSystem.cs index 3684ab7..7d868df 100644 --- a/fCraft/Physics/ParticleSystem.cs +++ b/fCraft/Physics/ParticleSystem.cs @@ -24,71 +24,69 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft; - -namespace fCraft -{ - public interface IParticleBehavior - { + +namespace fCraft { + + public interface IParticleBehavior { + int ProcessingStepsPerSecond { get; } + int MaxDistance { get; } + int MovesPerProcessingStep { get; } - void ModifyDirection(ref Vector3F direction, Block currentBlock /*etc*/); + void ModifyDirection( ref Vector3F direction, Block currentBlock /*etc*/); + + //false if stopped + bool VisitBlock( World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList updates, Block Sending ); - //false if stopped - bool VisitBlock(World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList updates, Block Sending); bool CanKillPlayer { get; } - void HitPlayer(World world, Vector3I pos, Player hitted, Player by, ref int restDistance, IList updates); + + void HitPlayer( World world, Vector3I pos, Player hitted, Player by, ref int restDistance, IList updates ); } - public class FireworkParticle : PhysicsTask - { + public class FireworkParticle : PhysicsTask { private Vector3I _startingPos; private int _nextZ; private Block _block; private bool _first = true; - private int _maxFall = new Random().Next(2, 5); + private int _maxFall = new Random().Next( 2, 5 ); private int Count = 0; - public FireworkParticle(World world, Vector3I pos, Block block) - : base(world) - { + public FireworkParticle( World world, Vector3I pos, Block block ) + : base( world ) { _startingPos = pos; _nextZ = pos.Z - 1; _block = block; } - protected override int PerformInternal() - { + protected override int PerformInternal() { Random _rand = new Random(); - if (_first){ - if (_world.Map.GetBlock(_startingPos.X, _startingPos.Y, _nextZ) != Block.Air || - Count > _maxFall){ + if ( _first ) { + if ( _world.Map.GetBlock( _startingPos.X, _startingPos.Y, _nextZ ) != Block.Air || + Count > _maxFall ) { return 0; } - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_startingPos.X, (short)_startingPos.Y, (short)_nextZ, _block)); + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_startingPos.X, ( short )_startingPos.Y, ( short )_nextZ, _block ) ); _first = false; - return _rand.Next(100, 401); + return _rand.Next( 100, 401 ); } - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_startingPos.X, (short)_startingPos.Y, (short)_nextZ, Block.Air)); + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_startingPos.X, ( short )_startingPos.Y, ( short )_nextZ, Block.Air ) ); Count++; _nextZ--; - if (_world.Map.GetBlock(_startingPos.X, _startingPos.Y, _nextZ) != Block.Air || - Count > _maxFall){ + if ( _world.Map.GetBlock( _startingPos.X, _startingPos.Y, _nextZ ) != Block.Air || + Count > _maxFall ) { return 0; - } - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_startingPos.X, (short)_startingPos.Y, (short)_nextZ, _block)); - return _rand.Next(100, 401); + } + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_startingPos.X, ( short )_startingPos.Y, ( short )_nextZ, _block ) ); + return _rand.Next( 100, 401 ); } } - public class Particle : PhysicsTask - { + public class Particle : PhysicsTask { private int _stepDelay; private Vector3I _startingPos; private Vector3I _pos; @@ -109,13 +107,12 @@ public class Particle : PhysicsTask /// The owner of the particle. /// The block type of the particle. /// The partcle behavior. Includes how fare and fast it moves, what happens if it hits a player an obstacle etc. - public Particle(World world, Vector3I pos, Vector3F direction, Player owner, - Block block, IParticleBehavior behavior) - : base(world) - { + public Particle( World world, Vector3I pos, Vector3F direction, Player owner, + Block block, IParticleBehavior behavior ) + : base( world ) { _direction = direction.Normalize(); - if (_direction == Vector3F.Zero) - throw new ArgumentException("direction vector cannot be zero"); + if ( _direction == Vector3F.Zero ) + throw new ArgumentException( "direction vector cannot be zero" ); _stepDelay = behavior.ProcessingStepsPerSecond <= 0 || behavior.ProcessingStepsPerSecond > 20 ? 50 @@ -128,440 +125,361 @@ public Particle(World world, Vector3I pos, Vector3F direction, Player owner, _block = block; _restDistance = behavior.MaxDistance; _behavior = behavior; - lock (_world.SyncRoot) - { + lock ( _world.SyncRoot ) { //draw it once right now - if (null != _map && ReferenceEquals(_map, _world.Map)) - { - _prevBlock = _map.GetBlock(pos); - if (Block.Undefined != _prevBlock) //out of bounds! - if (owner.CanPlace(_map, pos, Block.Wood, BlockChangeContext.Manual) == CanPlaceResult.Allowed) - UpdateMap(new BlockUpdate(null, pos, block)); + if ( null != _map && ReferenceEquals( _map, _world.Map ) ) { + _prevBlock = _map.GetBlock( pos ); + if ( Block.Undefined != _prevBlock ) //out of bounds! + if ( owner.CanPlace( _map, pos, Block.Wood, BlockChangeContext.Manual ) == CanPlaceResult.Allowed ) + UpdateMap( new BlockUpdate( null, pos, block ) ); } } } - protected override int PerformInternal() - { + + protected override int PerformInternal() { //lock is done already - if (Block.Undefined == _prevBlock) //created out of bounds, dont continue + if ( Block.Undefined == _prevBlock ) //created out of bounds, dont continue return 0; //fix for portal gun - if (_owner.orangePortal.Count > 0){ - if (_pos == _owner.orangePortal[0] || _pos == _owner.orangePortal[1]) + if ( _owner.orangePortal.Count > 0 ) { + if ( _pos == _owner.orangePortal[0] || _pos == _owner.orangePortal[1] ) return 0; - }if (_owner.bluePortal.Count > 0){ - if (_pos == _owner.bluePortal[0] || _pos == _owner.bluePortal[1]) + } + if ( _owner.bluePortal.Count > 0 ) { + if ( _pos == _owner.bluePortal[0] || _pos == _owner.bluePortal[1] ) return 0; } //delete at the previous position, restore water unconditionally, lava only when bullet is still there to prevent restoration of explosion lava - if (_prevBlock != Block.Water) _prevBlock = Block.Air; + if ( _prevBlock != Block.Water ) + _prevBlock = Block.Air; //edit: lazyfix, dont restore lava coz tnt. - if (Block.Undefined != _prevBlock) - { - if (_owner.CanPlace(_map, _pos, Block.Wood, BlockChangeContext.Manual) == CanPlaceResult.Allowed) - { - UpdateMap(new BlockUpdate(null, _pos, _prevBlock)); + if ( Block.Undefined != _prevBlock ) { + if ( _owner.CanPlace( _map, _pos, Block.Wood, BlockChangeContext.Manual ) == CanPlaceResult.Allowed ) { + UpdateMap( new BlockUpdate( null, _pos, _prevBlock ) ); } } List updates = new List(); - for (int i = 0; i < _behavior.MovesPerProcessingStep && _restDistance > 0; ++i) - { + for ( int i = 0; i < _behavior.MovesPerProcessingStep && _restDistance > 0; ++i ) { _pos = Move(); - _prevBlock = _map.GetBlock(_pos); + _prevBlock = _map.GetBlock( _pos ); - if (Block.Undefined == _prevBlock) - { + if ( Block.Undefined == _prevBlock ) { _restDistance = 0; break; } - _behavior.ModifyDirection(ref _direction, _prevBlock); //e.g. if you want it to be dependent on gravity or change direction depending on current block etc + _behavior.ModifyDirection( ref _direction, _prevBlock ); //e.g. if you want it to be dependent on gravity or change direction depending on current block etc - if (_behavior.VisitBlock(_world, _pos, _prevBlock, _owner, ref _restDistance, updates, _block) && _behavior.CanKillPlayer) - CheckHitPlayers(updates); + if ( _behavior.VisitBlock( _world, _pos, _prevBlock, _owner, ref _restDistance, updates, _block ) && _behavior.CanKillPlayer ) + CheckHitPlayers( updates ); } bool cont = _restDistance > 0; - if (cont) //check if the last update was for the current position and replace it with the particle + if ( cont ) //check if the last update was for the current position and replace it with the particle { int idx = updates.Count - 1; - if (idx >= 0 && updates[idx].X == _pos.X + if ( idx >= 0 && updates[idx].X == _pos.X && updates[idx].Y == _pos.Y - && updates[idx].Z == _pos.Z) - { - if (_owner.CanPlace(_map, _pos, Block.Wood, BlockChangeContext.Manual) == CanPlaceResult.Allowed) - { - updates[idx] = new BlockUpdate(null, _pos, _block); + && updates[idx].Z == _pos.Z ) { + if ( _owner.CanPlace( _map, _pos, Block.Wood, BlockChangeContext.Manual ) == CanPlaceResult.Allowed ) { + updates[idx] = new BlockUpdate( null, _pos, _block ); } - } - else - { - if (_owner.CanPlace(_map, _pos, Block.Wood, BlockChangeContext.Manual) == CanPlaceResult.Allowed) - { - updates.Add(new BlockUpdate(null, _pos, _block)); + } else { + if ( _owner.CanPlace( _map, _pos, Block.Wood, BlockChangeContext.Manual ) == CanPlaceResult.Allowed ) { + updates.Add( new BlockUpdate( null, _pos, _block ) ); } } } - for (int i = 0; i < updates.Count; ++i) - UpdateMap(updates[i]); + for ( int i = 0; i < updates.Count; ++i ) + UpdateMap( updates[i] ); return cont ? _stepDelay : 0; } - private Vector3I Move() - { + private Vector3I Move() { ++_currentStep; --_restDistance; - return (_startingPos + _currentStep * _direction).Round(); + return ( _startingPos + _currentStep * _direction ).Round(); } - private void CheckHitPlayers(List updates) - { - foreach (Player p in _world.Players) - { - if (ReferenceEquals(p, _owner) && (_startingPos - _pos).LengthSquared <= 2 * 2) //do not react on owner within 2 blocks of the starting position + private void CheckHitPlayers( List updates ) { + foreach ( Player p in _world.Players ) { + if ( ReferenceEquals( p, _owner ) && ( _startingPos - _pos ).LengthSquared <= 2 * 2 ) //do not react on owner within 2 blocks of the starting position continue; - if (p.CanBeKilled() && p.Position.DistanceSquaredTo(_pos.ToPlayerCoords()) <= 33 * 33) //less or equal than a block - _behavior.HitPlayer(_world, _pos, p, _owner, ref _restDistance, updates); + if ( p.CanBeKilled() && p.Position.DistanceSquaredTo( _pos.ToPlayerCoords() ) <= 33 * 33 ) //less or equal than a block + _behavior.HitPlayer( _world, _pos, p, _owner, ref _restDistance, updates ); } } } - internal class ExplosionParticleBehavior : IParticleBehavior - { - private static Random _r=new Random(); + internal class ExplosionParticleBehavior : IParticleBehavior { + private static Random _r = new Random(); - public int ProcessingStepsPerSecond - { + public int ProcessingStepsPerSecond { get { return 15; } } - public int MaxDistance - { - get { return _r.Next(6, 10); } + public int MaxDistance { + get { return _r.Next( 6, 10 ); } } - public int MovesPerProcessingStep - { + public int MovesPerProcessingStep { get { return 1; } } - public void ModifyDirection(ref Vector3F direction, Block currentBlock) - { - + public void ModifyDirection( ref Vector3F direction, Block currentBlock ) { } - //true if not stopped - public bool VisitBlock(World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList updates, Block sending) - { - if (Block.TNT == block) //explode it + //true if not stopped + public bool VisitBlock( World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList updates, Block sending ) { + if ( Block.TNT == block ) //explode it { - world.AddPhysicsTask(new TNTTask(world, pos, owner, false, true), _r.Next(150, 300)); - } - if (Block.Air != block && Block.Water != block && Block.Lava != block) - if (owner.CanPlace(world.Map, pos, Block.Wood, BlockChangeContext.Manual) == CanPlaceResult.Allowed) - updates.Add(new BlockUpdate(null, pos, Block.Air)); - return true; + world.AddPhysicsTask( new TNTTask( world, pos, owner, false, true ), _r.Next( 150, 300 ) ); + } + if ( Block.Air != block && Block.Water != block && Block.Lava != block ) + if ( owner.CanPlace( world.Map, pos, Block.Wood, BlockChangeContext.Manual ) == CanPlaceResult.Allowed ) + updates.Add( new BlockUpdate( null, pos, Block.Air ) ); + return true; } - public bool CanKillPlayer - { + public bool CanKillPlayer { get { return true; } } - public void HitPlayer(World world, Vector3I pos, Player hitted, Player by, ref int restDistance, IList updates) - { - hitted.Kill(world, String.Format("{0}&S was blown up by {1}", hitted.ClassyName, hitted.ClassyName == by.ClassyName ? "theirself" : by.ClassyName)); + public void HitPlayer( World world, Vector3I pos, Player hitted, Player by, ref int restDistance, IList updates ) { + hitted.Kill( world, String.Format( "{0}&S was blown up by {1}", hitted.ClassyName, hitted.ClassyName == by.ClassyName ? "theirself" : by.ClassyName ) ); } } - internal class BulletBehavior : IParticleBehavior - { + internal class BulletBehavior : IParticleBehavior { - public int ProcessingStepsPerSecond - { - get { return 20; } - } + public int ProcessingStepsPerSecond { + get { return 20; } + } - public int MaxDistance - { - get { return 100; } - } + public int MaxDistance { + get { return 100; } + } - public int MovesPerProcessingStep - { - get { return 1; } - } + public int MovesPerProcessingStep { + get { return 1; } + } + private const double G = 10; //blocks per second per second - private const double G = 10; //blocks per second per second - public void ModifyDirection(ref Vector3F direction, Block currentBlock) - { + public void ModifyDirection( ref Vector3F direction, Block currentBlock ) { + } - } - public bool VisitBlock(World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList updates, Block sending) - { - if (Block.Air != block) //hit a building + public bool VisitBlock( World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList updates, Block sending ) { + if ( Block.Air != block ) //hit a building { - if (owner.bluePortal.Count > 0) - { - if (pos == owner.bluePortal[0] || pos == owner.bluePortal[1]) - { + if ( owner.bluePortal.Count > 0 ) { + if ( pos == owner.bluePortal[0] || pos == owner.bluePortal[1] ) { return false; } } - if (owner.orangePortal.Count > 0) - { - if (pos == owner.orangePortal[0] || pos == owner.orangePortal[1]) - { + if ( owner.orangePortal.Count > 0 ) { + if ( pos == owner.orangePortal[0] || pos == owner.orangePortal[1] ) { return false; } } //blue portal - if (sending == Block.Water) - { - if (CanPlacePortal(pos.X, pos.Y, pos.Z, world.Map)) - { - if (owner.bluePortal.Count > 0) - { + if ( sending == Block.Water ) { + if ( CanPlacePortal( pos.X, pos.Y, pos.Z, world.Map ) ) { + if ( owner.bluePortal.Count > 0 ) { int i = 0; - foreach (Vector3I b in owner.bluePortal) - { - world.Map.QueueUpdate(new BlockUpdate(null, b, owner.blueOld[i])); + foreach ( Vector3I b in owner.bluePortal ) { + world.Map.QueueUpdate( new BlockUpdate( null, b, owner.blueOld[i] ) ); i++; } owner.blueOld.Clear(); owner.bluePortal.Clear(); } - owner.blueOld.Add(world.Map.GetBlock(pos)); - owner.blueOld.Add(world.Map.GetBlock(pos.X, pos.Y, pos.Z + 1)); + owner.blueOld.Add( world.Map.GetBlock( pos ) ); + owner.blueOld.Add( world.Map.GetBlock( pos.X, pos.Y, pos.Z + 1 ) ); owner.orangeOut = owner.Position.R; - for (double z = pos.Z; z < pos.Z + 2; z++) - { - world.Map.QueueUpdate(new BlockUpdate(null, (short)(pos.X), (short)(pos.Y), (short)z, Block.Water)); - owner.bluePortal.Add(new Vector3I((int)pos.X, (int)pos.Y, (int)z)); + for ( double z = pos.Z; z < pos.Z + 2; z++ ) { + world.Map.QueueUpdate( new BlockUpdate( null, ( short )( pos.X ), ( short )( pos.Y ), ( short )z, Block.Water ) ); + owner.bluePortal.Add( new Vector3I( ( int )pos.X, ( int )pos.Y, ( int )z ) ); } return false; - } - else - { + } else { return false; } } //orange portal - else if (sending == Block.Lava) - { - if (CanPlacePortal(pos.X, pos.Y, pos.Z, world.Map)) - { - if (owner.orangePortal.Count > 0) - { + else if ( sending == Block.Lava ) { + if ( CanPlacePortal( pos.X, pos.Y, pos.Z, world.Map ) ) { + if ( owner.orangePortal.Count > 0 ) { int i = 0; - foreach (Vector3I b in owner.orangePortal) - { - world.Map.QueueUpdate(new BlockUpdate(null, b, owner.orangeOld[i])); + foreach ( Vector3I b in owner.orangePortal ) { + world.Map.QueueUpdate( new BlockUpdate( null, b, owner.orangeOld[i] ) ); i++; } owner.orangeOld.Clear(); owner.orangePortal.Clear(); } - owner.orangeOld.Add(world.Map.GetBlock(pos)); - owner.orangeOld.Add(world.Map.GetBlock(pos.X, pos.Y, pos.Z + 1)); + owner.orangeOld.Add( world.Map.GetBlock( pos ) ); + owner.orangeOld.Add( world.Map.GetBlock( pos.X, pos.Y, pos.Z + 1 ) ); owner.blueOut = owner.Position.R; - for (double z = pos.Z; z < pos.Z + 2; z++) - { - world.Map.QueueUpdate(new BlockUpdate(null, (short)(pos.X), (short)(pos.Y), (short)z, Block.Lava)); - owner.orangePortal.Add(new Vector3I((int)pos.X, (int)pos.Y, (int)z)); + for ( double z = pos.Z; z < pos.Z + 2; z++ ) { + world.Map.QueueUpdate( new BlockUpdate( null, ( short )( pos.X ), ( short )( pos.Y ), ( short )z, Block.Lava ) ); + owner.orangePortal.Add( new Vector3I( ( int )pos.X, ( int )pos.Y, ( int )z ) ); } return false; - } - else - { + } else { return false; } } - updates.Add(new BlockUpdate(null, pos, world.Map.GetBlock(pos))); //restore + updates.Add( new BlockUpdate( null, pos, world.Map.GetBlock( pos ) ) ); //restore restDistance = 0; return false; } return true; } - - public static bool CanPlacePortal(int x, int y, int z, Map map) - { + public static bool CanPlacePortal( int x, int y, int z, Map map ) { int Count = 0; - for (int Z = z; Z < z + 2; Z++) - { - Block check = map.GetBlock(x, y, Z); - if (check != Block.Air && check != Block.Water && check != Block.Lava) - { + for ( int Z = z; Z < z + 2; Z++ ) { + Block check = map.GetBlock( x, y, Z ); + if ( check != Block.Air && check != Block.Water && check != Block.Lava ) { Count++; } } - if (Count == 2) - { + if ( Count == 2 ) { return true; - } - else - { + } else { return false; } } - public bool CanKillPlayer - { - get { return true; } - } + public bool CanKillPlayer { + get { return true; } + } - public void HitPlayer(World world, Vector3I pos, Player hitted, Player by, ref int restDistance, IList updates) - { - hitted.Kill(world, String.Format("{0}&S was shot by {1}", hitted.ClassyName, hitted.ClassyName == by.ClassyName ? "theirself" : by.ClassyName)); - updates.Add(new BlockUpdate(null, pos, Block.Air)); - restDistance = 0; - } - } + public void HitPlayer( World world, Vector3I pos, Player hitted, Player by, ref int restDistance, IList updates ) { + hitted.Kill( world, String.Format( "{0}&S was shot by {1}", hitted.ClassyName, hitted.ClassyName == by.ClassyName ? "theirself" : by.ClassyName ) ); + updates.Add( new BlockUpdate( null, pos, Block.Air ) ); + restDistance = 0; + } + } - internal class SpellStartBehavior : IParticleBehavior - { + internal class SpellStartBehavior : IParticleBehavior { private static Random _r = new Random(); - public int ProcessingStepsPerSecond - { + public int ProcessingStepsPerSecond { get { return 10; } } - public int MaxDistance - { - get { return _r.Next(6, 10); } + public int MaxDistance { + get { return _r.Next( 6, 10 ); } } - public int MovesPerProcessingStep - { + public int MovesPerProcessingStep { get { return 1; } } - public void ModifyDirection(ref Vector3F direction, Block currentBlock) - { - + public void ModifyDirection( ref Vector3F direction, Block currentBlock ) { } - public bool VisitBlock(World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList updates, Block sending) - { - if (Block.Air != block && Block.Water != block && Block.Lava != block) - { - updates.Add(new BlockUpdate(null, pos, Block.Air)); + + public bool VisitBlock( World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList updates, Block sending ) { + if ( Block.Air != block && Block.Water != block && Block.Lava != block ) { + updates.Add( new BlockUpdate( null, pos, Block.Air ) ); return true; - } - else - { + } else { return false; } } - public bool CanKillPlayer - { + public bool CanKillPlayer { get { return false; } } - public void HitPlayer(World world, Vector3I pos, Player hitted, Player by, ref int restDistance, IList updates) - { - + public void HitPlayer( World world, Vector3I pos, Player hitted, Player by, ref int restDistance, IList updates ) { } } - internal class TntBulletBehavior : IParticleBehavior - { + internal class TntBulletBehavior : IParticleBehavior { private static Random _r = new Random(); - public int ProcessingStepsPerSecond - { + public int ProcessingStepsPerSecond { get { return 20; } } - public int MaxDistance - { + public int MaxDistance { get { return 1024; } } - public int MovesPerProcessingStep - { + public int MovesPerProcessingStep { get { return 1; } } - private const double G = 10; //blocks per second per second - public void ModifyDirection(ref Vector3F direction, Block currentBlock) - { - double t = 1.0 / (ProcessingStepsPerSecond * MovesPerProcessingStep); - Vector3F v = direction * (ProcessingStepsPerSecond * MovesPerProcessingStep); - Vector3F dv = new Vector3F(0, 0, (float)(-G * t)); - direction = (v + dv).Normalize(); + + public void ModifyDirection( ref Vector3F direction, Block currentBlock ) { + double t = 1.0 / ( ProcessingStepsPerSecond * MovesPerProcessingStep ); + Vector3F v = direction * ( ProcessingStepsPerSecond * MovesPerProcessingStep ); + Vector3F dv = new Vector3F( 0, 0, ( float )( -G * t ) ); + direction = ( v + dv ).Normalize(); } - public bool VisitBlock(World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList updates, Block sending) - { - if (Block.Air != block && Block.Water != block) //explode it + public bool VisitBlock( World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList updates, Block sending ) { + if ( Block.Air != block && Block.Water != block ) //explode it { - updates.Add(new BlockUpdate(null, pos, Block.TNT)); - world.AddPhysicsTask(new TNTTask(world, pos, owner, false, true), 0); + updates.Add( new BlockUpdate( null, pos, Block.TNT ) ); + world.AddPhysicsTask( new TNTTask( world, pos, owner, false, true ), 0 ); restDistance = 0; return false; } return true; } - public bool CanKillPlayer - { + public bool CanKillPlayer { get { return true; } } - public void HitPlayer(World world, Vector3I pos, Player hitted, Player by, ref int restDistance, IList updates) - { - hitted.Kill(world, String.Format("{0}&S was torn to pieces by {1}", hitted.ClassyName, hitted.ClassyName == by.ClassyName ? "theirself" : by.ClassyName)); - updates.Add(new BlockUpdate(null, pos, Block.TNT)); - world.AddPhysicsTask(new TNTTask(world, pos, by, false, true), 0); + public void HitPlayer( World world, Vector3I pos, Player hitted, Player by, ref int restDistance, IList updates ) { + hitted.Kill( world, String.Format( "{0}&S was torn to pieces by {1}", hitted.ClassyName, hitted.ClassyName == by.ClassyName ? "theirself" : by.ClassyName ) ); + updates.Add( new BlockUpdate( null, pos, Block.TNT ) ); + world.AddPhysicsTask( new TNTTask( world, pos, by, false, true ), 0 ); restDistance = 0; } } - internal class FootballBehavior : IParticleBehavior - { + internal class FootballBehavior : IParticleBehavior { private static Random _r = new Random(); - public int ProcessingStepsPerSecond - { + public int ProcessingStepsPerSecond { get { return 20; } } - public int MaxDistance - { + public int MaxDistance { get { return 1024; } //check what happens at max } - public int MovesPerProcessingStep - { + public int MovesPerProcessingStep { get { return 1; } } - private const double G = 10; //blocks per second per second - public void ModifyDirection(ref Vector3F direction, Block currentBlock) //change this + + public void ModifyDirection( ref Vector3F direction, Block currentBlock ) //change this { - double t = 1.0 / (ProcessingStepsPerSecond * MovesPerProcessingStep); - Vector3F v = direction * (ProcessingStepsPerSecond * MovesPerProcessingStep); - Vector3F dv = new Vector3F(0, 0, (float)(-G * t)); - direction = (v + dv).Normalize(); + double t = 1.0 / ( ProcessingStepsPerSecond * MovesPerProcessingStep ); + Vector3F v = direction * ( ProcessingStepsPerSecond * MovesPerProcessingStep ); + Vector3F dv = new Vector3F( 0, 0, ( float )( -G * t ) ); + direction = ( v + dv ).Normalize(); } - public bool VisitBlock(World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList updates, Block sending) - { + public bool VisitBlock( World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList updates, Block sending ) { //add some bounce and stuff in here - if (Block.Air != block && Block.Water != block) //explode it + if ( Block.Air != block && Block.Water != block ) //explode it { restDistance = 0; return false; @@ -569,22 +487,16 @@ public bool VisitBlock(World world, Vector3I pos, Block block, Player owner, ref return true; } - public bool CanKillPlayer - { + public bool CanKillPlayer { get { return false; } } - public void HitPlayer(World world, Vector3I pos, Player hitted, Player by, ref int restDistance, IList updates) - { + public void HitPlayer( World world, Vector3I pos, Player hitted, Player by, ref int restDistance, IList updates ) { //if it hits a player, move at Delay to the floor in front of the player - for (int z = pos.Z; z > 0; z--) - { - if (world.Map.GetBlock(pos.X, pos.Y, z) != Block.Air) - { - + for ( int z = pos.Z; z > 0; z-- ) { + if ( world.Map.GetBlock( pos.X, pos.Y, z ) != Block.Air ) { } } } } -} - +} \ No newline at end of file diff --git a/fCraft/Physics/Physics.cs b/fCraft/Physics/Physics.cs index 1808243..df85732 100644 --- a/fCraft/Physics/Physics.cs +++ b/fCraft/Physics/Physics.cs @@ -24,17 +24,13 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Collections; -using fCraft.Events; using System.Xml.Linq; +using fCraft.Events; + +namespace fCraft { -namespace fCraft -{ /// // ░░░▄▄▄▄▀▀▀▀▀▀▀▀▄▄▄▄▄▄ //░░░░█░░░░▒▒▒▒▒▒▒▒▒▒▒▒░░▀▀▄ @@ -53,13 +49,12 @@ namespace fCraft //░░░░░░░░░░░░░░▀▄▄▄▄▄░░░░░█ // Trollphysics, incoming? Admit it, you just laughed. /// - public static class Physics - { + public static class Physics { + //init - public static void Load() - { + public static void Load() { Player.PlacingBlock += PlantPhysics.blockSquash; - SchedulerTask drownCheck = Scheduler.NewBackgroundTask(WaterPhysics.drownCheck).RunForever(TimeSpan.FromSeconds(3)); + SchedulerTask drownCheck = Scheduler.NewBackgroundTask( WaterPhysics.drownCheck ).RunForever( TimeSpan.FromSeconds( 3 ) ); Player.PlacingBlock += PlayerPlacingPhysics; } @@ -68,178 +63,136 @@ public static void Load() public const string XmlRootName = "Physics"; public const string XmlRootName2 = "OtherPhysics"; - public static XElement SaveSettings(World world) - { - return SaveSettings(XmlRootName, world); + public static XElement SaveSettings( World world ) { + return SaveSettings( XmlRootName, world ); } - public static XElement SaveOtherSettings(World world) - { - return SaveOtherSettings(XmlRootName2, world); + public static XElement SaveOtherSettings( World world ) { + return SaveOtherSettings( XmlRootName2, world ); } - public static XElement SaveSettings(string rootName, World world) - { - XElement root = new XElement(rootName); - if (world.plantPhysics) - { - root.Add(new XAttribute("plantPhysics", true)); + public static XElement SaveSettings( string rootName, World world ) { + XElement root = new XElement( rootName ); + if ( world.plantPhysics ) { + root.Add( new XAttribute( "plantPhysics", true ) ); } - if (world.tntPhysics) - { - root.Add(new XAttribute("tntPhysics", true)); + if ( world.tntPhysics ) { + root.Add( new XAttribute( "tntPhysics", true ) ); } - if (world.waterPhysics) - { - root.Add(new XAttribute("waterPhysics", true)); + if ( world.waterPhysics ) { + root.Add( new XAttribute( "waterPhysics", true ) ); } return root; } - public static XElement SaveOtherSettings(string rootName, World world) - { - XElement root = new XElement(rootName); - if (world.fireworkPhysics) - { - root.Add(new XAttribute("fireworkPhysics", true)); + + public static XElement SaveOtherSettings( string rootName, World world ) { + XElement root = new XElement( rootName ); + if ( world.fireworkPhysics ) { + root.Add( new XAttribute( "fireworkPhysics", true ) ); } - if (world.sandPhysics) - { - root.Add(new XAttribute("sandPhysics", true)); + if ( world.sandPhysics ) { + root.Add( new XAttribute( "sandPhysics", true ) ); } - if (world.gunPhysics) - { - root.Add(new XAttribute("gunPhysics", true)); + if ( world.gunPhysics ) { + root.Add( new XAttribute( "gunPhysics", true ) ); } return root; } - - public static void LoadSettings(XElement el, World world) - { + public static void LoadSettings( XElement el, World world ) { XAttribute temp; - if ((temp = el.Attribute("plantPhysics")) != null) - { + if ( ( temp = el.Attribute( "plantPhysics" ) ) != null ) { bool isPhy; - if (bool.TryParse(temp.Value, out isPhy)) - { - world.EnablePlantPhysics(Player.Console, false); + if ( bool.TryParse( temp.Value, out isPhy ) ) { + world.EnablePlantPhysics( Player.Console, false ); } } - if ((temp = el.Attribute("tntPhysics")) != null) - { + if ( ( temp = el.Attribute( "tntPhysics" ) ) != null ) { bool isPhy; - if (bool.TryParse(temp.Value, out isPhy)) - { - world.EnableTNTPhysics(Player.Console, false); + if ( bool.TryParse( temp.Value, out isPhy ) ) { + world.EnableTNTPhysics( Player.Console, false ); } } - if ((temp = el.Attribute("waterPhysics")) != null) - { + if ( ( temp = el.Attribute( "waterPhysics" ) ) != null ) { bool isPhy; - if (bool.TryParse(temp.Value, out isPhy)) - { - world.EnableWaterPhysics(Player.Console, false); + if ( bool.TryParse( temp.Value, out isPhy ) ) { + world.EnableWaterPhysics( Player.Console, false ); } } } - public static void LoadOtherSettings(XElement el, World world) - { + public static void LoadOtherSettings( XElement el, World world ) { XAttribute temp; - if ((temp = el.Attribute("sandPhysics")) != null) - { + if ( ( temp = el.Attribute( "sandPhysics" ) ) != null ) { bool isPhy; - if (bool.TryParse(temp.Value, out isPhy)) - { - world.EnableSandPhysics(Player.Console, false); + if ( bool.TryParse( temp.Value, out isPhy ) ) { + world.EnableSandPhysics( Player.Console, false ); } } - if ((temp = el.Attribute("fireworkPhysics")) != null) - { + if ( ( temp = el.Attribute( "fireworkPhysics" ) ) != null ) { bool isPhy; - if (bool.TryParse(temp.Value, out isPhy)) - { - world.EnableFireworkPhysics(Player.Console, false); + if ( bool.TryParse( temp.Value, out isPhy ) ) { + world.EnableFireworkPhysics( Player.Console, false ); } } - if ((temp = el.Attribute("gunPhysics")) != null) - { + if ( ( temp = el.Attribute( "gunPhysics" ) ) != null ) { bool isPhy; - if (bool.TryParse(temp.Value, out isPhy)) - { - world.EnableGunPhysics(Player.Console, false); + if ( bool.TryParse( temp.Value, out isPhy ) ) { + world.EnableGunPhysics( Player.Console, false ); } } } - #endregion + #endregion Serialization - public static void PlayerPlacingPhysics(object sender, PlayerPlacingBlockEventArgs e) - { + public static void PlayerPlacingPhysics( object sender, PlayerPlacingBlockEventArgs e ) { World world = e.Player.World; - if (e.Result != CanPlaceResult.Allowed){ + if ( e.Result != CanPlaceResult.Allowed ) { return; } - if (e.NewBlock == Block.Gold) - { - if (e.Context == BlockChangeContext.Manual) - { - if (e.Player.fireworkMode && world.fireworkPhysics) - { - if (world.FireworkCount > 10) - { + if ( e.NewBlock == Block.Gold ) { + if ( e.Context == BlockChangeContext.Manual ) { + if ( e.Player.fireworkMode && world.fireworkPhysics ) { + if ( world.FireworkCount > 10 ) { e.Result = CanPlaceResult.Revert; - e.Player.Message("&WThere are too many active fireworks on this world"); + e.Player.Message( "&WThere are too many active fireworks on this world" ); return; - } - else - { + } else { world.FireworkCount++; - world.AddPhysicsTask(new Firework(world, e.Coords), 300); + world.AddPhysicsTask( new Firework( world, e.Coords ), 300 ); } } } } - if (e.NewBlock == Block.TNT) - { - if (world.tntPhysics) - { - if (e.Context == BlockChangeContext.Manual) - { - lock (world.SyncRoot) - { - world.AddPhysicsTask(new TNTTask(world, e.Coords, e.Player, false, true), 3000); + if ( e.NewBlock == Block.TNT ) { + if ( world.tntPhysics ) { + if ( e.Context == BlockChangeContext.Manual ) { + lock ( world.SyncRoot ) { + world.AddPhysicsTask( new TNTTask( world, e.Coords, e.Player, false, true ), 3000 ); return; } } } } - if (e.NewBlock == Block.Sand || e.NewBlock == Block.Gravel) - { - if (e.Context == BlockChangeContext.Manual) - { - if (world.sandPhysics) - { - lock (world.SyncRoot) - { - world.AddPhysicsTask(new SandTask(world, e.Coords, e.NewBlock), 150); + if ( e.NewBlock == Block.Sand || e.NewBlock == Block.Gravel ) { + if ( e.Context == BlockChangeContext.Manual ) { + if ( world.sandPhysics ) { + lock ( world.SyncRoot ) { + world.AddPhysicsTask( new SandTask( world, e.Coords, e.NewBlock ), 150 ); return; } } } } - if (Physics.CanFloat(e.NewBlock)) - { - if (world.waterPhysics) - { - if (e.Context == BlockChangeContext.Manual) - { - world.AddPhysicsTask(new BlockFloat(world, e.Coords, e.NewBlock), 200); + if ( Physics.CanFloat( e.NewBlock ) ) { + if ( world.waterPhysics ) { + if ( e.Context == BlockChangeContext.Manual ) { + world.AddPhysicsTask( new BlockFloat( world, e.Coords, e.NewBlock ), 200 ); return; } } } - if (!Physics.CanFloat(e.NewBlock) + if ( !Physics.CanFloat( e.NewBlock ) && e.NewBlock != Block.Air && e.NewBlock != Block.Water && e.NewBlock != Block.Lava @@ -247,13 +200,10 @@ public static void PlayerPlacingPhysics(object sender, PlayerPlacingBlockEventAr && e.NewBlock != Block.RedFlower && e.NewBlock != Block.RedMushroom && e.NewBlock != Block.YellowFlower - && e.NewBlock != Block.Plant) - { - if (e.Context == BlockChangeContext.Manual) - { - if (world.waterPhysics) - { - world.AddPhysicsTask(new BlockSink(world, e.Coords, e.NewBlock), 200); + && e.NewBlock != Block.Plant ) { + if ( e.Context == BlockChangeContext.Manual ) { + if ( world.waterPhysics ) { + world.AddPhysicsTask( new BlockSink( world, e.Coords, e.NewBlock ), 200 ); return; } } @@ -261,10 +211,8 @@ public static void PlayerPlacingPhysics(object sender, PlayerPlacingBlockEventAr } //physics helpers & bools - public static bool CanSquash(Block block) - { - switch (block) - { + public static bool CanSquash( Block block ) { + switch ( block ) { case Block.BrownMushroom: case Block.Plant: case Block.RedFlower: @@ -275,10 +223,8 @@ public static bool CanSquash(Block block) return false; } - public static bool BlockThrough(Block block) - { - switch (block) - { + public static bool BlockThrough( Block block ) { + switch ( block ) { case Block.Air: case Block.Water: case Block.Lava: @@ -290,10 +236,8 @@ public static bool BlockThrough(Block block) } } - public static bool CanFloat(Block block) - { - switch (block) - { + public static bool CanFloat( Block block ) { + switch ( block ) { case Block.Red: case Block.Orange: case Block.Yellow: diff --git a/fCraft/Physics/PhysicsHeap.cs b/fCraft/Physics/PhysicsHeap.cs index 5e25bdb..a4cee2d 100644 --- a/fCraft/Physics/PhysicsHeap.cs +++ b/fCraft/Physics/PhysicsHeap.cs @@ -1,33 +1,31 @@ //Copyright (C) 2012 Lao Tszy (lao_tszy@yahoo.co.uk) - -//fCraft Copyright (C) 2009, 2010, 2011, 2012 Matvei Stefarov -//Permission is hereby granted, free of charge, to any person obtaining a copy of this -//software and associated documentation files (the "Software"), -//to deal in the Software without restriction, including without limitation the rights to use, + +//fCraft Copyright (C) 2009, 2010, 2011, 2012 Matvei Stefarov +//Permission is hereby granted, free of charge, to any person obtaining a copy of this +//software and associated documentation files (the "Software"), +//to deal in the Software without restriction, including without limitation the rights to use, //copy, modify, merge, publish, distribute, sublicense, -//and/or sell copies of the Software, and to permit persons to whom the Software is +//and/or sell copies of the Software, and to permit persons to whom the Software is //furnished to do so, subject to the following conditions: -//The above copyright notice and this permission notice shall be included in all copies +//The above copyright notice and this permission notice shall be included in all copies //or substantial portions of the Software. -//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, //INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -//HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +//HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION //WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -namespace fCraft -{ +namespace fCraft { + /// /// Base class for physic tasks /// - public abstract class PhysicsTask : IHeapKey - { + public abstract class PhysicsTask : IHeapKey { + /// /// the task due time in milliseconds since some start moment /// @@ -43,22 +41,20 @@ public abstract class PhysicsTask : IHeapKey protected World _world; protected Map _map; - protected PhysicsTask(World world) //a task must be created under the map syn root + protected PhysicsTask( World world ) //a task must be created under the map syn root { - if (null == world) - throw new ArgumentNullException("world"); + if ( null == world ) + throw new ArgumentNullException( "world" ); //if the map is null the task will not be rescheduled //if (null == world.Map) // throw new ArgumentException("world has no map"); - lock (world.SyncRoot) - { + lock ( world.SyncRoot ) { _world = world; _map = world.Map; } } - public Int64 GetHeapKey() - { + public Int64 GetHeapKey() { return DueTime; } @@ -67,30 +63,28 @@ public Int64 GetHeapKey() /// should not be rescheduled /// /// - public int Perform() - { - lock (_world.SyncRoot) - { - if (null == _map || !ReferenceEquals(_map, _world.Map)) + public int Perform() { + lock ( _world.SyncRoot ) { + if ( null == _map || !ReferenceEquals( _map, _world.Map ) ) return 0; return PerformInternal(); } } + /// /// The real implementation of the action /// /// protected abstract int PerformInternal(); - protected void UpdateMap(BlockUpdate upd) - { - _map.SetBlock(upd.X, upd.Y, upd.Z, upd.BlockType); - _map.QueueUpdate(upd); + protected void UpdateMap( BlockUpdate upd ) { + _map.SetBlock( upd.X, upd.Y, upd.Z, upd.BlockType ); + _map.QueueUpdate( upd ); } } - public interface IHeapKey where T : IComparable - { + public interface IHeapKey where T : IComparable { + T GetHeapKey(); } @@ -100,8 +94,7 @@ public interface IHeapKey where T : IComparable /// public class MinBinaryHeap where T : IHeapKey - where K : IComparable - { + where K : IComparable { private readonly List _heap = new List(); private int _free = 0; @@ -109,20 +102,18 @@ public class MinBinaryHeap /// Adds an element. /// /// The t. - public void Add(T t) - { + public void Add( T t ) { int me = _free++; - if (_heap.Count > me) + if ( _heap.Count > me ) _heap[me] = t; else - _heap.Add(t); + _heap.Add( t ); K myKey = t.GetHeapKey(); - while (me > 0) - { - int parent = ParentIdx(me); - if (_heap[parent].GetHeapKey().CompareTo(myKey) < 0) + while ( me > 0 ) { + int parent = ParentIdx( me ); + if ( _heap[parent].GetHeapKey().CompareTo( myKey ) < 0 ) break; - Swap(me, parent); + Swap( me, parent ); me = parent; } } @@ -131,57 +122,46 @@ public void Add(T t) /// Head of this heap. This call assumes that size was checked before accessing the head element. /// /// Head element. - public T Head() - { + public T Head() { return _heap[0]; } /// /// Removes the head. This call assumes that size was checked before removing the head element. /// - public void RemoveHead() - { + public void RemoveHead() { _heap[0] = _heap[--_free]; - _heap[_free] = default(T); //to enable garbage collection for the deleted item when necessary - if (0 == _free) + _heap[_free] = default( T ); //to enable garbage collection for the deleted item when necessary + if ( 0 == _free ) return; int me = 0; K myKey = _heap[0].GetHeapKey(); - for (; ; ) - { + for ( ; ; ) { int kid1, kid2; - Kids(me, out kid1, out kid2); - if (kid1 >= _free) + Kids( me, out kid1, out kid2 ); + if ( kid1 >= _free ) break; int minKid; K minKidKey; - if (kid2 >= _free) - { + if ( kid2 >= _free ) { minKid = kid1; minKidKey = _heap[minKid].GetHeapKey(); - } - else - { + } else { K key1 = _heap[kid1].GetHeapKey(); K key2 = _heap[kid2].GetHeapKey(); - if (key1.CompareTo(key2) < 0) - { + if ( key1.CompareTo( key2 ) < 0 ) { minKid = kid1; minKidKey = key1; - } - else - { + } else { minKid = kid2; minKidKey = key2; } } - if (myKey.CompareTo(minKidKey) > 0) - { - Swap(me, minKid); + if ( myKey.CompareTo( minKidKey ) > 0 ) { + Swap( me, minKid ); me = minKid; - } - else + } else break; } } @@ -189,37 +169,31 @@ public void RemoveHead() /// /// Heap size. /// - public int Size - { - get - { + public int Size { + get { return _free; } } - public void Clear() - { - for (int i = 0; i < _free; ++i) - _heap[i] = default(T); //enables garbage collecting for the deleted elements + public void Clear() { + for ( int i = 0; i < _free; ++i ) + _heap[i] = default( T ); //enables garbage collecting for the deleted elements _free = 0; } - private static int ParentIdx(int idx) - { - return (idx - 1) / 2; + private static int ParentIdx( int idx ) { + return ( idx - 1 ) / 2; } - private static void Kids(int idx, out int kid1, out int kid2) - { + private static void Kids( int idx, out int kid1, out int kid2 ) { kid1 = 2 * idx + 1; kid2 = kid1 + 1; } - private void Swap(int i1, int i2) - { + private void Swap( int i1, int i2 ) { T t = _heap[i1]; _heap[i1] = _heap[i2]; _heap[i2] = t; } } -} +} \ No newline at end of file diff --git a/fCraft/Physics/PhysicsScheduler.cs b/fCraft/Physics/PhysicsScheduler.cs index 7ad824a..80da69e 100644 --- a/fCraft/Physics/PhysicsScheduler.cs +++ b/fCraft/Physics/PhysicsScheduler.cs @@ -24,129 +24,107 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Threading; using System.Diagnostics; -using System.Collections.Generic; -using Util = RandomMaze.MazeUtil; -using fCraft.Drawing; +using System.Threading; -namespace fCraft -{ - public enum TaskCategory - { - Physics, - Life, - } +namespace fCraft { -public class PhysScheduler - { - private MinBinaryHeap _tasks = new MinBinaryHeap(); - private Stopwatch _watch = new Stopwatch(); //a good counter of elapsed milliseconds - private World _owner; - private EventWaitHandle _continue = new EventWaitHandle(false, EventResetMode.AutoReset); - private EventWaitHandle _stop = new EventWaitHandle(false, EventResetMode.AutoReset); - private Thread _thread; + public enum TaskCategory { + Physics, + Life, + } - public bool Started { get { return null != _thread; } } + public class PhysScheduler { + private MinBinaryHeap _tasks = new MinBinaryHeap(); + private Stopwatch _watch = new Stopwatch(); //a good counter of elapsed milliseconds + private World _owner; + private EventWaitHandle _continue = new EventWaitHandle( false, EventResetMode.AutoReset ); + private EventWaitHandle _stop = new EventWaitHandle( false, EventResetMode.AutoReset ); + private Thread _thread; - public PhysScheduler(World owner) - { - _owner = owner; - _watch.Reset(); - _watch.Start(); - } + public bool Started { get { return null != _thread; } } - private void ProcessTasks() - { - WaitHandle[] handles = new WaitHandle[] { _continue, _stop }; - int timeout = Timeout.Infinite; - for (; ; ) - { - int w = WaitHandle.WaitAny(handles, timeout); - if (1 == w) //stop - break; - PhysicsTask task; - //check if there is a due task - lock (_tasks) - { - if (_tasks.Size == 0) //sanity check - { - timeout = Timeout.Infinite; - continue; //nothing to do - } - task = _tasks.Head(); - Int64 now = _watch.ElapsedMilliseconds; - if (task.DueTime <= now) //due time! - _tasks.RemoveHead(); - else - { - timeout = (int)(task.DueTime - now); - continue; - } - } - int delay; - //preform it - try - { - delay = task.Deleted ? 0 : task.Perform(); //dont perform deleted tasks - } - catch (Exception e) - { - delay = 0; - Logger.Log(LogType.Error, "ProcessPhysicsTasks: " + e); - } - //decide what's next - lock (_tasks) - { - Int64 now = _watch.ElapsedMilliseconds; - if (delay > 0) - { - task.DueTime = now + delay; - _tasks.Add(task); - } - timeout = _tasks.Size > 0 ? Math.Max((int)(_tasks.Head().DueTime - now), 0) : Timeout.Infinite; - } - } - } + public PhysScheduler( World owner ) { + _owner = owner; + _watch.Reset(); + _watch.Start(); + } - public void Start() - { - if (null!=_thread) - { - return; - } - if (_tasks.Size>0) - _continue.Set(); - _thread = new Thread(ProcessTasks); - _thread.Start(); - } + private void ProcessTasks() { + WaitHandle[] handles = new WaitHandle[] { _continue, _stop }; + int timeout = Timeout.Infinite; + for ( ; ; ) { + int w = WaitHandle.WaitAny( handles, timeout ); + if ( 1 == w ) //stop + break; + PhysicsTask task; + //check if there is a due task + lock ( _tasks ) { + if ( _tasks.Size == 0 ) //sanity check + { + timeout = Timeout.Infinite; + continue; //nothing to do + } + task = _tasks.Head(); + Int64 now = _watch.ElapsedMilliseconds; + if ( task.DueTime <= now ) //due time! + _tasks.RemoveHead(); + else { + timeout = ( int )( task.DueTime - now ); + continue; + } + } + int delay; + //preform it + try { + delay = task.Deleted ? 0 : task.Perform(); //dont perform deleted tasks + } catch ( Exception e ) { + delay = 0; + Logger.Log( LogType.Error, "ProcessPhysicsTasks: " + e ); + } + //decide what's next + lock ( _tasks ) { + Int64 now = _watch.ElapsedMilliseconds; + if ( delay > 0 ) { + task.DueTime = now + delay; + _tasks.Add( task ); + } + timeout = _tasks.Size > 0 ? Math.Max( ( int )( _tasks.Head().DueTime - now ), 0 ) : Timeout.Infinite; + } + } + } - public void Stop() - { - if (null==_thread) - { - return; - } - _stop.Set(); - if (_thread.Join(10000)) - { - //blocked? - _thread.Abort(); //very bad - } - _thread = null; - _tasks.Clear(); - } + public void Start() { + if ( null != _thread ) { + return; + } + if ( _tasks.Size > 0 ) + _continue.Set(); + _thread = new Thread( ProcessTasks ); + _thread.Start(); + } - public void AddTask(PhysicsTask task, int delay) - { - task.DueTime = _watch.ElapsedMilliseconds + delay; - lock (_tasks) - { - _tasks.Add(task); - } - _continue.Set(); - } - } -} + public void Stop() { + if ( null == _thread ) { + return; + } + _stop.Set(); + if ( _thread.Join( 10000 ) ) { + //blocked? + _thread.Abort(); //very bad + } + _thread = null; + _tasks.Clear(); + } + public void AddTask( PhysicsTask task, int delay ) { + task.DueTime = _watch.ElapsedMilliseconds + delay; + lock ( _tasks ) { + _tasks.Add( task ); + } + _continue.Set(); + } + } +} \ No newline at end of file diff --git a/fCraft/Physics/PlantPhysics.cs b/fCraft/Physics/PlantPhysics.cs index aa93bbe..1f9eb33 100644 --- a/fCraft/Physics/PlantPhysics.cs +++ b/fCraft/Physics/PlantPhysics.cs @@ -24,59 +24,42 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using fCraft.Events; -using System.Threading; -using System.Diagnostics; -using System.IO; -using System.Net; using Util = RandomMaze.MazeUtil; -namespace fCraft -{ - public class PlantPhysics - { - public static void blockSquash(object sender, PlayerPlacingBlockEventArgs e) - { - try - { +namespace fCraft { + + public class PlantPhysics { + + public static void blockSquash( object sender, PlayerPlacingBlockEventArgs e ) { + try { Player player = e.Player; World world = player.World; - if (null==world) - return; - lock (world.SyncRoot) - { - if (null!=world.Map && world.IsLoaded && world.plantPhysics) - { - if (e.NewBlock == Block.Plant) - { - world.AddPhysicsTask(new PlantTask(world, (short)e.Coords.X, (short)e.Coords.Y, (short)e.Coords.Z), PlantTask.GetRandomDelay()); - } - Vector3I z = new Vector3I(e.Coords.X, e.Coords.Y, e.Coords.Z - 1); - if (world.Map.GetBlock(z) == Block.Grass && e.NewBlock!= Block.Air) - { - world.Map.QueueUpdate(new BlockUpdate(null, z, Block.Dirt)); - } - else if (Physics.CanSquash(world.Map.GetBlock(z)) && e.NewBlock!=Block.Air) - { - e.Result = CanPlaceResult.Revert; - Player.RaisePlayerPlacedBlockEvent(player, world.Map, z, world.Map.GetBlock(z), e.NewBlock, BlockChangeContext.Physics); - world.Map.QueueUpdate(new BlockUpdate(null, z, e.NewBlock)); - } - } - } - } - catch (Exception ex) - { - Logger.Log(LogType.SeriousError, "BlockSquash" + ex); + if ( null == world ) + return; + lock ( world.SyncRoot ) { + if ( null != world.Map && world.IsLoaded && world.plantPhysics ) { + if ( e.NewBlock == Block.Plant ) { + world.AddPhysicsTask( new PlantTask( world, ( short )e.Coords.X, ( short )e.Coords.Y, ( short )e.Coords.Z ), PlantTask.GetRandomDelay() ); + } + Vector3I z = new Vector3I( e.Coords.X, e.Coords.Y, e.Coords.Z - 1 ); + if ( world.Map.GetBlock( z ) == Block.Grass && e.NewBlock != Block.Air ) { + world.Map.QueueUpdate( new BlockUpdate( null, z, Block.Dirt ) ); + } else if ( Physics.CanSquash( world.Map.GetBlock( z ) ) && e.NewBlock != Block.Air ) { + e.Result = CanPlaceResult.Revert; + Player.RaisePlayerPlacedBlockEvent( player, world.Map, z, world.Map.GetBlock( z ), e.NewBlock, BlockChangeContext.Physics ); + world.Map.QueueUpdate( new BlockUpdate( null, z, e.NewBlock ) ); + } + } + } + } catch ( Exception ex ) { + Logger.Log( LogType.SeriousError, "BlockSquash" + ex ); } } } - public class GrassTask : PhysicsTask //one per world { private struct Coords //System.Tuple is a class and comparing to this struct causes a significant overhead, thus not used here @@ -84,74 +67,69 @@ private struct Coords //System.Tuple is a class and comparing to this struct cau public short X; public short Y; } + private const int Delay = 150; //not too often, since it has to scan the whole column at some (x, y) private short _i = 0; //current position private Coords[] _rndCoords; - public GrassTask(World world) - : base(world) - { + public GrassTask( World world ) + : base( world ) { int w, l; - lock (world.SyncRoot) - { + lock ( world.SyncRoot ) { w = _map.Width; l = _map.Length; } _rndCoords = new Coords[w * l]; //up to 250K per world with grass physics - for (short i = 0; i < w; ++i) - for (short j = 0; j < l; ++j) + for ( short i = 0; i < w; ++i ) + for ( short j = 0; j < l; ++j ) _rndCoords[i * l + j] = new Coords() { X = i, Y = j }; - Util.RndPermutate(_rndCoords); + Util.RndPermutate( _rndCoords ); } - protected override int PerformInternal() - { - if (_world == null || _map == null) return 0; - if (!_world.plantPhysics || 0 >= _rndCoords.Length) //+sanity check, now we are sure that we have at least 1 element in _rndCoords + protected override int PerformInternal() { + if ( _world == null || _map == null ) + return 0; + if ( !_world.plantPhysics || 0 >= _rndCoords.Length ) //+sanity check, now we are sure that we have at least 1 element in _rndCoords return 0; - if (_i >= _rndCoords.Length) - _i = 0; - Coords c = _rndCoords[_i++]; - + if ( _i >= _rndCoords.Length ) + _i = 0; + Coords c = _rndCoords[_i++]; bool shadowed = false; - for (short z = (short)(_map.Height - 1); z >= 0; --z) - { - if (_map == null) return 0; - Block b = _map.GetBlock(c.X, c.Y, z); + for ( short z = ( short )( _map.Height - 1 ); z >= 0; --z ) { + if ( _map == null ) + return 0; + Block b = _map.GetBlock( c.X, c.Y, z ); - if (!shadowed && Block.Dirt == b) //we have found dirt and there were nothing casting shadows above, so change it to grass and return + if ( !shadowed && Block.Dirt == b ) //we have found dirt and there were nothing casting shadows above, so change it to grass and return { - _map.QueueUpdate(new BlockUpdate(null, c.X, c.Y, z, Block.Grass)); + _map.QueueUpdate( new BlockUpdate( null, c.X, c.Y, z, Block.Grass ) ); shadowed = true; continue; } //since we scan the whole world anyway add the plant task for each not shadowed plant found - it will not harm - if (!shadowed && Block.Plant == b) - { - _world.AddPlantTask(c.X, c.Y, z); + if ( !shadowed && Block.Plant == b ) { + _world.AddPlantTask( c.X, c.Y, z ); continue; } - if (shadowed && Block.Grass == b) //grass should die when shadowed + if ( shadowed && Block.Grass == b ) //grass should die when shadowed { - _map.QueueUpdate(new BlockUpdate(null, c.X, c.Y, z, Block.Dirt)); + _map.QueueUpdate( new BlockUpdate( null, c.X, c.Y, z, Block.Dirt ) ); continue; } - if (!shadowed) - shadowed = CastsShadow(b); //check if the rest of the column is under a block which casts shadow and thus prevents plants from growing and makes grass to die + if ( !shadowed ) + shadowed = CastsShadow( b ); //check if the rest of the column is under a block which casts shadow and thus prevents plants from growing and makes grass to die } return Delay; } - public static bool CastsShadow(Block block) - { - switch (block) - { + public static bool CastsShadow( Block block ) { + switch ( block ) { case Block.Air: case Block.Glass: case Block.Leaves: @@ -167,15 +145,12 @@ public static bool CastsShadow(Block block) } } - - public class PlantTask : PhysicsTask - { + public class PlantTask : PhysicsTask { private const int MinDelay = 3000; private const int MaxDelay = 8000; private static Random _r = new Random(); - private enum TreeType - { + private enum TreeType { NoGrow, Normal, Palm, @@ -183,51 +158,44 @@ private enum TreeType private short _x, _y, _z; - public PlantTask(World w, short x, short y, short z) - : base(w) - { + public PlantTask( World w, short x, short y, short z ) + : base( w ) { _x = x; _y = y; _z = z; } - static public int GetRandomDelay() - { - return (_r.Next(MinDelay, MaxDelay)); + static public int GetRandomDelay() { + return ( _r.Next( MinDelay, MaxDelay ) ); } - protected override int PerformInternal() - { - if (_map.GetBlock(_x, _y, _z) != Block.Plant) //superflous task added by grass scanner or deleted plant. just forget it + protected override int PerformInternal() { + if ( _map.GetBlock( _x, _y, _z ) != Block.Plant ) //superflous task added by grass scanner or deleted plant. just forget it return 0; - TreeType type = TypeByBlock(_map.GetBlock(_x, _y, _z - 1)); - if (TreeType.NoGrow == type) + TreeType type = TypeByBlock( _map.GetBlock( _x, _y, _z - 1 ) ); + if ( TreeType.NoGrow == type ) return 0; - short height = (short)_r.Next(4, 7); - if (CanGrow(height)) - MakeTrunks(height, type); + short height = ( short )_r.Next( 4, 7 ); + if ( CanGrow( height ) ) + MakeTrunks( height, type ); return 0; //non-repeating task } - private bool CanGrow(int height) //no shadows and enough space + private bool CanGrow( int height ) //no shadows and enough space { - for (int z = _z + 1; z < _map.Height; ++z) - { - if (GrassTask.CastsShadow(_map.GetBlock(_x, _y, z))) + for ( int z = _z + 1; z < _map.Height; ++z ) { + if ( GrassTask.CastsShadow( _map.GetBlock( _x, _y, z ) ) ) return false; } - for (int x = _x - 5; x < _x + 5; ++x) - { - for (int y = _y - 5; y < _y + 5; ++y) - { - for (int z = _z + 1; z < _z + height; ++z) - { - Block b = _map.GetBlock(x, y, z); - if (Block.Air != b && Block.Leaves != b) + for ( int x = _x - 5; x < _x + 5; ++x ) { + for ( int y = _y - 5; y < _y + 5; ++y ) { + for ( int z = _z + 1; z < _z + height; ++z ) { + Block b = _map.GetBlock( x, y, z ); + if ( Block.Air != b && Block.Leaves != b ) return false; } } @@ -236,10 +204,8 @@ private bool CanGrow(int height) //no shadows and enough space return true; } - private static TreeType TypeByBlock(Block b) - { - switch (b) - { + private static TreeType TypeByBlock( Block b ) { + switch ( b ) { case Block.Grass: case Block.Dirt: return TreeType.Normal; @@ -249,16 +215,14 @@ private static TreeType TypeByBlock(Block b) return TreeType.NoGrow; } - private void MakeTrunks(short height, TreeType type) - { - for (short i = 0; i < height; ++i) - { - _map.QueueUpdate(new BlockUpdate(null, _x, _y, (short)(_z + i), Block.Log)); + private void MakeTrunks( short height, TreeType type ) { + for ( short i = 0; i < height; ++i ) { + _map.QueueUpdate( new BlockUpdate( null, _x, _y, ( short )( _z + i ), Block.Log ) ); } - if (TreeType.Normal == type) - TreeGeneration.MakeNormalFoliage(_world, new Vector3I(_x, _y, _z), height + 1); + if ( TreeType.Normal == type ) + TreeGeneration.MakeNormalFoliage( _world, new Vector3I( _x, _y, _z ), height + 1 ); else - TreeGeneration.MakePalmFoliage(_world, new Vector3I(_x, _y, _z), height); + TreeGeneration.MakePalmFoliage( _world, new Vector3I( _x, _y, _z ), height ); } } } \ No newline at end of file diff --git a/fCraft/Physics/SandPhysics.cs b/fCraft/Physics/SandPhysics.cs index 4035195..d39c697 100644 --- a/fCraft/Physics/SandPhysics.cs +++ b/fCraft/Physics/SandPhysics.cs @@ -24,59 +24,45 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft.Events; -namespace fCraft -{ - public class SandTask : PhysicsTask - { +namespace fCraft { + + public class SandTask : PhysicsTask { private const int Delay = 200; private Vector3I _pos; private int _nextPos; private bool _firstMove = true; private Block _type; - public SandTask(World world, Vector3I position, Block Type) - : base(world) - { + + public SandTask( World world, Vector3I position, Block Type ) + : base( world ) { _pos = position; _nextPos = position.Z - 1; _type = Type; } - protected override int PerformInternal() - { - lock (_world.SyncRoot) - { - if (_world.sandPhysics) - { - Block nblock = _world.Map.GetBlock(_pos.X, _pos.Y, _nextPos); - if (_firstMove) - { - if (_world.Map.GetBlock(_pos) != _type) - { + protected override int PerformInternal() { + lock ( _world.SyncRoot ) { + if ( _world.sandPhysics ) { + Block nblock = _world.Map.GetBlock( _pos.X, _pos.Y, _nextPos ); + if ( _firstMove ) { + if ( _world.Map.GetBlock( _pos ) != _type ) { return 0; } - if (_world.Map.GetBlock(_pos.X, _pos.Y, _nextPos) == Block.Air) - { - _world.Map.QueueUpdate(new BlockUpdate(null, _pos, Block.Air)); - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)_nextPos, _type)); + if ( _world.Map.GetBlock( _pos.X, _pos.Y, _nextPos ) == Block.Air ) { + _world.Map.QueueUpdate( new BlockUpdate( null, _pos, Block.Air ) ); + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )_nextPos, _type ) ); _nextPos--; _firstMove = false; return Delay; } } - if (_world.Map.GetBlock(_pos.X, _pos.Y, _nextPos) != Block.Air) - { + if ( _world.Map.GetBlock( _pos.X, _pos.Y, _nextPos ) != Block.Air ) { return 0; } - if (Physics.BlockThrough(nblock)) - { - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)(_nextPos + 1), Block.Air)); - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)_nextPos, _type)); + if ( Physics.BlockThrough( nblock ) ) { + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )( _nextPos + 1 ), Block.Air ) ); + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )_nextPos, _type ) ); _nextPos--; } } @@ -84,4 +70,4 @@ protected override int PerformInternal() } } } -} +} \ No newline at end of file diff --git a/fCraft/Physics/TreeGeneration.cs b/fCraft/Physics/TreeGeneration.cs index 39268d2..a4bb227 100644 --- a/fCraft/Physics/TreeGeneration.cs +++ b/fCraft/Physics/TreeGeneration.cs @@ -24,74 +24,52 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + // Code from Forester script by dudecon // Original: http://www.minecraftforum.net/viewtopic.php?f=25&t=9426 using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft.Events; -using fCraft; -namespace fCraft -{ - public static class TreeGeneration - { - public static Random Rand = new Random(); +namespace fCraft { - public static void MakeNormalFoliage(World w, Vector3I Pos, int Height) - { + public static class TreeGeneration { + public static Random Rand = new Random(); + public static void MakeNormalFoliage( World w, Vector3I Pos, int Height ) { int topy = Pos.Z + Height - 1; int start = topy - 2; int end = topy + 2; - for (int y = start; y < end; y++) - { + for ( int y = start; y < end; y++ ) { int rad; - if (y > start + 1) - { + if ( y > start + 1 ) { rad = 1; - } - else - { + } else { rad = 2; } - for (int xoff = -rad; xoff < rad + 1; xoff++) - { - for (int zoff = -rad; zoff < rad + 1; zoff++) - { - if (w.Map != null && w.IsLoaded) - { - if (Rand.NextDouble() > .618 && - Math.Abs(xoff) == Math.Abs(zoff) && - Math.Abs(xoff) == rad) - { + for ( int xoff = -rad; xoff < rad + 1; xoff++ ) { + for ( int zoff = -rad; zoff < rad + 1; zoff++ ) { + if ( w.Map != null && w.IsLoaded ) { + if ( Rand.NextDouble() > .618 && + Math.Abs( xoff ) == Math.Abs( zoff ) && + Math.Abs( xoff ) == rad ) { continue; } - w.Map.QueueUpdate(new - BlockUpdate(null, (short)(Pos.X + xoff), (short)(Pos.Y + zoff), (short)y, Block.Leaves)); + w.Map.QueueUpdate( new + BlockUpdate( null, ( short )( Pos.X + xoff ), ( short )( Pos.Y + zoff ), ( short )y, Block.Leaves ) ); } } } } } - - public static void MakePalmFoliage(World world, Vector3I Pos, int Height) - { - if (world.Map != null && world.IsLoaded) - { + public static void MakePalmFoliage( World world, Vector3I Pos, int Height ) { + if ( world.Map != null && world.IsLoaded ) { int z = Pos.Z + Height; - for (int xoff = -2; xoff < 3; xoff++) - { - for (int yoff = -2; yoff < 3; yoff++) - { - if (Math.Abs(xoff) == Math.Abs(yoff)) - { - if (world.Map != null && world.IsLoaded) - { - world.Map.QueueUpdate(new BlockUpdate(null, (short)(Pos.Z + xoff), (short)(Pos.Y + yoff), (short)z, Block.Leaves)); + for ( int xoff = -2; xoff < 3; xoff++ ) { + for ( int yoff = -2; yoff < 3; yoff++ ) { + if ( Math.Abs( xoff ) == Math.Abs( yoff ) ) { + if ( world.Map != null && world.IsLoaded ) { + world.Map.QueueUpdate( new BlockUpdate( null, ( short )( Pos.Z + xoff ), ( short )( Pos.Y + yoff ), ( short )z, Block.Leaves ) ); } } } @@ -99,5 +77,4 @@ public static void MakePalmFoliage(World world, Vector3I Pos, int Height) } } } -} - +} \ No newline at end of file diff --git a/fCraft/Physics/WaterPhysics.cs b/fCraft/Physics/WaterPhysics.cs index f81328c..95a0f4b 100644 --- a/fCraft/Physics/WaterPhysics.cs +++ b/fCraft/Physics/WaterPhysics.cs @@ -27,57 +27,44 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY using System; using System.Linq; -using System.Text; -using fCraft.Events; -using System.Threading; -using Util = RandomMaze.MazeUtil; -namespace fCraft -{ - public class BlockSink : PhysicsTask - { +namespace fCraft { + + public class BlockSink : PhysicsTask { private const int Delay = 200; private Vector3I _pos; //tnt position private int _nextPos; private bool _firstMove = true; private Block type; - public BlockSink(World world, Vector3I position, Block Type) - : base(world) - { + + public BlockSink( World world, Vector3I position, Block Type ) + : base( world ) { _pos = position; _nextPos = position.Z - 1; type = Type; } - protected override int PerformInternal() - { - lock (_world.SyncRoot) - { - if (_world.waterPhysics) - { - if (_firstMove) - { - if (_world.Map.GetBlock(_pos) != type) - { + protected override int PerformInternal() { + lock ( _world.SyncRoot ) { + if ( _world.waterPhysics ) { + if ( _firstMove ) { + if ( _world.Map.GetBlock( _pos ) != type ) { return 0; } - if (_world.Map.GetBlock(_pos.X, _pos.Y, _nextPos) == Block.Water) - { - _world.Map.QueueUpdate(new BlockUpdate(null, _pos, Block.Water)); - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)_nextPos, type)); + if ( _world.Map.GetBlock( _pos.X, _pos.Y, _nextPos ) == Block.Water ) { + _world.Map.QueueUpdate( new BlockUpdate( null, _pos, Block.Water ) ); + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )_nextPos, type ) ); _nextPos--; _firstMove = false; return Delay; } } - if (_world.Map.GetBlock(_pos.X, _pos.Y, _nextPos + 1) != type) - { + if ( _world.Map.GetBlock( _pos.X, _pos.Y, _nextPos + 1 ) != type ) { return 0; } - if (_world.Map.GetBlock(_pos.X, _pos.Y, _nextPos) == Block.Water) - { - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)(_nextPos + 1), Block.Water)); - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)_nextPos, type)); + if ( _world.Map.GetBlock( _pos.X, _pos.Y, _nextPos ) == Block.Water ) { + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )( _nextPos + 1 ), Block.Water ) ); + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )_nextPos, type ) ); _nextPos--; } } @@ -85,51 +72,42 @@ protected override int PerformInternal() } } } - public class BlockFloat : PhysicsTask - { + + public class BlockFloat : PhysicsTask { private const int Delay = 200; private Vector3I _pos; private int _nextPos; private bool _firstMove = true; private Block type; - public BlockFloat(World world, Vector3I position, Block Type) - : base(world) - { + public BlockFloat( World world, Vector3I position, Block Type ) + : base( world ) { _pos = position; _nextPos = position.Z + 1; type = Type; } - protected override int PerformInternal() - { - lock (_world.SyncRoot) - { - if (_world.waterPhysics) - { - if (_firstMove) - { - if (_world.Map.GetBlock(_pos) != type) - { + protected override int PerformInternal() { + lock ( _world.SyncRoot ) { + if ( _world.waterPhysics ) { + if ( _firstMove ) { + if ( _world.Map.GetBlock( _pos ) != type ) { return 0; } - if (_world.Map.GetBlock(_pos.X, _pos.Y, _nextPos) == Block.Water) - { - _world.Map.QueueUpdate(new BlockUpdate(null, _pos, Block.Water)); - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)_nextPos, type)); + if ( _world.Map.GetBlock( _pos.X, _pos.Y, _nextPos ) == Block.Water ) { + _world.Map.QueueUpdate( new BlockUpdate( null, _pos, Block.Water ) ); + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )_nextPos, type ) ); _nextPos++; _firstMove = false; return Delay; } } - if (_world.Map.GetBlock(_pos.X, _pos.Y, _nextPos - 1) != type) - { + if ( _world.Map.GetBlock( _pos.X, _pos.Y, _nextPos - 1 ) != type ) { return 0; } - if (_world.Map.GetBlock(_pos.X, _pos.Y, _nextPos) == Block.Water) - { - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)(_nextPos - 1), Block.Water)); - _world.Map.QueueUpdate(new BlockUpdate(null, (short)_pos.X, (short)_pos.Y, (short)_nextPos, type)); + if ( _world.Map.GetBlock( _pos.X, _pos.Y, _nextPos ) == Block.Water ) { + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )( _nextPos - 1 ), Block.Water ) ); + _world.Map.QueueUpdate( new BlockUpdate( null, ( short )_pos.X, ( short )_pos.Y, ( short )_nextPos, type ) ); _nextPos++; } } @@ -137,46 +115,36 @@ protected override int PerformInternal() } } } - class WaterPhysics - { - public static void drownCheck(SchedulerTask task) - { - try - { - foreach (Player p in Server.Players.Where(p=> !p.Immortal)) - { - if (p.World != null) //ignore console + + internal class WaterPhysics { + + public static void drownCheck( SchedulerTask task ) { + try { + foreach ( Player p in Server.Players.Where( p => !p.Immortal ) ) { + if ( p.World != null ) //ignore console { - if (p.World.waterPhysics) - { + if ( p.World.waterPhysics ) { Position pos = new Position( - (short)(p.Position.X / 32), - (short)(p.Position.Y / 32), - (short)((p.Position.Z + 1) / 32) + ( short )( p.Position.X / 32 ), + ( short )( p.Position.Y / 32 ), + ( short )( ( p.Position.Z + 1 ) / 32 ) ); - if (p.WorldMap.GetBlock(pos.X, pos.Y, pos.Z) == Block.Water) - { - if (p.DrownTime == null || (DateTime.UtcNow - p.DrownTime).TotalSeconds > 33) - { + if ( p.WorldMap.GetBlock( pos.X, pos.Y, pos.Z ) == Block.Water ) { + if ( p.DrownTime == null || ( DateTime.UtcNow - p.DrownTime ).TotalSeconds > 33 ) { p.DrownTime = DateTime.UtcNow; } - if ((DateTime.UtcNow - p.DrownTime).TotalSeconds > 30) - { - p.TeleportTo(p.WorldMap.Spawn); - p.World.Players.Message("{0}&S drowned and died", p.ClassyName); + if ( ( DateTime.UtcNow - p.DrownTime ).TotalSeconds > 30 ) { + p.TeleportTo( p.WorldMap.Spawn ); + p.World.Players.Message( "{0}&S drowned and died", p.ClassyName ); } - } - else - { + } else { p.DrownTime = DateTime.UtcNow; } } } } - } - catch (Exception ex) - { - Logger.Log(LogType.SeriousError, "" + ex); + } catch ( Exception ex ) { + Logger.Log( LogType.SeriousError, "" + ex ); } } } diff --git a/fCraft/Player/Chat.cs b/fCraft/Player/Chat.cs index 8823db4..9b7d85c 100644 --- a/fCraft/Player/Chat.cs +++ b/fCraft/Player/Chat.cs @@ -1,110 +1,104 @@ // Copyright 2009-2013 Matvei Stefarov using System; using System.Collections.Generic; +using System.IO; using System.Linq; -using fCraft.Events; -using JetBrains.Annotations; using System.Text; using System.Text.RegularExpressions; -using System.IO; +using fCraft.Events; +using JetBrains.Annotations; namespace fCraft { + /// Helper class for handling player-generated chat. public static class Chat { public static List Swears = new List(); public static IEnumerable badWordMatchers; - static System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); + private static System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); #region SendGlobal + /// Sends a global (white) chat. /// Player writing the message. /// Message text. /// True if message was sent, false if it was cancelled by an event callback. public static bool SendGlobal( [NotNull] Player player, [NotNull] string rawMessage ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( rawMessage == null ) throw new ArgumentNullException( "rawMessage" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( rawMessage == null ) + throw new ArgumentNullException( "rawMessage" ); string OriginalMessage = rawMessage; - if (Server.Moderation && !Server.VoicedPlayers.Contains(player) && player.World != null) - { - player.Message("&WError: Server Moderation is activated. Message failed to send"); + if ( Server.Moderation && !Server.VoicedPlayers.Contains( player ) && player.World != null ) { + player.Message( "&WError: Server Moderation is activated. Message failed to send" ); return false; } - rawMessage = rawMessage.Replace("$name", "Hello my name is " + player.ClassyName); - rawMessage = rawMessage.Replace("$kicks", "I have kicked " + player.Info.TimesKickedOthers.ToString() + " players."); - rawMessage = rawMessage.Replace("$bans", "I have banned " + player.Info.TimesBannedOthers.ToString() + " players."); - rawMessage = rawMessage.Replace("$awesome", "It is my professional opinion, that " + ConfigKey.ServerName.GetString() + " is the best server on Minecraft"); - rawMessage = rawMessage.Replace("$server", ConfigKey.ServerName.GetString()); - rawMessage = rawMessage.Replace("$motd", ConfigKey.MOTD.GetString()); - rawMessage = rawMessage.Replace("$date", DateTime.UtcNow.ToShortDateString()); - rawMessage = rawMessage.Replace("$time", DateTime.Now.ToString()); - - if (!player.Can(Permission.ChatWithCaps)) - { + rawMessage = rawMessage.Replace( "$name", "Hello my name is " + player.ClassyName ); + rawMessage = rawMessage.Replace( "$kicks", "I have kicked " + player.Info.TimesKickedOthers.ToString() + " players." ); + rawMessage = rawMessage.Replace( "$bans", "I have banned " + player.Info.TimesBannedOthers.ToString() + " players." ); + rawMessage = rawMessage.Replace( "$awesome", "It is my professional opinion, that " + ConfigKey.ServerName.GetString() + " is the best server on Minecraft" ); + rawMessage = rawMessage.Replace( "$server", ConfigKey.ServerName.GetString() ); + rawMessage = rawMessage.Replace( "$motd", ConfigKey.MOTD.GetString() ); + rawMessage = rawMessage.Replace( "$date", DateTime.UtcNow.ToShortDateString() ); + rawMessage = rawMessage.Replace( "$time", DateTime.Now.ToString() ); + + if ( !player.Can( Permission.ChatWithCaps ) ) { int caps = 0; - for (int i = 0; i < rawMessage.Length; i++) - { - if (Char.IsUpper(rawMessage[i])) - { + for ( int i = 0; i < rawMessage.Length; i++ ) { + if ( Char.IsUpper( rawMessage[i] ) ) { caps++; - if (caps > ConfigKey.MaxCaps.GetInt()) - { + if ( caps > ConfigKey.MaxCaps.GetInt() ) { rawMessage = rawMessage.ToLower(); - player.Message("Your message was changed to lowercase as it exceeded the maximum amount of capital letters."); + player.Message( "Your message was changed to lowercase as it exceeded the maximum amount of capital letters." ); } } } } - if (!player.Can(Permission.Swear)) - { - if (!File.Exists("SwearWords.txt")) - { + if ( !player.Can( Permission.Swear ) ) { + if ( !File.Exists( "SwearWords.txt" ) ) { StringBuilder sb = new StringBuilder(); - sb.AppendLine("#This txt file should be filled with bad words that you want to be filtered out"); - sb.AppendLine("#I have included some examples, excuse my language :P"); - sb.AppendLine("fuck"); - sb.AppendLine("fucking"); - sb.AppendLine("fucked"); - sb.AppendLine("dick"); - sb.AppendLine("bitch"); - sb.AppendLine("shit"); - sb.AppendLine("shitting"); - sb.AppendLine("shithead"); - sb.AppendLine("cunt"); - sb.AppendLine("nigger"); - sb.AppendLine("wanker"); - sb.AppendLine("wank"); - sb.AppendLine("wanking"); - sb.AppendLine("piss"); - File.WriteAllText("SwearWords.txt", sb.ToString()); + sb.AppendLine( "#This txt file should be filled with bad words that you want to be filtered out" ); + sb.AppendLine( "#I have included some examples, excuse my language :P" ); + sb.AppendLine( "fuck" ); + sb.AppendLine( "fucking" ); + sb.AppendLine( "fucked" ); + sb.AppendLine( "dick" ); + sb.AppendLine( "bitch" ); + sb.AppendLine( "shit" ); + sb.AppendLine( "shitting" ); + sb.AppendLine( "shithead" ); + sb.AppendLine( "cunt" ); + sb.AppendLine( "nigger" ); + sb.AppendLine( "wanker" ); + sb.AppendLine( "wank" ); + sb.AppendLine( "wanking" ); + sb.AppendLine( "piss" ); + File.WriteAllText( "SwearWords.txt", sb.ToString() ); } - string CensoredText = Color.ReplacePercentCodes(ConfigKey.SwearName.GetString()) + Color.White; - if (ConfigKey.SwearName.GetString() == null) - { + string CensoredText = Color.ReplacePercentCodes( ConfigKey.SwearName.GetString() ) + Color.White; + if ( ConfigKey.SwearName.GetString() == null ) { CensoredText = "&CBlock&F"; } const string PatternTemplate = @"\b({0})(s?)\b"; const RegexOptions Options = RegexOptions.IgnoreCase; - if (Swears.Count == 0) - { - Swears.AddRange(File.ReadAllLines("SwearWords.txt"). - Where(line => line.StartsWith("#") == false || line.Trim().Equals(String.Empty))); + if ( Swears.Count == 0 ) { + Swears.AddRange( File.ReadAllLines( "SwearWords.txt" ). + Where( line => line.StartsWith( "#" ) == false || line.Trim().Equals( String.Empty ) ) ); } - if (badWordMatchers == null) - { + if ( badWordMatchers == null ) { badWordMatchers = Swears. - Select(x => new Regex(string.Format(PatternTemplate, x), Options)); + Select( x => new Regex( string.Format( PatternTemplate, x ), Options ) ); } string output = badWordMatchers. - Aggregate(rawMessage, (current, matcher) => matcher.Replace(current, CensoredText)); + Aggregate( rawMessage, ( current, matcher ) => matcher.Replace( current, CensoredText ) ); rawMessage = output; } - var recepientList = Server.Players.NotIgnoring(player); + var recepientList = Server.Players.NotIgnoring( player ); string formattedMessage = String.Format( "{0}&F: {1}", player.ClassyName, @@ -116,16 +110,19 @@ public static bool SendGlobal( [NotNull] Player player, [NotNull] string rawMess ChatMessageType.Global, recepientList ); - if( !SendInternal( e ) ) return false; + if ( !SendInternal( e ) ) + return false; Logger.Log( LogType.GlobalChat, "{0}: {1}", player.Name, OriginalMessage ); return true; } - #endregion + + #endregion SendGlobal + #region Emotes - static readonly char[] UnicodeReplacements = " ☺☻♥♦♣♠•◘○\n♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼".ToCharArray(); + private static readonly char[] UnicodeReplacements = " ☺☻♥♦♣♠•◘○\n♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼".ToCharArray(); /// List of chat keywords, and emotes that they stand for. public static readonly Dictionary EmoteKeywords = new Dictionary { @@ -235,83 +232,71 @@ public static bool SendGlobal( [NotNull] Player player, [NotNull] string rawMess { "house", '\u007F' } // ⌂ }; + private static readonly Regex EmoteSymbols = new Regex( "[\x00-\x1F\x7F☺☻♥♦♣♠•◘○\n♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼⌂]" ); - static readonly Regex EmoteSymbols = new Regex("[\x00-\x1F\x7F☺☻♥♦♣♠•◘○\n♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼⌂]"); /// Strips all emote symbols (ASCII control characters). Does not strip UTF-8 equivalents of emotes. /// Message to strip emotes from. /// Message with its emotes stripped. [NotNull, Pure] - public static string StripEmotes([NotNull] string message) - { - if (message == null) throw new ArgumentNullException("message"); - return EmoteSymbols.Replace(message, ""); + public static string StripEmotes( [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + return EmoteSymbols.Replace( message, "" ); } - - /// Replaces emote keywords with actual emotes, using Chat.EmoteKeywords mapping. + /// Replaces emote keywords with actual emotes, using Chat.EmoteKeywords mapping. /// Keywords are enclosed in curly braces, and are case-insensitive. /// String to process. /// Processed string. /// input is null. [NotNull, Pure] - public static string ReplaceEmoteKeywords([NotNull] string message) - { - if (message == null) throw new ArgumentNullException("message"); - int startIndex = message.IndexOf('{'); - if (startIndex == -1) - { + public static string ReplaceEmoteKeywords( [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + int startIndex = message.IndexOf( '{' ); + if ( startIndex == -1 ) { return message; // break out early if there are no opening braces } - StringBuilder output = new StringBuilder(message.Length); + StringBuilder output = new StringBuilder( message.Length ); int lastAppendedIndex = 0; - while (startIndex != -1) - { - int endIndex = message.IndexOf('}', startIndex + 1); - if (endIndex == -1) - { + while ( startIndex != -1 ) { + int endIndex = message.IndexOf( '}', startIndex + 1 ); + if ( endIndex == -1 ) { break; // abort if there are no more closing braces } // see if emote was escaped (if odd number of backslashes precede it) bool escaped = false; - for (int i = startIndex - 1; i >= 0 && message[i] == '\\'; i--) - { + for ( int i = startIndex - 1; i >= 0 && message[i] == '\\'; i-- ) { escaped = !escaped; } // extract the keyword - string keyword = message.Substring(startIndex + 1, endIndex - startIndex - 1); + string keyword = message.Substring( startIndex + 1, endIndex - startIndex - 1 ); char substitute; - if (EmoteKeywords.TryGetValue(keyword.ToLowerInvariant(), out substitute)) - { - if (escaped) - { + if ( EmoteKeywords.TryGetValue( keyword.ToLowerInvariant(), out substitute ) ) { + if ( escaped ) { // it was escaped; remove escaping character startIndex++; - output.Append(message, lastAppendedIndex, startIndex - lastAppendedIndex - 2); + output.Append( message, lastAppendedIndex, startIndex - lastAppendedIndex - 2 ); lastAppendedIndex = startIndex - 1; - } - else - { + } else { // it was not escaped; insert substitute character - output.Append(message, lastAppendedIndex, startIndex - lastAppendedIndex); - output.Append(substitute); + output.Append( message, lastAppendedIndex, startIndex - lastAppendedIndex ); + output.Append( substitute ); startIndex = endIndex + 1; lastAppendedIndex = startIndex; } - } - else - { + } else { startIndex++; // unrecognized macro, keep going } - startIndex = message.IndexOf('{', startIndex); + startIndex = message.IndexOf( '{', startIndex ); } // append the leftovers - output.Append(message, lastAppendedIndex, message.Length - lastAppendedIndex); + output.Append( message, lastAppendedIndex, message.Length - lastAppendedIndex ); return output.ToString(); } - /// Substitutes percent color codes (e.g. %C) with equivalent ampersand color codes (&C). /// Also replaces newline codes (%N) with actual newlines (\n). /// Message to process. @@ -319,83 +304,71 @@ public static string ReplaceEmoteKeywords([NotNull] string message) /// Processed string. /// message is null. [NotNull, Pure] - public static string ReplacePercentColorCodes([NotNull] string message, bool allowNewlines) - { - if (message == null) throw new ArgumentNullException("message"); - int startIndex = message.IndexOf('%'); - if (startIndex == -1) - { + public static string ReplacePercentColorCodes( [NotNull] string message, bool allowNewlines ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + int startIndex = message.IndexOf( '%' ); + if ( startIndex == -1 ) { return message; // break out early if there are no percent marks } - StringBuilder output = new StringBuilder(message.Length); + StringBuilder output = new StringBuilder( message.Length ); int lastAppendedIndex = 0; - while (startIndex != -1 && startIndex < message.Length - 1) - { + while ( startIndex != -1 && startIndex < message.Length - 1 ) { // see if colorcode was escaped (if odd number of backslashes precede it) bool escaped = false; - for (int i = startIndex - 1; i >= 0 && message[i] == '\\'; i--) - { + for ( int i = startIndex - 1; i >= 0 && message[i] == '\\'; i-- ) { escaped = !escaped; } // extract the colorcode char colorCode = message[startIndex + 1]; - if (Color.IsValidColorCode(colorCode) || allowNewlines && (colorCode == 'n' || colorCode == 'N')) - { - if (escaped) - { + if ( Color.IsValidColorCode( colorCode ) || allowNewlines && ( colorCode == 'n' || colorCode == 'N' ) ) { + if ( escaped ) { // it was escaped; remove escaping character startIndex++; - output.Append(message, lastAppendedIndex, startIndex - lastAppendedIndex - 2); + output.Append( message, lastAppendedIndex, startIndex - lastAppendedIndex - 2 ); lastAppendedIndex = startIndex - 1; - } - else - { + } else { // it was not escaped; insert substitute character - output.Append(message, lastAppendedIndex, startIndex - lastAppendedIndex); - output.Append('&'); + output.Append( message, lastAppendedIndex, startIndex - lastAppendedIndex ); + output.Append( '&' ); lastAppendedIndex = startIndex + 1; startIndex += 2; } - } - else - { + } else { startIndex++; // unrecognized colorcode, keep going } - startIndex = message.IndexOf('%', startIndex); + startIndex = message.IndexOf( '%', startIndex ); } // append the leftovers - output.Append(message, lastAppendedIndex, message.Length - lastAppendedIndex); + output.Append( message, lastAppendedIndex, message.Length - lastAppendedIndex ); return output.ToString(); } /// Replaces keywords with appropriate values. [NotNull] - public static string ReplaceTextKeywords([NotNull] Player player, [NotNull] string input) - { - if (player == null) throw new ArgumentNullException("player"); - if (input == null) throw new ArgumentNullException("input"); - StringBuilder sb = new StringBuilder(input); - sb.Replace("{SERVER_NAME}", ConfigKey.ServerName.GetString()); - sb.Replace("{RANK}", player.Info.Rank.ClassyName); - sb.Replace("{TIME}", DateTime.Now.ToShortTimeString()); // localized - if (player.World == null) - { - sb.Replace("{WORLD}", "(No World)"); + public static string ReplaceTextKeywords( [NotNull] Player player, [NotNull] string input ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( input == null ) + throw new ArgumentNullException( "input" ); + StringBuilder sb = new StringBuilder( input ); + sb.Replace( "{SERVER_NAME}", ConfigKey.ServerName.GetString() ); + sb.Replace( "{RANK}", player.Info.Rank.ClassyName ); + sb.Replace( "{TIME}", DateTime.Now.ToShortTimeString() ); // localized + if ( player.World == null ) { + sb.Replace( "{WORLD}", "(No World)" ); + } else { + sb.Replace( "{WORLD}", player.World.ClassyName ); } - else - { - sb.Replace("{WORLD}", player.World.ClassyName); - } - sb.Replace("{WORLDS}", WorldManager.Worlds.Length.ToString()); - sb.Replace("{MOTD}", ConfigKey.MOTD.GetString()); - sb.Replace("{VERSION}", Updater.CurrentRelease.VersionString); - if (input.IndexOf("{PLAYER") != -1) - { - Player[] playerList = Server.Players.CanBeSeen(player).Union(player).ToArray(); - sb.Replace("{PLAYER_NAME}", player.ClassyName); - sb.Replace("{PLAYER_LIST}", playerList.JoinToClassyString()); - sb.Replace("{PLAYERS}", playerList.Length.ToString()); + sb.Replace( "{WORLDS}", WorldManager.Worlds.Length.ToString() ); + sb.Replace( "{MOTD}", ConfigKey.MOTD.GetString() ); + sb.Replace( "{VERSION}", Updater.CurrentRelease.VersionString ); + if ( input.IndexOf( "{PLAYER" ) != -1 ) { + Player[] playerList = Server.Players.CanBeSeen( player ).Union( player ).ToArray(); + sb.Replace( "{PLAYER_NAME}", player.ClassyName ); + sb.Replace( "{PLAYER_LIST}", playerList.JoinToClassyString() ); + sb.Replace( "{PLAYERS}", playerList.Length.ToString() ); } return sb.ToString(); } @@ -405,12 +378,12 @@ public static string ReplaceTextKeywords([NotNull] Player player, [NotNull] stri /// Processed message. /// message is null. [NotNull, Pure] - public static string StripNewlines([NotNull] string message) - { - if (message == null) throw new ArgumentNullException("message"); - message = message.Replace("\n", ""); - message = message.Replace("&n", ""); - message = message.Replace("&N", ""); + public static string StripNewlines( [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + message = message.Replace( "\n", "" ); + message = message.Replace( "&n", "" ); + message = message.Replace( "&N", "" ); return message; } @@ -419,11 +392,11 @@ public static string StripNewlines([NotNull] string message) /// Processed message. /// message is null. [NotNull, Pure] - public static string ReplaceNewlines([NotNull] string message) - { - if (message == null) throw new ArgumentNullException("message"); - message = message.Replace("&n", "\n"); - message = message.Replace("&N", "\n"); + public static string ReplaceNewlines( [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + message = message.Replace( "&n", "\n" ); + message = message.Replace( "&N", "\n" ); return message; } @@ -432,118 +405,121 @@ public static string ReplaceNewlines([NotNull] string message) /// Processed string. /// message is null. [NotNull, Pure] - public static string UnescapeBackslashes([NotNull] string message) - { - if (message == null) throw new ArgumentNullException("message"); - if (message.IndexOf('\\') != -1) - { - return message.Replace(@"\\", @"\"); - } - else - { + public static string UnescapeBackslashes( [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( message.IndexOf( '\\' ) != -1 ) { + return message.Replace( @"\\", @"\" ); + } else { return message; } } - /// Replaces UTF-8 symbol characters with ASCII control characters, matching Code Page 437. /// Opposite of ReplaceEmotesWithUncode. /// String to process. /// Processed string, with its UTF-8 symbol characters replaced. /// input is null. [NotNull] - public static string ReplaceUncodeWithEmotes([NotNull] string input) - { - if (input == null) throw new ArgumentNullException("input"); - StringBuilder sb = new StringBuilder(input); - for (int i = 1; i < UnicodeReplacements.Length; i++) - { - sb.Replace(UnicodeReplacements[i], (char)i); + public static string ReplaceUncodeWithEmotes( [NotNull] string input ) { + if ( input == null ) + throw new ArgumentNullException( "input" ); + StringBuilder sb = new StringBuilder( input ); + for ( int i = 1; i < UnicodeReplacements.Length; i++ ) { + sb.Replace( UnicodeReplacements[i], ( char )i ); } - sb.Replace('⌂', '\u007F'); + sb.Replace( '⌂', '\u007F' ); return sb.ToString(); } - - /// Replaces ASCII control characters with UTF-8 symbol characters, matching Code Page 437. + /// Replaces ASCII control characters with UTF-8 symbol characters, matching Code Page 437. /// Opposite of ReplaceUncodeWithEmotes. /// String to process. /// Processed string, with its ASCII control characters replaced. /// input is null. [NotNull] - public static string ReplaceEmotesWithUncode([NotNull] string input) - { - if (input == null) throw new ArgumentNullException("input"); - StringBuilder sb = new StringBuilder(input); - for (int i = 1; i < UnicodeReplacements.Length; i++) - { - sb.Replace((char)i, UnicodeReplacements[i]); + public static string ReplaceEmotesWithUncode( [NotNull] string input ) { + if ( input == null ) + throw new ArgumentNullException( "input" ); + StringBuilder sb = new StringBuilder( input ); + for ( int i = 1; i < UnicodeReplacements.Length; i++ ) { + sb.Replace( ( char )i, UnicodeReplacements[i] ); } - sb.Replace('\u007F', '⌂'); + sb.Replace( '\u007F', '⌂' ); return sb.ToString(); } - #endregion - + #endregion Emotes #region SendAdmin - public static bool SendAdmin(Player player, string rawMessage) - { - if (player == null) throw new ArgumentNullException("player"); - if (rawMessage == null) throw new ArgumentNullException("rawMessage"); - var recepientList = Server.Players.Can(Permission.ReadAdminChat) - .NotIgnoring(player); - - string formattedMessage = String.Format("&9(Admin){0}&b: {1}", + + public static bool SendAdmin( Player player, string rawMessage ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( rawMessage == null ) + throw new ArgumentNullException( "rawMessage" ); + var recepientList = Server.Players.Can( Permission.ReadAdminChat ) + .NotIgnoring( player ); + + string formattedMessage = String.Format( "&9(Admin){0}&b: {1}", player.ClassyName, - rawMessage); + rawMessage ); - var e = new ChatSendingEventArgs(player, + var e = new ChatSendingEventArgs( player, rawMessage, formattedMessage, ChatMessageType.Staff, - recepientList); + recepientList ); - if (!SendInternal(e)) return false; + if ( !SendInternal( e ) ) + return false; - Logger.Log(LogType.GlobalChat, "(Admin){0}: {1}", player.Name, rawMessage); + Logger.Log( LogType.GlobalChat, "(Admin){0}: {1}", player.Name, rawMessage ); return true; } - #endregion + + #endregion SendAdmin #region SendCustom - public static bool SendCustom(Player player, string rawMessage) - { - if (player == null) throw new ArgumentNullException("player"); - if (rawMessage == null) throw new ArgumentNullException("rawMessage"); - var recepientList = Server.Players.Can(Permission.ReadCustomChat) - .NotIgnoring(player); - - string formattedMessage = String.Format(Color.Custom + "({2}){0}&b: {1}", + + public static bool SendCustom( Player player, string rawMessage ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( rawMessage == null ) + throw new ArgumentNullException( "rawMessage" ); + var recepientList = Server.Players.Can( Permission.ReadCustomChat ) + .NotIgnoring( player ); + + string formattedMessage = String.Format( Color.Custom + "({2}){0}&b: {1}", player.ClassyName, - rawMessage, ConfigKey.CustomChatName.GetString()); + rawMessage, ConfigKey.CustomChatName.GetString() ); - var e = new ChatSendingEventArgs(player, + var e = new ChatSendingEventArgs( player, rawMessage, formattedMessage, ChatMessageType.Staff, - recepientList); + recepientList ); - if (!SendInternal(e)) return false; + if ( !SendInternal( e ) ) + return false; - Logger.Log(LogType.GlobalChat, "({2}){0}: {1}", player.Name, rawMessage, ConfigKey.CustomChatName.GetString()); + Logger.Log( LogType.GlobalChat, "({2}){0}: {1}", player.Name, rawMessage, ConfigKey.CustomChatName.GetString() ); return true; } - #endregion + + #endregion SendCustom #region SendMe + /// Sends an action message (/Me). /// Player writing the message. /// Message text. /// True if message was sent, false if it was cancelled by an event callback. public static bool SendMe( [NotNull] Player player, [NotNull] string rawMessage ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( rawMessage == null ) throw new ArgumentNullException( "rawMessage" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( rawMessage == null ) + throw new ArgumentNullException( "rawMessage" ); var recepientList = Server.Players.NotIgnoring( player ); string formattedMessage = String.Format( "&M*{0} {1}", @@ -556,24 +532,30 @@ public static bool SendMe( [NotNull] Player player, [NotNull] string rawMessage ChatMessageType.Me, recepientList ); - if( !SendInternal( e ) ) return false; + if ( !SendInternal( e ) ) + return false; Logger.Log( LogType.GlobalChat, "(me){0}: {1}", player.Name, rawMessage ); return true; } - #endregion + + #endregion SendMe #region SendPM + /// Sends a private message (PM). Does NOT send a copy of the message to the sender. /// Sender player. /// Recepient player. /// Message text. /// True if message was sent, false if it was cancelled by an event callback. public static bool SendPM( [NotNull] Player from, [NotNull] Player to, [NotNull] string rawMessage ) { - if( from == null ) throw new ArgumentNullException( "from" ); - if( to == null ) throw new ArgumentNullException( "to" ); - if( rawMessage == null ) throw new ArgumentNullException( "rawMessage" ); + if ( from == null ) + throw new ArgumentNullException( "from" ); + if ( to == null ) + throw new ArgumentNullException( "to" ); + if ( rawMessage == null ) + throw new ArgumentNullException( "rawMessage" ); var recepientList = new[] { to }; string formattedMessage = String.Format( "&Pfrom {0}: {1}", from.Name, rawMessage ); @@ -584,25 +566,31 @@ public static bool SendPM( [NotNull] Player from, [NotNull] Player to, [NotNull] ChatMessageType.PM, recepientList ); - if( !SendInternal( e ) ) return false; + if ( !SendInternal( e ) ) + return false; Logger.Log( LogType.PrivateChat, "{0} to {1}: {2}", from.Name, to.Name, rawMessage ); return true; } - #endregion + + #endregion SendPM #region SendRank + /// Sends a rank-wide message (@@Rank message). /// Player writing the message. /// Target rank. /// Message text. /// True if message was sent, false if it was cancelled by an event callback. public static bool SendRank( [NotNull] Player player, [NotNull] Rank rank, [NotNull] string rawMessage ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( rank == null ) throw new ArgumentNullException( "rank" ); - if( rawMessage == null ) throw new ArgumentNullException( "rawMessage" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( rank == null ) + throw new ArgumentNullException( "rank" ); + if ( rawMessage == null ) + throw new ArgumentNullException( "rawMessage" ); var recepientList = rank.Players.NotIgnoring( player ).Union( player ); string formattedMessage = String.Format( "&P({0}&P){1}: {2}", @@ -616,23 +604,28 @@ public static bool SendRank( [NotNull] Player player, [NotNull] Rank rank, [NotN ChatMessageType.Rank, recepientList ); - if( !SendInternal( e ) ) return false; + if ( !SendInternal( e ) ) + return false; Logger.Log( LogType.RankChat, "(rank {0}){1}: {2}", rank.Name, player.Name, rawMessage ); return true; } - #endregion + + #endregion SendRank #region SendSay + /// Sends a global announcement (/Say). /// Player writing the message. /// Message text. /// True if message was sent, false if it was cancelled by an event callback. public static bool SendSay( [NotNull] Player player, [NotNull] string rawMessage ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( rawMessage == null ) throw new ArgumentNullException( "rawMessage" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( rawMessage == null ) + throw new ArgumentNullException( "rawMessage" ); var recepientList = Server.Players.NotIgnoring( player ); string formattedMessage = Color.Say + rawMessage; @@ -643,22 +636,27 @@ public static bool SendSay( [NotNull] Player player, [NotNull] string rawMessage ChatMessageType.Say, recepientList ); - if( !SendInternal( e ) ) return false; + if ( !SendInternal( e ) ) + return false; Logger.Log( LogType.GlobalChat, "(say){0}: {1}", player.Name, rawMessage ); return true; } - #endregion + + #endregion SendSay #region SendStaff + /// Sends a staff message (/Staff). /// Player writing the message. /// Message text. /// True if message was sent, false if it was cancelled by an event callback. public static bool SendStaff( [NotNull] Player player, [NotNull] string rawMessage ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( rawMessage == null ) throw new ArgumentNullException( "rawMessage" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( rawMessage == null ) + throw new ArgumentNullException( "rawMessage" ); var recepientList = Server.Players.Can( Permission.ReadStaffChat ) .NotIgnoring( player ) .Union( player ); @@ -673,24 +671,27 @@ public static bool SendStaff( [NotNull] Player player, [NotNull] string rawMessa ChatMessageType.Staff, recepientList ); - if( !SendInternal( e ) ) return false; + if ( !SendInternal( e ) ) + return false; Logger.Log( LogType.GlobalChat, "(staff){0}: {1}", player.Name, rawMessage ); return true; } - #endregion + #endregion SendStaff - static bool SendInternal( [NotNull] ChatSendingEventArgs e ) { - if( e == null ) throw new ArgumentNullException( "e" ); - if( RaiseSendingEvent( e ) ) return false; + private static bool SendInternal( [NotNull] ChatSendingEventArgs e ) { + if ( e == null ) + throw new ArgumentNullException( "e" ); + if ( RaiseSendingEvent( e ) ) + return false; int recepients = e.RecepientList.Message( e.FormattedMessage ); // Only increment the MessagesWritten count if someone other than // the player was on the recepient list. - if( recepients > 1 || (recepients == 1 && e.RecepientList.First() != e.Player) ) { + if ( recepients > 1 || ( recepients == 1 && e.RecepientList.First() != e.Player ) ) { e.Player.Info.ProcessMessageWritten(); } @@ -698,56 +699,59 @@ static bool SendInternal( [NotNull] ChatSendingEventArgs e ) { return true; } - /// Checks for unprintable or illegal characters in a message. /// Message to check. /// True if message contains invalid chars. False if message is clean. public static bool ContainsInvalidChars( string message ) { - return message.Any(t => t < ' ' || t == '&' || t > '~'); + return message.Any( t => t < ' ' || t == '&' || t > '~' ); } - /// Determines the type of player-supplies message based on its syntax. internal static RawMessageType GetRawMessageType( string message ) { - if( string.IsNullOrEmpty( message ) ) return RawMessageType.Invalid; - if( message == "/" ) return RawMessageType.RepeatCommand; - if( message.Equals( "/ok", StringComparison.OrdinalIgnoreCase ) ) return RawMessageType.Confirmation; - if( message.EndsWith( " /" ) ) return RawMessageType.PartialMessage; - if( message.EndsWith( " //" ) ) message = message.Substring( 0, message.Length - 1 ); - - switch( message[0] ) { + if ( string.IsNullOrEmpty( message ) ) + return RawMessageType.Invalid; + if ( message == "/" ) + return RawMessageType.RepeatCommand; + if ( message.Equals( "/ok", StringComparison.OrdinalIgnoreCase ) ) + return RawMessageType.Confirmation; + if ( message.EndsWith( " /" ) ) + return RawMessageType.PartialMessage; + if ( message.EndsWith( " //" ) ) + message = message.Substring( 0, message.Length - 1 ); + + switch ( message[0] ) { case '/': - if( message.Length < 2 ) { + if ( message.Length < 2 ) { // message too short to be a command return RawMessageType.Invalid; } - if( message[1] == '/' ) { + if ( message[1] == '/' ) { // escaped slash in the beginning: "//blah" return RawMessageType.Chat; } - if( message[1] != ' ' ) { + if ( message[1] != ' ' ) { // normal command: "/cmd" return RawMessageType.Command; } return RawMessageType.Invalid; case '@': - if( message.Length < 4 || message.IndexOf( ' ' ) == -1 ) { + if ( message.Length < 4 || message.IndexOf( ' ' ) == -1 ) { // message too short to be a PM or rank chat return RawMessageType.Invalid; } - if( message[1] == '@' ) { + if ( message[1] == '@' ) { return RawMessageType.RankChat; } - if( message[1] == '-' && message[2] == ' ' ) { + if ( message[1] == '-' && message[2] == ' ' ) { // name shortcut: "@- blah" return RawMessageType.PrivateChat; } - if( message[1] == ' ' && message.IndexOf( ' ', 2 ) != -1 ) { + if ( message[1] == ' ' && message.IndexOf( ' ', 2 ) != -1 ) { // alternative PM notation: "@ name blah" return RawMessageType.PrivateChat; } - if( message[1] != ' ' ) { + if ( message[1] != ' ' ) { // primary PM notation: "@name blah" return RawMessageType.PrivateChat; } @@ -756,34 +760,32 @@ internal static RawMessageType GetRawMessageType( string message ) { return RawMessageType.Chat; } - #region Events - static bool RaiseSendingEvent( ChatSendingEventArgs args ) { + private static bool RaiseSendingEvent( ChatSendingEventArgs args ) { var h = Sending; - if( h == null ) return false; + if ( h == null ) + return false; h( null, args ); return args.Cancel; } - - static void RaiseSentEvent( ChatSendingEventArgs args, int count ) { + private static void RaiseSentEvent( ChatSendingEventArgs args, int count ) { var h = Sent; - if( h != null ) h( null, new ChatSentEventArgs( args.Player, args.Message, args.FormattedMessage, - args.MessageType, args.RecepientList, count ) ); + if ( h != null ) + h( null, new ChatSentEventArgs( args.Player, args.Message, args.FormattedMessage, + args.MessageType, args.RecepientList, count ) ); } - /// Occurs when a chat message is about to be sent. Cancellable. public static event EventHandler Sending; /// Occurs after a chat message has been sent. public static event EventHandler Sent; - #endregion + #endregion Events } - public enum ChatMessageType { Other, @@ -797,10 +799,9 @@ public enum ChatMessageType { World } - - /// Type of message sent by the player. Determined by CommandManager.GetMessageType() public enum RawMessageType { + /// Unparseable chat syntax (rare). Invalid, @@ -830,7 +831,9 @@ public enum RawMessageType { #region Events namespace fCraft.Events { + public sealed class ChatSendingEventArgs : EventArgs, IPlayerEvent, ICancellableEvent { + internal ChatSendingEventArgs( Player player, string message, string formattedMessage, ChatMessageType messageType, IEnumerable recepientList ) { Player = player; @@ -841,15 +844,20 @@ internal ChatSendingEventArgs( Player player, string message, string formattedMe } public Player Player { get; private set; } + public string Message { get; private set; } + public string FormattedMessage { get; set; } + public ChatMessageType MessageType { get; private set; } + public readonly IEnumerable RecepientList; + public bool Cancel { get; set; } } - public sealed class ChatSentEventArgs : EventArgs, IPlayerEvent { + internal ChatSentEventArgs( Player player, string message, string formattedMessage, ChatMessageType messageType, IEnumerable recepientList, int recepientCount ) { Player = player; @@ -861,11 +869,17 @@ internal ChatSentEventArgs( Player player, string message, string formattedMessa } public Player Player { get; private set; } + public string Message { get; private set; } + public string FormattedMessage { get; private set; } + public ChatMessageType MessageType { get; private set; } + public IEnumerable RecepientList { get; private set; } + public int RecepientCount { get; private set; } } -#endregion + +#endregion Events } \ No newline at end of file diff --git a/fCraft/Player/ChatTimer.cs b/fCraft/Player/ChatTimer.cs index e0a6c57..aa3217c 100644 --- a/fCraft/Player/ChatTimer.cs +++ b/fCraft/Player/ChatTimer.cs @@ -6,9 +6,10 @@ using JetBrains.Annotations; namespace fCraft { + public sealed class ChatTimer { public static readonly TimeSpan MinDuration = TimeSpan.FromSeconds( 1 ); - static readonly TimeSpan Hour = TimeSpan.FromHours( 1 ); + private static readonly TimeSpan Hour = TimeSpan.FromHours( 1 ); public readonly int Id; @@ -32,25 +33,24 @@ public TimeSpan TimeLeft { [NotNull] public string StartedBy { get; private set; } + private readonly SchedulerTask task; + private int announceIntervalIndex, lastHourAnnounced; - readonly SchedulerTask task; - int announceIntervalIndex, lastHourAnnounced; - - - ChatTimer( TimeSpan duration, [CanBeNull] string message, [NotNull] string startedBy ) { - if( startedBy == null ) throw new ArgumentNullException( "startedBy" ); + private ChatTimer( TimeSpan duration, [CanBeNull] string message, [NotNull] string startedBy ) { + if ( startedBy == null ) + throw new ArgumentNullException( "startedBy" ); StartedBy = startedBy; Message = message; StartTime = DateTime.UtcNow; EndTime = StartTime.Add( duration ); Duration = duration; - int oneSecondRepeats = (int)duration.TotalSeconds + 1; - if( duration > Hour ) { + int oneSecondRepeats = ( int )duration.TotalSeconds + 1; + if ( duration > Hour ) { announceIntervalIndex = AnnounceIntervals.Length - 1; - lastHourAnnounced = (int)duration.TotalHours; + lastHourAnnounced = ( int )duration.TotalHours; } else { - for( int i = 0; i < AnnounceIntervals.Length; i++ ) { - if( duration <= AnnounceIntervals[i] ) { + for ( int i = 0; i < AnnounceIntervals.Length; i++ ) { + if ( duration <= AnnounceIntervals[i] ) { announceIntervalIndex = i - 1; break; } @@ -65,31 +65,31 @@ public TimeSpan TimeLeft { oneSecondRepeats ); } - static void TimerCallback( [NotNull] SchedulerTask task ) { - if( task == null ) throw new ArgumentNullException( "task" ); - ChatTimer timer = (ChatTimer)task.UserState; - if( task.MaxRepeats == 1 ) { - if( String.IsNullOrEmpty( timer.Message ) ) { + private static void TimerCallback( [NotNull] SchedulerTask task ) { + if ( task == null ) + throw new ArgumentNullException( "task" ); + ChatTimer timer = ( ChatTimer )task.UserState; + if ( task.MaxRepeats == 1 ) { + if ( String.IsNullOrEmpty( timer.Message ) ) { Chat.SendSay( Player.Console, "(Timer Up)" ); } else { Chat.SendSay( Player.Console, "(Timer Up) " + timer.Message ); } timer.Stop(); - - } else if( timer.announceIntervalIndex >= 0 ) { - if( timer.lastHourAnnounced != (int)timer.TimeLeft.TotalHours ) { - timer.lastHourAnnounced = (int)timer.TimeLeft.TotalHours; + } else if ( timer.announceIntervalIndex >= 0 ) { + if ( timer.lastHourAnnounced != ( int )timer.TimeLeft.TotalHours ) { + timer.lastHourAnnounced = ( int )timer.TimeLeft.TotalHours; timer.Announce( TimeSpan.FromHours( Math.Ceiling( timer.TimeLeft.TotalHours ) ) ); } - if( timer.TimeLeft <= AnnounceIntervals[timer.announceIntervalIndex] ) { + if ( timer.TimeLeft <= AnnounceIntervals[timer.announceIntervalIndex] ) { timer.Announce( AnnounceIntervals[timer.announceIntervalIndex] ); timer.announceIntervalIndex--; } } } - void Announce( TimeSpan timeLeft ) { - if( String.IsNullOrEmpty( Message ) ) { + private void Announce( TimeSpan timeLeft ) { + if ( String.IsNullOrEmpty( Message ) ) { Chat.SendSay( Player.Console, "(Timer) " + timeLeft.ToMiniString() ); } else { Chat.SendSay( Player.Console, @@ -105,18 +105,18 @@ public void Stop() { RemoveTimerFromList( this ); } - #region Static public static ChatTimer Start( TimeSpan duration, [CanBeNull] string message, [NotNull] string startedBy ) { - if( startedBy == null ) throw new ArgumentNullException( "startedBy" ); - if( duration < MinDuration ) { + if ( startedBy == null ) + throw new ArgumentNullException( "startedBy" ); + if ( duration < MinDuration ) { throw new ArgumentException( "Timer duration should be at least 1s", "duration" ); } return new ChatTimer( duration, message, startedBy ); } - static readonly TimeSpan[] AnnounceIntervals = new[] { + private static readonly TimeSpan[] AnnounceIntervals = new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3), @@ -139,29 +139,29 @@ public static ChatTimer Start( TimeSpan duration, [CanBeNull] string message, [N TimeSpan.FromMinutes(50) }; - static int timerCounter; - static readonly object TimerListLock = new object(); - static readonly Dictionary Timers = new Dictionary(); + private static int timerCounter; + private static readonly object TimerListLock = new object(); + private static readonly Dictionary Timers = new Dictionary(); - static void AddTimerToList( [NotNull] ChatTimer timer ) { - if( timer == null ) throw new ArgumentNullException( "timer" ); - lock( TimerListLock ) { + private static void AddTimerToList( [NotNull] ChatTimer timer ) { + if ( timer == null ) + throw new ArgumentNullException( "timer" ); + lock ( TimerListLock ) { Timers.Add( timer.Id, timer ); } } - - static void RemoveTimerFromList( [NotNull] ChatTimer timer ) { - if( timer == null ) throw new ArgumentNullException( "timer" ); - lock( TimerListLock ) { + private static void RemoveTimerFromList( [NotNull] ChatTimer timer ) { + if ( timer == null ) + throw new ArgumentNullException( "timer" ); + lock ( TimerListLock ) { Timers.Remove( timer.Id ); } } - public static ChatTimer[] TimerList { get { - lock( TimerListLock ) { + lock ( TimerListLock ) { return Timers.Values.ToArray(); } } @@ -169,9 +169,9 @@ public static ChatTimer[] TimerList { [CanBeNull] public static ChatTimer FindTimerById( int id ) { - lock( TimerListLock ) { + lock ( TimerListLock ) { ChatTimer result; - if( Timers.TryGetValue( id, out result ) ) { + if ( Timers.TryGetValue( id, out result ) ) { return result; } else { return null; @@ -179,6 +179,6 @@ public static ChatTimer FindTimerById( int id ) { } } - #endregion + #endregion Static } } \ No newline at end of file diff --git a/fCraft/Player/Permission.cs b/fCraft/Player/Permission.cs index 55387f5..a2f98e0 100644 --- a/fCraft/Player/Permission.cs +++ b/fCraft/Player/Permission.cs @@ -1,12 +1,12 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft { - // See comment at the top of Config.cs for a history of changes. /// Enumeration of permission types/categories. /// Every rank definition contains a combination of these. public enum Permission { + /// Ability to chat and to PM players. /// Note that players without this permission can still /// type in commands, receive PMs, and read chat. @@ -149,6 +149,7 @@ public enum Permission { /// Ability to enable/disable, clear, and configure BlockDB. ManageBlockDB, + /// Ability to create/remove or view info on Message Blocks. ManageMessageBlocks, @@ -164,6 +165,7 @@ public enum Permission { ShutdownServer, UsePortal, + /// Ability to create or delete a portal. ManagePortal, @@ -244,6 +246,5 @@ public enum Permission { /// Allows a player to become immortal, immune to all damage Immortal - } -} +} \ No newline at end of file diff --git a/fCraft/Player/Player.Events.cs b/fCraft/Player/Player.Events.cs index 9c62584..7b92cd2 100644 --- a/fCraft/Player/Player.Events.cs +++ b/fCraft/Player/Player.Events.cs @@ -5,192 +5,190 @@ using JetBrains.Annotations; namespace fCraft { + partial class Player { + /// Occurs when a player is connecting (cancellable). /// Player name is verified and bans are checked before this event is raised. public static event EventHandler Connecting; - /// Occurs when a player has connected, but before the player has joined any world. /// Allows changing the player's starting world. public static event EventHandler Connected; - /// Occurs after a player has connected and joined the starting world. public static event EventHandler Ready; - /// Occurs when player is about to move (cancellable). public static event EventHandler Moving; - /// Occurs when player has moved. public static event EventHandler Moved; - /// Occurs when player clicked a block (cancellable). /// Note that a click will not necessarily result in a block being placed or deleted. public static event EventHandler Clicking; - /// Occurs after a player has clicked a block. /// Note that a click will not necessarily result in a block being placed or deleted. public static event EventHandler Clicked; - /// Occurs when a player is about to place a block. /// Permission checks are done before calling this event, and their result may be overridden. public static event EventHandler PlacingBlock; - /// Occurs when a player has placed a block. /// This event does not occur if the block placement was disallowed. public static event EventHandler PlacedBlock; - - /// Occurs before a player is kicked (cancellable). + /// Occurs before a player is kicked (cancellable). /// Kick may be caused by /Kick, /Ban, /BanIP, or /BanAll commands, or by idling. /// Callbacks may override whether the kick will be announced or recorded in PlayerDB. public static event EventHandler BeingKicked; - /// Occurs after a player has been kicked. Specifically, it happens after /// kick has been announced and recorded to PlayerDB (if applicable), just before the /// target player disconnects. /// Kick may be caused by /Kick, /Ban, /BanIP, or /BanAll commands, or by idling. public static event EventHandler Kicked; - /// Happens after a player has hidden or unhidden. public static event EventHandler HideChanged; - /// Occurs when a player disconnects. public static event EventHandler Disconnected; - /// Occurs when a player intends to join a world (cancellable). public static event EventHandler JoiningWorld; - /// Occurs after a player has joined a world. public static event EventHandler JoinedWorld; - - static bool RaisePlayerConnectingEvent( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + private static bool RaisePlayerConnectingEvent( [NotNull] Player player ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); var h = Connecting; - if( h == null ) return false; + if ( h == null ) + return false; var e = new PlayerConnectingEventArgs( player ); h( null, e ); return e.Cancel; } - - static World RaisePlayerConnectedEvent( [NotNull] Player player, World world ) { - if( player == null ) throw new ArgumentNullException( "player" ); + private static World RaisePlayerConnectedEvent( [NotNull] Player player, World world ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); var h = Connected; - if( h == null ) return world; + if ( h == null ) + return world; var e = new PlayerConnectedEventArgs( player, world ); h( null, e ); return e.StartingWorld; } - - static void RaisePlayerReadyEvent( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + private static void RaisePlayerReadyEvent( [NotNull] Player player ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); var h = Ready; - if( h != null ) h( null, new PlayerEventArgs( player ) ); + if ( h != null ) + h( null, new PlayerEventArgs( player ) ); } - - static bool RaisePlayerMovingEvent( [NotNull] Player player, Position newPos ) { - if( player == null ) throw new ArgumentNullException( "player" ); + private static bool RaisePlayerMovingEvent( [NotNull] Player player, Position newPos ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); var h = Moving; - if( h == null ) return false; + if ( h == null ) + return false; var e = new PlayerMovingEventArgs( player, newPos ); h( null, e ); return e.Cancel; } - public static void RaisePlayerMovedEvent( [NotNull] Player player, Position oldPos ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); var h = Moved; - if( h != null ) h( null, new PlayerMovedEventArgs( player, oldPos ) ); + if ( h != null ) + h( null, new PlayerMovedEventArgs( player, oldPos ) ); } - public static bool RaisePlayerClickingEvent( [NotNull] PlayerClickingEventArgs e ) { - if( e == null ) throw new ArgumentNullException( "e" ); + if ( e == null ) + throw new ArgumentNullException( "e" ); var h = Clicking; - if( h == null ) return false; + if ( h == null ) + return false; h( null, e ); return e.Cancel; } - - public static void RaisePlayerClickedEvent( Player player, Vector3I coords, - ClickAction action, Block block ) { + public static void RaisePlayerClickedEvent( Player player, Vector3I coords, + ClickAction action, Block block ) { var handler = Clicked; - if( handler != null ) { + if ( handler != null ) { handler( null, new PlayerClickedEventArgs( player, coords, action, block ) ); } } - public static void RaisePlayerPlacedBlockEvent( Player player, Map map, Vector3I coords, Block oldBlock, Block newBlock, BlockChangeContext context ) { var handler = PlacedBlock; - if( handler != null ) { + if ( handler != null ) { handler( null, new PlayerPlacedBlockEventArgs( player, map, coords, oldBlock, newBlock, context ) ); } } - - static void RaisePlayerBeingKickedEvent( [NotNull] PlayerBeingKickedEventArgs e ) { - if( e == null ) throw new ArgumentNullException( "e" ); + private static void RaisePlayerBeingKickedEvent( [NotNull] PlayerBeingKickedEventArgs e ) { + if ( e == null ) + throw new ArgumentNullException( "e" ); var h = BeingKicked; - if( h != null ) h( null, e ); + if ( h != null ) + h( null, e ); } - - static void RaisePlayerKickedEvent( [NotNull] PlayerKickedEventArgs e ) { - if( e == null ) throw new ArgumentNullException( "e" ); + private static void RaisePlayerKickedEvent( [NotNull] PlayerKickedEventArgs e ) { + if ( e == null ) + throw new ArgumentNullException( "e" ); var h = Kicked; - if( h != null ) h( null, e ); + if ( h != null ) + h( null, e ); } - internal static void RaisePlayerHideChangedEvent( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); var h = HideChanged; - if( h != null ) h( null, new PlayerEventArgs( player ) ); + if ( h != null ) + h( null, new PlayerEventArgs( player ) ); } - - static void RaisePlayerDisconnectedEvent( [NotNull] Player player, LeaveReason leaveReason ) { - if( player == null ) throw new ArgumentNullException( "player" ); + private static void RaisePlayerDisconnectedEvent( [NotNull] Player player, LeaveReason leaveReason ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); var h = Disconnected; - if( h != null ) h( null, new PlayerDisconnectedEventArgs( player, leaveReason, false ) ); + if ( h != null ) + h( null, new PlayerDisconnectedEventArgs( player, leaveReason, false ) ); } - - static bool RaisePlayerJoiningWorldEvent( [NotNull] Player player, [NotNull] World newWorld, WorldChangeReason reason, + private static bool RaisePlayerJoiningWorldEvent( [NotNull] Player player, [NotNull] World newWorld, WorldChangeReason reason, string textLine1, string textLine2 ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( newWorld == null ) throw new ArgumentNullException( "newWorld" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( newWorld == null ) + throw new ArgumentNullException( "newWorld" ); var h = JoiningWorld; - if( h == null ) return false; + if ( h == null ) + return false; var e = new PlayerJoiningWorldEventArgs( player, player.World, newWorld, reason, textLine1, textLine2 ); h( null, e ); return e.Cancel; } - - static void RaisePlayerJoinedWorldEvent( Player player, World oldWorld, WorldChangeReason reason ) { + private static void RaisePlayerJoinedWorldEvent( Player player, World oldWorld, WorldChangeReason reason ) { var h = JoinedWorld; - if( h != null ) h( null, new PlayerJoinedWorldEventArgs( player, oldWorld, player.World, reason ) ); + if ( h != null ) + h( null, new PlayerJoinedWorldEventArgs( player, oldWorld, player.World, reason ) ); } } } @@ -198,6 +196,7 @@ static void RaisePlayerJoinedWorldEvent( Player player, World oldWorld, WorldCha namespace fCraft.Events { public sealed class PlayerEventArgs : EventArgs, IPlayerEvent { + internal PlayerEventArgs( Player player ) { Player = player; } @@ -205,60 +204,69 @@ internal PlayerEventArgs( Player player ) { public Player Player { get; private set; } } - public sealed class SessionConnectingEventArgs : EventArgs, ICancellableEvent { + internal SessionConnectingEventArgs( [NotNull] IPAddress ip ) { - if( ip == null ) throw new ArgumentNullException( "ip" ); + if ( ip == null ) + throw new ArgumentNullException( "ip" ); IP = ip; } [NotNull] public IPAddress IP { get; private set; } + public bool Cancel { get; set; } } - public sealed class SessionDisconnectedEventArgs : EventArgs { + internal SessionDisconnectedEventArgs( [NotNull] Player player, LeaveReason leaveReason ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Player = player; LeaveReason = leaveReason; } [NotNull] public Player Player { get; private set; } + public LeaveReason LeaveReason { get; private set; } } - public sealed class PlayerConnectingEventArgs : EventArgs, IPlayerEvent, ICancellableEvent { + internal PlayerConnectingEventArgs( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Player = player; } [NotNull] public Player Player { get; private set; } + public bool Cancel { get; set; } } - public sealed class PlayerConnectedEventArgs : EventArgs, IPlayerEvent { + internal PlayerConnectedEventArgs( [NotNull] Player player, World startingWorld ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Player = player; StartingWorld = startingWorld; } [NotNull] public Player Player { get; private set; } + public World StartingWorld { get; set; } } - public sealed class PlayerMovingEventArgs : EventArgs, IPlayerEvent, ICancellableEvent { + internal PlayerMovingEventArgs( [NotNull] Player player, Position newPos ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Player = player; OldPosition = player.Position; NewPosition = newPos; @@ -266,15 +274,19 @@ internal PlayerMovingEventArgs( [NotNull] Player player, Position newPos ) { [NotNull] public Player Player { get; private set; } + public Position OldPosition { get; private set; } + public Position NewPosition { get; set; } + public bool Cancel { get; set; } } - public sealed class PlayerMovedEventArgs : EventArgs, IPlayerEvent { + internal PlayerMovedEventArgs( [NotNull] Player player, Position oldPos ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Player = player; OldPosition = oldPos; NewPosition = player.Position; @@ -282,15 +294,18 @@ internal PlayerMovedEventArgs( [NotNull] Player player, Position oldPos ) { [NotNull] public Player Player { get; private set; } + public Position OldPosition { get; private set; } + public Position NewPosition { get; private set; } } - public sealed class PlayerClickingEventArgs : EventArgs, IPlayerEvent, ICancellableEvent { + internal PlayerClickingEventArgs( [NotNull] Player player, Vector3I coords, ClickAction action, Block block ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Player = player; Coords = coords; Action = action; @@ -299,17 +314,22 @@ internal PlayerClickingEventArgs( [NotNull] Player player, Vector3I coords, [NotNull] public Player Player { get; private set; } + public Vector3I Coords { get; set; } + public Block Block { get; set; } + /// Whether the player is building a block (right-click) or deleting it (left-click). public ClickAction Action { get; set; } + public bool Cancel { get; set; } } - public sealed class PlayerClickedEventArgs : EventArgs, IPlayerEvent { + internal PlayerClickedEventArgs( [NotNull] Player player, Vector3I coords, ClickAction action, Block block ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Player = player; Coords = coords; Block = block; @@ -318,13 +338,16 @@ internal PlayerClickedEventArgs( [NotNull] Player player, Vector3I coords, Click [NotNull] public Player Player { get; private set; } + public Vector3I Coords { get; private set; } + public Block Block { get; private set; } + public ClickAction Action { get; private set; } } - public sealed class PlayerPlacingBlockEventArgs : PlayerPlacedBlockEventArgs { + internal PlayerPlacingBlockEventArgs( [NotNull] Player player, [NotNull] Map map, Vector3I coords, Block oldBlock, Block newBlock, BlockChangeContext context, CanPlaceResult result ) : base( player, map, coords, oldBlock, newBlock, context ) { @@ -334,11 +357,12 @@ internal PlayerPlacingBlockEventArgs( [NotNull] Player player, [NotNull] Map map public CanPlaceResult Result { get; set; } } - public class PlayerPlacedBlockEventArgs : EventArgs, IPlayerEvent { + internal PlayerPlacedBlockEventArgs( [NotNull] Player player, [NotNull] Map map, Vector3I coords, Block oldBlock, Block newBlock, BlockChangeContext context ) { - if( map == null ) throw new ArgumentNullException( "map" ); + if ( map == null ) + throw new ArgumentNullException( "map" ); Player = player; Map = map; Coords = coords; @@ -347,7 +371,6 @@ internal PlayerPlacedBlockEventArgs( [NotNull] Player player, [NotNull] Map map, Context = context; } - [NotNull] public Player Player { get; private set; } @@ -355,13 +378,16 @@ internal PlayerPlacedBlockEventArgs( [NotNull] Player player, [NotNull] Map map, public Map Map { get; private set; } public Vector3I Coords { get; private set; } + public Block OldBlock { get; private set; } + public Block NewBlock { get; private set; } + public BlockChangeContext Context { get; private set; } } - public sealed class PlayerBeingKickedEventArgs : PlayerKickedEventArgs, ICancellableEvent { + internal PlayerBeingKickedEventArgs( [NotNull] Player player, [NotNull] Player kicker, [CanBeNull] string reason, bool announce, bool recordToPlayerDB, LeaveReason context ) : base( player, kicker, reason, announce, recordToPlayerDB, context ) { @@ -370,12 +396,14 @@ internal PlayerBeingKickedEventArgs( [NotNull] Player player, [NotNull] Player k public bool Cancel { get; set; } } - public class PlayerKickedEventArgs : EventArgs, IPlayerEvent { + internal PlayerKickedEventArgs( [NotNull] Player player, [NotNull] Player kicker, [CanBeNull] string reason, bool announce, bool recordToPlayerDB, LeaveReason context ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( kicker == null ) throw new ArgumentNullException( "kicker" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( kicker == null ) + throw new ArgumentNullException( "kicker" ); Player = player; Kicker = kicker; Reason = reason; @@ -406,10 +434,11 @@ internal PlayerKickedEventArgs( [NotNull] Player player, [NotNull] Player kicker public LeaveReason Context { get; protected set; } } - public sealed class PlayerDisconnectedEventArgs : EventArgs, IPlayerEvent { + internal PlayerDisconnectedEventArgs( [NotNull] Player player, LeaveReason leaveReason, bool isFake ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Player = player; LeaveReason = leaveReason; IsFake = isFake; @@ -417,17 +446,21 @@ internal PlayerDisconnectedEventArgs( [NotNull] Player player, LeaveReason leave [NotNull] public Player Player { get; private set; } + public LeaveReason LeaveReason { get; private set; } + public bool IsFake { get; private set; } } - public sealed class PlayerJoiningWorldEventArgs : EventArgs, IPlayerEvent, ICancellableEvent { + internal PlayerJoiningWorldEventArgs( [NotNull] Player player, [CanBeNull] World oldWorld, [NotNull] World newWorld, WorldChangeReason reason, string textLine1, string textLine2 ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( newWorld == null ) throw new ArgumentNullException( "newWorld" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( newWorld == null ) + throw new ArgumentNullException( "newWorld" ); Player = player; OldWorld = oldWorld; NewWorld = newWorld; @@ -446,15 +479,19 @@ internal PlayerJoiningWorldEventArgs( [NotNull] Player player, [CanBeNull] World public World NewWorld { get; private set; } public WorldChangeReason Reason { get; private set; } + public string TextLine1 { get; set; } + public string TextLine2 { get; set; } + public bool Cancel { get; set; } } - public sealed class PlayerJoinedWorldEventArgs : EventArgs, IPlayerEvent { + public PlayerJoinedWorldEventArgs( [NotNull] Player player, World oldWorld, World newWorld, WorldChangeReason reason ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Player = player; OldWorld = oldWorld; NewWorld = newWorld; @@ -463,8 +500,11 @@ public PlayerJoinedWorldEventArgs( [NotNull] Player player, World oldWorld, Worl [NotNull] public Player Player { get; private set; } + public World OldWorld { get; private set; } + public World NewWorld { get; private set; } + public WorldChangeReason Reason { get; private set; } } } \ No newline at end of file diff --git a/fCraft/Player/Player.cs b/fCraft/Player/Player.cs index 97e70d7..a298c2d 100644 --- a/fCraft/Player/Player.cs +++ b/fCraft/Player/Player.cs @@ -1,18 +1,17 @@ // Copyright 2009-2013 Matvei Stefarov using System; +using System.Collections.Concurrent; using System.Collections.Generic; -using System.IO; +using System.Drawing; using System.Linq; using System.Net; -using System.Net.Cache; using System.Threading; using fCraft.Drawing; using fCraft.Events; using JetBrains.Annotations; -using System.Collections.Concurrent; -using System.Drawing; namespace fCraft { + /// Callback for a player-made selection of one or more blocks on a map. /// A command may request a number of marks/blocks to select, and a specify callback /// to be executed when the desired number of marks/blocks is reached. @@ -20,10 +19,9 @@ namespace fCraft { /// An array of 3D marks/blocks, in terms of block coordinates. /// An optional argument to pass to the callback, /// the value of player.selectionArgs - public delegate void SelectionCallback ( Player player, Vector3I[] marks, object tag ); - - public delegate void ConfirmationCallback ( Player player, object tag, bool fromConsole ); + public delegate void SelectionCallback( Player player, Vector3I[] marks, object tag ); + public delegate void ConfirmationCallback( Player player, object tag, bool fromConsole ); /// Object representing volatile state ("session") of a connected player. /// For persistent state of a known player account, see PlayerInfo. @@ -34,13 +32,13 @@ public sealed partial class Player : IClassy { /// Note that Player.Console.World is always null, /// and that prevents console from calling certain commands (like /TP). public static Player Console, AutoRank; + public bool IsAway; #region Properties public readonly bool IsSuper; - /// Whether the player has completed the login sequence. public SessionState State { get; private set; } @@ -70,7 +68,6 @@ public bool IsOnline { /// Deaf players can't hear anything. public bool IsDeaf { get; set; } - /// The world that the player is currently on. May be null. /// Use .JoinWorld() to make players teleport to another world. [CanBeNull] @@ -83,7 +80,8 @@ public bool IsOnline { public Map WorldMap { get { World world = World; - if ( world == null ) PlayerOpException.ThrowNoWorld( this ); + if ( world == null ) + PlayerOpException.ThrowNoWorld( this ); return world.LoadMap(); } } @@ -91,7 +89,6 @@ public Map WorldMap { /// Player's position in the current world. public Position Position; - /// Time when the session connected. public DateTime LoginTime { get; private set; } @@ -101,10 +98,10 @@ public Map WorldMap { /// Last time when this player was patrolled by someone. public DateTime LastPatrolTime { get; set; } - public Font font = new Font( "Times New Roman", 14, FontStyle.Regular, GraphicsUnit.Pixel ); - System.Drawing.Text.PrivateFontCollection FontC; - public FontFamily LoadFontFamily ( string fileName ) { + private System.Drawing.Text.PrivateFontCollection FontC; + + public FontFamily LoadFontFamily( string fileName ) { FontC = new System.Drawing.Text.PrivateFontCollection();//assing memory space to FontC FontC.AddFontFile( fileName );//we add the full path of the ttf file return FontC.Families[0];//returns the family object as usual. @@ -114,7 +111,6 @@ public FontFamily LoadFontFamily ( string fileName ) { [CanBeNull] public Command LastCommand { get; private set; } - /// Plain version of the name (no formatting). [NotNull] public string Name { @@ -126,7 +122,8 @@ public string Name { public string ListName { get { string displayedName = Name; - if ( iName != null ) displayedName = Color.ReplacePercentCodes( iName ); //impersonate + if ( iName != null ) + displayedName = Color.ReplacePercentCodes( iName ); //impersonate if ( ConfigKey.RankPrefixesInList.Enabled() ) { displayedName = Info.Rank.Prefix + displayedName; } @@ -146,20 +143,22 @@ public string ClassyName { /// Whether the client supports advanced WoM client functionality. public bool IsUsingWoM { get; private set; } - /// Metadata associated with the session/player. [NotNull] public MetadataCollection Metadata { get; private set; } - #endregion + #endregion Properties #region Flying + public bool IsFlying = false; public ConcurrentDictionary FlyCache; public readonly object FlyLock = new object(); - #endregion + + #endregion Flying #region PhysicsHelpers + public ConcurrentDictionary TowerCache = new ConcurrentDictionary(); public bool towerMode = false; public Vector3I towerOrigin; @@ -174,43 +173,54 @@ public string ClassyName { public byte orangeOut; public bool GunMode = false; - public bool fireworkMode = false; //Physics public DateTime DrownTime; + public DateTime LastTimeTNTFired = DateTime.MinValue; + //note that this method updates the fired time, assuming that following this check the TNT will be fired //this is a bad design generally, but sometimes its tempting to dont give a fuck - public bool CanFireTNT () { + public bool CanFireTNT() { bool ret = ( DateTime.UtcNow - LastTimeTNTFired ) > TimeSpan.FromSeconds( 1 ); if ( ret ) LastTimeTNTFired = DateTime.UtcNow; return ret; } - #endregion + + #endregion PhysicsHelpers #region Killing + public DateTime LastTimeKilled; public bool Immortal = false; + //Kill protection - public bool CanBeKilled () { - if ( Immortal ) return false; + public bool CanBeKilled() { + if ( Immortal ) + return false; if ( ( DateTime.UtcNow - LastTimeKilled ).TotalSeconds < 15 ) { return false; } return true; } - #endregion + + #endregion Killing #region General purpose state storage for plugins + private readonly ConcurrentDictionary _publicAuxStateObjects = new ConcurrentDictionary(); + public IDictionary PublicAuxStateObjects { get { return _publicAuxStateObjects; } } - #endregion + + #endregion General purpose state storage for plugins #region Portals + //Portals public bool StandingInPortal = false; + public bool CanUsePortal = true; public String PortalWorld; public String PortalName; @@ -220,11 +230,14 @@ public bool CanBeKilled () { public bool PortalsEnabled = true; public readonly object PortalLock = new object(); public Portals.Portal PortalCache = new Portals.Portal(); - #endregion + + #endregion Portals public readonly object MessageBlockLock = new object(); public DateTime LastUsedMessageBlock; + #region Game + //List of weapons usable in game modes //byte ID will be used for gungame public enum GameWeapon : byte { @@ -242,14 +255,17 @@ public enum GameWeapon : byte { //used for impersonation (skin changing) //if null, default skin is used public string iName = null; + public bool entityChanged = false; - #endregion + + #endregion Game // This constructor is used to create pseudoplayers (such as Console and /dummy). // Such players have unlimited permissions, but no world. // This should be replaced by a more generic solution, like an IEntity interface. - internal Player ( [NotNull] string name ) { - if ( name == null ) throw new ArgumentNullException( "name" ); + internal Player( [NotNull] string name ) { + if ( name == null ) + throw new ArgumentNullException( "name" ); Info = new PlayerInfo( name, RankManager.HighestRank, true, RankChangeType.AutoPromoted ); spamBlockLog = new Queue( Info.Rank.AntiGriefBlocks ); IP = IPAddress.Loopback; @@ -257,10 +273,13 @@ internal Player ( [NotNull] string name ) { State = SessionState.Offline; IsSuper = true; } - public void BassKick ( [NotNull] Player player, [NotNull] string reason, LeaveReason context, - bool announce, bool raiseEvents, bool recordToPlayerDB ) { - if ( player == null ) throw new ArgumentNullException( "player" ); - if ( reason == null ) throw new ArgumentNullException( "reason" ); + + public void BassKick( [NotNull] Player player, [NotNull] string reason, LeaveReason context, + bool announce, bool raiseEvents, bool recordToPlayerDB ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( reason == null ) + throw new ArgumentNullException( "reason" ); if ( !Enum.IsDefined( typeof( LeaveReason ), context ) ) { throw new ArgumentOutOfRangeException( "context" ); } @@ -287,7 +306,8 @@ public void BassKick ( [NotNull] Player player, [NotNull] string reason, LeaveRe if ( raiseEvents ) { var e = new PlayerBeingKickedEventArgs( this, player, reason, announce, recordToPlayerDB, context ); RaisePlayerBeingKickedEvent( e ); - if ( e.Cancel ) PlayerOpException.ThrowCancelled( player, Info ); + if ( e.Cancel ) + PlayerOpException.ThrowCancelled( player, Info ); recordToPlayerDB = e.RecordToPlayerDB; } @@ -327,15 +347,17 @@ public void BassKick ( [NotNull] Player player, [NotNull] string reason, LeaveRe #region Chat and Messaging - static readonly TimeSpan ConfirmationTimeout = TimeSpan.FromSeconds( 60 ); + private static readonly TimeSpan ConfirmationTimeout = TimeSpan.FromSeconds( 60 ); + + private int muteWarnings; - int muteWarnings; [CanBeNull] - string partialMessage; + private string partialMessage; // Parses message incoming from the player - public void ParseMessage ( [NotNull] string rawMessage, bool fromConsole ) { - if ( rawMessage == null ) throw new ArgumentNullException( "rawMessage" ); + public void ParseMessage( [NotNull] string rawMessage, bool fromConsole ) { + if ( rawMessage == null ) + throw new ArgumentNullException( "rawMessage" ); if ( rawMessage.Equals( "/nvm", StringComparison.OrdinalIgnoreCase ) ) { if ( partialMessage != null ) { MessageNow( "Partial message cancelled." ); @@ -361,14 +383,16 @@ public void ParseMessage ( [NotNull] string rawMessage, bool fromConsole ) { switch ( Chat.GetRawMessageType( rawMessage ) ) { case RawMessageType.Chat: { - if ( !Can( Permission.Chat ) ) return; + if ( !Can( Permission.Chat ) ) + return; if ( Info.IsMuted ) { MessageMuted(); return; } - if ( DetectChatSpam() ) return; + if ( DetectChatSpam() ) + return; // Escaped slash removed AFTER logging, to avoid confusion with real commands if ( rawMessage.StartsWith( "//" ) ) { @@ -380,8 +404,8 @@ public void ParseMessage ( [NotNull] string rawMessage, bool fromConsole ) { } Chat.SendGlobal( this, rawMessage ); - } break; - + } + break; case RawMessageType.Command: { if ( rawMessage.EndsWith( "//" ) ) { @@ -408,8 +432,8 @@ public void ParseMessage ( [NotNull] string rawMessage, bool fromConsole ) { LastCommand = cmd; } } - } break; - + } + break; case RawMessageType.RepeatCommand: { if ( LastCommand == null ) { @@ -427,18 +451,20 @@ public void ParseMessage ( [NotNull] string rawMessage, bool fromConsole ) { SendToSpectators( LastCommand.RawMessage ); CommandManager.ParseCommand( this, LastCommand, fromConsole ); } - } break; - + } + break; case RawMessageType.PrivateChat: { - if ( !Can( Permission.Chat ) ) return; + if ( !Can( Permission.Chat ) ) + return; if ( Info.IsMuted ) { MessageMuted(); return; } - if ( DetectChatSpam() ) return; + if ( DetectChatSpam() ) + return; if ( rawMessage.EndsWith( "//" ) ) { rawMessage = rawMessage.Substring( 0, rawMessage.Length - 1 ); @@ -484,7 +510,6 @@ public void ParseMessage ( [NotNull] string rawMessage, bool fromConsole ) { if ( !CanSee( target ) ) { // message was sent to a hidden player MessageNoPlayer( otherPlayerName ); - } else { // message was sent normally LastUsedPlayerName = target.Name; @@ -499,25 +524,25 @@ public void ParseMessage ( [NotNull] string rawMessage, bool fromConsole ) { target.Name, messageText ); } } - } else if ( allPlayers.Length == 0 ) { MessageNoPlayer( otherPlayerName ); - } else { MessageManyMatches( "player", allPlayers ); } - } break; - + } + break; case RawMessageType.RankChat: { - if ( !Can( Permission.Chat ) ) return; + if ( !Can( Permission.Chat ) ) + return; if ( Info.IsMuted ) { MessageMuted(); return; } - if ( DetectChatSpam() ) return; + if ( DetectChatSpam() ) + return; if ( rawMessage.EndsWith( "//" ) ) { rawMessage = rawMessage.Substring( 0, rawMessage.Length - 1 ); @@ -545,8 +570,8 @@ public void ParseMessage ( [NotNull] string rawMessage, bool fromConsole ) { } Chat.SendRank( this, rank, messageText ); - } break; - + } + break; case RawMessageType.Confirmation: { if ( Info.IsFrozen ) { @@ -565,8 +590,8 @@ public void ParseMessage ( [NotNull] string rawMessage, bool fromConsole ) { } else { MessageNow( "There is no command to confirm." ); } - } break; - + } + break; case RawMessageType.PartialMessage: partialMessage = rawMessage.Substring( 0, rawMessage.Length - 1 ); @@ -579,20 +604,22 @@ public void ParseMessage ( [NotNull] string rawMessage, bool fromConsole ) { } } - - public void SendToSpectators ( [NotNull] string message, [NotNull] params object[] args ) { - if ( message == null ) throw new ArgumentNullException( "message" ); - if ( args == null ) throw new ArgumentNullException( "args" ); + public void SendToSpectators( [NotNull] string message, [NotNull] params object[] args ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( args == null ) + throw new ArgumentNullException( "args" ); Player[] spectators = Server.Players.Where( p => p.spectatedPlayer == this ).ToArray(); if ( spectators.Length > 0 ) { spectators.Message( "[Spectate]: &F" + message, args ); } } + private const string WoMAlertPrefix = "^detail.user.alert="; - const string WoMAlertPrefix = "^detail.user.alert="; - public void MessageAlt ( [NotNull] string message ) { - if ( message == null ) throw new ArgumentNullException( "message" ); + public void MessageAlt( [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); if ( this == Console ) { Logger.LogToConsole( message ); } else if ( IsUsingWoM ) { @@ -607,15 +634,17 @@ public void MessageAlt ( [NotNull] string message ) { } [StringFormatMethod( "message" )] - public void MessageAlt ( [NotNull] string message, [NotNull] params object[] args ) { - if ( message == null ) throw new ArgumentNullException( "message" ); - if ( args == null ) throw new ArgumentNullException( "args" ); + public void MessageAlt( [NotNull] string message, [NotNull] params object[] args ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( args == null ) + throw new ArgumentNullException( "args" ); MessageAlt( String.Format( message, args ) ); } - - public void Message ( [NotNull] string message ) { - if ( message == null ) throw new ArgumentNullException( "message" ); + public void Message( [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); if ( IsSuper ) { Logger.LogToConsole( message ); } else { @@ -625,27 +654,32 @@ public void Message ( [NotNull] string message ) { } } - [StringFormatMethod( "message" )] - public void Message ( [NotNull] string message, [NotNull] object arg ) { - if ( message == null ) throw new ArgumentNullException( "message" ); - if ( arg == null ) throw new ArgumentNullException( "arg" ); + public void Message( [NotNull] string message, [NotNull] object arg ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( arg == null ) + throw new ArgumentNullException( "arg" ); Message( String.Format( message, arg ) ); } [StringFormatMethod( "message" )] - public void Message ( [NotNull] string message, [NotNull] params object[] args ) { - if ( message == null ) throw new ArgumentNullException( "message" ); - if ( args == null ) throw new ArgumentNullException( "args" ); + public void Message( [NotNull] string message, [NotNull] params object[] args ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( args == null ) + throw new ArgumentNullException( "args" ); Message( String.Format( message, args ) ); } - [StringFormatMethod( "message" )] - public void MessagePrefixed ( [NotNull] string prefix, [NotNull] string message, [NotNull] params object[] args ) { - if ( prefix == null ) throw new ArgumentNullException( "prefix" ); - if ( message == null ) throw new ArgumentNullException( "message" ); - if ( args == null ) throw new ArgumentNullException( "args" ); + public void MessagePrefixed( [NotNull] string prefix, [NotNull] string message, [NotNull] params object[] args ) { + if ( prefix == null ) + throw new ArgumentNullException( "prefix" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( args == null ) + throw new ArgumentNullException( "args" ); if ( args.Length > 0 ) { message = String.Format( message, args ); } @@ -658,12 +692,14 @@ public void MessagePrefixed ( [NotNull] string prefix, [NotNull] string message, } } - [StringFormatMethod( "message" )] - internal void MessageNow ( [NotNull] string message, [NotNull] params object[] args ) { - if ( message == null ) throw new ArgumentNullException( "message" ); - if ( args == null ) throw new ArgumentNullException( "args" ); - if ( IsDeaf ) return; + internal void MessageNow( [NotNull] string message, [NotNull] params object[] args ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( args == null ) + throw new ArgumentNullException( "args" ); + if ( IsDeaf ) + return; if ( args.Length > 0 ) { message = String.Format( message, args ); } @@ -679,13 +715,16 @@ internal void MessageNow ( [NotNull] string message, [NotNull] params object[] a } } - [StringFormatMethod( "message" )] - internal void MessageNowPrefixed ( [NotNull] string prefix, [NotNull] string message, [NotNull] params object[] args ) { - if ( prefix == null ) throw new ArgumentNullException( "prefix" ); - if ( message == null ) throw new ArgumentNullException( "message" ); - if ( args == null ) throw new ArgumentNullException( "args" ); - if ( IsDeaf ) return; + internal void MessageNowPrefixed( [NotNull] string prefix, [NotNull] string message, [NotNull] params object[] args ) { + if ( prefix == null ) + throw new ArgumentNullException( "prefix" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( args == null ) + throw new ArgumentNullException( "args" ); + if ( IsDeaf ) + return; if ( args.Length > 0 ) { message = String.Format( message, args ); } @@ -701,42 +740,45 @@ internal void MessageNowPrefixed ( [NotNull] string prefix, [NotNull] string mes } } - #region Macros - public void MessageNoPlayer ( [NotNull] string playerName ) { - if ( playerName == null ) throw new ArgumentNullException( "playerName" ); + public void MessageNoPlayer( [NotNull] string playerName ) { + if ( playerName == null ) + throw new ArgumentNullException( "playerName" ); Message( "No players found matching \"{0}\"", playerName ); } - - public void MessageNoWorld ( [NotNull] string worldName ) { - if ( worldName == null ) throw new ArgumentNullException( "worldName" ); + public void MessageNoWorld( [NotNull] string worldName ) { + if ( worldName == null ) + throw new ArgumentNullException( "worldName" ); Message( "No worlds found matching \"{0}\". See &H/Worlds", worldName ); } - - public void MessageManyMatches ( [NotNull] string itemType, [NotNull] IEnumerable names ) { - if ( itemType == null ) throw new ArgumentNullException( "itemType" ); - if ( names == null ) throw new ArgumentNullException( "names" ); + public void MessageManyMatches( [NotNull] string itemType, [NotNull] IEnumerable names ) { + if ( itemType == null ) + throw new ArgumentNullException( "itemType" ); + if ( names == null ) + throw new ArgumentNullException( "names" ); string nameList = names.JoinToString( ", ", p => p.ClassyName ); Message( "More than one {0} matched: {1}", itemType, nameList ); } - public void MessageManyDisplayedNamesMatches ( [NotNull] string itemType, [NotNull] PlayerInfo[] names ) { - if ( itemType == null ) throw new ArgumentNullException( "itemType" ); - if ( names == null ) throw new ArgumentNullException( "names" ); + public void MessageManyDisplayedNamesMatches( [NotNull] string itemType, [NotNull] PlayerInfo[] names ) { + if ( itemType == null ) + throw new ArgumentNullException( "itemType" ); + if ( names == null ) + throw new ArgumentNullException( "names" ); string nameList = names.JoinToString( ", ", p => p.Name + "&S(" + p.DisplayedName + "&S)" ); Message( "More than one {0} matched: {1}", itemType, nameList ); } - - public void MessageNoAccess ( [NotNull] params Permission[] permissions ) { - if ( permissions == null ) throw new ArgumentNullException( "permissions" ); + public void MessageNoAccess( [NotNull] params Permission[] permissions ) { + if ( permissions == null ) + throw new ArgumentNullException( "permissions" ); Rank reqRank = RankManager.GetMinRankWithAllPermissions( permissions ); if ( reqRank == null ) { Message( "None of the ranks have permissions for this command." ); @@ -746,9 +788,9 @@ public void MessageNoAccess ( [NotNull] params Permission[] permissions ) { } } - - public void MessageNoAccess ( [NotNull] CommandDescriptor cmd ) { - if ( cmd == null ) throw new ArgumentNullException( "cmd" ); + public void MessageNoAccess( [NotNull] CommandDescriptor cmd ) { + if ( cmd == null ) + throw new ArgumentNullException( "cmd" ); Rank reqRank = cmd.MinRank; if ( reqRank == null ) { Message( "This command is disabled on the server." ); @@ -758,70 +800,64 @@ public void MessageNoAccess ( [NotNull] CommandDescriptor cmd ) { } } - - public void MessageNoRank ( [NotNull] string rankName ) { - if ( rankName == null ) throw new ArgumentNullException( "rankName" ); + public void MessageNoRank( [NotNull] string rankName ) { + if ( rankName == null ) + throw new ArgumentNullException( "rankName" ); Message( "Unrecognized rank \"{0}\". See &H/Ranks", rankName ); } - - public void MessageUnsafePath () { + public void MessageUnsafePath() { Message( "&WYou cannot access files outside the map folder." ); } - - public void MessageNoZone ( [NotNull] string zoneName ) { - if ( zoneName == null ) throw new ArgumentNullException( "zoneName" ); + public void MessageNoZone( [NotNull] string zoneName ) { + if ( zoneName == null ) + throw new ArgumentNullException( "zoneName" ); Message( "No zones found matching \"{0}\". See &H/Zones", zoneName ); } - - public void MessageInvalidWorldName ( [NotNull] string worldName ) { + public void MessageInvalidWorldName( [NotNull] string worldName ) { Message( "Unacceptable world name: \"{0}\"", worldName ); Message( "World names must be 1-16 characters long, and only contain letters, numbers, and underscores." ); } - - public void MessageInvalidPlayerName ( [NotNull] string playerName ) { + public void MessageInvalidPlayerName( [NotNull] string playerName ) { Message( "\"{0}\" is not a valid player name.", playerName ); } - - public void MessageMuted () { + public void MessageMuted() { Message( "You are muted for {0} longer.", Info.TimeMutedLeft.ToMiniString() ); } - - public void MessageMaxTimeSpan () { + public void MessageMaxTimeSpan() { Message( "Specify a time range up to {0:0}d.", DateTimeUtil.MaxTimeSpan.TotalDays ); } - #endregion - + #endregion Macros #region Ignore - readonly HashSet ignoreList = new HashSet(); - readonly object ignoreLock = new object(); - + private readonly HashSet ignoreList = new HashSet(); + private readonly object ignoreLock = new object(); /// Checks whether this player is currently ignoring a given PlayerInfo. - public bool IsIgnoring ( [NotNull] PlayerInfo other ) { - if ( other == null ) throw new ArgumentNullException( "other" ); + public bool IsIgnoring( [NotNull] PlayerInfo other ) { + if ( other == null ) + throw new ArgumentNullException( "other" ); lock ( ignoreLock ) { return ignoreList.Contains( other ); } } - /// Adds a given PlayerInfo to the ignore list. /// Not that ignores are not persistent, and are reset when a player disconnects. /// Player to ignore. /// True if the player is now ignored, /// false is the player has already been ignored previously. - public bool Ignore ( [NotNull] PlayerInfo other ) { - if ( other == null ) throw new ArgumentNullException( "other" ); + public bool Ignore( [NotNull] PlayerInfo other ) { + if ( other == null ) + throw new ArgumentNullException( "other" ); lock ( ignoreLock ) { if ( !ignoreList.Contains( other ) ) { ignoreList.Add( other ); @@ -832,19 +868,18 @@ public bool Ignore ( [NotNull] PlayerInfo other ) { } } - /// Removes a given PlayerInfo from the ignore list. /// PlayerInfo to unignore. /// True if the player is no longer ignored, /// false if the player was already not ignored. - public bool Unignore ( [NotNull] PlayerInfo other ) { - if ( other == null ) throw new ArgumentNullException( "other" ); + public bool Unignore( [NotNull] PlayerInfo other ) { + if ( other == null ) + throw new ArgumentNullException( "other" ); lock ( ignoreLock ) { return ignoreList.Remove( other ); } } - /// Returns a list of all currently-ignored players. [NotNull] public PlayerInfo[] IgnoreList { @@ -855,8 +890,7 @@ public PlayerInfo[] IgnoreList { } } - #endregion - + #endregion Ignore #region Confirmation @@ -866,8 +900,9 @@ public PlayerInfo[] IgnoreList { [CanBeNull] public object ConfirmArgument { get; private set; } - static void ConfirmCommandCallback ( [NotNull] Player player, object tag, bool fromConsole ) { - if ( player == null ) throw new ArgumentNullException( "player" ); + private static void ConfirmCommandCallback( [NotNull] Player player, object tag, bool fromConsole ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); Command cmd = ( Command )tag; cmd.Rewind(); cmd.IsConfirmed = true; @@ -884,32 +919,35 @@ static void ConfirmCommandCallback ( [NotNull] Player player, object tag, bool f /// Message to print before "Type /ok to continue". /// Optional String.Format() arguments, for the message. [StringFormatMethod( "message" )] - public void Confirm ( [NotNull] Command cmd, [NotNull] string message, [NotNull] params object[] args ) { + public void Confirm( [NotNull] Command cmd, [NotNull] string message, [NotNull] params object[] args ) { Confirm( ConfirmCommandCallback, cmd, message, args ); } [StringFormatMethod( "message" )] - public void Confirm ( [NotNull] ConfirmationCallback callback, [CanBeNull] object arg, [NotNull] string message, [NotNull] params object[] args ) { - if ( callback == null ) throw new ArgumentNullException( "callback" ); - if ( message == null ) throw new ArgumentNullException( "message" ); - if ( args == null ) throw new ArgumentNullException( "args" ); + public void Confirm( [NotNull] ConfirmationCallback callback, [CanBeNull] object arg, [NotNull] string message, [NotNull] params object[] args ) { + if ( callback == null ) + throw new ArgumentNullException( "callback" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( args == null ) + throw new ArgumentNullException( "args" ); ConfirmCallback = callback; ConfirmArgument = arg; ConfirmRequestTime = DateTime.UtcNow; Message( "{0} Type &H/ok&S to continue.", String.Format( message, args ) ); } - #endregion - + #endregion Confirmation #region AntiSpam public static int AntispamMessageCount = 3; public static int AntispamInterval = 4; - readonly Queue spamChatLog = new Queue( AntispamMessageCount ); + private readonly Queue spamChatLog = new Queue( AntispamMessageCount ); - internal bool DetectChatSpam () { - if ( IsSuper ) return false; + internal bool DetectChatSpam() { + if ( IsSuper ) + return false; if ( spamChatLog.Count >= AntispamMessageCount ) { DateTime oldestTime = spamChatLog.Dequeue(); if ( DateTime.UtcNow.Subtract( oldestTime ).TotalSeconds < AntispamInterval ) { @@ -919,7 +957,8 @@ internal bool DetectChatSpam () { Server.Message( "&W{0}&S was kicked for repeated spamming.", ClassyName ); } else { TimeSpan autoMuteDuration = TimeSpan.FromSeconds( ConfigKey.AntispamMuteDuration.GetInt() ); - if ( autoMuteDuration == TimeSpan.FromSeconds(0) ) return false; + if ( autoMuteDuration == TimeSpan.FromSeconds( 0 ) ) + return false; Info.Mute( Console, autoMuteDuration, false, true ); Message( "You have been muted for {0} seconds. Slow down.", autoMuteDuration ); } @@ -930,15 +969,14 @@ internal bool DetectChatSpam () { return false; } - #endregion - - #endregion + #endregion AntiSpam + #endregion Chat and Messaging #region Placing Blocks // for grief/spam detection - readonly Queue spamBlockLog = new Queue(); + private readonly Queue spamBlockLog = new Queue(); /// Last blocktype used by the player. /// Make sure to use in conjunction with Player.GetBind() to ensure that bindings are properly applied. @@ -947,11 +985,11 @@ internal bool DetectChatSpam () { /// Max distance that player may be from a block to reach it (hack detection). public static int MaxBlockPlacementRange { get; set; } - /// Handles manually-placed/deleted blocks. /// Returns true if player's action should result in a kick. - public bool PlaceBlock ( Vector3I coord, ClickAction action, Block type ) { - if ( World == null ) PlayerOpException.ThrowNoWorld( this ); + public bool PlaceBlock( Vector3I coord, ClickAction action, Block type ) { + if ( World == null ) + PlayerOpException.ThrowNoWorld( this ); Map map = WorldMap; LastUsedBlockType = type; @@ -978,7 +1016,8 @@ public bool PlaceBlock ( Vector3I coord, ClickAction action, Block type ) { return false; } - if ( CheckBlockSpam() ) return true; + if ( CheckBlockSpam() ) + return true; BlockChangeContext context = BlockChangeContext.Manual; if ( IsPainting && action == ClickAction.Delete ) { @@ -1021,7 +1060,6 @@ public bool PlaceBlock ( Vector3I coord, ClickAction action, Block type ) { SendNow( PacketWriter.MakeSetBlock( coordBelow, Block.DoubleStair ) ); RevertBlockNow( coord ); break; - } else { // handle normal blocks blockUpdate = new BlockUpdate( this, coord, type ); @@ -1055,6 +1093,7 @@ public bool PlaceBlock ( Vector3I coord, ClickAction action, Block type ) { case SecurityCheckResult.RankTooHigh: Message( "&WYour rank is not allowed to build in this world." ); break; + case SecurityCheckResult.BlackListed: Message( "&WYou are not allowed to build in this world." ); break; @@ -1082,15 +1121,14 @@ public bool PlaceBlock ( Vector3I coord, ClickAction action, Block type ) { return false; } - /// Gets the block from given location in player's world, /// and sends it (async) to the player. /// Used to undo player's attempted block placement/deletion. - public void RevertBlock ( Vector3I coords ) { + public void RevertBlock( Vector3I coords ) { SendLowPriority( PacketWriter.MakeSetBlock( coords, WorldMap.GetBlock( coords ) ) ); } - public void Kill ( World inWorld, string message ) { + public void Kill( World inWorld, string message ) { LastTimeKilled = DateTime.UtcNow; inWorld.Players.Message( message ); TeleportTo( inWorld.Map.Spawn ); @@ -1099,14 +1137,14 @@ public void Kill ( World inWorld, string message ) { /// Gets the block from given location in player's world, and sends it (sync) to the player. /// Used to undo player's attempted block placement/deletion. /// To avoid threading issues, only use this from this player's IoThread. - void RevertBlockNow ( Vector3I coords ) { + private void RevertBlockNow( Vector3I coords ) { SendNow( PacketWriter.MakeSetBlock( coords, WorldMap.GetBlock( coords ) ) ); } - // returns true if the player is spamming and should be kicked. - bool CheckBlockSpam () { - if ( Info.Rank.AntiGriefBlocks == 0 || Info.Rank.AntiGriefSeconds == 0 ) return false; + private bool CheckBlockSpam() { + if ( Info.Rank.AntiGriefBlocks == 0 || Info.Rank.AntiGriefSeconds == 0 ) + return false; if ( spamBlockLog.Count >= Info.Rank.AntiGriefBlocks ) { DateTime oldestTime = spamBlockLog.Dequeue(); double spamTimer = DateTime.UtcNow.Subtract( oldestTime ).TotalSeconds; @@ -1123,33 +1161,33 @@ bool CheckBlockSpam () { return false; } - #endregion - + #endregion Placing Blocks #region Binding - readonly Block[] bindings = new Block[50]; + private readonly Block[] bindings = new Block[50]; - public void Bind ( Block type, Block replacement ) { + public void Bind( Block type, Block replacement ) { bindings[( byte )type] = replacement; } - public void ResetBind ( Block type ) { + public void ResetBind( Block type ) { bindings[( byte )type] = type; } - public void ResetBind ( [NotNull] params Block[] types ) { - if ( types == null ) throw new ArgumentNullException( "types" ); + public void ResetBind( [NotNull] params Block[] types ) { + if ( types == null ) + throw new ArgumentNullException( "types" ); foreach ( Block type in types ) { ResetBind( type ); } } - public Block GetBind ( Block type ) { + public Block GetBind( Block type ) { return bindings[( byte )type]; } - public void ResetAllBinds () { + public void ResetAllBinds() { foreach ( Block block in Enum.GetValues( typeof( Block ) ) ) { if ( block != Block.Undefined ) { ResetBind( block ); @@ -1157,58 +1195,57 @@ public void ResetAllBinds () { } } - #endregion - + #endregion Binding #region Permission Checks /// Returns true if player has ALL of the given permissions. - public bool Can ( [NotNull] params Permission[] permissions ) { - if ( permissions == null ) throw new ArgumentNullException( "permissions" ); + public bool Can( [NotNull] params Permission[] permissions ) { + if ( permissions == null ) + throw new ArgumentNullException( "permissions" ); return IsSuper || permissions.All( Info.Rank.Can ); } - /// Returns true if player has ANY of the given permissions. - public bool CanAny ( [NotNull] params Permission[] permissions ) { - if ( permissions == null ) throw new ArgumentNullException( "permissions" ); + public bool CanAny( [NotNull] params Permission[] permissions ) { + if ( permissions == null ) + throw new ArgumentNullException( "permissions" ); return IsSuper || permissions.Any( Info.Rank.Can ); } - /// Returns true if player has the given permission. - public bool Can ( Permission permission ) { + public bool Can( Permission permission ) { return IsSuper || Info.Rank.Can( permission ); } - /// Returns true if player has the given permission, /// and is allowed to affect players of the given rank. - public bool Can ( Permission permission, [NotNull] Rank other ) { - if ( other == null ) throw new ArgumentNullException( "other" ); + public bool Can( Permission permission, [NotNull] Rank other ) { + if ( other == null ) + throw new ArgumentNullException( "other" ); return IsSuper || Info.Rank.Can( permission, other ); } - /// Returns true if player is allowed to run /// draw commands that affect a given number of blocks. - public bool CanDraw ( int volume ) { - if ( volume < 0 ) throw new ArgumentOutOfRangeException( "volume" ); + public bool CanDraw( int volume ) { + if ( volume < 0 ) + throw new ArgumentOutOfRangeException( "volume" ); return IsSuper || ( Info.Rank.DrawLimit == 0 ) || ( volume <= Info.Rank.DrawLimit ); } - /// Returns true if player is allowed to join a given world. - public bool CanJoin ( [NotNull] World worldToJoin ) { - if ( worldToJoin == null ) throw new ArgumentNullException( "worldToJoin" ); + public bool CanJoin( [NotNull] World worldToJoin ) { + if ( worldToJoin == null ) + throw new ArgumentNullException( "worldToJoin" ); return IsSuper || worldToJoin.AccessSecurity.Check( Info ); } - /// Checks whether player is allowed to place a block on the current world at given coordinates. /// Raises the PlayerPlacingBlock event. - public CanPlaceResult CanPlace ( [NotNull] Map map, Vector3I coords, Block newBlock, BlockChangeContext context ) { - if ( map == null ) throw new ArgumentNullException( "map" ); + public CanPlaceResult CanPlace( [NotNull] Map map, Vector3I coords, Block newBlock, BlockChangeContext context ) { + if ( map == null ) + throw new ArgumentNullException( "map" ); CanPlaceResult result; // check whether coordinate is in bounds @@ -1274,55 +1311,55 @@ public CanPlaceResult CanPlace ( [NotNull] Map map, Vector3I coords, Block newBl eventCheck: var handler = PlacingBlock; - if ( handler == null ) return result; + if ( handler == null ) + return result; var e = new PlayerPlacingBlockEventArgs( this, map, coords, oldBlock, newBlock, context, result ); handler( null, e ); return e.Result; } - /// Whether this player can currently see another player as being online. /// Visibility is determined by whether the other player is hiding or spectating. /// Players can always see themselves. Super players (e.g. Console) can see all. /// Hidden players can only be seen by those of sufficient rank. - public bool CanSee ( [NotNull] Player other ) { - if ( other == null ) throw new ArgumentNullException( "other" ); + public bool CanSee( [NotNull] Player other ) { + if ( other == null ) + throw new ArgumentNullException( "other" ); return other == this || IsSuper || !other.Info.IsHidden || Info.Rank.CanSee( other.Info.Rank ); } - /// Whether this player can currently see another player moving. /// Behaves very similarly to CanSee method, except when spectating: /// Players can never see someone who's spectating them. If other player is spectating /// someone else, they are treated as hidden and can only be seen by those of sufficient rank. - public bool CanSeeMoving ( [NotNull] Player other ) { - if ( other == null ) throw new ArgumentNullException( "other" ); + public bool CanSeeMoving( [NotNull] Player other ) { + if ( other == null ) + throw new ArgumentNullException( "other" ); return other == this || IsSuper || other.spectatedPlayer == null && !other.Info.IsHidden || ( other.spectatedPlayer != this && Info.Rank.CanSee( other.Info.Rank ) ); } - /// Whether this player should see a given world on the /Worlds list by default. - public bool CanSee ( [NotNull] World world ) { - if ( world == null ) throw new ArgumentNullException( "world" ); + public bool CanSee( [NotNull] World world ) { + if ( world == null ) + throw new ArgumentNullException( "world" ); return CanJoin( world ) && !world.IsHidden; } - #endregion - + #endregion Permission Checks #region Undo / Redo - readonly LinkedList undoStack = new LinkedList(); - readonly LinkedList redoStack = new LinkedList(); + private readonly LinkedList undoStack = new LinkedList(); + private readonly LinkedList redoStack = new LinkedList(); - internal UndoState RedoPop () { + internal UndoState RedoPop() { if ( redoStack.Count > 0 ) { var lastNode = redoStack.Last; redoStack.RemoveLast(); @@ -1332,21 +1369,21 @@ internal UndoState RedoPop () { } } - internal UndoState RedoBegin ( DrawOperation op ) { + internal UndoState RedoBegin( DrawOperation op ) { LastDrawOp = op; UndoState newState = new UndoState( op ); undoStack.AddLast( newState ); return newState; } - internal UndoState UndoBegin ( DrawOperation op ) { + internal UndoState UndoBegin( DrawOperation op ) { LastDrawOp = op; UndoState newState = new UndoState( op ); redoStack.AddLast( newState ); return newState; } - public UndoState UndoPop () { + public UndoState UndoPop() { if ( undoStack.Count > 0 ) { var lastNode = undoStack.Last; undoStack.RemoveLast(); @@ -1356,7 +1393,7 @@ public UndoState UndoPop () { } } - public UndoState DrawBegin ( DrawOperation op ) { + public UndoState DrawBegin( DrawOperation op ) { LastDrawOp = op; UndoState newState = new UndoState( op ); undoStack.AddLast( newState ); @@ -1367,16 +1404,15 @@ public UndoState DrawBegin ( DrawOperation op ) { return newState; } - public void UndoClear () { + public void UndoClear() { undoStack.Clear(); } - public void RedoClear () { + public void RedoClear() { redoStack.Clear(); } - #endregion - + #endregion Undo / Redo #region Drawing, Selection @@ -1386,7 +1422,6 @@ public void RedoClear () { [CanBeNull] public DrawOperation LastDrawOp { get; set; } - /// Whether player is currently making a selection. public bool IsMakingSelection { get { return SelectionMarksExpected > 0; } @@ -1404,22 +1439,22 @@ public int SelectionMarkCount { public bool IsRepeatingSelection { get; set; } [CanBeNull] - Command selectionRepeatCommand; + private Command selectionRepeatCommand; [CanBeNull] - SelectionCallback selectionCallback; + private SelectionCallback selectionCallback; - readonly Queue selectionMarks = new Queue(); + private readonly Queue selectionMarks = new Queue(); [CanBeNull] - object selectionArgs; + private object selectionArgs; [CanBeNull] - Permission[] selectionPermissions; - + private Permission[] selectionPermissions; - public void SelectionAddMark ( Vector3I pos, bool executeCallbackIfNeeded ) { - if ( !IsMakingSelection ) throw new InvalidOperationException( "No selection in progress." ); + public void SelectionAddMark( Vector3I pos, bool executeCallbackIfNeeded ) { + if ( !IsMakingSelection ) + throw new InvalidOperationException( "No selection in progress." ); selectionMarks.Enqueue( pos ); if ( SelectionMarkCount >= SelectionMarksExpected ) { if ( executeCallbackIfNeeded ) { @@ -1433,8 +1468,7 @@ public void SelectionAddMark ( Vector3I pos, bool executeCallbackIfNeeded ) { } } - - public void SelectionExecute () { + public void SelectionExecute() { if ( !IsMakingSelection || selectionCallback == null ) { throw new InvalidOperationException( "No selection in progress." ); } @@ -1454,12 +1488,12 @@ public void SelectionExecute () { } } - - public void SelectionStart ( int marksExpected, + public void SelectionStart( int marksExpected, [NotNull] SelectionCallback callback, [CanBeNull] object args, [CanBeNull] params Permission[] requiredPermissions ) { - if ( callback == null ) throw new ArgumentNullException( "callback" ); + if ( callback == null ) + throw new ArgumentNullException( "callback" ); selectionArgs = args; SelectionMarksExpected = marksExpected; selectionMarks.Clear(); @@ -1467,13 +1501,11 @@ public void SelectionStart ( int marksExpected, selectionPermissions = requiredPermissions; } - - public void SelectionResetMarks () { + public void SelectionResetMarks() { selectionMarks.Clear(); } - - public void SelectionCancel () { + public void SelectionCancel() { selectionMarks.Clear(); SelectionMarksExpected = 0; selectionCallback = null; @@ -1481,17 +1513,18 @@ public void SelectionCancel () { selectionPermissions = null; } - #endregion - + #endregion Drawing, Selection #region Copy/Paste - CopyState[] copyInformation; + private CopyState[] copyInformation; + public CopyState[] CopyInformation { get { return copyInformation; } } - int copySlot; + private int copySlot; + public int CopySlot { get { return copySlot; } set { @@ -1502,29 +1535,31 @@ public int CopySlot { } } - internal void InitCopySlots () { + internal void InitCopySlots() { Array.Resize( ref copyInformation, Info.Rank.CopySlots ); CopySlot = Math.Min( CopySlot, Info.Rank.CopySlots - 1 ); } [CanBeNull] - public CopyState GetCopyInformation () { + public CopyState GetCopyInformation() { return CopyInformation[copySlot]; } - public void SetCopyInformation ( [CanBeNull] CopyState info ) { - if ( info != null ) info.Slot = copySlot; + public void SetCopyInformation( [CanBeNull] CopyState info ) { + if ( info != null ) + info.Slot = copySlot; CopyInformation[copySlot] = info; } - #endregion + #endregion Copy/Paste + [CanBeNull] - Player possessionPlayer; + private Player possessionPlayer; #region Spectating [CanBeNull] - Player spectatedPlayer; + private Player spectatedPlayer; /// Player currently being spectated. Use Spectate/StopSpectate methods to set. [CanBeNull] @@ -1535,15 +1570,15 @@ public Player SpectatedPlayer { [CanBeNull] public PlayerInfo LastSpectatedPlayer { get; private set; } - readonly object spectateLock = new object(); + private readonly object spectateLock = new object(); public bool IsSpectating { get { return ( spectatedPlayer != null ); } } - - public bool Spectate ( [NotNull] Player target ) { - if ( target == null ) throw new ArgumentNullException( "target" ); + public bool Spectate( [NotNull] Player target ) { + if ( target == null ) + throw new ArgumentNullException( "target" ); lock ( spectateLock ) { if ( target == this ) { PlayerOpException.ThrowCannotTargetSelf( this, Info, "spectate" ); @@ -1553,7 +1588,8 @@ public bool Spectate ( [NotNull] Player target ) { PlayerOpException.ThrowPermissionLimit( this, target.Info, "spectate", Permission.Spectate ); } - if ( spectatedPlayer == target ) return false; + if ( spectatedPlayer == target ) + return false; spectatedPlayer = target; LastSpectatedPlayer = target.Info; @@ -1562,17 +1598,19 @@ public bool Spectate ( [NotNull] Player target ) { } } - public bool StopSpectating () { + public bool StopSpectating() { lock ( spectateLock ) { - if ( spectatedPlayer == null ) return false; + if ( spectatedPlayer == null ) + return false; Message( "Stopped spectating {0}", spectatedPlayer.ClassyName ); spectatedPlayer = null; return true; } } - public bool Possess ( [NotNull] Player target ) { - if ( target == null ) throw new ArgumentNullException( "target" ); + public bool Possess( [NotNull] Player target ) { + if ( target == null ) + throw new ArgumentNullException( "target" ); lock ( spectateLock ) { if ( target == this ) { PlayerOpException.ThrowCannotTargetSelf( this, Info, "possess" ); @@ -1582,38 +1620,42 @@ public bool Possess ( [NotNull] Player target ) { PlayerOpException.ThrowPermissionLimit( this, target.Info, "possess", Permission.Possess ); } - if ( target.possessionPlayer == this ) return false; + if ( target.possessionPlayer == this ) + return false; target.possessionPlayer = this; Message( "Now Possessing {0}&S. Type &H/unpossess&S to stop.", target.ClassyName ); return true; } } - public bool StopPossessing ( [NotNull]Player target ) { + + public bool StopPossessing( [NotNull]Player target ) { lock ( spectateLock ) { - if ( target.possessionPlayer == null ) return false; + if ( target.possessionPlayer == null ) + return false; Message( "Stopped possessing {0}", target.ClassyName ); target.possessionPlayer = null; return true; } } - #endregion - + #endregion Spectating #region Static Utilities - /// Ensures that a player name has the correct length and character set. - public static bool IsValidName ( [NotNull] string name ) { - if ( name == null ) throw new ArgumentNullException( "name" ); - if ( name.Length < 2 || name.Length > 16 ) return false; + public static bool IsValidName( [NotNull] string name ) { + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( name.Length < 2 || name.Length > 16 ) + return false; return ContainsValidCharacters( name ); } /// Ensures that a player name has the correct length and character set. - public static bool ContainsValidCharacters ( [NotNull] string name ) { - if ( name == null ) throw new ArgumentNullException( "name" ); + public static bool ContainsValidCharacters( [NotNull] string name ) { + if ( name == null ) + throw new ArgumentNullException( "name" ); // ReSharper disable LoopCanBeConvertedToQuery for ( int i = 0; i < name.Length; i++ ) { char ch = name[i]; @@ -1625,16 +1667,14 @@ public static bool ContainsValidCharacters ( [NotNull] string name ) { return true; } - #endregion + #endregion Static Utilities - - public void TeleportTo ( Position pos ) { + public void TeleportTo( Position pos ) { StopSpectating(); Send( PacketWriter.MakeSelfTeleport( pos ) ); Position = pos; } - /// Time since the player was last active (moved, talked, or clicked). public TimeSpan IdleTime { get { @@ -1642,13 +1682,11 @@ public TimeSpan IdleTime { } } - /// Resets the IdleTimer to 0. - public void ResetIdleTimer () { + public void ResetIdleTimer() { LastActiveTime = DateTime.UtcNow; } - #region Kick /// Advanced kick command. @@ -1658,13 +1696,15 @@ public void ResetIdleTimer () { /// Whether the kick should be announced publicly on the server and IRC. /// Whether Player.BeingKicked and Player.Kicked events should be raised. /// Whether the kick should be counted towards player's record. - public void Kick ( [NotNull] Player player, [CanBeNull] string reason, LeaveReason context, - bool announce, bool raiseEvents, bool recordToPlayerDB ) { - if ( player == null ) throw new ArgumentNullException( "player" ); + public void Kick( [NotNull] Player player, [CanBeNull] string reason, LeaveReason context, + bool announce, bool raiseEvents, bool recordToPlayerDB ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); if ( !Enum.IsDefined( typeof( LeaveReason ), context ) ) { throw new ArgumentOutOfRangeException( "context" ); } - if ( reason != null && reason.Trim().Length == 0 ) reason = null; + if ( reason != null && reason.Trim().Length == 0 ) + reason = null; // Check if player can ban/unban in general if ( !player.Can( Permission.Kick ) ) { @@ -1688,7 +1728,8 @@ public void Kick ( [NotNull] Player player, [CanBeNull] string reason, LeaveReas if ( raiseEvents ) { var e = new PlayerBeingKickedEventArgs( this, player, reason, announce, recordToPlayerDB, context ); RaisePlayerBeingKickedEvent( e ); - if ( e.Cancel ) PlayerOpException.ThrowCancelled( player, Info ); + if ( e.Cancel ) + PlayerOpException.ThrowCancelled( player, Info ); recordToPlayerDB = e.RecordToPlayerDB; } @@ -1727,8 +1768,7 @@ public void Kick ( [NotNull] Player player, [CanBeNull] string reason, LeaveReas } } - #endregion - + #endregion Kick [CanBeNull] public string LastUsedPlayerName { get; set; } @@ -1736,9 +1776,8 @@ public void Kick ( [NotNull] Player player, [CanBeNull] string reason, LeaveReas [CanBeNull] public string LastUsedWorldName { get; set; } - /// Name formatted for the debugger. - public override string ToString () { + public override string ToString() { if ( Info != null ) { return String.Format( "Player({0})", Info.Name ); } else { @@ -1747,11 +1786,10 @@ public override string ToString () { } } - - sealed class PlayerListSorter : IComparer { + internal sealed class PlayerListSorter : IComparer { public static readonly PlayerListSorter Instance = new PlayerListSorter(); - public int Compare ( Player x, Player y ) { + public int Compare( Player x, Player y ) { if ( x.Info.Rank == y.Info.Rank ) { return StringComparer.OrdinalIgnoreCase.Compare( x.Name, y.Name ); } else { diff --git a/fCraft/Player/PlayerConstants.cs b/fCraft/Player/PlayerConstants.cs index 2e550bc..cc3e25c 100644 --- a/fCraft/Player/PlayerConstants.cs +++ b/fCraft/Player/PlayerConstants.cs @@ -3,8 +3,10 @@ // This file condenses some of the player-related enumerations namespace fCraft { + /// List of possible reasons for players leaving the server. public enum LeaveReason : byte { + /// Unknown leave reason (default) Unknown = 0x00, @@ -45,7 +47,6 @@ public enum LeaveReason : byte { /// Banned indirectly by /BanAll BanAll = 0x22, - /// Server-side error (uncaught exception in session's thread) ServerError = 0x30, @@ -58,7 +59,6 @@ public enum LeaveReason : byte { /// World was full (forced join failed) WorldFull = 0x33, - /// Login failed due to protocol violation/mismatch (e.g. SMP client) ProtocolViolation = 0x41, @@ -72,9 +72,9 @@ public enum LeaveReason : byte { RageQuit = 0x44, } - /// Mode of player name verification. public enum NameVerificationMode { + /// Player names are not checked. /// Any connecting player can assume any identity. Never, @@ -90,9 +90,9 @@ public enum NameVerificationMode { Always } - /// Describes the way player's rank was set. public enum RankChangeType : byte { + /// Default rank (never been promoted or demoted). Default = 0, @@ -109,10 +109,10 @@ public enum RankChangeType : byte { AutoDemoted = 4 } - /// Bandwidth use mode. /// This setting affects the way player receive movement updates. public enum BandwidthUseMode : byte { + /// Use server default. Default = 0, @@ -132,7 +132,6 @@ public enum BandwidthUseMode : byte { VeryHigh = 5 } - /// A list of possible results of Player.CanPlace() permission test. public enum CanPlaceResult { @@ -162,12 +161,12 @@ public enum CanPlaceResult { /// A plugin callback cancelled block placement/deletion. /// A copy of the old block will not be sent to the player (he may go out of sync). PluginDeniedNoUpdate, - + Revert } - public enum WorldChangeReason { + /// First world that the player joins upon entering the server (main). FirstWorld, @@ -196,8 +195,8 @@ public enum WorldChangeReason { Portal } - public enum BanStatus : byte { + /// Player is not banned. NotBanned, @@ -208,8 +207,8 @@ public enum BanStatus : byte { Banned } - public enum ClickAction : byte { + /// Deleting a block (left-click in Minecraft). Delete = 0, @@ -217,8 +216,8 @@ public enum ClickAction : byte { Build = 1 } - public enum SessionState { + /// There is no session associated with this player (e.g. Console). Offline, diff --git a/fCraft/Player/PlayerDB.cs b/fCraft/Player/PlayerDB.cs index ca112e3..5accf1d 100644 --- a/fCraft/Player/PlayerDB.cs +++ b/fCraft/Player/PlayerDB.cs @@ -12,21 +12,22 @@ using JetBrains.Annotations; namespace fCraft { + /// Persistent database of player information. public static class PlayerDB { - static readonly Trie Trie = new Trie(); - static List list = new List(); + private static readonly Trie Trie = new Trie(); + private static List list = new List(); /// Cached list of all players in the database. /// May be quite long. Make sure to copy a reference to - /// the list before accessing it in a loop, since this + /// the list before accessing it in a loop, since this /// array be frequently be replaced by an updated one. public static PlayerInfo[] PlayerInfoList { get; private set; } - static int maxID = 255; - const int BufferSize = 64 * 1024; + private static int maxID = 255; + private const int BufferSize = 64 * 1024; - /* + /* * Version 0 - before 0.530 - all dates/times are local * Version 1 - 0.530-0.536 - all dates and times are stored as UTC unix timestamps (milliseconds) * Version 2 - 0.600 dev - all dates and times are stored as UTC unix timestamps (seconds) @@ -36,7 +37,7 @@ public static class PlayerDB { */ public const int FormatVersion = 5; - const string Header = "fCraft PlayerDB | Row format: " + + private const string Header = "fCraft PlayerDB | Row format: " + "Name,IPAddress,Rank,RankChangeDate,RankChangedBy,Banned,BanDate,BannedBy," + "UnbanDate,UnbannedBy,BanReason,UnbanReason,LastFailedLoginDate," + "LastFailedLoginIP,MojangAccount,FirstLoginDate,LastLoginDate,TotalTime," + @@ -46,36 +47,35 @@ public static class PlayerDB { "LastKickBy,LastKickReason,BannedUntil,IsFrozen,FrozenBy,FrozenOn,MutedUntil,MutedBy," + "Password,IsOnline,BandwidthUseMode,IsHidden,LastModified,DisplayedName"; - // used to ensure PlayerDB consistency when adding/removing PlayerDB entries - static readonly object AddLocker = new object(); + private static readonly object AddLocker = new object(); // used to prevent concurrent access to the PlayerDB file - static readonly object SaveLoadLocker = new object(); - + private static readonly object SaveLoadLocker = new object(); public static bool IsLoaded { get; private set; } - - static void CheckIfLoaded() { - if( !IsLoaded ) throw new InvalidOperationException( "PlayerDB is not loaded." ); + private static void CheckIfLoaded() { + if ( !IsLoaded ) + throw new InvalidOperationException( "PlayerDB is not loaded." ); } [NotNull] public static PlayerInfo AddFakeEntry( [NotNull] string name, RankChangeType rankChangeType ) { - if( name == null ) throw new ArgumentNullException( "name" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); CheckIfLoaded(); PlayerInfo info; - lock( AddLocker ) { + lock ( AddLocker ) { info = Trie.Get( name ); - if( info != null ) { + if ( info != null ) { throw new ArgumentException( "A PlayerDB entry already exists for this name.", "name" ); } var e = new PlayerInfoCreatingEventArgs( name, IPAddress.None, RankManager.DefaultRank, true ); PlayerInfo.RaiseCreatingEvent( e ); - if( e.Cancel ) { + if ( e.Cancel ) { throw new OperationCanceledException( "Cancelled by a plugin." ); } @@ -89,23 +89,21 @@ public static PlayerInfo AddFakeEntry( [NotNull] string name, RankChangeType ran return info; } - #region Saving/Loading internal static void Load() { - lock( SaveLoadLocker ) { - if( File.Exists( Paths.PlayerDBFileName ) ) { + lock ( SaveLoadLocker ) { + if ( File.Exists( Paths.PlayerDBFileName ) ) { Stopwatch sw = Stopwatch.StartNew(); - using( FileStream fs = OpenRead( Paths.PlayerDBFileName ) ) { - using( StreamReader reader = new StreamReader( fs, Encoding.UTF8, true, BufferSize ) ) { - + using ( FileStream fs = OpenRead( Paths.PlayerDBFileName ) ) { + using ( StreamReader reader = new StreamReader( fs, Encoding.UTF8, true, BufferSize ) ) { string header = reader.ReadLine(); // if PlayerDB is an empty file - if( header == null ) { + if ( header == null ) { Logger.Log( LogType.Warning, "PlayerDB.Load: PlayerDB file is empty." ); } else { - lock( AddLocker ) { + lock ( AddLocker ) { LoadInternal( reader, header ); } } @@ -123,42 +121,45 @@ internal static void Load() { } } - static void LoadInternal( StreamReader reader, string header ) { + private static void LoadInternal( StreamReader reader, string header ) { int version = IdentifyFormatVersion( header ); - if( version > FormatVersion ) { + if ( version > FormatVersion ) { Logger.Log( LogType.Warning, "PlayerDB.Load: Attempting to load unsupported PlayerDB format ({0}). Errors may occur.", version ); - } else if( version < FormatVersion ) { + } else if ( version < FormatVersion ) { Logger.Log( LogType.Warning, "PlayerDB.Load: Converting PlayerDB to a newer format (version {0} to {1}).", version, FormatVersion ); } int emptyRecords = 0; - while( true ) { + while ( true ) { string line = reader.ReadLine(); - if( line == null ) break; + if ( line == null ) + break; string[] fields = line.Split( ',' ); - if( fields.Length >= PlayerInfo.MinFieldCount ) { + if ( fields.Length >= PlayerInfo.MinFieldCount ) { #if !DEBUG try { #endif PlayerInfo info; - switch( version ) { + switch ( version ) { case 0: info = PlayerInfo.LoadFormat0( fields, true ); break; + case 1: info = PlayerInfo.LoadFormat1( fields ); break; + default: // Versions 2-5 differ in semantics only, not in actual serialization format. info = PlayerInfo.LoadFormat2( fields ); break; } - if( info.ID > maxID ) { + if ( info.ID > maxID ) { maxID = info.ID; Logger.Log( LogType.Warning, "PlayerDB.Load: Adjusting wrongly saved MaxID ({0} to {1})." ); } @@ -166,9 +167,8 @@ static void LoadInternal( StreamReader reader, string header ) { // A record is considered "empty" if the player has never logged in. // Empty records may be created by /Import, /Ban, and /Rank commands on typos. // Deleting such records should have no negative impact on DB completeness. - if( (info.LastIP.Equals( IPAddress.None ) || info.LastIP.Equals( IPAddress.Any ) || info.TimesVisited == 0) && + if ( ( info.LastIP.Equals( IPAddress.None ) || info.LastIP.Equals( IPAddress.Any ) || info.TimesVisited == 0 ) && !info.IsBanned && info.Rank == RankManager.DefaultRank ) { - Logger.Log( LogType.SystemActivity, "PlayerDB.Load: Skipping an empty record for player \"{0}\"", info.Name ); @@ -177,7 +177,7 @@ static void LoadInternal( StreamReader reader, string header ) { } // Check for duplicates. Unless PlayerDB.txt was altered externally, this does not happen. - if( Trie.ContainsKey( info.Name ) ) { + if ( Trie.ContainsKey( info.Name ) ) { Logger.Log( LogType.Error, "PlayerDB.Load: Duplicate record for player \"{0}\" skipped.", info.Name ); @@ -186,7 +186,7 @@ static void LoadInternal( StreamReader reader, string header ) { list.Add( info ); } #if !DEBUG - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.LogAndReportCrash( "Error while parsing PlayerInfo record: " + line, "800Craft", ex, @@ -200,7 +200,7 @@ static void LoadInternal( StreamReader reader, string header ) { } } - if( emptyRecords > 0 ) { + if ( emptyRecords > 0 ) { Logger.Log( LogType.Warning, "PlayerDB.Load: Skipped {0} empty records.", emptyRecords ); } @@ -208,11 +208,11 @@ static void LoadInternal( StreamReader reader, string header ) { RunCompatibilityChecks( version ); } - static Dictionary rankMapping; + private static Dictionary rankMapping; internal static Rank GetRankByIndex( int index ) { Rank rank; - if( rankMapping.TryGetValue( index, out rank ) ) { + if ( rankMapping.TryGetValue( index, out rank ) ) { return rank; } else { Logger.Log( LogType.Error, @@ -222,27 +222,26 @@ internal static Rank GetRankByIndex( int index ) { } } - - static void RunCompatibilityChecks( int loadedVersion ) { + private static void RunCompatibilityChecks( int loadedVersion ) { // Sorting the list allows finding players by ID using binary search. list.Sort( PlayerIDComparer.Instance ); - if( loadedVersion < 4 ) { + if ( loadedVersion < 4 ) { int unhid = 0, unfroze = 0, unmuted = 0; Logger.Log( LogType.SystemActivity, "PlayerDB: Checking consistency of banned player records..." ); - for( int i = 0; i < list.Count; i++ ) { - if( list[i].IsBanned ) { - if( list[i].IsHidden ) { + for ( int i = 0; i < list.Count; i++ ) { + if ( list[i].IsBanned ) { + if ( list[i].IsHidden ) { unhid++; list[i].IsHidden = false; } - if( list[i].IsFrozen ) { + if ( list[i].IsFrozen ) { list[i].Unfreeze(); unfroze++; } - if( list[i].IsMuted ) { + if ( list[i].IsMuted ) { list[i].Unmute(); unmuted++; } @@ -254,42 +253,42 @@ static void RunCompatibilityChecks( int loadedVersion ) { } } - - static int IdentifyFormatVersion( [NotNull] string header ) { - if( header == null ) throw new ArgumentNullException( "header" ); - if( header.StartsWith( "playerName" ) ) return 0; + private static int IdentifyFormatVersion( [NotNull] string header ) { + if ( header == null ) + throw new ArgumentNullException( "header" ); + if ( header.StartsWith( "playerName" ) ) + return 0; string[] headerParts = header.Split( ' ' ); - if( headerParts.Length < 2 ) { + if ( headerParts.Length < 2 ) { throw new FormatException( "Invalid PlayerDB header format: " + header ); } int maxIDField; - if( Int32.TryParse( headerParts[0], out maxIDField ) ) { - if( maxIDField >= 255 ) {// IDs start at 256 + if ( Int32.TryParse( headerParts[0], out maxIDField ) ) { + if ( maxIDField >= 255 ) {// IDs start at 256 maxID = maxIDField; } } int version; - if( Int32.TryParse( headerParts[1], out version ) ) { + if ( Int32.TryParse( headerParts[1], out version ) ) { return version; } else { return 0; } } - public static void Save() { CheckIfLoaded(); const string tempFileName = Paths.PlayerDBFileName + ".temp"; - lock( SaveLoadLocker ) { + lock ( SaveLoadLocker ) { PlayerInfo[] listCopy = PlayerInfoList; Stopwatch sw = Stopwatch.StartNew(); - using( FileStream fs = OpenWrite( tempFileName ) ) { - using( StreamWriter writer = new StreamWriter( fs, Encoding.UTF8, BufferSize ) ) { + using ( FileStream fs = OpenWrite( tempFileName ) ) { + using ( StreamWriter writer = new StreamWriter( fs, Encoding.UTF8, BufferSize ) ) { writer.WriteLine( "{0} {1} {2}", maxID, FormatVersion, Header ); StringBuilder sb = new StringBuilder(); - for( int i = 0; i < listCopy.Length; i++ ) { + for ( int i = 0; i < listCopy.Length; i++ ) { listCopy[i].Serialize( sb ); writer.WriteLine( sb.ToString() ); sb.Length = 0; @@ -303,36 +302,36 @@ public static void Save() { try { Paths.MoveOrReplace( tempFileName, Paths.PlayerDBFileName ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.Log( LogType.Error, "PlayerDB.Save: An error occured while trying to save PlayerDB: {0}", ex ); } } } - - static FileStream OpenRead( string fileName ) { + private static FileStream OpenRead( string fileName ) { return new FileStream( fileName, FileMode.Open, FileAccess.Read, FileShare.Read, BufferSize, FileOptions.SequentialScan ); } - - static FileStream OpenWrite( string fileName ) { + private static FileStream OpenWrite( string fileName ) { return new FileStream( fileName, FileMode.Create, FileAccess.Write, FileShare.None, BufferSize ); } - #endregion - + #endregion Saving/Loading #region Scheduled Saving - static SchedulerTask saveTask; - static TimeSpan saveInterval = TimeSpan.FromSeconds( 90 ); + private static SchedulerTask saveTask; + private static TimeSpan saveInterval = TimeSpan.FromSeconds( 90 ); + public static TimeSpan SaveInterval { get { return saveInterval; } set { - if( value.Ticks < 0 ) throw new ArgumentException( "Save interval may not be negative" ); + if ( value.Ticks < 0 ) + throw new ArgumentException( "Save interval may not be negative" ); saveInterval = value; - if( saveTask != null ) saveTask.Interval = value; + if ( saveTask != null ) + saveTask.Interval = value; } } @@ -341,31 +340,33 @@ internal static void StartSaveTask() { .RunForever( SaveInterval, SaveInterval + TimeSpan.FromSeconds( 15 ) ); } - static void SaveTask( SchedulerTask task ) { + private static void SaveTask( SchedulerTask task ) { Save(); } - #endregion - + #endregion Scheduled Saving #region Lookup [NotNull] public static PlayerInfo FindOrCreateInfoForPlayer( [NotNull] string name, [NotNull] IPAddress lastIP ) { - if( name == null ) throw new ArgumentNullException( "name" ); - if( lastIP == null ) throw new ArgumentNullException( "lastIP" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( lastIP == null ) + throw new ArgumentNullException( "lastIP" ); CheckIfLoaded(); PlayerInfo info; // this flag is used to avoid executing PlayerInfoCreated event in the lock bool raiseCreatedEvent = false; - lock( AddLocker ) { + lock ( AddLocker ) { info = Trie.Get( name ); - if( info == null ) { + if ( info == null ) { var e = new PlayerInfoCreatingEventArgs( name, lastIP, RankManager.DefaultRank, false ); PlayerInfo.RaiseCreatingEvent( e ); - if( e.Cancel ) throw new OperationCanceledException( "Cancelled by a plugin." ); + if ( e.Cancel ) + throw new OperationCanceledException( "Cancelled by a plugin." ); info = new PlayerInfo( name, lastIP, e.StartingRank ); Trie.Add( name, info ); @@ -376,171 +377,181 @@ public static PlayerInfo FindOrCreateInfoForPlayer( [NotNull] string name, [NotN } } - if( raiseCreatedEvent ) { + if ( raiseCreatedEvent ) { PlayerInfo.RaiseCreatedEvent( info, false ); } return info; } - [NotNull] public static PlayerInfo[] FindPlayers( [NotNull] IPAddress address ) { - if( address == null ) throw new ArgumentNullException( "address" ); + if ( address == null ) + throw new ArgumentNullException( "address" ); return FindPlayers( address, Int32.MaxValue ); } - [NotNull] public static PlayerInfo[] FindPlayers( [NotNull] IPAddress address, int limit ) { - if( address == null ) throw new ArgumentNullException( "address" ); - if( limit < 0 ) throw new ArgumentOutOfRangeException( "limit" ); + if ( address == null ) + throw new ArgumentNullException( "address" ); + if ( limit < 0 ) + throw new ArgumentOutOfRangeException( "limit" ); CheckIfLoaded(); List result = new List(); int count = 0; PlayerInfo[] cache = PlayerInfoList; - for( int i = 0; i < cache.Length; i++ ) { - if( cache[i].LastIP.Equals( address ) ) { + for ( int i = 0; i < cache.Length; i++ ) { + if ( cache[i].LastIP.Equals( address ) ) { result.Add( cache[i] ); count++; - if( count >= limit ) return result.ToArray(); + if ( count >= limit ) + return result.ToArray(); } } return result.ToArray(); } - [NotNull] public static PlayerInfo[] FindPlayersCidr( [NotNull] IPAddress address, byte range ) { - if( address == null ) throw new ArgumentNullException( "address" ); - if( range > 32 ) throw new ArgumentOutOfRangeException( "range" ); + if ( address == null ) + throw new ArgumentNullException( "address" ); + if ( range > 32 ) + throw new ArgumentOutOfRangeException( "range" ); return FindPlayersCidr( address, range, Int32.MaxValue ); } - [NotNull] public static PlayerInfo[] FindPlayersCidr( [NotNull] IPAddress address, byte range, int limit ) { - if( address == null ) throw new ArgumentNullException( "address" ); - if( range > 32 ) throw new ArgumentOutOfRangeException( "range" ); - if( limit < 0 ) throw new ArgumentOutOfRangeException( "limit" ); + if ( address == null ) + throw new ArgumentNullException( "address" ); + if ( range > 32 ) + throw new ArgumentOutOfRangeException( "range" ); + if ( limit < 0 ) + throw new ArgumentOutOfRangeException( "limit" ); CheckIfLoaded(); List result = new List(); int count = 0; uint addressInt = address.AsUInt(); uint netMask = IPAddressUtil.NetMask( range ); PlayerInfo[] cache = PlayerInfoList; - for( int i = 0; i < cache.Length; i++ ) { - if( cache[i].LastIP.Match( addressInt, netMask ) ) { + for ( int i = 0; i < cache.Length; i++ ) { + if ( cache[i].LastIP.Match( addressInt, netMask ) ) { result.Add( cache[i] ); count++; - if( count >= limit ) return result.ToArray(); + if ( count >= limit ) + return result.ToArray(); } } return result.ToArray(); } - [NotNull] public static PlayerInfo[] FindPlayers( [NotNull] Regex regex ) { - if( regex == null ) throw new ArgumentNullException( "regex" ); + if ( regex == null ) + throw new ArgumentNullException( "regex" ); return FindPlayers( regex, Int32.MaxValue ); } - [NotNull] public static PlayerInfo[] FindPlayers( [NotNull] Regex regex, int limit ) { - if( regex == null ) throw new ArgumentNullException( "regex" ); + if ( regex == null ) + throw new ArgumentNullException( "regex" ); CheckIfLoaded(); List result = new List(); int count = 0; PlayerInfo[] cache = PlayerInfoList; - for( int i = 0; i < cache.Length; i++ ) { - if( regex.IsMatch( cache[i].Name ) ) { + for ( int i = 0; i < cache.Length; i++ ) { + if ( regex.IsMatch( cache[i].Name ) ) { result.Add( cache[i] ); count++; - if( count >= limit ) break; + if ( count >= limit ) + break; } } return result.ToArray(); } - [NotNull] public static PlayerInfo[] FindPlayers( [NotNull] string namePart ) { - if( namePart == null ) throw new ArgumentNullException( "namePart" ); + if ( namePart == null ) + throw new ArgumentNullException( "namePart" ); return FindPlayers( namePart, Int32.MaxValue ); } - [NotNull] public static PlayerInfo[] FindPlayers( [NotNull] string namePart, int limit ) { - if( namePart == null ) throw new ArgumentNullException( "namePart" ); + if ( namePart == null ) + throw new ArgumentNullException( "namePart" ); CheckIfLoaded(); - lock( AddLocker ) { + lock ( AddLocker ) { //return Trie.ValuesStartingWith( namePart ).Take( limit ).ToArray(); // <- works, but is slightly slower return Trie.GetList( namePart, limit ).ToArray(); } } - /// Searches for player names starting with namePart, returning just one or none of the matches. /// Partial or full player name /// PlayerInfo to output (will be set to null if no single match was found) /// true if one or zero matches were found, false if multiple matches were found internal static bool FindPlayerInfo( [NotNull] string namePart, out PlayerInfo info ) { - if( namePart == null ) throw new ArgumentNullException( "namePart" ); + if ( namePart == null ) + throw new ArgumentNullException( "namePart" ); CheckIfLoaded(); - lock( AddLocker ) { + lock ( AddLocker ) { return Trie.GetOneMatch( namePart, out info ); } } - [CanBeNull] public static PlayerInfo FindPlayerInfoExact( [NotNull] string name ) { - if( name == null ) throw new ArgumentNullException( "name" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); CheckIfLoaded(); - lock( AddLocker ) { + lock ( AddLocker ) { return Trie.Get( name ); } } - public static PlayerInfo[] FindPlayerInfoByEmail ( [NotNull] string name ) { - if ( name == null ) throw new ArgumentNullException( "name" ); + public static PlayerInfo[] FindPlayerInfoByEmail( [NotNull] string name ) { + if ( name == null ) + throw new ArgumentNullException( "name" ); CheckIfLoaded(); return PlayerInfoList.Where( p => p.MojangAccount == name ).ToArray(); } - public static int FindHostNameCount ( [NotNull] string name ) { - if ( name == null ) throw new ArgumentNullException( "name" ); + public static int FindHostNameCount( [NotNull] string name ) { + if ( name == null ) + throw new ArgumentNullException( "name" ); CheckIfLoaded(); return PlayerInfoList.Where( p => p.MojangAccount.EndsWith( name ) ).ToArray().Length; } [CanBeNull] public static PlayerInfo FindPlayerInfoOrPrintMatches( [NotNull] Player player, [NotNull] string name ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( name == null ) throw new ArgumentNullException( "name" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); CheckIfLoaded(); - if( name == "-" ) { - if( player.LastUsedPlayerName != null ) { + if ( name == "-" ) { + if ( player.LastUsedPlayerName != null ) { name = player.LastUsedPlayerName; } else { player.Message( "Cannot repeat player name: you haven't used any names yet." ); return null; } } - if( !Player.ContainsValidCharacters( name ) ) { + if ( !Player.ContainsValidCharacters( name ) ) { player.MessageInvalidPlayerName( name ); return null; } PlayerInfo target = FindPlayerInfoExact( name ); - if( target == null ) { + if ( target == null ) { PlayerInfo[] targets = FindPlayers( name ); - if( targets.Length == 0 ) { + if ( targets.Length == 0 ) { player.MessageNoPlayer( name ); return null; - - } else if( targets.Length > 1 ) { + } else if ( targets.Length > 1 ) { Array.Sort( targets, new PlayerInfoComparer( player ) ); player.MessageManyMatches( "player", targets.Take( 25 ).ToArray() ); return null; @@ -551,17 +562,18 @@ public static PlayerInfo FindPlayerInfoOrPrintMatches( [NotNull] Player player, return target; } - [NotNull] public static string FindExactClassyName( [CanBeNull] string name ) { - if( string.IsNullOrEmpty( name ) ) return "?"; + if ( string.IsNullOrEmpty( name ) ) + return "?"; PlayerInfo info = FindPlayerInfoExact( name ); - if( info == null ) return name; - else return info.ClassyName; + if ( info == null ) + return name; + else + return info.ClassyName; } - #endregion - + #endregion Lookup #region Stats @@ -571,11 +583,10 @@ public static int BannedCount { } } - public static float BannedPercentage { get { var listCache = PlayerInfoList; - if( listCache.Length == 0 ) { + if ( listCache.Length == 0 ) { return 0; } else { return listCache.Count( t => t.IsBanned ) * 100f / listCache.Length; @@ -583,29 +594,26 @@ public static float BannedPercentage { } } - public static int Size { get { return Trie.Count; } } - #endregion - + #endregion Stats public static int GetNextID() { return Interlocked.Increment( ref maxID ); } - /// Finds PlayerInfo by ID. Returns null of not found. [CanBeNull] public static PlayerInfo FindPlayerInfoByID( int id ) { CheckIfLoaded(); PlayerInfo dummy = new PlayerInfo( id ); - lock( AddLocker ) { + lock ( AddLocker ) { int index = list.BinarySearch( dummy, PlayerIDComparer.Instance ); - if( index >= 0 ) { + if ( index >= 0 ) { return list[index]; } else { return null; @@ -613,21 +621,24 @@ public static PlayerInfo FindPlayerInfoByID( int id ) { } } - public static int MassRankChange( [NotNull] Player player, [NotNull] Rank from, [NotNull] Rank to, [NotNull] string reason ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( from == null ) throw new ArgumentNullException( "from" ); - if( to == null ) throw new ArgumentNullException( "to" ); - if( reason == null ) throw new ArgumentNullException( "reason" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( from == null ) + throw new ArgumentNullException( "from" ); + if ( to == null ) + throw new ArgumentNullException( "to" ); + if ( reason == null ) + throw new ArgumentNullException( "reason" ); CheckIfLoaded(); int affected = 0; string fullReason = reason + "~MassRank"; - lock( AddLocker ) { - for( int i = 0; i < PlayerInfoList.Length; i++ ) { - if( PlayerInfoList[i].Rank == from ) { + lock ( AddLocker ) { + for ( int i = 0; i < PlayerInfoList.Length; i++ ) { + if ( PlayerInfoList[i].Rank == from ) { try { list[i].ChangeRank( player, to, fullReason, true, true, false ); - } catch( PlayerOpException ex ) { + } catch ( PlayerOpException ex ) { player.Message( ex.MessageColored ); } affected++; @@ -637,22 +648,20 @@ public static int MassRankChange( [NotNull] Player player, [NotNull] Rank from, } } - - static void UpdateCache() { - lock( AddLocker ) { + private static void UpdateCache() { + lock ( AddLocker ) { PlayerInfoList = list.ToArray(); } } - #region Experimental & Debug things internal static int CountInactivePlayers() { - lock( AddLocker ) { + lock ( AddLocker ) { Dictionary> playersByIP = new Dictionary>(); PlayerInfo[] playerInfoListCache = PlayerInfoList; - for( int i = 0; i < playerInfoListCache.Length; i++ ) { - if( !playersByIP.ContainsKey( playerInfoListCache[i].LastIP ) ) { + for ( int i = 0; i < playerInfoListCache.Length; i++ ) { + if ( !playersByIP.ContainsKey( playerInfoListCache[i].LastIP ) ) { playersByIP[playerInfoListCache[i].LastIP] = new List(); } playersByIP[playerInfoListCache[i].LastIP].Add( PlayerInfoList[i] ); @@ -660,30 +669,30 @@ internal static int CountInactivePlayers() { int count = 0; // ReSharper disable LoopCanBeConvertedToQuery - for( int i = 0; i < playerInfoListCache.Length; i++ ) { + for ( int i = 0; i < playerInfoListCache.Length; i++ ) { // ReSharper restore LoopCanBeConvertedToQuery - if( PlayerIsInactive( playersByIP, playerInfoListCache[i], true ) ) count++; + if ( PlayerIsInactive( playersByIP, playerInfoListCache[i], true ) ) + count++; } return count; } } - internal static int RemoveInactivePlayers() { int count = 0; - lock( AddLocker ) { + lock ( AddLocker ) { Dictionary> playersByIP = new Dictionary>(); PlayerInfo[] playerInfoListCache = PlayerInfoList; - for( int i = 0; i < playerInfoListCache.Length; i++ ) { - if( !playersByIP.ContainsKey( playerInfoListCache[i].LastIP ) ) { + for ( int i = 0; i < playerInfoListCache.Length; i++ ) { + if ( !playersByIP.ContainsKey( playerInfoListCache[i].LastIP ) ) { playersByIP[playerInfoListCache[i].LastIP] = new List(); } playersByIP[playerInfoListCache[i].LastIP].Add( PlayerInfoList[i] ); } List newList = new List(); - for( int i = 0; i < playerInfoListCache.Length; i++ ) { + for ( int i = 0; i < playerInfoListCache.Length; i++ ) { PlayerInfo p = playerInfoListCache[i]; - if( PlayerIsInactive( playersByIP, p, true ) ) { + if ( PlayerIsInactive( playersByIP, p, true ) ) { count++; } else { newList.Add( p ); @@ -692,7 +701,7 @@ internal static int RemoveInactivePlayers() { list = newList; Trie.Clear(); - foreach( PlayerInfo p in list ) { + foreach ( PlayerInfo p in list ) { Trie.Add( p.Name, p ); } @@ -702,34 +711,36 @@ internal static int RemoveInactivePlayers() { return count; } - - static bool PlayerIsInactive( [NotNull] IDictionary> playersByIP, [NotNull] PlayerInfo player, bool checkIP ) { - if( playersByIP == null ) throw new ArgumentNullException( "playersByIP" ); - if( player == null ) throw new ArgumentNullException( "player" ); - if( player.BanStatus != BanStatus.NotBanned || player.UnbanDate != DateTime.MinValue || + private static bool PlayerIsInactive( [NotNull] IDictionary> playersByIP, [NotNull] PlayerInfo player, bool checkIP ) { + if ( playersByIP == null ) + throw new ArgumentNullException( "playersByIP" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( player.BanStatus != BanStatus.NotBanned || player.UnbanDate != DateTime.MinValue || player.IsFrozen || player.IsMuted || player.TimesKicked != 0 || player.Rank != RankManager.DefaultRank || player.PreviousRank != null ) { return false; } - if( player.TotalTime.TotalMinutes > 30 || player.TimeSinceLastSeen.TotalDays < 30 ) { + if ( player.TotalTime.TotalMinutes > 30 || player.TimeSinceLastSeen.TotalDays < 30 ) { return false; } - if( IPBanList.Get( player.LastIP ) != null ) { + if ( IPBanList.Get( player.LastIP ) != null ) { return false; } - if( checkIP ) { - return playersByIP[player.LastIP].All( other => (other == player) || PlayerIsInactive( playersByIP, other, false ) ); + if ( checkIP ) { + return playersByIP[player.LastIP].All( other => ( other == player ) || PlayerIsInactive( playersByIP, other, false ) ); } return true; } - internal static void SwapPlayerInfo( [NotNull] PlayerInfo p1, [NotNull] PlayerInfo p2 ) { - if( p1 == null ) throw new ArgumentNullException( "p1" ); - if( p2 == null ) throw new ArgumentNullException( "p2" ); - lock( AddLocker ) { - lock( SaveLoadLocker ) { - if( p1.IsOnline || p2.IsOnline ) { + if ( p1 == null ) + throw new ArgumentNullException( "p1" ); + if ( p2 == null ) + throw new ArgumentNullException( "p2" ); + lock ( AddLocker ) { + lock ( SaveLoadLocker ) { + if ( p1.IsOnline || p2.IsOnline ) { throw new Exception( "Both players must be offline to swap info." ); } Swap( ref p1.BanDate, ref p2.BanDate ); @@ -788,30 +799,30 @@ internal static void SwapPlayerInfo( [NotNull] PlayerInfo p1, [NotNull] PlayerIn } } - - static void Swap( ref T t1, ref T t2 ) { + private static void Swap( ref T t1, ref T t2 ) { var temp = t2; t2 = t1; t1 = temp; } - #endregion - + #endregion Experimental & Debug things - sealed class PlayerIDComparer : IComparer { + private sealed class PlayerIDComparer : IComparer { public static readonly PlayerIDComparer Instance = new PlayerIDComparer(); - private PlayerIDComparer() { } + + private PlayerIDComparer() { + } public int Compare( PlayerInfo x, PlayerInfo y ) { return x.ID - y.ID; } } - public static StringBuilder AppendEscaped( [NotNull] this StringBuilder sb, [CanBeNull] string str ) { - if( sb == null ) throw new ArgumentNullException( "sb" ); - if( !String.IsNullOrEmpty( str ) ) { - if( str.IndexOf( ',' ) > -1 ) { + if ( sb == null ) + throw new ArgumentNullException( "sb" ); + if ( !String.IsNullOrEmpty( str ) ) { + if ( str.IndexOf( ',' ) > -1 ) { int startIndex = sb.Length; sb.Append( str ); sb.Replace( ',', '\xFF', startIndex, str.Length ); diff --git a/fCraft/Player/PlayerEnumerable.cs b/fCraft/Player/PlayerEnumerable.cs index 3caf31a..af18cd9 100644 --- a/fCraft/Player/PlayerEnumerable.cs +++ b/fCraft/Player/PlayerEnumerable.cs @@ -6,6 +6,7 @@ // ReSharper disable LoopCanBeConvertedToQuery namespace fCraft { + /// Contains a set of utilities that simplify working with sets of players. /// All the utilities are implemented as extension methods, /// and it is recommended that you invoke them as extension methods. @@ -19,97 +20,103 @@ public static class PlayerEnumerable { /// Filtered collection of players. [NotNull] public static IEnumerable Ranked( this IEnumerable source, Rank rank ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( rank == null ) throw new ArgumentNullException( "rank" ); - foreach( Player player in source ) { - if( player.Info.Rank == rank ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( rank == null ) + throw new ArgumentNullException( "rank" ); + foreach ( Player player in source ) { + if ( player.Info.Rank == rank ) { yield return player; } } } - /// Filters a collection of players, leaving only those NOT of the given rank. /// Original collection of players. Will not get modified. /// Undesired rank. /// Filtered collection of players. [NotNull] public static IEnumerable NotRanked( this IEnumerable source, Rank rank ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( rank == null ) throw new ArgumentNullException( "rank" ); - foreach( Player player in source ) { - if( player.Info.Rank != rank ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( rank == null ) + throw new ArgumentNullException( "rank" ); + foreach ( Player player in source ) { + if ( player.Info.Rank != rank ) { yield return player; } } } - /// Filters a collection of players, leaving only those above the given rank. /// Original collection of players. Will not get modified. /// All ranks above this one will be kept. This and lower ranks will be filtered out. /// Filtered collection of players. [NotNull] public static IEnumerable RankedAbove( this IEnumerable source, Rank minRank ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( minRank == null ) throw new ArgumentNullException( "minRank" ); - foreach( Player player in source ) { - if( player.Info.Rank > minRank ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( minRank == null ) + throw new ArgumentNullException( "minRank" ); + foreach ( Player player in source ) { + if ( player.Info.Rank > minRank ) { yield return player; } } } - /// Filters a collection of players, leaving only those of or above the given rank. /// Original collection of players. Will not get modified. /// Minimum desired rank. /// Filtered collection of players. [NotNull] public static IEnumerable RankedAtLeast( this IEnumerable source, Rank minRank ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( minRank == null ) throw new ArgumentNullException( "minRank" ); - foreach( Player player in source ) { - if( player.Info.Rank >= minRank ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( minRank == null ) + throw new ArgumentNullException( "minRank" ); + foreach ( Player player in source ) { + if ( player.Info.Rank >= minRank ) { yield return player; } } } - /// Filters a collection of players, leaving only those below the given rank. /// Original collection of players. Will not get modified. /// All ranks below this one will be kept. This and higher ranks will be filtered out. /// Filtered collection of players. [NotNull] public static IEnumerable RankedBelow( this IEnumerable source, Rank maxRank ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( maxRank == null ) throw new ArgumentNullException( "maxRank" ); - foreach( Player player in source ) { - if( player.Info.Rank < maxRank ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( maxRank == null ) + throw new ArgumentNullException( "maxRank" ); + foreach ( Player player in source ) { + if ( player.Info.Rank < maxRank ) { yield return player; } } } - /// Filters a collection of players, leaving only those of or below the given rank. /// Original collection of players. Will not get modified. /// Maximum desired rank. /// Filtered collection of players. [NotNull] public static IEnumerable RankedAtMost( this IEnumerable source, Rank maxRank ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( maxRank == null ) throw new ArgumentNullException( "maxRank" ); - foreach( Player player in source ) { - if( player.Info.Rank <= maxRank ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( maxRank == null ) + throw new ArgumentNullException( "maxRank" ); + foreach ( Player player in source ) { + if ( player.Info.Rank <= maxRank ) { yield return player; } } } - #endregion - + #endregion Rank Filters #region Permissions @@ -119,15 +126,15 @@ public static IEnumerable RankedAtMost( this IEnumerable source, /// Filtered collection of players. [NotNull] public static IEnumerable Can( [NotNull] this IEnumerable source, Permission permission ) { - if( source == null ) throw new ArgumentNullException( "source" ); - foreach( Player player in source ) { - if( player.Can( permission ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + foreach ( Player player in source ) { + if ( player.Can( permission ) ) { yield return player; } } } - /// Filters a collection of players, leaving only those who have the given permission, /// and with permission limits allowing operation on the given rank. /// Original collection of players. Will not get modified. @@ -136,30 +143,30 @@ public static IEnumerable Can( [NotNull] this IEnumerable source /// Filtered collection of players. [NotNull] public static IEnumerable Can( [NotNull] this IEnumerable source, Permission permission, [NotNull] Rank affectedRank ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( affectedRank == null ) throw new ArgumentNullException( "affectedRank" ); - foreach( Player player in source ) { - if( player.Can( permission, affectedRank ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( affectedRank == null ) + throw new ArgumentNullException( "affectedRank" ); + foreach ( Player player in source ) { + if ( player.Can( permission, affectedRank ) ) { yield return player; } } } - /// Filters a collection of players, leaving only those who do NOT have the given permission. /// Original collection of players. Will not get modified. /// Permission that players are required to NOT have. /// Filtered collection of players. [NotNull] public static IEnumerable Cant( [NotNull] this IEnumerable source, Permission permission ) { - foreach( Player player in source ) { - if( !player.Can( permission ) ) { + foreach ( Player player in source ) { + if ( !player.Can( permission ) ) { yield return player; } } } - /// Filters a collection of players, leaving only those who do NOT have the given permission, /// or with permission limits NOT allowing operation on the given rank. /// Original collection of players. Will not get modified. @@ -168,16 +175,17 @@ public static IEnumerable Cant( [NotNull] this IEnumerable sourc /// Filtered collection of players. [NotNull] public static IEnumerable Cant( [NotNull] this IEnumerable source, Permission permission, [NotNull] Rank affectedRank ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( affectedRank == null ) throw new ArgumentNullException( "affectedRank" ); - foreach( Player player in source ) { - if( !player.Can( permission, affectedRank ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( affectedRank == null ) + throw new ArgumentNullException( "affectedRank" ); + foreach ( Player player in source ) { + if ( !player.Can( permission, affectedRank ) ) { yield return player; } } } - /// Filters a collection of players, leaving only those who can see the target. /// Does not include the target itself. /// Original collection of players. Will not get modified. @@ -185,16 +193,17 @@ public static IEnumerable Cant( [NotNull] this IEnumerable sourc /// Filtered collection of players. [NotNull] public static IEnumerable CanSee( [NotNull] this IEnumerable source, [NotNull] Player targetPlayer ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( targetPlayer == null ) throw new ArgumentNullException( "targetPlayer" ); - foreach( Player player in source ) { - if( player != targetPlayer && player.CanSee( targetPlayer ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( targetPlayer == null ) + throw new ArgumentNullException( "targetPlayer" ); + foreach ( Player player in source ) { + if ( player != targetPlayer && player.CanSee( targetPlayer ) ) { yield return player; } } } - /// Filters a collection of players, leaving only those who can NOT see the target. /// Does not include the target itself. /// Original collection of players. Will not get modified. @@ -202,49 +211,52 @@ public static IEnumerable CanSee( [NotNull] this IEnumerable sou /// Filtered collection of players. [NotNull] public static IEnumerable CantSee( [NotNull] this IEnumerable source, [NotNull] Player targetPlayer ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( targetPlayer == null ) throw new ArgumentNullException( "targetPlayer" ); - foreach( Player player in source ) { - if( player != targetPlayer && !player.CanSee( targetPlayer ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( targetPlayer == null ) + throw new ArgumentNullException( "targetPlayer" ); + foreach ( Player player in source ) { + if ( player != targetPlayer && !player.CanSee( targetPlayer ) ) { yield return player; } } } - /// Filters a collection of players, leaving only those who can be seen by the given player. /// Original collection of players. Will not get modified. /// Player whose vision is being tested. /// Filtered collection of players. [NotNull] public static IEnumerable CanBeSeen( [NotNull] this IEnumerable source, [NotNull] Player observer ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( observer == null ) throw new ArgumentNullException( "observer" ); - foreach( Player player in source ) { - if( player != observer && observer.CanSee( player ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( observer == null ) + throw new ArgumentNullException( "observer" ); + foreach ( Player player in source ) { + if ( player != observer && observer.CanSee( player ) ) { yield return player; } } } - /// Filters a collection of players, leaving only those who can NOT be seen by the given player. /// Original collection of players. Will not get modified. /// Player whose vision is being tested. /// Filtered collection of players. [NotNull] public static IEnumerable CantBeSeen( [NotNull] this IEnumerable source, [NotNull] Player observer ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( observer == null ) throw new ArgumentNullException( "observer" ); - foreach( Player player in source ) { - if( player != observer && !observer.CanSee( player ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( observer == null ) + throw new ArgumentNullException( "observer" ); + foreach ( Player player in source ) { + if ( player != observer && !observer.CanSee( player ) ) { yield return player; } } } - #endregion - + #endregion Permissions #region Ignore @@ -254,97 +266,103 @@ public static IEnumerable CantBeSeen( [NotNull] this IEnumerable /// Filtered collection of players. [NotNull] public static IEnumerable Ignoring( [NotNull] this IEnumerable source, [NotNull] Player player ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( player == null ) throw new ArgumentNullException( "player" ); - foreach( Player otherPlayer in source ) { - if( otherPlayer.IsIgnoring( player.Info ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + foreach ( Player otherPlayer in source ) { + if ( otherPlayer.IsIgnoring( player.Info ) ) { yield return otherPlayer; } } } - /// Filters a collection of players, leaving only those who are NOT ignoring the given player. /// Original collection of players. Will not get modified. /// Player whose ignore standing is being checked. /// Filtered collection of players. [NotNull] public static IEnumerable NotIgnoring( [NotNull] this IEnumerable source, [NotNull] Player player ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( player == null ) throw new ArgumentNullException( "player" ); - foreach( Player otherPlayer in source ) { - if( !otherPlayer.IsIgnoring( player.Info ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + foreach ( Player otherPlayer in source ) { + if ( !otherPlayer.IsIgnoring( player.Info ) ) { yield return otherPlayer; } } } - /// Filters a collection of players, leaving only those who are ignoring the given player. /// Original collection of players. Will not get modified. /// Player whose ignore standing is being checked. /// Filtered collection of players. [NotNull] public static IEnumerable Ignoring( [NotNull] this IEnumerable source, [NotNull] PlayerInfo playerInfo ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( playerInfo == null ) throw new ArgumentNullException( "playerInfo" ); - foreach( Player otherPlayer in source ) { - if( otherPlayer.IsIgnoring( playerInfo ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( playerInfo == null ) + throw new ArgumentNullException( "playerInfo" ); + foreach ( Player otherPlayer in source ) { + if ( otherPlayer.IsIgnoring( playerInfo ) ) { yield return otherPlayer; } } } - /// Filters a collection of players, leaving only those who are NOT ignoring the given player. /// Original collection of players. Will not get modified. /// Player whose ignore standing is being checked. /// Filtered collection of players. [NotNull] public static IEnumerable NotIgnoring( [NotNull] this IEnumerable source, [NotNull] PlayerInfo playerInfo ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( playerInfo == null ) throw new ArgumentNullException( "playerInfo" ); - foreach( Player otherPlayer in source ) { - if( !otherPlayer.IsIgnoring( playerInfo ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( playerInfo == null ) + throw new ArgumentNullException( "playerInfo" ); + foreach ( Player otherPlayer in source ) { + if ( !otherPlayer.IsIgnoring( playerInfo ) ) { yield return otherPlayer; } } } - /// Filters a collection of players, leaving only those who are ignored by the given player. /// Original collection of players. Will not get modified. /// Player whose disposition is being checked. /// Filtered collection of players. [NotNull] public static IEnumerable IgnoredBy( [NotNull] this IEnumerable source, [NotNull] Player ignorer ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( ignorer == null ) throw new ArgumentNullException( "ignorer" ); - foreach( Player otherPlayer in source ) { - if( ignorer.IsIgnoring( otherPlayer.Info ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( ignorer == null ) + throw new ArgumentNullException( "ignorer" ); + foreach ( Player otherPlayer in source ) { + if ( ignorer.IsIgnoring( otherPlayer.Info ) ) { yield return otherPlayer; } } } - /// Filters a collection of players, leaving only those who are NOT ignored by the given player. /// Original collection of players. Will not get modified. /// Player whose disposition is being checked. /// Filtered collection of players. [NotNull] public static IEnumerable NotIgnoredBy( [NotNull] this IEnumerable source, [NotNull] Player ignorer ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( ignorer == null ) throw new ArgumentNullException( "ignorer" ); - foreach( Player otherPlayer in source ) { - if( !ignorer.IsIgnoring( otherPlayer.Info ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( ignorer == null ) + throw new ArgumentNullException( "ignorer" ); + foreach ( Player otherPlayer in source ) { + if ( !ignorer.IsIgnoring( otherPlayer.Info ) ) { yield return otherPlayer; } } } - #endregion - + #endregion Ignore #region Worlds @@ -354,33 +372,35 @@ public static IEnumerable NotIgnoredBy( [NotNull] this IEnumerable Filtered collection of players. [NotNull] public static IEnumerable InWorld( [NotNull] this IEnumerable source, [NotNull] World world ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( world == null ) throw new ArgumentNullException( "world" ); - foreach( Player player in source ) { - if( player.World == world ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( world == null ) + throw new ArgumentNullException( "world" ); + foreach ( Player player in source ) { + if ( player.World == world ) { yield return player; } } } - /// Filters a collection of players, leaving only those who are currently NOT located on the given world. /// Original collection of players. Will not get modified. /// World that players are desired to NOT be on. /// Filtered collection of players. [NotNull] public static IEnumerable NotInWorld( [NotNull] this IEnumerable source, [NotNull] World world ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( world == null ) throw new ArgumentNullException( "world" ); - foreach( Player player in source ) { - if( player.World != world ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( world == null ) + throw new ArgumentNullException( "world" ); + foreach ( Player player in source ) { + if ( player.World != world ) { yield return player; } } } - #endregion - + #endregion Worlds #region Personal Inclusion / Exclusion @@ -393,18 +413,17 @@ public static IEnumerable NotInWorld( [NotNull] this IEnumerable [NotNull] public static IEnumerable Union( [NotNull] this IEnumerable source, [NotNull] Player includedPlayer ) { bool found = false; - foreach( Player player in source ) { + foreach ( Player player in source ) { yield return player; - if( player == includedPlayer ) { + if ( player == includedPlayer ) { found = true; } } - if( !found ) { + if ( !found ) { yield return includedPlayer; } } - /// Removes player from the given set. /// Precisely speaking, produces the set difference between the given collection of players and a given player. /// Original set of players. Will not get modified. @@ -412,15 +431,14 @@ public static IEnumerable Union( [NotNull] this IEnumerable sour /// A set that contains all players in the input sequence, minus the given player. [NotNull] public static IEnumerable Except( [NotNull] this IEnumerable source, [CanBeNull] Player excludedPlayer ) { - foreach( Player player in source ) { - if( player != excludedPlayer ) { + foreach ( Player player in source ) { + if ( player != excludedPlayer ) { yield return player; } } } - #endregion - + #endregion Personal Inclusion / Exclusion #region IPAddress @@ -430,33 +448,35 @@ public static IEnumerable Except( [NotNull] this IEnumerable sou /// Filtered collection of players. [NotNull] public static IEnumerable FromIP( [NotNull] this IEnumerable source, [NotNull] IPAddress ip ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( ip == null ) throw new ArgumentNullException( "ip" ); - foreach( Player player in source ) { - if( ip.Equals( player.IP ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( ip == null ) + throw new ArgumentNullException( "ip" ); + foreach ( Player player in source ) { + if ( ip.Equals( player.IP ) ) { yield return player; } } } - /// Filters a collection of players, leaving only those NOT connected from a given IP. /// Original collection of players. Will not get modified. /// IP that we are excluding. /// Filtered collection of players. [NotNull] public static IEnumerable NotFromIP( [NotNull] this IEnumerable source, [NotNull] IPAddress ip ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( ip == null ) throw new ArgumentNullException( "ip" ); - foreach( Player player in source ) { - if( !ip.Equals( player.IP ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( ip == null ) + throw new ArgumentNullException( "ip" ); + foreach ( Player player in source ) { + if ( !ip.Equals( player.IP ) ) { yield return player; } } } - #endregion - + #endregion IPAddress #region Messaging @@ -466,11 +486,13 @@ public static IEnumerable NotFromIP( [NotNull] this IEnumerable /// Number of players who received the message. public static int Message( [NotNull] this IEnumerable source, [NotNull] string message ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( message == null ) throw new ArgumentNullException( "message" ); + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); int i = 0; - foreach( Packet packet in LineWrapper.Wrap( message ) ) { - foreach( Player player in source ) { + foreach ( Packet packet in LineWrapper.Wrap( message ) ) { + foreach ( Player player in source ) { player.Send( packet ); i++; } @@ -486,12 +508,15 @@ public static int Message( [NotNull] this IEnumerable source, public static int Message( [NotNull] this IEnumerable source, [CanBeNull] Player except, [NotNull] string message ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( message == null ) throw new ArgumentNullException( "message" ); + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); int i = 0; - foreach( Packet packet in LineWrapper.Wrap( message ) ) { - foreach( Player player in source ) { - if( player == except ) continue; + foreach ( Packet packet in LineWrapper.Wrap( message ) ) { + foreach ( Player player in source ) { + if ( player == except ) + continue; player.Send( packet ); i++; } @@ -510,13 +535,17 @@ public static int Message( [NotNull] this IEnumerable source, [CanBeNull] Player except, [NotNull] string message, [NotNull] params object[] formatArgs ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( message == null ) throw new ArgumentNullException( "message" ); - if( formatArgs == null ) throw new ArgumentNullException( "formatArgs" ); + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( formatArgs == null ) + throw new ArgumentNullException( "formatArgs" ); int i = 0; - foreach( Packet packet in LineWrapper.Wrap( String.Format( message, formatArgs ) ) ) { - foreach( Player player in source ) { - if( player == except ) continue; + foreach ( Packet packet in LineWrapper.Wrap( String.Format( message, formatArgs ) ) ) { + foreach ( Player player in source ) { + if ( player == except ) + continue; player.Send( packet ); i++; } @@ -524,7 +553,6 @@ public static int Message( [NotNull] this IEnumerable source, return i; } - /// Formats and broadcasts a message. /// List of players who will receive the message. /// String/message to send. @@ -534,12 +562,15 @@ public static int Message( [NotNull] this IEnumerable source, public static int Message( [NotNull] this IEnumerable source, [NotNull] string message, [NotNull] params object[] formatArgs ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( message == null ) throw new ArgumentNullException( "message" ); - if( formatArgs == null ) throw new ArgumentNullException( "formatArgs" ); + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( formatArgs == null ) + throw new ArgumentNullException( "formatArgs" ); int i = 0; - foreach( Packet packet in LineWrapper.Wrap( String.Format( message, formatArgs ) ) ) { - foreach( Player player in source ) { + foreach ( Packet packet in LineWrapper.Wrap( String.Format( message, formatArgs ) ) ) { + foreach ( Player player in source ) { player.Send( packet ); i++; } @@ -547,7 +578,6 @@ public static int Message( [NotNull] this IEnumerable source, return i; } - /// Broadcasts a message, prefixing wrapped lines. /// List of players who will receive the message. /// Prefix to prepend to prepend to each line after the 1st, @@ -555,12 +585,15 @@ public static int Message( [NotNull] this IEnumerable source, /// String/message to send. /// Number of players who received the message. public static int MessagePrefixed( [NotNull] this IEnumerable source, [NotNull] string prefix, [NotNull] string message ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( prefix == null ) throw new ArgumentNullException( "prefix" ); - if( message == null ) throw new ArgumentNullException( "message" ); + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( prefix == null ) + throw new ArgumentNullException( "prefix" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); int i = 0; - foreach( Packet packet in LineWrapper.WrapPrefixed( prefix, message ) ) { - foreach( Player player in source ) { + foreach ( Packet packet in LineWrapper.WrapPrefixed( prefix, message ) ) { + foreach ( Player player in source ) { player.Send( packet ); i++; } @@ -568,7 +601,6 @@ public static int MessagePrefixed( [NotNull] this IEnumerable source, [N return i; } - /// Formats and broadcasts a message, prefixing wrapped lines. /// List of players who will receive the message. /// Prefix to prepend to prepend to each line after the 1st, @@ -578,13 +610,17 @@ public static int MessagePrefixed( [NotNull] this IEnumerable source, [N /// Number of players who received the message. [StringFormatMethod( "message" )] public static int MessagePrefixed( [NotNull] this IEnumerable source, [NotNull] string prefix, [NotNull] string message, params object[] formatArgs ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( message == null ) throw new ArgumentNullException( "message" ); - if( prefix == null ) throw new ArgumentNullException( "prefix" ); - if( formatArgs == null ) throw new ArgumentNullException( "formatArgs" ); + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( prefix == null ) + throw new ArgumentNullException( "prefix" ); + if ( formatArgs == null ) + throw new ArgumentNullException( "formatArgs" ); int i = 0; - foreach( Packet packet in LineWrapper.WrapPrefixed( prefix, String.Format( message, formatArgs ) ) ) { - foreach( Player player in source ) { + foreach ( Packet packet in LineWrapper.WrapPrefixed( prefix, String.Format( message, formatArgs ) ) ) { + foreach ( Player player in source ) { player.Send( packet ); i++; } @@ -592,9 +628,6 @@ public static int MessagePrefixed( [NotNull] this IEnumerable source, [N return i; } - - - /// Formats and broadcasts a message, showing on top-left for those who use WoM. /// List of players who will receive the message. /// String/message to send. @@ -604,19 +637,21 @@ public static int MessagePrefixed( [NotNull] this IEnumerable source, [N public static int MessageAlt( [NotNull] this IEnumerable source, [NotNull] string message, [NotNull] params object[] formatArgs ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( message == null ) throw new ArgumentNullException( "message" ); - if( formatArgs == null ) throw new ArgumentNullException( "formatArgs" ); + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( formatArgs == null ) + throw new ArgumentNullException( "formatArgs" ); int i = 0; - foreach( Player player in source ) { + foreach ( Player player in source ) { player.MessageAlt( message, formatArgs ); i++; } return i; } - #endregion - + #endregion Messaging #region Packet Sending @@ -625,64 +660,67 @@ public static int MessageAlt( [NotNull] this IEnumerable source, /// Packet to send. /// Number of players who received the packet. public static int Send( [NotNull] this IEnumerable source, Packet packet ) { - if( source == null ) throw new ArgumentNullException( "source" ); + if ( source == null ) + throw new ArgumentNullException( "source" ); int i = 0; - foreach( Player player in source ) { + foreach ( Player player in source ) { player.Send( packet ); i++; } return i; } - /// Broadcasts a packet with normal priority. /// List of players who will receive the packet. /// Player to exclude from the recepient list. /// Packet to send. /// Number of players who received the packet. public static int Send( [NotNull] this IEnumerable source, [CanBeNull] Player except, Packet packet ) { - if( source == null ) throw new ArgumentNullException( "source" ); + if ( source == null ) + throw new ArgumentNullException( "source" ); int i = 0; - foreach( Player player in source ) { - if( player == except ) continue; + foreach ( Player player in source ) { + if ( player == except ) + continue; player.Send( packet ); i++; } return i; } - /// Broadcasts a packet with low priority. /// List of players who will receive the packet. /// Packet to send. /// Number of players who received the packet. public static int SendLowPriority( [NotNull] this IEnumerable source, Packet packet ) { - if( source == null ) throw new ArgumentNullException( "source" ); + if ( source == null ) + throw new ArgumentNullException( "source" ); int i = 0; - foreach( Player player in source ) { + foreach ( Player player in source ) { player.SendLowPriority( packet ); i++; } return i; } - /// Broadcasts a packet with low priority. /// List of players who will receive the packet. /// Player to exclude from the recepient list. /// Packet to send. /// Number of players who received the packet. public static int SendLowPriority( [NotNull] this IEnumerable source, [CanBeNull] Player except, Packet packet ) { - if( source == null ) throw new ArgumentNullException( "source" ); + if ( source == null ) + throw new ArgumentNullException( "source" ); int i = 0; - foreach( Player player in source ) { - if( player == except ) continue; + foreach ( Player player in source ) { + if ( player == except ) + continue; player.SendLowPriority( packet ); i++; } return i; } - #endregion + #endregion Packet Sending } } \ No newline at end of file diff --git a/fCraft/Player/PlayerInfo.Actions.cs b/fCraft/Player/PlayerInfo.Actions.cs index 6e1412f..72cc51d 100644 --- a/fCraft/Player/PlayerInfo.Actions.cs +++ b/fCraft/Player/PlayerInfo.Actions.cs @@ -8,8 +8,9 @@ using JetBrains.Annotations; namespace fCraft { + public sealed partial class PlayerInfo { - readonly object actionLock = new object(); + private readonly object actionLock = new object(); #region Ban / Unban @@ -23,7 +24,6 @@ public void Ban( [NotNull] Player player, [CanBeNull] string reason, bool announ BanPlayerInfoInternal( player, reason, false, announce, raiseEvents ); } - /// Unbans a player. Throws PlayerOpException on problems. /// Player who is unbanning. /// Reason for unban. May be empty, if permitted by server configuration. @@ -34,33 +34,34 @@ public void Unban( [NotNull] Player player, [CanBeNull] string reason, bool anno BanPlayerInfoInternal( player, reason, true, announce, raiseEvents ); } - - void BanPlayerInfoInternal( [NotNull] Player player, [CanBeNull] string reason, + private void BanPlayerInfoInternal( [NotNull] Player player, [CanBeNull] string reason, bool unban, bool announce, bool raiseEvents ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( reason != null && reason.Trim().Length == 0 ) reason = null; + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( reason != null && reason.Trim().Length == 0 ) + reason = null; - lock( actionLock ) { + lock ( actionLock ) { // Check if player can ban/unban in general - if( !player.Can( Permission.Ban ) ) { + if ( !player.Can( Permission.Ban ) ) { PlayerOpException.ThrowPermissionMissing( player, this, unban ? "unban" : "ban", Permission.Ban ); } // Check if player is trying to ban/unban self - if( player.Info == this ) { + if ( player.Info == this ) { PlayerOpException.ThrowCannotTargetSelf( player, this, unban ? "unban" : "ban" ); } // See if target is already banned/unbanned - if( unban && BanStatus != BanStatus.Banned ) { + if ( unban && BanStatus != BanStatus.Banned ) { PlayerOpException.ThrowPlayerNotBanned( player, this, "banned" ); - } else if( !unban && BanStatus == BanStatus.Banned ) { + } else if ( !unban && BanStatus == BanStatus.Banned ) { PlayerOpException.ThrowPlayerAlreadyBanned( player, this, "banned" ); } // Check if player has sufficient rank permissions - if( !unban && !player.Can( Permission.Ban, Rank ) ) { + if ( !unban && !player.Can( Permission.Ban, Rank ) ) { PlayerOpException.ThrowPermissionLimit( player, this, "ban", Permission.Ban ); } @@ -68,50 +69,51 @@ void BanPlayerInfoInternal( [NotNull] Player player, [CanBeNull] string reason, // Raise PlayerInfo.BanChanging event PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs( this, player, unban, reason, announce ); - if( raiseEvents ) { + if ( raiseEvents ) { RaiseBanChangingEvent( e ); - if( e.Cancel ) PlayerOpException.ThrowCancelled( player, this ); + if ( e.Cancel ) + PlayerOpException.ThrowCancelled( player, this ); reason = e.Reason; } // Actually ban bool result; - if( unban ) { + if ( unban ) { result = ProcessUnban( player.Name, reason ); } else { result = ProcessBan( player, player.Name, reason ); } // Check what happened - if( result ) { - if( raiseEvents ) { + if ( result ) { + if ( raiseEvents ) { RaiseBanChangedEvent( e ); } Player target = PlayerObject; - string verb = (unban ? "unbanned" : "banned"); + string verb = ( unban ? "unbanned" : "banned" ); Logger.Log( LogType.UserActivity, "{0} {1} {2}. Reason: {3}", player.Name, verb, Name, reason ?? "" ); - if( target != null ) { + if ( target != null ) { // Log and announce ban/unban - if( announce ) { + if ( announce ) { Server.Message( target, "{0}&W was {1} by {2}", target.ClassyName, verb, player.ClassyName ); } - if (unban){ - if (target.Info.BannedUntil > DateTime.UtcNow){ - player.Message("&SBypassed BannedUntil field for {0}&S, target is no longer tempbanned"); + if ( unban ) { + if ( target.Info.BannedUntil > DateTime.UtcNow ) { + player.Message( "&SBypassed BannedUntil field for {0}&S, target is no longer tempbanned" ); target.Info.BannedUntil = DateTime.MinValue; } } // Kick the target - if( !unban ) { + if ( !unban ) { string kickReason; - if( reason != null ) { + if ( reason != null ) { kickReason = String.Format( "Banned by {0}: {1}", player.Name, reason ); } else { kickReason = String.Format( "Banned by {0}", player.Name ); @@ -120,24 +122,23 @@ void BanPlayerInfoInternal( [NotNull] Player player, [CanBeNull] string reason, target.Kick( kickReason, LeaveReason.Ban ); } } else { - if( announce ) { + if ( announce ) { Server.Message( "{0}&W (offline) was {1} by {2}", ClassyName, verb, player.ClassyName ); } } // Announce ban/unban reason - if( announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { - if( unban ) { + if ( announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { + if ( unban ) { Server.Message( "&WUnban reason: {0}", reason ); } else { Server.Message( "&WBan reason: {0}", reason ); } } - } else { // Player is already banned/unbanned - if( unban ) { + if ( unban ) { PlayerOpException.ThrowPlayerNotBanned( player, this, "banned" ); } else { PlayerOpException.ThrowPlayerAlreadyBanned( player, this, "banned" ); @@ -146,7 +147,6 @@ void BanPlayerInfoInternal( [NotNull] Player player, [CanBeNull] string reason, } } - /// Bans given player and their IP address. /// All players from IP are kicked. Throws PlayerOpException on problems. /// Player who is banning. @@ -156,38 +156,40 @@ void BanPlayerInfoInternal( [NotNull] Player player, [CanBeNull] string reason, /// BanChanging, and BanChanged events should be raised. /// public void BanIP( [NotNull] Player player, [CanBeNull] string reason, bool announce, bool raiseEvents ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( reason != null && reason.Trim().Length == 0 ) reason = null; - lock( actionLock ) { - if( !player.Can( Permission.Ban, Permission.BanIP ) ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( reason != null && reason.Trim().Length == 0 ) + reason = null; + lock ( actionLock ) { + if ( !player.Can( Permission.Ban, Permission.BanIP ) ) { PlayerOpException.ThrowPermissionMissing( player, this, "IP-ban", Permission.Ban, Permission.BanIP ); } IPAddress address = LastIP; // Check if player is trying to ban self - if( player.Info == this || address.Equals( player.IP ) && !player.IsSuper ) { + if ( player.Info == this || address.Equals( player.IP ) && !player.IsSuper ) { PlayerOpException.ThrowCannotTargetSelf( player, this, "IP-ban" ); } // Check if a non-bannable address was given (0.0.0.0 or 255.255.255.255) - if( address.Equals( IPAddress.None ) || address.Equals( IPAddress.Any ) ) { + if ( address.Equals( IPAddress.None ) || address.Equals( IPAddress.Any ) ) { PlayerOpException.ThrowInvalidIP( player, this, address ); } // Check if any high-ranked players use this address PlayerInfo unbannable = PlayerDB.FindPlayers( address ) .FirstOrDefault( info => !player.Can( Permission.Ban, info.Rank ) ); - if( unbannable != null ) { + if ( unbannable != null ) { PlayerOpException.ThrowPermissionLimitIP( player, unbannable, address ); } // Check existing ban statuses bool needNameBan = !IsBanned; bool needIPBan = !IPBanList.Contains( address ); - if( !needIPBan && !needNameBan ) { + if ( !needIPBan && !needNameBan ) { string msg, colorMsg; - if( player.Can( Permission.ViewPlayerIPs ) ) { + if ( player.Can( Permission.ViewPlayerIPs ) ) { msg = String.Format( "Given player ({0}) and their IP address ({1}) are both already banned.", Name, address ); colorMsg = String.Format( "&SGiven player ({0}&S) and their IP address ({1}) are both already banned.", @@ -202,8 +204,8 @@ public void BanIP( [NotNull] Player player, [CanBeNull] string reason, bool anno } // Check if target is IPBan-exempt - bool targetIsExempt = (BanStatus == BanStatus.IPBanExempt); - if( !needIPBan && targetIsExempt ) { + bool targetIsExempt = ( BanStatus == BanStatus.IPBanExempt ); + if ( !needIPBan && targetIsExempt ) { string msg = String.Format( "Given player ({0}) is exempt from IP bans. Remove the exemption and retry.", Name ); string colorMsg = String.Format( "&SGiven player ({0}&S) is exempt from IP bans. Remove the exemption and retry.", @@ -212,36 +214,36 @@ public void BanIP( [NotNull] Player player, [CanBeNull] string reason, bool anno } // Ban the name - if( needNameBan ) { + if ( needNameBan ) { Ban( player, reason, announce, raiseEvents ); } PlayerOpException.CheckBanReason( reason, player, this, false ); // Ban the IP - if( needIPBan ) { + if ( needIPBan ) { IPBanInfo banInfo = new IPBanInfo( address, Name, player.Name, reason ); - if( IPBanList.Add( banInfo, raiseEvents ) ) { + if ( IPBanList.Add( banInfo, raiseEvents ) ) { Logger.Log( LogType.UserActivity, "{0} banned {1} (BanIP {2}). Reason: {3}", player.Name, address, Name, reason ?? "" ); // Announce ban on the server - if( announce ) { + if ( announce ) { var can = Server.Players.Can( Permission.ViewPlayerIPs ); can.Message( "&WPlayer {0}&W was IP-banned ({1}) by {2}", ClassyName, address, player.ClassyName ); var cant = Server.Players.Cant( Permission.ViewPlayerIPs ); cant.Message( "&WPlayer {0}&W was IP-banned by {1}", ClassyName, player.ClassyName ); - if( ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { + if ( ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { Server.Message( "&WBanIP reason: {0}", reason ); } } } else { // IP is already banned string msg, colorMsg; - if( player.Can( Permission.ViewPlayerIPs ) ) { + if ( player.Can( Permission.ViewPlayerIPs ) ) { msg = String.Format( "IP of player {0} ({1}) is already banned.", Name, address ); colorMsg = String.Format( "&SIP of player {0}&S ({1}) is already banned.", @@ -258,7 +260,6 @@ public void BanIP( [NotNull] Player player, [CanBeNull] string reason, bool anno } } - /// Unbans given player and their IP address. Throws PlayerOpException on problems. /// Player who is unbanning. /// Reason for unban. May be empty, if permitted by server configuration. @@ -267,55 +268,57 @@ public void BanIP( [NotNull] Player player, [CanBeNull] string reason, bool anno /// BanChanging, and BanChanged events should be raised. /// public void UnbanIP( [NotNull] Player player, [CanBeNull] string reason, bool announce, bool raiseEvents ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( reason != null && reason.Trim().Length == 0 ) reason = null; - lock( actionLock ) { - if( !player.Can( Permission.Ban, Permission.BanIP ) ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( reason != null && reason.Trim().Length == 0 ) + reason = null; + lock ( actionLock ) { + if ( !player.Can( Permission.Ban, Permission.BanIP ) ) { PlayerOpException.ThrowPermissionMissing( player, this, "IP-unban", Permission.Ban, Permission.BanIP ); } IPAddress address = LastIP; // Check if player is trying to unban self - if( player.Info == this || address.Equals( player.IP ) && !player.IsSuper ) { + if ( player.Info == this || address.Equals( player.IP ) && !player.IsSuper ) { PlayerOpException.ThrowCannotTargetSelf( player, this, "IP-unban" ); } // Check if a non-bannable address was given (0.0.0.0 or 255.255.255.255) - if( address.Equals( IPAddress.None ) || address.Equals( IPAddress.Any ) ) { + if ( address.Equals( IPAddress.None ) || address.Equals( IPAddress.Any ) ) { PlayerOpException.ThrowInvalidIP( player, this, address ); } // Check existing unban statuses bool needNameUnban = IsBanned; - bool needIPUnban = (IPBanList.Get( address ) != null); - if( !needIPUnban && !needNameUnban ) { + bool needIPUnban = ( IPBanList.Get( address ) != null ); + if ( !needIPUnban && !needNameUnban ) { PlayerOpException.ThrowPlayerAndIPNotBanned( player, this, address ); } PlayerOpException.CheckBanReason( reason, player, this, true ); // Unban the name - if( needNameUnban ) { + if ( needNameUnban ) { Unban( player, reason, announce, raiseEvents ); } // Unban the IP - if( needIPUnban ) { - if( IPBanList.Remove( address, raiseEvents ) ) { + if ( needIPUnban ) { + if ( IPBanList.Remove( address, raiseEvents ) ) { Logger.Log( LogType.UserActivity, "{0} unbanned {1} (UnbanIP {2}). Reason: {3}", player.Name, address, Name, reason ?? "" ); // Announce unban on the server - if( announce ) { + if ( announce ) { var can = Server.Players.Can( Permission.ViewPlayerIPs ); can.Message( "&WPlayer {0}&W was IP-unbanned ({1}) by {2}", ClassyName, address, player.ClassyName ); var cant = Server.Players.Cant( Permission.ViewPlayerIPs ); cant.Message( "&WPlayer {0}&W was IP-unbanned by {1}", ClassyName, player.ClassyName ); - if( ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { + if ( ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { Server.Message( "&WUnbanIP reason: {0}", reason ); } } @@ -326,7 +329,6 @@ public void UnbanIP( [NotNull] Player player, [CanBeNull] string reason, bool an } } - /// Bans given player, their IP, and all other accounts on IP. /// All players from IP are kicked. Throws PlayerOpException on problems. /// Player who is banning. @@ -336,10 +338,12 @@ public void UnbanIP( [NotNull] Player player, [CanBeNull] string reason, bool an /// BanChanging, and BanChanged events should be raised. /// public void BanAll( [NotNull] Player player, [CanBeNull] string reason, bool announce, bool raiseEvents ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( reason != null && reason.Trim().Length == 0 ) reason = null; - lock( actionLock ) { - if( !player.Can( Permission.Ban, Permission.BanIP, Permission.BanAll ) ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( reason != null && reason.Trim().Length == 0 ) + reason = null; + lock ( actionLock ) { + if ( !player.Can( Permission.Ban, Permission.BanIP, Permission.BanAll ) ) { PlayerOpException.ThrowPermissionMissing( player, this, "ban-all", Permission.Ban, Permission.BanIP, Permission.BanAll ); } @@ -347,19 +351,19 @@ public void BanAll( [NotNull] Player player, [CanBeNull] string reason, bool ann IPAddress address = LastIP; // Check if player is trying to ban self - if( player.Info == this || address.Equals( player.IP ) && !player.IsSuper ) { + if ( player.Info == this || address.Equals( player.IP ) && !player.IsSuper ) { PlayerOpException.ThrowCannotTargetSelf( player, this, "ban-all" ); } // Check if a non-bannable address was given (0.0.0.0 or 255.255.255.255) - if( address.Equals( IPAddress.None ) || address.Equals( IPAddress.Any ) ) { + if ( address.Equals( IPAddress.None ) || address.Equals( IPAddress.Any ) ) { PlayerOpException.ThrowInvalidIP( player, this, address ); } // Check if any high-ranked players use this address PlayerInfo[] allPlayersOnIP = PlayerDB.FindPlayers( address ); PlayerInfo infoWhomPlayerCantBan = allPlayersOnIP.FirstOrDefault( info => !player.Can( Permission.Ban, info.Rank ) ); - if( infoWhomPlayerCantBan != null ) { + if ( infoWhomPlayerCantBan != null ) { PlayerOpException.ThrowPermissionLimitIP( player, infoWhomPlayerCantBan, address ); } @@ -367,15 +371,15 @@ public void BanAll( [NotNull] Player player, [CanBeNull] string reason, bool ann bool somethingGotBanned = false; // Ban the IP - if( !IPBanList.Contains( address ) ) { + if ( !IPBanList.Contains( address ) ) { IPBanInfo banInfo = new IPBanInfo( address, Name, player.Name, reason ); - if( IPBanList.Add( banInfo, raiseEvents ) ) { + if ( IPBanList.Add( banInfo, raiseEvents ) ) { Logger.Log( LogType.UserActivity, "{0} banned {1} (BanAll {2}). Reason: {3}", player.Name, address, Name, reason ?? "" ); // Announce ban on the server - if( announce ) { + if ( announce ) { var can = Server.Players.Can( Permission.ViewPlayerIPs ); can.Message( "&WPlayer {0}&W was IP-banned ({1}) by {2}", ClassyName, address, player.ClassyName ); @@ -388,20 +392,22 @@ public void BanAll( [NotNull] Player player, [CanBeNull] string reason, bool ann } // Ban individual players - foreach( PlayerInfo targetAlt in allPlayersOnIP ) { - if( targetAlt.BanStatus != BanStatus.NotBanned ) continue; + foreach ( PlayerInfo targetAlt in allPlayersOnIP ) { + if ( targetAlt.BanStatus != BanStatus.NotBanned ) + continue; // Raise PlayerInfo.BanChanging event PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs( targetAlt, player, false, reason, announce ); - if( raiseEvents ) { + if ( raiseEvents ) { RaiseBanChangingEvent( e ); - if( e.Cancel ) continue; + if ( e.Cancel ) + continue; reason = e.Reason; } // Do the ban - if( targetAlt.ProcessBan( player, player.Name, reason ) ) { - if( raiseEvents ) { + if ( targetAlt.ProcessBan( player, player.Name, reason ) ) { + if ( raiseEvents ) { RaiseBanChangedEvent( e ); } @@ -409,8 +415,8 @@ public void BanAll( [NotNull] Player player, [CanBeNull] string reason, bool ann Logger.Log( LogType.UserActivity, "{0} banned {1} (BanAll {2}). Reason: {3}", player.Name, targetAlt.Name, Name, reason ?? "" ); - if( announce ) { - if( targetAlt == this ) { + if ( announce ) { + if ( targetAlt == this ) { Server.Message( "&WPlayer {0}&W was banned by {1}&W (BanAll)", targetAlt.ClassyName, player.ClassyName ); } else { @@ -423,32 +429,31 @@ public void BanAll( [NotNull] Player player, [CanBeNull] string reason, bool ann } // If no one ended up getting banned, quit here - if( !somethingGotBanned ) { + if ( !somethingGotBanned ) { PlayerOpException.ThrowNoOneToBan( player, this, address ); } // Announce BanAll reason towards the end of all bans - if( announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { + if ( announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { Server.Message( "&WBanAll reason: {0}", reason ); } // Kick all players from IP Player[] targetsOnline = Server.Players.FromIP( address ).ToArray(); - if( targetsOnline.Length > 0 ) { + if ( targetsOnline.Length > 0 ) { string kickReason; - if( reason != null ) { + if ( reason != null ) { kickReason = String.Format( "Banned by {0}: {1}", player.Name, reason ); } else { kickReason = String.Format( "Banned by {0}", player.Name ); } - for( int i = 0; i < targetsOnline.Length; i++ ) { + for ( int i = 0; i < targetsOnline.Length; i++ ) { targetsOnline[i].Kick( kickReason, LeaveReason.BanAll ); } } } } - /// Unbans given player, their IP address, and all other accounts on IP. /// Throws PlayerOpException on problems. /// Player who is unbanning. @@ -458,10 +463,12 @@ public void BanAll( [NotNull] Player player, [CanBeNull] string reason, bool ann /// BanChanging, and BanChanged events should be raised. /// public void UnbanAll( [NotNull] Player player, [CanBeNull] string reason, bool announce, bool raiseEvents ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( reason != null && reason.Trim().Length == 0 ) reason = null; - lock( actionLock ) { - if( !player.Can( Permission.Ban, Permission.BanIP, Permission.BanAll ) ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( reason != null && reason.Trim().Length == 0 ) + reason = null; + lock ( actionLock ) { + if ( !player.Can( Permission.Ban, Permission.BanIP, Permission.BanAll ) ) { PlayerOpException.ThrowPermissionMissing( player, this, "unban-all", Permission.Ban, Permission.BanIP, Permission.BanAll ); } @@ -469,12 +476,12 @@ public void UnbanAll( [NotNull] Player player, [CanBeNull] string reason, bool a IPAddress address = LastIP; // Check if player is trying to unban self - if( player.Info == this || address.Equals( player.IP ) && !player.IsSuper ) { + if ( player.Info == this || address.Equals( player.IP ) && !player.IsSuper ) { PlayerOpException.ThrowCannotTargetSelf( player, this, "unban-all" ); } // Check if a non-bannable address was given (0.0.0.0 or 255.255.255.255) - if( address.Equals( IPAddress.None ) || address.Equals( IPAddress.Any ) ) { + if ( address.Equals( IPAddress.None ) || address.Equals( IPAddress.Any ) ) { PlayerOpException.ThrowInvalidIP( player, this, address ); } @@ -482,14 +489,14 @@ public void UnbanAll( [NotNull] Player player, [CanBeNull] string reason, bool a bool somethingGotUnbanned = false; // Unban the IP - if( IPBanList.Contains( address ) ) { - if( IPBanList.Remove( address, raiseEvents ) ) { + if ( IPBanList.Contains( address ) ) { + if ( IPBanList.Remove( address, raiseEvents ) ) { Logger.Log( LogType.UserActivity, "{0} unbanned {1} (UnbanAll {2}). Reason: {3}", player.Name, address, Name, reason ?? "" ); // Announce unban on the server - if( announce ) { + if ( announce ) { var can = Server.Players.Can( Permission.ViewPlayerIPs ); can.Message( "&WPlayer {0}&W was IP-unbanned ({1}) by {2}", ClassyName, address, player.ClassyName ); @@ -504,20 +511,22 @@ public void UnbanAll( [NotNull] Player player, [CanBeNull] string reason, bool a // Unban individual players PlayerInfo[] allPlayersOnIP = PlayerDB.FindPlayers( address ); - foreach( PlayerInfo targetAlt in allPlayersOnIP ) { - if( targetAlt.BanStatus != BanStatus.Banned ) continue; + foreach ( PlayerInfo targetAlt in allPlayersOnIP ) { + if ( targetAlt.BanStatus != BanStatus.Banned ) + continue; // Raise PlayerInfo.BanChanging event PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs( targetAlt, player, true, reason, announce ); - if( raiseEvents ) { + if ( raiseEvents ) { RaiseBanChangingEvent( e ); - if( e.Cancel ) continue; + if ( e.Cancel ) + continue; reason = e.Reason; } // Do the ban - if( targetAlt.ProcessUnban( player.Name, reason ) ) { - if( raiseEvents ) { + if ( targetAlt.ProcessUnban( player.Name, reason ) ) { + if ( raiseEvents ) { RaiseBanChangedEvent( e ); } @@ -525,8 +534,8 @@ public void UnbanAll( [NotNull] Player player, [CanBeNull] string reason, bool a Logger.Log( LogType.UserActivity, "{0} unbanned {1} (UnbanAll {2}). Reason: {3}", player.Name, targetAlt.Name, Name, reason ?? "" ); - if( announce ) { - if( targetAlt == this ) { + if ( announce ) { + if ( targetAlt == this ) { Server.Message( "&WPlayer {0}&W was unbanned by {1}&W (UnbanAll)", targetAlt.ClassyName, player.ClassyName ); } else { @@ -539,23 +548,24 @@ public void UnbanAll( [NotNull] Player player, [CanBeNull] string reason, bool a } // If no one ended up getting unbanned, quit here - if( !somethingGotUnbanned ) { + if ( !somethingGotUnbanned ) { PlayerOpException.ThrowNoOneToUnban( player, this, address ); } // Announce UnbanAll reason towards the end of all unbans - if( announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { + if ( announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { Server.Message( "&WUnbanAll reason: {0}", reason ); } } } - internal bool ProcessBan( [NotNull] Player bannedBy, [NotNull] string bannedByName, [CanBeNull] string banReason ) { - if( bannedBy == null ) throw new ArgumentNullException( "bannedBy" ); - if( bannedByName == null ) throw new ArgumentNullException( "bannedByName" ); - lock( actionLock ) { - if( IsBanned ) { + if ( bannedBy == null ) + throw new ArgumentNullException( "bannedBy" ); + if ( bannedByName == null ) + throw new ArgumentNullException( "bannedByName" ); + lock ( actionLock ) { + if ( IsBanned ) { return false; } BanStatus = BanStatus.Banned; @@ -565,10 +575,10 @@ internal bool ProcessBan( [NotNull] Player bannedBy, [NotNull] string bannedByNa Interlocked.Increment( ref bannedBy.Info.TimesBannedOthers ); MutedUntil = DateTime.MinValue; MutedBy = null; - if( IsFrozen ) { + if ( IsFrozen ) { try { Unfreeze( bannedBy, false, true ); - } catch( PlayerOpException ex ) { + } catch ( PlayerOpException ex ) { Logger.Log( LogType.Warning, "PlayerInfo.ProcessBan: {0}", ex.Message ); } @@ -579,11 +589,11 @@ internal bool ProcessBan( [NotNull] Player bannedBy, [NotNull] string bannedByNa } } - internal bool ProcessUnban( [NotNull] string unbannedByName, [CanBeNull] string unbanReason ) { - if( unbannedByName == null ) throw new ArgumentNullException( "unbannedByName" ); - lock( actionLock ) { - if( IsBanned ) { + if ( unbannedByName == null ) + throw new ArgumentNullException( "unbannedByName" ); + lock ( actionLock ) { + if ( IsBanned ) { BanStatus = BanStatus.NotBanned; UnbannedBy = unbannedByName; UnbanDate = DateTime.UtcNow; @@ -596,8 +606,7 @@ internal bool ProcessUnban( [NotNull] string unbannedByName, [CanBeNull] string } } - #endregion - + #endregion Ban / Unban #region ChangeRank @@ -611,36 +620,39 @@ internal bool ProcessUnban( [NotNull] string unbannedByName, [CanBeNull] string /// public void ChangeRank( [NotNull] Player player, [NotNull] Rank newRank, [CanBeNull] string reason, bool announce, bool raiseEvents, bool auto ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( newRank == null ) throw new ArgumentNullException( "newRank" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( newRank == null ) + throw new ArgumentNullException( "newRank" ); - if( reason != null && reason.Trim().Length == 0 ) reason = null; + if ( reason != null && reason.Trim().Length == 0 ) + reason = null; - bool promoting = (newRank > Rank); - string verb = (promoting ? "promote" : "demote"); - string verbed = (promoting ? "promoted" : "demoted"); + bool promoting = ( newRank > Rank ); + string verb = ( promoting ? "promote" : "demote" ); + string verbed = ( promoting ? "promoted" : "demoted" ); // Check if player is trying to promote/demote self - if( player.Info == this ) { + if ( player.Info == this ) { PlayerOpException.ThrowCannotTargetSelf( player, this, verb ); } // Check if target already has the desired rank - if( newRank == Rank ) { + if ( newRank == Rank ) { string msg = String.Format( "Player {0} is already ranked {1}", Name, Rank.Name ); string colorMsg = String.Format( "&SPlayer {0}&S is already ranked {1}", ClassyName, Rank.ClassyName ); throw new PlayerOpException( player, this, PlayerOpExceptionCode.NoActionNeeded, msg, colorMsg ); } // Check if player has permissions in general - if( promoting && !player.Can( Permission.Promote ) ) { + if ( promoting && !player.Can( Permission.Promote ) ) { PlayerOpException.ThrowPermissionMissing( player, this, verb, Permission.Promote ); - } else if( !promoting && !player.Can( Permission.Demote ) ) { + } else if ( !promoting && !player.Can( Permission.Demote ) ) { PlayerOpException.ThrowPermissionMissing( player, this, verb, Permission.Demote ); } // Check if player's specific permission limits are enough - if( promoting && !player.Can( Permission.Promote, newRank ) ) { + if ( promoting && !player.Can( Permission.Promote, newRank ) ) { string msg = String.Format( "Cannot promote {0} to {1}: you may only promote players up to rank {2}.", Name, newRank.Name, player.Info.Rank.GetLimit( Permission.Promote ).Name ); @@ -649,7 +661,7 @@ public void ChangeRank( [NotNull] Player player, [NotNull] Rank newRank, [CanBeN player.Info.Rank.GetLimit( Permission.Promote ).ClassyName ); throw new PlayerOpException( player, this, PlayerOpExceptionCode.PermissionLimitTooLow, msg, colorMsg ); - } else if( !promoting && !player.Can( Permission.Demote, Rank ) ) { + } else if ( !promoting && !player.Can( Permission.Demote, Rank ) ) { string msg = String.Format( "Cannot demote {0} (ranked {1}): you may only demote players ranked {2} or below.", Name, Rank.Name, player.Info.Rank.GetLimit( Permission.Demote ).Name ); @@ -664,14 +676,14 @@ public void ChangeRank( [NotNull] Player player, [NotNull] Rank newRank, [CanBeN PlayerOpException.CheckRankChangeReason( reason, player, this, promoting ); RankChangeType changeType; - if( newRank >= Rank ) { - changeType = (auto ? RankChangeType.AutoPromoted : RankChangeType.Promoted); + if ( newRank >= Rank ) { + changeType = ( auto ? RankChangeType.AutoPromoted : RankChangeType.Promoted ); } else { - changeType = (auto ? RankChangeType.AutoDemoted : RankChangeType.Demoted); + changeType = ( auto ? RankChangeType.AutoDemoted : RankChangeType.Demoted ); } // Raise PlayerInfo.RankChanging event - if( raiseEvents && RaiseRankChangingEvent( this, player, newRank, reason, changeType, announce ) ) { + if ( raiseEvents && RaiseRankChangingEvent( this, player, newRank, reason, changeType, announce ) ) { PlayerOpException.ThrowCancelled( player, this ); } @@ -680,7 +692,8 @@ public void ChangeRank( [NotNull] Player player, [NotNull] Rank newRank, [CanBeN "{0} {1} {2} from {3} to {4}. Reason: {5}", player.Name, verbed, Name, Rank.Name, newRank.Name, reason ?? "" ); //add promocount - if (promoting) player.Info.PromoCount++; + if ( promoting ) + player.Info.PromoCount++; // Actually change rank Rank oldRank = Rank; @@ -688,14 +701,16 @@ public void ChangeRank( [NotNull] Player player, [NotNull] Rank newRank, [CanBeN // Make necessary adjustments related to rank change Player target = PlayerObject; - if( target == null ) { - if( raiseEvents ) RaiseRankChangedEvent( this, player, oldRank, reason, changeType, announce ); - if( IsHidden && !Rank.Can( Permission.Hide ) ) { + if ( target == null ) { + if ( raiseEvents ) + RaiseRankChangedEvent( this, player, oldRank, reason, changeType, announce ); + if ( IsHidden && !Rank.Can( Permission.Hide ) ) { IsHidden = false; } } else { Server.RaisePlayerListChangedEvent(); - if( raiseEvents ) RaiseRankChangedEvent( this, player, oldRank, reason, changeType, announce ); + if ( raiseEvents ) + RaiseRankChangedEvent( this, player, oldRank, reason, changeType, announce ); // reset binds (water, lava, admincrete) target.ResetAllBinds(); @@ -704,31 +719,31 @@ public void ChangeRank( [NotNull] Player player, [NotNull] Rank newRank, [CanBeN target.Send( PacketWriter.MakeSetPermission( target ) ); // cancel selection in progress - if( target.IsMakingSelection ) { + if ( target.IsMakingSelection ) { target.Message( "Selection cancelled." ); target.SelectionCancel(); } // reset brush to normal, if not allowed to draw advanced - if( !target.Can( Permission.DrawAdvanced ) ) { + if ( !target.Can( Permission.DrawAdvanced ) ) { target.Brush = NormalBrushFactory.Instance; } // unhide, if needed - if( IsHidden && !target.Can( Permission.Hide ) ) { + if ( IsHidden && !target.Can( Permission.Hide ) ) { IsHidden = false; player.Message( "You are no longer hidden." ); } // check if target is still allowed to spectate Player spectatedPlayer = target.SpectatedPlayer; - if( spectatedPlayer != null && !target.Can( Permission.Spectate, spectatedPlayer.Info.Rank ) ) { + if ( spectatedPlayer != null && !target.Can( Permission.Spectate, spectatedPlayer.Info.Rank ) ) { target.StopSpectating(); } // check if others are still allowed to spectate target - foreach( Player spectator in Server.Players.Where( p => p.SpectatedPlayer == target ) ) { - if( !spectator.Can( Permission.Spectate, newRank ) ) { + foreach ( Player spectator in Server.Players.Where( p => p.SpectatedPlayer == target ) ) { + if ( !spectator.Can( Permission.Spectate, newRank ) ) { spectator.StopSpectating(); } } @@ -741,7 +756,7 @@ public void ChangeRank( [NotNull] Player player, [NotNull] Rank newRank, [CanBeN verbed, newRank.ClassyName, player.ClassyName ); - if( reason != null ) { + if ( reason != null ) { target.Message( "{0} reason: {1}", promoting ? "Promotion" : "Demotion", reason ); @@ -749,8 +764,8 @@ public void ChangeRank( [NotNull] Player player, [NotNull] Rank newRank, [CanBeN } // Announce the rank change - if( announce ) { - if( ConfigKey.AnnounceRankChanges.Enabled() ) { + if ( announce ) { + if ( ConfigKey.AnnounceRankChanges.Enabled() ) { Server.Message( target, "{0}&S {1} {2}&S from {3}&S to {4}", player.ClassyName, @@ -758,7 +773,7 @@ public void ChangeRank( [NotNull] Player player, [NotNull] Rank newRank, [CanBeN ClassyName, oldRank.ClassyName, newRank.ClassyName ); - if( ConfigKey.AnnounceRankChangeReasons.Enabled() && reason != null ) { + if ( ConfigKey.AnnounceRankChangeReasons.Enabled() && reason != null ) { Server.Message( target, "&S{0} reason: {1}", promoting ? "Promotion" : "Demotion", @@ -770,7 +785,7 @@ public void ChangeRank( [NotNull] Player player, [NotNull] Rank newRank, [CanBeN ClassyName, oldRank.ClassyName, newRank.ClassyName ); - if( target != null && reason != null ) { + if ( target != null && reason != null ) { target.Message( "&S{0} reason: {1}", promoting ? "Promotion" : "Demotion", reason ); @@ -779,8 +794,7 @@ public void ChangeRank( [NotNull] Player player, [NotNull] Rank newRank, [CanBeN } } - #endregion - + #endregion ChangeRank #region Freeze / Unfreeze @@ -790,33 +804,34 @@ public void ChangeRank( [NotNull] Player player, [NotNull] Rank newRank, [CanBeN /// Whether to announce freezing publicly on the server. /// Whether to raise PlayerInfo.FreezeChanging and PlayerInfo.FreezeChanged events. public void Freeze( [NotNull] Player player, bool announce, bool raiseEvents ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); // Check if player is trying to freeze self - if( player.Info == this ) { + if ( player.Info == this ) { PlayerOpException.ThrowCannotTargetSelf( player, this, "freeze" ); } - lock( actionLock ) { + lock ( actionLock ) { // Check if player can freeze in general - if( !player.Can( Permission.Freeze ) ) { + if ( !player.Can( Permission.Freeze ) ) { PlayerOpException.ThrowPermissionMissing( player, this, "freeze", Permission.Freeze ); } // Check if player has sufficient rank permissions - if( !player.Can( Permission.Freeze, Rank ) ) { + if ( !player.Can( Permission.Freeze, Rank ) ) { PlayerOpException.ThrowPermissionLimit( player, this, "freeze", Permission.Freeze ); } // Check if target is already frozen - if( IsFrozen ) { + if ( IsFrozen ) { string msg = String.Format( "Player {0} is already frozen (by {1}).", Name, FrozenBy ); string colorMsg = String.Format( "&SPlayer {0}&S is already frozen (by {1}&S).", ClassyName, FrozenByClassy ); throw new PlayerOpException( player, this, PlayerOpExceptionCode.NoActionNeeded, msg, colorMsg ); } // Raise PlayerInfo.FreezeChanging event - if( raiseEvents && RaiseFreezeChangingEvent( this, player, false, announce ) ) { + if ( raiseEvents && RaiseFreezeChangingEvent( this, player, false, announce ) ) { PlayerOpException.ThrowCancelled( player, this ); } @@ -829,14 +844,15 @@ public void Freeze( [NotNull] Player player, bool announce, bool raiseEvents ) { // Apply side effects Player target = PlayerObject; - if( target != null ) target.IsDeaf = false; + if ( target != null ) + target.IsDeaf = false; // Log and announce Logger.Log( LogType.UserActivity, "{0} froze {1}", player.Name, Name ); - if( announce ) { - if( target != null ) { + if ( announce ) { + if ( target != null ) { target.Message( "&WYou were frozen by {0}", player.ClassyName ); } Server.Message( target, "&SPlayer {0}&S was frozen by {1}", @@ -844,43 +860,44 @@ public void Freeze( [NotNull] Player player, bool announce, bool raiseEvents ) { } // Raise PlayerInfo.FreezeChanged event - if( raiseEvents ) RaiseFreezeChangedEvent( this, player, false, announce ); + if ( raiseEvents ) + RaiseFreezeChangedEvent( this, player, false, announce ); } } - /// Unfreezes this player. Throws PlayerOpException on problems. /// Player who is doing the unfreezing. /// Whether to announce freezing publicly on the server. /// Whether to raise PlayerInfo.FreezeChanging and PlayerInfo.FreezeChanged events. public void Unfreeze( [NotNull] Player player, bool announce, bool raiseEvents ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); // Check if player is trying to freeze self - if( player.Info == this ) { + if ( player.Info == this ) { PlayerOpException.ThrowCannotTargetSelf( player, this, "unfreeze" ); } - lock( actionLock ) { + lock ( actionLock ) { // Check if player can freeze in general - if( !player.Can( Permission.Freeze ) ) { + if ( !player.Can( Permission.Freeze ) ) { PlayerOpException.ThrowPermissionMissing( player, this, "unfreeze", Permission.Freeze ); } // Check if target is already frozen - if( !IsFrozen ) { + if ( !IsFrozen ) { string msg = String.Format( "Player {0} is not currently frozen.", Name ); string colorMsg = String.Format( "&SPlayer {0}&S is not currently frozen.", ClassyName ); throw new PlayerOpException( player, this, PlayerOpExceptionCode.NoActionNeeded, msg, colorMsg ); } // Check if player has sufficient rank permissions - if( !player.Can( Permission.Freeze, Rank ) ) { + if ( !player.Can( Permission.Freeze, Rank ) ) { PlayerOpException.ThrowPermissionLimit( player, this, "unfreeze", Permission.Freeze ); } // Raise PlayerInfo.FreezeChanging event - if( raiseEvents && RaiseFreezeChangingEvent( this, player, true, announce ) ) { + if ( raiseEvents && RaiseFreezeChangingEvent( this, player, true, announce ) ) { PlayerOpException.ThrowCancelled( player, this ); } @@ -891,9 +908,9 @@ public void Unfreeze( [NotNull] Player player, bool announce, bool raiseEvents ) Logger.Log( LogType.UserActivity, "{0} unfroze {1}", player.Name, Name ); - if( announce ) { + if ( announce ) { Player target = PlayerObject; - if( target != null ) { + if ( target != null ) { target.Message( "&WYou were unfrozen by {0}", player.ClassyName ); } Server.Message( target, "&SPlayer {0}&S was unfrozen by {1}", @@ -901,20 +918,19 @@ public void Unfreeze( [NotNull] Player player, bool announce, bool raiseEvents ) } // Raise PlayerInfo.FreezeChanged event - if( raiseEvents ) RaiseFreezeChangedEvent( this, player, true, announce ); + if ( raiseEvents ) + RaiseFreezeChangedEvent( this, player, true, announce ); } } - internal void Unfreeze() { - lock( actionLock ) { + lock ( actionLock ) { IsFrozen = false; LastModified = DateTime.UtcNow; } } - #endregion - + #endregion Freeze / Unfreeze #region Mute / Unmute @@ -926,34 +942,34 @@ internal void Unfreeze() { /// Whether to announce muting publicly on the sever. /// Whether to raise PlayerInfo.MuteChanging and MuteChanged events. public void Mute( [NotNull] Player player, TimeSpan duration, bool announce, bool raiseEvents ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( duration <= TimeSpan.Zero ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( duration <= TimeSpan.Zero ) { throw new ArgumentException( "Mute duration may not be zero or negative.", "duration" ); } // Check if player is trying to mute self - if( player.Info == this ) { + if ( player.Info == this ) { PlayerOpException.ThrowCannotTargetSelf( player, this, "mute" ); } - lock( actionLock ) { + lock ( actionLock ) { // Check if player can mute in general - if( !player.Can( Permission.Mute ) ) { + if ( !player.Can( Permission.Mute ) ) { PlayerOpException.ThrowPermissionMissing( player, this, "mute", Permission.Mute ); } // Check if player has sufficient rank permissions - if( !player.Can( Permission.Mute, Rank ) ) { + if ( !player.Can( Permission.Mute, Rank ) ) { PlayerOpException.ThrowPermissionLimit( player, this, "mute", Permission.Mute ); } // Check if target is already muted for longer DateTime newMutedUntil = DateTime.UtcNow.Add( duration ); - if( newMutedUntil > MutedUntil ) { - + if ( newMutedUntil > MutedUntil ) { // raise PlayerInfo.MuteChanging event - if( raiseEvents ) { - if( RaiseMuteChangingEvent( this, player, duration, false, announce ) ) { + if ( raiseEvents ) { + if ( RaiseMuteChangingEvent( this, player, duration, false, announce ) ) { PlayerOpException.ThrowCancelled( player, this ); } } @@ -964,7 +980,7 @@ public void Mute( [NotNull] Player player, TimeSpan duration, bool announce, boo LastModified = DateTime.UtcNow; // raise PlayerInfo.MuteChanged event - if( raiseEvents ) { + if ( raiseEvents ) { RaiseMuteChangedEvent( this, player, duration, false, announce ); } @@ -972,9 +988,9 @@ public void Mute( [NotNull] Player player, TimeSpan duration, bool announce, boo Logger.Log( LogType.UserActivity, "Player {0} was muted by {1} for {2}", Name, player.Name, duration ); - if( announce ) { + if ( announce ) { Player target = PlayerObject; - if( target != null ) { + if ( target != null ) { target.Message( "You were muted by {0}&S for {1}", player.ClassyName, duration.ToMiniString() ); } @@ -982,7 +998,6 @@ public void Mute( [NotNull] Player player, TimeSpan duration, bool announce, boo "&SPlayer {0}&S was muted by {1}&S for {2}", ClassyName, player.ClassyName, duration.ToMiniString() ); } - } else { // no action needed - already muted for same or longer duration string msg = String.Format( "Player {0} was already muted by {1} ({2} left)", @@ -996,40 +1011,39 @@ public void Mute( [NotNull] Player player, TimeSpan duration, bool announce, boo } } - /// Unmutes this player (allows them to write chat again). /// Player who is doing the unmuting. /// Whether to announce unmuting publicly on the sever. /// Whether to raise PlayerInfo.MuteChanging and MuteChanged events. public void Unmute( [NotNull] Player player, bool announce, bool raiseEvents ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); // Check if player is trying to unmute self - if( player.Info == this ) { + if ( player.Info == this ) { PlayerOpException.ThrowCannotTargetSelf( player, this, "unmute" ); } - lock( actionLock ) { + lock ( actionLock ) { TimeSpan timeLeft = TimeMutedLeft; // Check if player can unmute in general - if( !player.Can( Permission.Mute ) ) { + if ( !player.Can( Permission.Mute ) ) { PlayerOpException.ThrowPermissionMissing( player, this, "unmute", Permission.Mute ); } // Check if player has sufficient rank permissions - if (!player.Can(Permission.Mute, Rank)) - { - PlayerOpException.ThrowPermissionLimit(player, this, "mute", Permission.Mute); + if ( !player.Can( Permission.Mute, Rank ) ) { + PlayerOpException.ThrowPermissionLimit( player, this, "mute", Permission.Mute ); } - if( timeLeft <= TimeSpan.Zero ) { + if ( timeLeft <= TimeSpan.Zero ) { string msg = String.Format( "Player {0} is not currently muted.", Name ); string msgColor = String.Format( "&SPlayer {0}&S is not currently muted.", ClassyName ); throw new PlayerOpException( player, this, PlayerOpExceptionCode.NoActionNeeded, msg, msgColor ); } // raise PlayerInfo.MuteChanging event - if( raiseEvents ) { - if( RaiseMuteChangingEvent( this, player, timeLeft, true, announce ) ) { + if ( raiseEvents ) { + if ( RaiseMuteChangingEvent( this, player, timeLeft, true, announce ) ) { PlayerOpException.ThrowCancelled( player, this ); } } @@ -1037,7 +1051,7 @@ public void Unmute( [NotNull] Player player, bool announce, bool raiseEvents ) { Unmute(); // raise PlayerInfo.MuteChanged event - if( raiseEvents ) { + if ( raiseEvents ) { RaiseMuteChangedEvent( this, player, timeLeft, true, announce ); } @@ -1045,9 +1059,9 @@ public void Unmute( [NotNull] Player player, bool announce, bool raiseEvents ) { Logger.Log( LogType.UserActivity, "Player {0} was unmuted by {1} ({2} was left on the mute)", Name, player.Name, timeLeft ); - if( announce ) { + if ( announce ) { Player target = PlayerObject; - if( target != null ) { + if ( target != null ) { target.Message( "You were unmuted by {0}", player.ClassyName ); } Server.Message( target, @@ -1057,15 +1071,14 @@ public void Unmute( [NotNull] Player player, bool announce, bool raiseEvents ) { } } - internal void Unmute() { - lock( actionLock ) { + lock ( actionLock ) { MutedUntil = DateTime.MinValue; MutedBy = null; LastModified = DateTime.UtcNow; } } - #endregion + #endregion Mute / Unmute } } \ No newline at end of file diff --git a/fCraft/Player/PlayerInfo.Events.cs b/fCraft/Player/PlayerInfo.Events.cs index 719bc0e..9484cb4 100644 --- a/fCraft/Player/PlayerInfo.Events.cs +++ b/fCraft/Player/PlayerInfo.Events.cs @@ -5,6 +5,7 @@ using JetBrains.Annotations; namespace fCraft { + sealed partial class PlayerInfo { /// Occurs when a new PlayerDB entry is being created. @@ -38,88 +39,92 @@ sealed partial class PlayerInfo { /// Occurs after a player has been muted or unmuted. public static event EventHandler MuteChanged; - internal static void RaiseCreatingEvent( [NotNull] PlayerInfoCreatingEventArgs e ) { var h = Creating; - if( h != null ) h( null, e ); + if ( h != null ) + h( null, e ); } - internal static void RaiseCreatedEvent( [NotNull] PlayerInfo info, bool isUnrecognized ) { var h = Created; - if( h != null ) h( null, new PlayerInfoCreatedEventArgs( info, isUnrecognized ) ); + if ( h != null ) + h( null, new PlayerInfoCreatedEventArgs( info, isUnrecognized ) ); } - - static bool RaiseRankChangingEvent( [NotNull] PlayerInfo playerInfo, [NotNull] Player rankChanger, [NotNull] Rank newRank, + private static bool RaiseRankChangingEvent( [NotNull] PlayerInfo playerInfo, [NotNull] Player rankChanger, [NotNull] Rank newRank, [CanBeNull] string reason, RankChangeType rankChangeType, bool announce ) { var h = RankChanging; - if( h == null ) return false; + if ( h == null ) + return false; var e = new PlayerInfoRankChangingEventArgs( playerInfo, rankChanger, newRank, reason, rankChangeType, announce ); h( null, e ); return e.Cancel; } - - static void RaiseRankChangedEvent( [NotNull] PlayerInfo playerInfo, [NotNull] Player rankChanger, [NotNull] Rank oldRank, + private static void RaiseRankChangedEvent( [NotNull] PlayerInfo playerInfo, [NotNull] Player rankChanger, [NotNull] Rank oldRank, [CanBeNull] string reason, RankChangeType rankChangeType, bool announce ) { var h = RankChanged; - if( h != null ) h( null, new PlayerInfoRankChangedEventArgs( playerInfo, rankChanger, oldRank, reason, rankChangeType, announce ) ); + if ( h != null ) + h( null, new PlayerInfoRankChangedEventArgs( playerInfo, rankChanger, oldRank, reason, rankChangeType, announce ) ); } - internal static void RaiseBanChangingEvent( [NotNull] PlayerInfoBanChangingEventArgs e ) { - if( e == null ) throw new ArgumentNullException( "e" ); + if ( e == null ) + throw new ArgumentNullException( "e" ); var h = BanChanging; - if( h != null ) h( null, e ); + if ( h != null ) + h( null, e ); } - internal static void RaiseBanChangedEvent( [NotNull] PlayerInfoBanChangingEventArgs e ) { - if( e == null ) throw new ArgumentNullException( "e" ); + if ( e == null ) + throw new ArgumentNullException( "e" ); var h = BanChanged; - if( h != null ) h( null, new PlayerInfoBanChangedEventArgs( e.PlayerInfo, e.Banner, e.IsBeingUnbanned, e.Reason, e.Announce ) ); + if ( h != null ) + h( null, new PlayerInfoBanChangedEventArgs( e.PlayerInfo, e.Banner, e.IsBeingUnbanned, e.Reason, e.Announce ) ); } - - static bool RaiseFreezeChangingEvent( [NotNull] PlayerInfo target, [NotNull] Player freezer, bool unfreezing, bool announce ) { + private static bool RaiseFreezeChangingEvent( [NotNull] PlayerInfo target, [NotNull] Player freezer, bool unfreezing, bool announce ) { var h = FreezeChanging; - if( h == null ) return false; + if ( h == null ) + return false; var e = new PlayerInfoFrozenChangingEventArgs( target, freezer, unfreezing, announce ); h( null, e ); return e.Cancel; } - - static void RaiseFreezeChangedEvent( [NotNull] PlayerInfo target, [NotNull] Player freezer, bool unfreezing, bool announce ) { + private static void RaiseFreezeChangedEvent( [NotNull] PlayerInfo target, [NotNull] Player freezer, bool unfreezing, bool announce ) { var h = FreezeChanged; - if( h != null ) h( null, new PlayerInfoFrozenChangedEventArgs( target, freezer, unfreezing, announce ) ); + if ( h != null ) + h( null, new PlayerInfoFrozenChangedEventArgs( target, freezer, unfreezing, announce ) ); } - - static bool RaiseMuteChangingEvent( [NotNull] PlayerInfo target, [NotNull] Player muter, + private static bool RaiseMuteChangingEvent( [NotNull] PlayerInfo target, [NotNull] Player muter, TimeSpan duration, bool unmuting, bool announce ) { var h = MuteChanging; - if( h == null ) return false; + if ( h == null ) + return false; var e = new PlayerInfoMuteChangingEventArgs( target, muter, duration, unmuting, announce ); h( null, e ); return !e.Cancel; } - - static void RaiseMuteChangedEvent( [NotNull] PlayerInfo target, [NotNull] Player muter, + private static void RaiseMuteChangedEvent( [NotNull] PlayerInfo target, [NotNull] Player muter, TimeSpan duration, bool unmuting, bool announce ) { var h = MuteChanged; - if( h != null ) h( null, new PlayerInfoMuteChangedEventArgs( target, muter, duration, unmuting, announce ) ); + if ( h != null ) + h( null, new PlayerInfoMuteChangedEventArgs( target, muter, duration, unmuting, announce ) ); } } } - namespace fCraft.Events { + public class PlayerInfoEventArgs : EventArgs { + protected PlayerInfoEventArgs( [NotNull] PlayerInfo playerInfo ) { - if( playerInfo == null ) throw new ArgumentNullException( "playerInfo" ); + if ( playerInfo == null ) + throw new ArgumentNullException( "playerInfo" ); PlayerInfo = playerInfo; } @@ -127,12 +132,14 @@ protected PlayerInfoEventArgs( [NotNull] PlayerInfo playerInfo ) { public PlayerInfo PlayerInfo { get; private set; } } - public sealed class PlayerInfoCreatingEventArgs : EventArgs, ICancellableEvent { + internal PlayerInfoCreatingEventArgs( [NotNull] string name, [CanBeNull] IPAddress ip, [NotNull] Rank startingRank, bool isUnrecognized ) { - if( name == null ) throw new ArgumentNullException( "name" ); - if( startingRank == null ) throw new ArgumentNullException( "startingRank" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( startingRank == null ) + throw new ArgumentNullException( "startingRank" ); Name = name; StartingRank = startingRank; IP = ip; @@ -147,12 +154,14 @@ internal PlayerInfoCreatingEventArgs( [NotNull] string name, [CanBeNull] IPAddre [CanBeNull] public IPAddress IP { get; private set; } + public bool IsUnrecognized { get; private set; } + public bool Cancel { get; set; } } - public sealed class PlayerInfoCreatedEventArgs : PlayerInfoEventArgs { + internal PlayerInfoCreatedEventArgs( [NotNull] PlayerInfo playerInfo, bool isUnrecognized ) : base( playerInfo ) { IsUnrecognized = isUnrecognized; @@ -161,14 +170,16 @@ internal PlayerInfoCreatedEventArgs( [NotNull] PlayerInfo playerInfo, bool isUnr public bool IsUnrecognized { get; private set; } } - public class PlayerInfoRankChangedEventArgs : PlayerInfoEventArgs { + internal PlayerInfoRankChangedEventArgs( [NotNull] PlayerInfo playerInfo, [NotNull] Player rankChanger, [NotNull] Rank oldRank, [CanBeNull] string reason, RankChangeType rankChangeType, bool announce ) : base( playerInfo ) { - if( rankChanger == null ) throw new ArgumentNullException( "rankChanger" ); - if( oldRank == null ) throw new ArgumentNullException( "oldRank" ); + if ( rankChanger == null ) + throw new ArgumentNullException( "rankChanger" ); + if ( oldRank == null ) + throw new ArgumentNullException( "oldRank" ); RankChanger = rankChanger; OldRank = oldRank; NewRank = playerInfo.Rank; @@ -186,7 +197,7 @@ internal PlayerInfoRankChangedEventArgs( [NotNull] PlayerInfo playerInfo, [NotNu [NotNull] public Rank NewRank { get; protected set; } - [CanBeNull] + [CanBeNull] public string Reason { get; private set; } public bool Announce { get; private set; } @@ -194,8 +205,8 @@ internal PlayerInfoRankChangedEventArgs( [NotNull] PlayerInfo playerInfo, [NotNu public RankChangeType RankChangeType { get; private set; } } - public sealed class PlayerInfoRankChangingEventArgs : PlayerInfoRankChangedEventArgs, ICancellableEvent { + internal PlayerInfoRankChangingEventArgs( [NotNull] PlayerInfo playerInfo, [NotNull] Player rankChanger, [NotNull] Rank newRank, [CanBeNull] string reason, RankChangeType rankChangeType, bool announce ) @@ -206,12 +217,13 @@ internal PlayerInfoRankChangingEventArgs( [NotNull] PlayerInfo playerInfo, [NotN public bool Cancel { get; set; } } - public sealed class PlayerInfoBanChangedEventArgs : PlayerInfoEventArgs { + internal PlayerInfoBanChangedEventArgs( [NotNull] PlayerInfo target, [NotNull] Player banner, bool isBeingUnbanned, string reason, bool announce ) : base( target ) { - if( banner == null ) throw new ArgumentNullException( "banner" ); + if ( banner == null ) + throw new ArgumentNullException( "banner" ); Banner = banner; IsBeingUnbanned = isBeingUnbanned; Reason = reason; @@ -220,13 +232,16 @@ internal PlayerInfoBanChangedEventArgs( [NotNull] PlayerInfo target, [NotNull] P [NotNull] public Player Banner { get; private set; } + public bool IsBeingUnbanned { get; private set; } + public bool Announce { get; private set; } + public string Reason { get; private set; } } - public sealed class PlayerInfoBanChangingEventArgs : PlayerInfoEventArgs, ICancellableEvent { + internal PlayerInfoBanChangingEventArgs( [NotNull] PlayerInfo target, [NotNull] Player banner, bool isBeingUnbanned, [CanBeNull] string reason, bool announce ) : base( target ) { @@ -238,15 +253,19 @@ internal PlayerInfoBanChangingEventArgs( [NotNull] PlayerInfo target, [NotNull] [NotNull] public Player Banner { get; private set; } + public bool IsBeingUnbanned { get; private set; } + [CanBeNull] public string Reason { get; set; } + public bool Announce { get; private set; } + public bool Cancel { get; set; } } - public sealed class PlayerInfoFrozenChangingEventArgs : PlayerInfoFrozenChangedEventArgs, ICancellableEvent { + internal PlayerInfoFrozenChangingEventArgs( [NotNull] PlayerInfo target, [NotNull] Player freezer, bool unfreezing, bool announce ) : base( target, freezer, unfreezing, announce ) { } @@ -254,11 +273,12 @@ internal PlayerInfoFrozenChangingEventArgs( [NotNull] PlayerInfo target, [NotNul public bool Cancel { get; set; } } - public class PlayerInfoFrozenChangedEventArgs : PlayerInfoEventArgs { + internal PlayerInfoFrozenChangedEventArgs( [NotNull] PlayerInfo target, [NotNull] Player freezer, bool unfreezing, bool announce ) : base( target ) { - if( freezer == null ) throw new ArgumentNullException( "freezer" ); + if ( freezer == null ) + throw new ArgumentNullException( "freezer" ); Freezer = freezer; Unfreezing = unfreezing; Announce = announce; @@ -266,36 +286,42 @@ internal PlayerInfoFrozenChangedEventArgs( [NotNull] PlayerInfo target, [NotNull [NotNull] public Player Freezer { get; private set; } + public bool Unfreezing { get; private set; } + public bool Announce { get; private set; } } - public sealed class PlayerInfoMuteChangingEventArgs : PlayerInfoMuteChangedEventArgs, ICancellableEvent { + internal PlayerInfoMuteChangingEventArgs( [NotNull] PlayerInfo target, [NotNull] Player muter, TimeSpan duration, bool unmuting, bool announce ) : base( target, muter, duration, unmuting, announce ) { } + public bool Cancel { get; set; } } - public class PlayerInfoMuteChangedEventArgs : PlayerInfoEventArgs { + internal PlayerInfoMuteChangedEventArgs( [NotNull] PlayerInfo target, [NotNull] Player muter, TimeSpan duration, bool unmuting, bool announce ) : base( target ) { - if( muter == null ) throw new ArgumentNullException( "muter" ); + if ( muter == null ) + throw new ArgumentNullException( "muter" ); Muter = muter; Duration = duration; Unmuting = unmuting; Announce = announce; } - [NotNull] public Player Muter { get; private set; } + public TimeSpan Duration { get; private set; } + public bool Unmuting { get; private set; } + public bool Announce { get; private set; } } } \ No newline at end of file diff --git a/fCraft/Player/PlayerInfo.cs b/fCraft/Player/PlayerInfo.cs index a77f7b4..686d551 100644 --- a/fCraft/Player/PlayerInfo.cs +++ b/fCraft/Player/PlayerInfo.cs @@ -1,13 +1,14 @@ // Copyright 2009-2013 Matvei Stefarov using System; using System.Collections.Generic; +using System.IO; using System.Net; using System.Text; using System.Threading; using JetBrains.Annotations; -using System.IO; namespace fCraft { + /// Object representing persistent state ("record") of a player, online or offline. /// There is exactly one PlayerInfo object for each known Minecraft account. All data is stored in the PlayerDB. public sealed partial class PlayerInfo : IClassy { @@ -47,7 +48,7 @@ public sealed partial class PlayerInfo : IClassy { public int PromoCount; //dummy - + public int DummyID; public string DummyName; public Position DummyPos; @@ -59,20 +60,22 @@ public sealed partial class PlayerInfo : IClassy { //Games public bool ArrivedLate = false; + public bool InGame = false; //slap, kill public DateTime LastUsedSlap; + public DateTime LastUsedKill; public bool KillWait = false; //bromode public string oldname; + public bool changedName = false; public bool HasVoted = false; - #region Rank /// Player's current rank. @@ -106,8 +109,7 @@ public string RankChangedByClassy { /// Type of the most recent promotion/demotion. public RankChangeType RankChangeType; - #endregion - + #endregion Rank #region Bans @@ -140,52 +142,42 @@ public string BannedByClassy { public bool IsTempbanned; - public bool UnWarn() - { - if (IsWarned) - { + public bool UnWarn() { + if ( IsWarned ) { IsWarned = false; return true; - } - else - { + } else { return false; } } - public bool Warn(string by) - { - if (by == null) throw new ArgumentNullException("by"); - if (!IsWarned) - { + + public bool Warn( string by ) { + if ( by == null ) + throw new ArgumentNullException( "by" ); + if ( !IsWarned ) { IsWarned = true; WarnedOn = DateTime.UtcNow; WarnedBy = by; return true; - } - else - { + } else { return false; } } - public bool Tempban(string by, TimeSpan timespan) - { - if (by == null) throw new ArgumentNullException("by"); - if (timespan <= TimeSpan.Zero) - { - throw new ArgumentException("Tempban duration must be longer than 0", "timespan"); + public bool Tempban( string by, TimeSpan timespan ) { + if ( by == null ) + throw new ArgumentNullException( "by" ); + if ( timespan <= TimeSpan.Zero ) { + throw new ArgumentException( "Tempban duration must be longer than 0", "timespan" ); } - DateTime newBannedUntil = DateTime.UtcNow.Add(timespan); + DateTime newBannedUntil = DateTime.UtcNow.Add( timespan ); - if (newBannedUntil > BannedUntil) - { + if ( newBannedUntil > BannedUntil ) { BannedUntil = newBannedUntil; BannedBy = by; LastModified = DateTime.UtcNow; return true; - } - else - { + } else { return false; } } @@ -219,8 +211,7 @@ public string UnbannedByClassy { [NotNull] public IPAddress LastFailedLoginIP = IPAddress.None; - #endregion - + #endregion Bans #region Stats @@ -248,8 +239,7 @@ public string UnbannedByClassy { /// Number of bans issued by this player. public int TimesBannedOthers; - #endregion - + #endregion Stats #region Kicks @@ -275,8 +265,7 @@ public string LastKickByClassy { [CanBeNull] public string LastKickReason; - #endregion - + #endregion Kicks #region Freeze And Mute @@ -319,8 +308,7 @@ public string MutedByClassy { } } - #endregion - + #endregion Freeze And Mute /// Whether the player is currently online. /// Another way to check online status is to check if PlayerObject is null. @@ -340,14 +328,13 @@ public string MutedByClassy { [NotNull] public IPAddress LastIP; - #region Constructors and Serialization internal PlayerInfo( int id ) { ID = id; } - PlayerInfo() { + private PlayerInfo() { // reset everything to defaults LastIP = IPAddress.None; RankChangeDate = DateTime.MinValue; @@ -371,11 +358,13 @@ internal PlayerInfo( int id ) { public PlayerInfo( [NotNull] string name, [NotNull] Rank rank, bool setLoginDate, RankChangeType rankChangeType ) : this() { - if( name == null ) throw new ArgumentNullException( "name" ); - if( rank == null ) throw new ArgumentNullException( "rank" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( rank == null ) + throw new ArgumentNullException( "rank" ); Name = name; Rank = rank; - if( setLoginDate ) { + if ( setLoginDate ) { FirstLoginDate = DateTime.UtcNow; LastLoginDate = FirstLoginDate; LastSeen = FirstLoginDate; @@ -384,13 +373,15 @@ public PlayerInfo( [NotNull] string name, [NotNull] Rank rank, RankChangeType = rankChangeType; } - // generate blank info for a new player public PlayerInfo( [NotNull] string name, [NotNull] IPAddress lastIP, [NotNull] Rank startingRank ) : this() { - if( name == null ) throw new ArgumentNullException( "name" ); - if( lastIP == null ) throw new ArgumentNullException( "lastIP" ); - if( startingRank == null ) throw new ArgumentNullException( "startingRank" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( lastIP == null ) + throw new ArgumentNullException( "lastIP" ); + if ( startingRank == null ) + throw new ArgumentNullException( "startingRank" ); FirstLoginDate = DateTime.UtcNow; LastSeen = DateTime.UtcNow; LastLoginDate = DateTime.UtcNow; @@ -400,50 +391,56 @@ public PlayerInfo( [NotNull] string name, [NotNull] IPAddress lastIP, [NotNull] LastIP = lastIP; } - #endregion - + #endregion Constructors and Serialization #region Loading internal static PlayerInfo LoadFormat2( string[] fields ) { PlayerInfo info = new PlayerInfo { Name = fields[0] }; - if( fields[1].Length == 0 || !IPAddress.TryParse( fields[1], out info.LastIP ) ) { + if ( fields[1].Length == 0 || !IPAddress.TryParse( fields[1], out info.LastIP ) ) { info.LastIP = IPAddress.None; } info.Rank = Rank.Parse( fields[2] ) ?? RankManager.DefaultRank; fields[3].ToDateTime( ref info.RankChangeDate ); - if( fields[4].Length > 0 ) info.RankChangedBy = fields[4]; + if ( fields[4].Length > 0 ) + info.RankChangedBy = fields[4]; - switch( fields[5] ) { + switch ( fields[5] ) { case "b": info.BanStatus = BanStatus.Banned; break; + case "x": info.BanStatus = BanStatus.IPBanExempt; break; + default: info.BanStatus = BanStatus.NotBanned; break; } // ban information - if( fields[6].ToDateTime( ref info.BanDate ) ) { - if( fields[7].Length > 0 ) info.BannedBy = Unescape( fields[7] ); - if( fields[10].Length > 0 ) info.BanReason = Unescape( fields[10] ); + if ( fields[6].ToDateTime( ref info.BanDate ) ) { + if ( fields[7].Length > 0 ) + info.BannedBy = Unescape( fields[7] ); + if ( fields[10].Length > 0 ) + info.BanReason = Unescape( fields[10] ); } // unban information - if( fields[8].ToDateTime( ref info.UnbanDate ) ) { - if( fields[9].Length > 0 ) info.UnbannedBy = Unescape( fields[9] ); - if( fields[11].Length > 0 ) info.UnbanReason = Unescape( fields[11] ); + if ( fields[8].ToDateTime( ref info.UnbanDate ) ) { + if ( fields[9].Length > 0 ) + info.UnbannedBy = Unescape( fields[9] ); + if ( fields[11].Length > 0 ) + info.UnbanReason = Unescape( fields[11] ); } // failed logins fields[12].ToDateTime( ref info.LastFailedLoginDate ); - if( fields[13].Length > 1 || !IPAddress.TryParse( fields[13], out info.LastFailedLoginIP ) ) { // LEGACY + if ( fields[13].Length > 1 || !IPAddress.TryParse( fields[13], out info.LastFailedLoginIP ) ) { // LEGACY info.LastFailedLoginIP = IPAddress.None; } // 14 is now mojang account @@ -458,28 +455,34 @@ internal static PlayerInfo LoadFormat2( string[] fields ) { fields[17].ToTimeSpan( out info.TotalTime ); // stats - if( fields[18].Length > 0 ) Int32.TryParse( fields[18], out info.BlocksBuilt ); - if( fields[19].Length > 0 ) Int32.TryParse( fields[19], out info.BlocksDeleted ); + if ( fields[18].Length > 0 ) + Int32.TryParse( fields[18], out info.BlocksBuilt ); + if ( fields[19].Length > 0 ) + Int32.TryParse( fields[19], out info.BlocksDeleted ); Int32.TryParse( fields[20], out info.TimesVisited ); - if( fields[20].Length > 0 ) Int32.TryParse( fields[21], out info.MessagesWritten ); + if ( fields[20].Length > 0 ) + Int32.TryParse( fields[21], out info.MessagesWritten ); // field 23 are no longer in use - Int32.TryParse(fields[22], out info.PromoCount); //promocount - if (fields[23].Length > 0) info.TitleName = fields[23].ToString(); //titlename - - if( fields[24].Length > 0 ) info.PreviousRank = Rank.Parse( fields[24] ); - if( fields[25].Length > 0 ) info.RankChangeReason = Unescape( fields[25] ); + Int32.TryParse( fields[22], out info.PromoCount ); //promocount + if ( fields[23].Length > 0 ) + info.TitleName = fields[23].ToString(); //titlename + + if ( fields[24].Length > 0 ) + info.PreviousRank = Rank.Parse( fields[24] ); + if ( fields[25].Length > 0 ) + info.RankChangeReason = Unescape( fields[25] ); Int32.TryParse( fields[26], out info.TimesKicked ); Int32.TryParse( fields[27], out info.TimesKickedOthers ); Int32.TryParse( fields[28], out info.TimesBannedOthers ); info.ID = Int32.Parse( fields[29] ); - if( info.ID < 256 ) + if ( info.ID < 256 ) info.ID = PlayerDB.GetNextID(); byte rankChangeTypeCode; - if( Byte.TryParse( fields[30], out rankChangeTypeCode ) ) { - info.RankChangeType = (RankChangeType)rankChangeTypeCode; - if( !Enum.IsDefined( typeof( RankChangeType ), rankChangeTypeCode ) ) { + if ( Byte.TryParse( fields[30], out rankChangeTypeCode ) ) { + info.RankChangeType = ( RankChangeType )rankChangeTypeCode; + if ( !Enum.IsDefined( typeof( RankChangeType ), rankChangeTypeCode ) ) { info.GuessRankChangeType(); } } else { @@ -487,96 +490,106 @@ internal static PlayerInfo LoadFormat2( string[] fields ) { } fields[31].ToDateTime( ref info.LastKickDate ); - if( !fields[32].ToDateTime( ref info.LastSeen ) || info.LastSeen < info.LastLoginDate ) { + if ( !fields[32].ToDateTime( ref info.LastSeen ) || info.LastSeen < info.LastLoginDate ) { info.LastSeen = info.LastLoginDate; } Int64.TryParse( fields[33], out info.BlocksDrawn ); - if( fields[34].Length > 0 ) info.LastKickBy = Unescape( fields[34] ); - if( fields[35].Length > 0 ) info.LastKickReason = Unescape( fields[35] ); + if ( fields[34].Length > 0 ) + info.LastKickBy = Unescape( fields[34] ); + if ( fields[35].Length > 0 ) + info.LastKickReason = Unescape( fields[35] ); fields[36].ToDateTime( ref info.BannedUntil ); - info.IsFrozen = (fields[37] == "f"); - if( fields[38].Length > 0 ) info.FrozenBy = Unescape( fields[38] ); + info.IsFrozen = ( fields[37] == "f" ); + if ( fields[38].Length > 0 ) + info.FrozenBy = Unescape( fields[38] ); fields[39].ToDateTime( ref info.FrozenOn ); fields[40].ToDateTime( ref info.MutedUntil ); - if( fields[41].Length > 0 ) info.MutedBy = Unescape( fields[41] ); + if ( fields[41].Length > 0 ) + info.MutedBy = Unescape( fields[41] ); info.Password = Unescape( fields[42] ); // fields[43] is "online", and is ignored byte bandwidthUseModeCode; - if( Byte.TryParse( fields[44], out bandwidthUseModeCode ) ) { - info.BandwidthUseMode = (BandwidthUseMode)bandwidthUseModeCode; - if( !Enum.IsDefined( typeof( BandwidthUseMode ), bandwidthUseModeCode ) ) { + if ( Byte.TryParse( fields[44], out bandwidthUseModeCode ) ) { + info.BandwidthUseMode = ( BandwidthUseMode )bandwidthUseModeCode; + if ( !Enum.IsDefined( typeof( BandwidthUseMode ), bandwidthUseModeCode ) ) { info.BandwidthUseMode = BandwidthUseMode.Default; } } else { info.BandwidthUseMode = BandwidthUseMode.Default; } - if( fields.Length > 45 ) { - if( fields[45].Length == 0 ) { + if ( fields.Length > 45 ) { + if ( fields[45].Length == 0 ) { info.IsHidden = false; } else { info.IsHidden = info.Rank.Can( Permission.Hide ); } } - if( fields.Length > 46 ) { + if ( fields.Length > 46 ) { fields[46].ToDateTime( ref info.LastModified ); } - if( fields.Length > 47 && fields[47].Length > 0 ) { + if ( fields.Length > 47 && fields[47].Length > 0 ) { info.DisplayedName = Unescape( fields[47] ); } - if( info.LastSeen < info.FirstLoginDate ) { + if ( info.LastSeen < info.FirstLoginDate ) { info.LastSeen = info.FirstLoginDate; } - if( info.LastLoginDate < info.FirstLoginDate ) { + if ( info.LastLoginDate < info.FirstLoginDate ) { info.LastLoginDate = info.FirstLoginDate; } return info; } - internal static PlayerInfo LoadFormat1( string[] fields ) { PlayerInfo info = new PlayerInfo { Name = fields[0] }; - if( fields[1].Length == 0 || !IPAddress.TryParse( fields[1], out info.LastIP ) ) { + if ( fields[1].Length == 0 || !IPAddress.TryParse( fields[1], out info.LastIP ) ) { info.LastIP = IPAddress.None; } info.Rank = Rank.Parse( fields[2] ) ?? RankManager.DefaultRank; fields[3].ToDateTimeLegacy( ref info.RankChangeDate ); - if( fields[4].Length > 0 ) info.RankChangedBy = fields[4]; + if ( fields[4].Length > 0 ) + info.RankChangedBy = fields[4]; - switch( fields[5] ) { + switch ( fields[5] ) { case "b": info.BanStatus = BanStatus.Banned; break; + case "x": info.BanStatus = BanStatus.IPBanExempt; break; + default: info.BanStatus = BanStatus.NotBanned; break; } // ban information - if( fields[6].ToDateTimeLegacy( ref info.BanDate ) ) { - if( fields[7].Length > 0 ) info.BannedBy = Unescape( fields[7] ); - if( fields[10].Length > 0 ) info.BanReason = Unescape( fields[10] ); + if ( fields[6].ToDateTimeLegacy( ref info.BanDate ) ) { + if ( fields[7].Length > 0 ) + info.BannedBy = Unescape( fields[7] ); + if ( fields[10].Length > 0 ) + info.BanReason = Unescape( fields[10] ); } // unban information - if( fields[8].ToDateTimeLegacy( ref info.UnbanDate ) ) { - if( fields[9].Length > 0 ) info.UnbannedBy = Unescape( fields[9] ); - if( fields[11].Length > 0 ) info.UnbanReason = Unescape( fields[11] ); + if ( fields[8].ToDateTimeLegacy( ref info.UnbanDate ) ) { + if ( fields[9].Length > 0 ) + info.UnbannedBy = Unescape( fields[9] ); + if ( fields[11].Length > 0 ) + info.UnbanReason = Unescape( fields[11] ); } // failed logins fields[12].ToDateTimeLegacy( ref info.LastFailedLoginDate ); - if( fields[13].Length > 1 || !IPAddress.TryParse( fields[13], out info.LastFailedLoginIP ) ) { // LEGACY + if ( fields[13].Length > 1 || !IPAddress.TryParse( fields[13], out info.LastFailedLoginIP ) ) { // LEGACY info.LastFailedLoginIP = IPAddress.None; } // skip 14 @@ -587,26 +600,31 @@ internal static PlayerInfo LoadFormat1( string[] fields ) { fields[17].ToTimeSpanLegacy( ref info.TotalTime ); // stats - if( fields[18].Length > 0 ) Int32.TryParse( fields[18], out info.BlocksBuilt ); - if( fields[19].Length > 0 ) Int32.TryParse( fields[19], out info.BlocksDeleted ); + if ( fields[18].Length > 0 ) + Int32.TryParse( fields[18], out info.BlocksBuilt ); + if ( fields[19].Length > 0 ) + Int32.TryParse( fields[19], out info.BlocksDeleted ); Int32.TryParse( fields[20], out info.TimesVisited ); - if( fields[20].Length > 0 ) Int32.TryParse( fields[21], out info.MessagesWritten ); + if ( fields[20].Length > 0 ) + Int32.TryParse( fields[21], out info.MessagesWritten ); // fields 22-23 are no longer in use - if( fields[24].Length > 0 ) info.PreviousRank = Rank.Parse( fields[24] ); - if( fields[25].Length > 0 ) info.RankChangeReason = Unescape( fields[25] ); + if ( fields[24].Length > 0 ) + info.PreviousRank = Rank.Parse( fields[24] ); + if ( fields[25].Length > 0 ) + info.RankChangeReason = Unescape( fields[25] ); Int32.TryParse( fields[26], out info.TimesKicked ); Int32.TryParse( fields[27], out info.TimesKickedOthers ); Int32.TryParse( fields[28], out info.TimesBannedOthers ); info.ID = Int32.Parse( fields[29] ); - if( info.ID < 256 ) + if ( info.ID < 256 ) info.ID = PlayerDB.GetNextID(); byte rankChangeTypeCode; - if( Byte.TryParse( fields[30], out rankChangeTypeCode ) ) { - info.RankChangeType = (RankChangeType)rankChangeTypeCode; - if( !Enum.IsDefined( typeof( RankChangeType ), rankChangeTypeCode ) ) { + if ( Byte.TryParse( fields[30], out rankChangeTypeCode ) ) { + info.RankChangeType = ( RankChangeType )rankChangeTypeCode; + if ( !Enum.IsDefined( typeof( RankChangeType ), rankChangeTypeCode ) ) { info.GuessRankChangeType(); } } else { @@ -614,101 +632,111 @@ internal static PlayerInfo LoadFormat1( string[] fields ) { } fields[31].ToDateTimeLegacy( ref info.LastKickDate ); - if( !fields[32].ToDateTimeLegacy( ref info.LastSeen ) || info.LastSeen < info.LastLoginDate ) { + if ( !fields[32].ToDateTimeLegacy( ref info.LastSeen ) || info.LastSeen < info.LastLoginDate ) { info.LastSeen = info.LastLoginDate; } Int64.TryParse( fields[33], out info.BlocksDrawn ); - if( fields[34].Length > 0 ) info.LastKickBy = Unescape( fields[34] ); - if( fields[34].Length > 0 ) info.LastKickReason = Unescape( fields[35] ); + if ( fields[34].Length > 0 ) + info.LastKickBy = Unescape( fields[34] ); + if ( fields[34].Length > 0 ) + info.LastKickReason = Unescape( fields[35] ); fields[36].ToDateTimeLegacy( ref info.BannedUntil ); - info.IsFrozen = (fields[37] == "f"); - if( fields[38].Length > 0 ) info.FrozenBy = Unescape( fields[38] ); + info.IsFrozen = ( fields[37] == "f" ); + if ( fields[38].Length > 0 ) + info.FrozenBy = Unescape( fields[38] ); fields[39].ToDateTimeLegacy( ref info.FrozenOn ); fields[40].ToDateTimeLegacy( ref info.MutedUntil ); - if( fields[41].Length > 0 ) info.MutedBy = Unescape( fields[41] ); + if ( fields[41].Length > 0 ) + info.MutedBy = Unescape( fields[41] ); info.Password = Unescape( fields[42] ); // fields[43] is "online", and is ignored byte bandwidthUseModeCode; - if( Byte.TryParse( fields[44], out bandwidthUseModeCode ) ) { - info.BandwidthUseMode = (BandwidthUseMode)bandwidthUseModeCode; - if( !Enum.IsDefined( typeof( BandwidthUseMode ), bandwidthUseModeCode ) ) { + if ( Byte.TryParse( fields[44], out bandwidthUseModeCode ) ) { + info.BandwidthUseMode = ( BandwidthUseMode )bandwidthUseModeCode; + if ( !Enum.IsDefined( typeof( BandwidthUseMode ), bandwidthUseModeCode ) ) { info.BandwidthUseMode = BandwidthUseMode.Default; } } else { info.BandwidthUseMode = BandwidthUseMode.Default; } - if( fields.Length > 45 ) { - if( fields[45].Length == 0 ) { + if ( fields.Length > 45 ) { + if ( fields[45].Length == 0 ) { info.IsHidden = false; } else { info.IsHidden = info.Rank.Can( Permission.Hide ); } } - if( info.LastSeen < info.FirstLoginDate ) { + if ( info.LastSeen < info.FirstLoginDate ) { info.LastSeen = info.FirstLoginDate; } - if( info.LastLoginDate < info.FirstLoginDate ) { + if ( info.LastLoginDate < info.FirstLoginDate ) { info.LastLoginDate = info.FirstLoginDate; } return info; } - internal static PlayerInfo LoadFormat0( string[] fields, bool convertDatesToUtc ) { PlayerInfo info = new PlayerInfo { Name = fields[0] }; - if( fields[1].Length == 0 || !IPAddress.TryParse( fields[1], out info.LastIP ) ) { + if ( fields[1].Length == 0 || !IPAddress.TryParse( fields[1], out info.LastIP ) ) { info.LastIP = IPAddress.None; } info.Rank = Rank.Parse( fields[2] ) ?? RankManager.DefaultRank; DateTimeUtil.TryParseLocalDate( fields[3], out info.RankChangeDate ); - if( fields[4].Length > 0 ) { + if ( fields[4].Length > 0 ) { info.RankChangedBy = fields[4]; - if( info.RankChangedBy == "-" ) info.RankChangedBy = null; + if ( info.RankChangedBy == "-" ) + info.RankChangedBy = null; } - switch( fields[5] ) { + switch ( fields[5] ) { case "b": info.BanStatus = BanStatus.Banned; break; + case "x": info.BanStatus = BanStatus.IPBanExempt; break; + default: info.BanStatus = BanStatus.NotBanned; break; } // ban information - if( DateTimeUtil.TryParseLocalDate( fields[6], out info.BanDate ) ) { - if( fields[7].Length > 0 ) info.BannedBy = fields[7]; - if( fields[10].Length > 0 ) { + if ( DateTimeUtil.TryParseLocalDate( fields[6], out info.BanDate ) ) { + if ( fields[7].Length > 0 ) + info.BannedBy = fields[7]; + if ( fields[10].Length > 0 ) { info.BanReason = UnescapeOldFormat( fields[10] ); - if( info.BanReason == "-" ) info.BanReason = null; + if ( info.BanReason == "-" ) + info.BanReason = null; } } // unban information - if( DateTimeUtil.TryParseLocalDate( fields[8], out info.UnbanDate ) ) { - if( fields[9].Length > 0 ) info.UnbannedBy = fields[9]; - if( fields[11].Length > 0 ) { + if ( DateTimeUtil.TryParseLocalDate( fields[8], out info.UnbanDate ) ) { + if ( fields[9].Length > 0 ) + info.UnbannedBy = fields[9]; + if ( fields[11].Length > 0 ) { info.UnbanReason = UnescapeOldFormat( fields[11] ); - if( info.UnbanReason == "-" ) info.UnbanReason = null; + if ( info.UnbanReason == "-" ) + info.UnbanReason = null; } } // failed logins - if( fields[12].Length > 1 ) { + if ( fields[12].Length > 1 ) { DateTimeUtil.TryParseLocalDate( fields[12], out info.LastFailedLoginDate ); } - if( fields[13].Length > 1 || !IPAddress.TryParse( fields[13], out info.LastFailedLoginIP ) ) { // LEGACY + if ( fields[13].Length > 1 || !IPAddress.TryParse( fields[13], out info.LastFailedLoginIP ) ) { // LEGACY info.LastFailedLoginIP = IPAddress.None; } // skip 14 @@ -719,101 +747,119 @@ internal static PlayerInfo LoadFormat0( string[] fields, bool convertDatesToUtc TimeSpan.TryParse( fields[17], out info.TotalTime ); // stats - if( fields[18].Length > 0 ) Int32.TryParse( fields[18], out info.BlocksBuilt ); - if( fields[19].Length > 0 ) Int32.TryParse( fields[19], out info.BlocksDeleted ); + if ( fields[18].Length > 0 ) + Int32.TryParse( fields[18], out info.BlocksBuilt ); + if ( fields[19].Length > 0 ) + Int32.TryParse( fields[19], out info.BlocksDeleted ); Int32.TryParse( fields[20], out info.TimesVisited ); - if( fields[20].Length > 0 ) Int32.TryParse( fields[21], out info.MessagesWritten ); + if ( fields[20].Length > 0 ) + Int32.TryParse( fields[21], out info.MessagesWritten ); // fields 22-23 are no longer in use - if( fields.Length > MinFieldCount ) { - if( fields[24].Length > 0 ) info.PreviousRank = Rank.Parse( fields[24] ); - if( fields[25].Length > 0 ) info.RankChangeReason = UnescapeOldFormat( fields[25] ); + if ( fields.Length > MinFieldCount ) { + if ( fields[24].Length > 0 ) + info.PreviousRank = Rank.Parse( fields[24] ); + if ( fields[25].Length > 0 ) + info.RankChangeReason = UnescapeOldFormat( fields[25] ); Int32.TryParse( fields[26], out info.TimesKicked ); Int32.TryParse( fields[27], out info.TimesKickedOthers ); Int32.TryParse( fields[28], out info.TimesBannedOthers ); - if( fields.Length > 29 ) { + if ( fields.Length > 29 ) { info.ID = Int32.Parse( fields[29] ); - if( info.ID < 256 ) + if ( info.ID < 256 ) info.ID = PlayerDB.GetNextID(); byte rankChangeTypeCode; - if( Byte.TryParse( fields[30], out rankChangeTypeCode ) ) { - info.RankChangeType = (RankChangeType)rankChangeTypeCode; - if( !Enum.IsDefined( typeof( RankChangeType ), rankChangeTypeCode ) ) { + if ( Byte.TryParse( fields[30], out rankChangeTypeCode ) ) { + info.RankChangeType = ( RankChangeType )rankChangeTypeCode; + if ( !Enum.IsDefined( typeof( RankChangeType ), rankChangeTypeCode ) ) { info.GuessRankChangeType(); } } else { info.GuessRankChangeType(); } DateTimeUtil.TryParseLocalDate( fields[31], out info.LastKickDate ); - if( !DateTimeUtil.TryParseLocalDate( fields[32], out info.LastSeen ) || info.LastSeen < info.LastLoginDate ) { + if ( !DateTimeUtil.TryParseLocalDate( fields[32], out info.LastSeen ) || info.LastSeen < info.LastLoginDate ) { info.LastSeen = info.LastLoginDate; } Int64.TryParse( fields[33], out info.BlocksDrawn ); - if( fields[34].Length > 0 ) info.LastKickBy = UnescapeOldFormat( fields[34] ); - if( fields[35].Length > 0 ) info.LastKickReason = UnescapeOldFormat( fields[35] ); - + if ( fields[34].Length > 0 ) + info.LastKickBy = UnescapeOldFormat( fields[34] ); + if ( fields[35].Length > 0 ) + info.LastKickReason = UnescapeOldFormat( fields[35] ); } else { info.ID = PlayerDB.GetNextID(); info.GuessRankChangeType(); info.LastSeen = info.LastLoginDate; } - if( fields.Length > 36 ) { + if ( fields.Length > 36 ) { DateTimeUtil.TryParseLocalDate( fields[36], out info.BannedUntil ); - info.IsFrozen = (fields[37] == "f"); - if( fields[38].Length > 0 ) info.FrozenBy = UnescapeOldFormat( fields[38] ); + info.IsFrozen = ( fields[37] == "f" ); + if ( fields[38].Length > 0 ) + info.FrozenBy = UnescapeOldFormat( fields[38] ); DateTimeUtil.TryParseLocalDate( fields[39], out info.FrozenOn ); DateTimeUtil.TryParseLocalDate( fields[40], out info.MutedUntil ); - if( fields[41].Length > 0 ) info.MutedBy = UnescapeOldFormat( fields[41] ); + if ( fields[41].Length > 0 ) + info.MutedBy = UnescapeOldFormat( fields[41] ); info.Password = UnescapeOldFormat( fields[42] ); // fields[43] is "online", and is ignored } - if( fields.Length > 44 ) { - if( fields[44].Length != 0 ) { - info.BandwidthUseMode = (BandwidthUseMode)Int32.Parse( fields[44] ); + if ( fields.Length > 44 ) { + if ( fields[44].Length != 0 ) { + info.BandwidthUseMode = ( BandwidthUseMode )Int32.Parse( fields[44] ); } } } - if( info.LastSeen < info.FirstLoginDate ) { + if ( info.LastSeen < info.FirstLoginDate ) { info.LastSeen = info.FirstLoginDate; } - if( info.LastLoginDate < info.FirstLoginDate ) { + if ( info.LastLoginDate < info.FirstLoginDate ) { info.LastLoginDate = info.FirstLoginDate; } - if( convertDatesToUtc ) { - if( info.RankChangeDate != DateTime.MinValue ) info.RankChangeDate = info.RankChangeDate.ToUniversalTime(); - if( info.BanDate != DateTime.MinValue ) info.BanDate = info.BanDate.ToUniversalTime(); - if( info.UnbanDate != DateTime.MinValue ) info.UnbanDate = info.UnbanDate.ToUniversalTime(); - if( info.LastFailedLoginDate != DateTime.MinValue ) info.LastFailedLoginDate = info.LastFailedLoginDate.ToUniversalTime(); - if( info.FirstLoginDate != DateTime.MinValue ) info.FirstLoginDate = info.FirstLoginDate.ToUniversalTime(); - if( info.LastLoginDate != DateTime.MinValue ) info.LastLoginDate = info.LastLoginDate.ToUniversalTime(); - if( info.LastKickDate != DateTime.MinValue ) info.LastKickDate = info.LastKickDate.ToUniversalTime(); - if( info.LastSeen != DateTime.MinValue ) info.LastSeen = info.LastSeen.ToUniversalTime(); - if( info.BannedUntil != DateTime.MinValue ) info.BannedUntil = info.BannedUntil.ToUniversalTime(); - if( info.FrozenOn != DateTime.MinValue ) info.FrozenOn = info.FrozenOn.ToUniversalTime(); - if( info.MutedUntil != DateTime.MinValue ) info.MutedUntil = info.MutedUntil.ToUniversalTime(); + if ( convertDatesToUtc ) { + if ( info.RankChangeDate != DateTime.MinValue ) + info.RankChangeDate = info.RankChangeDate.ToUniversalTime(); + if ( info.BanDate != DateTime.MinValue ) + info.BanDate = info.BanDate.ToUniversalTime(); + if ( info.UnbanDate != DateTime.MinValue ) + info.UnbanDate = info.UnbanDate.ToUniversalTime(); + if ( info.LastFailedLoginDate != DateTime.MinValue ) + info.LastFailedLoginDate = info.LastFailedLoginDate.ToUniversalTime(); + if ( info.FirstLoginDate != DateTime.MinValue ) + info.FirstLoginDate = info.FirstLoginDate.ToUniversalTime(); + if ( info.LastLoginDate != DateTime.MinValue ) + info.LastLoginDate = info.LastLoginDate.ToUniversalTime(); + if ( info.LastKickDate != DateTime.MinValue ) + info.LastKickDate = info.LastKickDate.ToUniversalTime(); + if ( info.LastSeen != DateTime.MinValue ) + info.LastSeen = info.LastSeen.ToUniversalTime(); + if ( info.BannedUntil != DateTime.MinValue ) + info.BannedUntil = info.BannedUntil.ToUniversalTime(); + if ( info.FrozenOn != DateTime.MinValue ) + info.FrozenOn = info.FrozenOn.ToUniversalTime(); + if ( info.MutedUntil != DateTime.MinValue ) + info.MutedUntil = info.MutedUntil.ToUniversalTime(); } return info; } - - void GuessRankChangeType() { - if( PreviousRank != null ) { - if( RankChangeReason == "~AutoRank" || RankChangeReason == "~AutoRankAll" || RankChangeReason == "~MassRank" ) { - if( PreviousRank > Rank ) { + private void GuessRankChangeType() { + if ( PreviousRank != null ) { + if ( RankChangeReason == "~AutoRank" || RankChangeReason == "~AutoRankAll" || RankChangeReason == "~MassRank" ) { + if ( PreviousRank > Rank ) { RankChangeType = RankChangeType.AutoDemoted; - } else if( PreviousRank < Rank ) { + } else if ( PreviousRank < Rank ) { RankChangeType = RankChangeType.AutoPromoted; } } else { - if( PreviousRank > Rank ) { + if ( PreviousRank > Rank ) { RankChangeType = RankChangeType.Demoted; - } else if( PreviousRank < Rank ) { + } else if ( PreviousRank < Rank ) { RankChangeType = RankChangeType.Promoted; } } @@ -822,9 +868,9 @@ void GuessRankChangeType() { } } - internal static PlayerInfo LoadBinaryFormat0( [NotNull] BinaryReader reader ) { - if( reader == null ) throw new ArgumentNullException( "reader" ); + if ( reader == null ) + throw new ArgumentNullException( "reader" ); // ReSharper disable UseObjectOrCollectionInitializer PlayerInfo info = new PlayerInfo(); // ReSharper restore UseObjectOrCollectionInitializer @@ -837,27 +883,27 @@ internal static PlayerInfo LoadBinaryFormat0( [NotNull] BinaryReader reader ) { // Rank int rankIndex = Read7BitEncodedInt( reader ); - info.Rank = PlayerDB.GetRankByIndex(rankIndex); + info.Rank = PlayerDB.GetRankByIndex( rankIndex ); { bool hasPrevRank = reader.ReadBoolean(); - if( hasPrevRank ) { + if ( hasPrevRank ) { int prevRankIndex = Read7BitEncodedInt( reader ); info.Rank = PlayerDB.GetRankByIndex( prevRankIndex ); } } - info.RankChangeType = (RankChangeType)reader.ReadByte(); - if( info.RankChangeType != RankChangeType.Default ) { + info.RankChangeType = ( RankChangeType )reader.ReadByte(); + if ( info.RankChangeType != RankChangeType.Default ) { info.RankChangeDate = ReadDate( reader ); info.RankChangedBy = ReadString( reader ); info.RankChangeReason = ReadString( reader ); } // Bans - info.BanStatus = (BanStatus)reader.ReadByte(); + info.BanStatus = ( BanStatus )reader.ReadByte(); info.BanDate = ReadDate( reader ); info.BannedBy = ReadString( reader ); info.BanReason = ReadString( reader ); - if( info.BanStatus == BanStatus.Banned ) { + if ( info.BanStatus == BanStatus.Banned ) { info.BannedUntil = ReadDate( reader ); info.LastFailedLoginDate = ReadDate( reader ); info.LastFailedLoginIP = new IPAddress( reader.ReadBytes( 4 ) ); @@ -873,7 +919,7 @@ internal static PlayerInfo LoadBinaryFormat0( [NotNull] BinaryReader reader ) { info.TotalTime = new TimeSpan( reader.ReadUInt32() * TimeSpan.TicksPerSecond ); info.BlocksBuilt = Read7BitEncodedInt( reader ); info.BlocksDeleted = Read7BitEncodedInt( reader ); - if( reader.ReadBoolean() ) { + if ( reader.ReadBoolean() ) { info.BlocksDrawn = reader.ReadInt64(); } info.TimesVisited = Read7BitEncodedInt( reader ); @@ -883,7 +929,7 @@ internal static PlayerInfo LoadBinaryFormat0( [NotNull] BinaryReader reader ) { // Kicks info.TimesKicked = Read7BitEncodedInt( reader ); - if( info.TimesKicked > 0 ) { + if ( info.TimesKicked > 0 ) { info.LastKickDate = ReadDate( reader ); info.LastKickBy = ReadString( reader ); info.LastKickReason = ReadString( reader ); @@ -891,12 +937,12 @@ internal static PlayerInfo LoadBinaryFormat0( [NotNull] BinaryReader reader ) { // Freeze/Mute info.IsFrozen = reader.ReadBoolean(); - if( info.IsFrozen ) { + if ( info.IsFrozen ) { info.FrozenOn = ReadDate( reader ); info.FrozenBy = ReadString( reader ); } info.MutedUntil = ReadDate( reader ); - if( info.MutedUntil != DateTime.MinValue ) { + if ( info.MutedUntil != DateTime.MinValue ) { info.MutedBy = ReadString( reader ); } @@ -906,55 +952,52 @@ internal static PlayerInfo LoadBinaryFormat0( [NotNull] BinaryReader reader ) { info.IsOnline = reader.ReadBoolean(); info.IsHidden = reader.ReadBoolean(); info.LastIP = new IPAddress( reader.ReadBytes( 4 ) ); - info.LeaveReason = (LeaveReason)reader.ReadByte(); - info.BandwidthUseMode = (BandwidthUseMode)reader.ReadByte(); + info.LeaveReason = ( LeaveReason )reader.ReadByte(); + info.BandwidthUseMode = ( BandwidthUseMode )reader.ReadByte(); return info; } - - static DateTime ReadDate( [NotNull] BinaryReader reader ) { - if( reader.ReadBoolean() ) { + private static DateTime ReadDate( [NotNull] BinaryReader reader ) { + if ( reader.ReadBoolean() ) { return DateTimeUtil.ToDateTime( reader.ReadUInt32() ); } else { return DateTime.MinValue; } } - - static string ReadString( [NotNull] BinaryReader reader ) { - if( reader.ReadBoolean() ) { + private static string ReadString( [NotNull] BinaryReader reader ) { + if ( reader.ReadBoolean() ) { return reader.ReadString(); } else { return null; } } - - static int Read7BitEncodedInt( [NotNull] BinaryReader reader ) { + private static int Read7BitEncodedInt( [NotNull] BinaryReader reader ) { byte num3; int num = 0; int num2 = 0; do { - if( num2 == 0x23 ) { + if ( num2 == 0x23 ) { throw new FormatException( "Invalid 7bit encoded integer." ); } num3 = reader.ReadByte(); - num |= (num3 & 0x7f) << num2; + num |= ( num3 & 0x7f ) << num2; num2 += 7; } - while( (num3 & 0x80) != 0 ); + while ( ( num3 & 0x80 ) != 0 ); return num; } - #endregion - + #endregion Loading #region Saving internal void Serialize( StringBuilder sb ) { sb.Append( Name ).Append( ',' ); // 0 - if( !LastIP.Equals( IPAddress.None ) ) sb.Append( LastIP ); // 1 + if ( !LastIP.Equals( IPAddress.None ) ) + sb.Append( LastIP ); // 1 sb.Append( ',' ); sb.Append( Rank.FullName ).Append( ',' ); // 2 @@ -962,10 +1005,11 @@ internal void Serialize( StringBuilder sb ) { sb.AppendEscaped( RankChangedBy ).Append( ',' ); // 4 - switch( BanStatus ) { + switch ( BanStatus ) { case BanStatus.Banned: sb.Append( 'b' ); break; + case BanStatus.IPBanExempt: sb.Append( 'x' ); break; @@ -981,69 +1025,76 @@ internal void Serialize( StringBuilder sb ) { LastFailedLoginDate.ToUnixTimeString( sb ).Append( ',' ); // 12 - if( !LastFailedLoginIP.Equals( IPAddress.None ) ) sb.Append( LastFailedLoginIP.ToString() ); // 13 - sb.Append( ','); + if ( !LastFailedLoginIP.Equals( IPAddress.None ) ) + sb.Append( LastFailedLoginIP.ToString() ); // 13 + sb.Append( ',' ); - sb.Append( MojangAccount); //14 + sb.Append( MojangAccount ); //14 sb.Append( ',' ); FirstLoginDate.ToUnixTimeString( sb ).Append( ',' ); // 15 LastLoginDate.ToUnixTimeString( sb ).Append( ',' ); // 16 Player pObject = PlayerObject; - if( pObject != null ) { - (TotalTime.Add( TimeSinceLastLogin )).ToTickString( sb ).Append( ',' ); // 17 + if ( pObject != null ) { + ( TotalTime.Add( TimeSinceLastLogin ) ).ToTickString( sb ).Append( ',' ); // 17 } else { TotalTime.ToTickString( sb ).Append( ',' ); // 17 } - if( BlocksBuilt > 0 ) sb.Digits( BlocksBuilt ); // 18 + if ( BlocksBuilt > 0 ) + sb.Digits( BlocksBuilt ); // 18 sb.Append( ',' ); - if( BlocksDeleted > 0 ) sb.Digits( BlocksDeleted ); // 19 + if ( BlocksDeleted > 0 ) + sb.Digits( BlocksDeleted ); // 19 sb.Append( ',' ); sb.Append( TimesVisited ).Append( ',' ); // 20 - - if( MessagesWritten > 0 ) sb.Digits( MessagesWritten ); // 21 + if ( MessagesWritten > 0 ) + sb.Digits( MessagesWritten ); // 21 sb.Append( ',' ); - if (PromoCount > 0) sb.Digits(PromoCount); //22 - sb.Append(','); //23 is now titlename + if ( PromoCount > 0 ) + sb.Digits( PromoCount ); //22 + sb.Append( ',' ); //23 is now titlename - sb.Append(TitleName); //23 - sb.Append(','); - + sb.Append( TitleName ); //23 + sb.Append( ',' ); - if( PreviousRank != null ) sb.Append( PreviousRank.FullName ); // 24 + if ( PreviousRank != null ) + sb.Append( PreviousRank.FullName ); // 24 sb.Append( ',' ); sb.AppendEscaped( RankChangeReason ).Append( ',' ); // 25 - - if( TimesKicked > 0 ) sb.Digits( TimesKicked ); // 26 + if ( TimesKicked > 0 ) + sb.Digits( TimesKicked ); // 26 sb.Append( ',' ); - if( TimesKickedOthers > 0 ) sb.Digits( TimesKickedOthers ); // 27 + if ( TimesKickedOthers > 0 ) + sb.Digits( TimesKickedOthers ); // 27 sb.Append( ',' ); - if( TimesBannedOthers > 0 ) sb.Digits( TimesBannedOthers ); // 28 + if ( TimesBannedOthers > 0 ) + sb.Digits( TimesBannedOthers ); // 28 sb.Append( ',' ); - sb.Digits( ID ).Append( ',' ); // 29 - sb.Digits( (int)RankChangeType ).Append( ',' ); // 30 - + sb.Digits( ( int )RankChangeType ).Append( ',' ); // 30 LastKickDate.ToUnixTimeString( sb ).Append( ',' ); // 31 - if( IsOnline ) DateTime.UtcNow.ToUnixTimeString( sb ); // 32 - else LastSeen.ToUnixTimeString( sb ); + if ( IsOnline ) + DateTime.UtcNow.ToUnixTimeString( sb ); // 32 + else + LastSeen.ToUnixTimeString( sb ); sb.Append( ',' ); - if( BlocksDrawn > 0 ) sb.Append( BlocksDrawn ); // 33 + if ( BlocksDrawn > 0 ) + sb.Append( BlocksDrawn ); // 33 sb.Append( ',' ); sb.AppendEscaped( LastKickBy ).Append( ',' ); // 34 @@ -1051,7 +1102,7 @@ internal void Serialize( StringBuilder sb ) { BannedUntil.ToUnixTimeString( sb ); // 36 - if( IsFrozen ) { + if ( IsFrozen ) { sb.Append( ',' ).Append( 'f' ).Append( ',' ); // 37 sb.AppendEscaped( FrozenBy ).Append( ',' ); // 38 FrozenOn.ToUnixTimeString( sb ).Append( ',' ); // 39 @@ -1059,7 +1110,7 @@ internal void Serialize( StringBuilder sb ) { sb.Append( ',', 4 ); // 37-39 } - if( MutedUntil > DateTime.UtcNow ) { + if ( MutedUntil > DateTime.UtcNow ) { MutedUntil.ToUnixTimeString( sb ).Append( ',' ); // 40 sb.AppendEscaped( MutedBy ).Append( ',' ); // 41 } else { @@ -1068,13 +1119,16 @@ internal void Serialize( StringBuilder sb ) { sb.AppendEscaped( Password ).Append( ',' ); // 42 - if( IsOnline ) sb.Append( 'o' ); // 43 + if ( IsOnline ) + sb.Append( 'o' ); // 43 sb.Append( ',' ); - if( BandwidthUseMode != BandwidthUseMode.Default ) sb.Append( (int)BandwidthUseMode ); // 44 + if ( BandwidthUseMode != BandwidthUseMode.Default ) + sb.Append( ( int )BandwidthUseMode ); // 44 sb.Append( ',' ); - if( IsHidden ) sb.Append( 'h' ); // 45 + if ( IsHidden ) + sb.Append( 'h' ); // 45 sb.Append( ',' ); LastModified.ToUnixTimeString( sb ); // 46 @@ -1083,43 +1137,43 @@ internal void Serialize( StringBuilder sb ) { sb.AppendEscaped( DisplayedName ); // 47 } - internal void Serialize( [NotNull] BinaryWriter writer ) { - if( writer == null ) throw new ArgumentNullException( "writer" ); + if ( writer == null ) + throw new ArgumentNullException( "writer" ); // General writer.Write( Name ); // 0 WriteString( writer, DisplayedName ); // 1 Write7BitEncodedInt( writer, ID ); // 2 - if( IsOnline ) { - writer.Write( (uint)DateTime.UtcNow.ToUnixTime() ); // 5 + if ( IsOnline ) { + writer.Write( ( uint )DateTime.UtcNow.ToUnixTime() ); // 5 } else { - writer.Write( (uint)LastSeen.ToUnixTime() ); // 5 + writer.Write( ( uint )LastSeen.ToUnixTime() ); // 5 } // Rank Write7BitEncodedInt( writer, Rank.Index ); // 7 { - bool hasPrevRank = (PreviousRank != null); + bool hasPrevRank = ( PreviousRank != null ); writer.Write( hasPrevRank ); - if( hasPrevRank ) { + if ( hasPrevRank ) { Write7BitEncodedInt( writer, PreviousRank.Index ); // 8 } } - writer.Write( (byte)RankChangeType ); // 12 - if( RankChangeType != RankChangeType.Default ) { + writer.Write( ( byte )RankChangeType ); // 12 + if ( RankChangeType != RankChangeType.Default ) { WriteDate( writer, RankChangeDate ); // 9 WriteString( writer, RankChangedBy ); // 10 WriteString( writer, RankChangeReason ); // 11 } // Bans - writer.Write( (byte)BanStatus ); // 13 + writer.Write( ( byte )BanStatus ); // 13 WriteDate( writer, BanDate ); // 14 WriteString( writer, BannedBy ); // 15 //fuck knows WriteString( writer, MojangAccount ); // 15 WriteString( writer, BanReason ); // 16 - if( BanStatus == BanStatus.Banned ) { + if ( BanStatus == BanStatus.Banned ) { WriteDate( writer, BannedUntil ); // 14 WriteDate( writer, LastFailedLoginDate ); // 20 writer.Write( LastFailedLoginIP.GetAddressBytes() ); // 21 @@ -1130,27 +1184,28 @@ internal void Serialize( [NotNull] BinaryWriter writer ) { } // Stats - writer.Write( (uint)FirstLoginDate.ToUnixTime() ); // 3 - writer.Write( (uint)LastLoginDate.ToUnixTime() ); // 4 - if( IsOnline ) { - writer.Write( (uint)TotalTime.Add( TimeSinceLastLogin ).ToSeconds() ); // 22 + writer.Write( ( uint )FirstLoginDate.ToUnixTime() ); // 3 + writer.Write( ( uint )LastLoginDate.ToUnixTime() ); // 4 + if ( IsOnline ) { + writer.Write( ( uint )TotalTime.Add( TimeSinceLastLogin ).ToSeconds() ); // 22 } else { - writer.Write( (uint)TotalTime.ToSeconds() ); // 22 + writer.Write( ( uint )TotalTime.ToSeconds() ); // 22 } Write7BitEncodedInt( writer, BlocksBuilt ); // 23 Write7BitEncodedInt( writer, BlocksDeleted ); // 24 writer.Write( BlocksDrawn > 0 ); - if( BlocksDrawn > 0 ) writer.Write( BlocksDrawn ); // 25 + if ( BlocksDrawn > 0 ) + writer.Write( BlocksDrawn ); // 25 Write7BitEncodedInt( writer, TimesVisited ); // 26 Write7BitEncodedInt( writer, MessagesWritten ); // 27 - Write7BitEncodedInt(writer, PromoCount); //22 (?) - WriteString(writer, TitleName); //23 (?) + Write7BitEncodedInt( writer, PromoCount ); //22 (?) + WriteString( writer, TitleName ); //23 (?) Write7BitEncodedInt( writer, TimesKickedOthers ); // 28 Write7BitEncodedInt( writer, TimesBannedOthers ); // 29 // Kicks Write7BitEncodedInt( writer, TimesKicked ); // 30 - if( TimesKicked > 0 ) { + if ( TimesKicked > 0 ) { WriteDate( writer, LastKickDate ); // 31 WriteString( writer, LastKickBy ); // 32 WriteString( writer, LastKickReason ); // 33 @@ -1158,55 +1213,51 @@ internal void Serialize( [NotNull] BinaryWriter writer ) { // Freeze/Mute writer.Write( IsFrozen ); // 34 - if( IsFrozen ) { + if ( IsFrozen ) { WriteDate( writer, FrozenOn ); // 35 WriteString( writer, FrozenBy ); // 36 } WriteDate( writer, MutedUntil ); // 37 - if( MutedUntil != DateTime.MinValue ) { + if ( MutedUntil != DateTime.MinValue ) { WriteString( writer, MutedBy ); // 38 } // Misc WriteString( writer, Password ); - writer.Write( (uint)LastModified.ToUnixTime() ); + writer.Write( ( uint )LastModified.ToUnixTime() ); writer.Write( IsOnline ); // 39 writer.Write( IsHidden ); // 40 writer.Write( LastIP.GetAddressBytes() ); // 41 - writer.Write( (byte)LeaveReason ); // 6 - writer.Write( (byte)BandwidthUseMode ); // 6 + writer.Write( ( byte )LeaveReason ); // 6 + writer.Write( ( byte )BandwidthUseMode ); // 6 } - - static void WriteDate( [NotNull] BinaryWriter writer, DateTime dateTime ) { - bool hasDate = (dateTime != DateTime.MinValue); + private static void WriteDate( [NotNull] BinaryWriter writer, DateTime dateTime ) { + bool hasDate = ( dateTime != DateTime.MinValue ); writer.Write( hasDate ); - if( hasDate ) { - writer.Write( (uint)dateTime.ToUnixTime() ); + if ( hasDate ) { + writer.Write( ( uint )dateTime.ToUnixTime() ); } } - - static void WriteString( [NotNull] BinaryWriter writer, [CanBeNull] string str ) { - bool hasString = (str != null); + private static void WriteString( [NotNull] BinaryWriter writer, [CanBeNull] string str ) { + bool hasString = ( str != null ); writer.Write( hasString ); - if( hasString ) { + if ( hasString ) { writer.Write( str ); } } - - static void Write7BitEncodedInt( [NotNull] BinaryWriter writer, int value ) { - uint num = (uint)value; - while( num >= 0x80 ) { - writer.Write( (byte)(num | 0x80) ); + private static void Write7BitEncodedInt( [NotNull] BinaryWriter writer, int value ) { + uint num = ( uint )value; + while ( num >= 0x80 ) { + writer.Write( ( byte )( num | 0x80 ) ); num = num >> 7; } - writer.Write( (byte)num ); + writer.Write( ( byte )num ); } - #endregion - + #endregion Saving #region Update Handlers @@ -1215,9 +1266,9 @@ public void ProcessMessageWritten() { LastModified = DateTime.UtcNow; } - public void ProcessLogin( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); LastIP = player.IP; LastLoginDate = DateTime.UtcNow; LastSeen = DateTime.UtcNow; @@ -1227,17 +1278,17 @@ public void ProcessLogin( [NotNull] Player player ) { LastModified = DateTime.UtcNow; } - public void ProcessFailedLogin( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); LastFailedLoginDate = DateTime.UtcNow; LastFailedLoginIP = player.IP; LastModified = DateTime.UtcNow; } - public void ProcessLogout( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); TotalTime += player.LastActiveTime.Subtract( player.LoginTime ); LastSeen = DateTime.UtcNow; IsOnline = false; @@ -1246,10 +1297,11 @@ public void ProcessLogout( [NotNull] Player player ) { LastModified = DateTime.UtcNow; } - public void ProcessRankChange( [NotNull] Rank newRank, [NotNull] string changer, [CanBeNull] string reason, RankChangeType type ) { - if( newRank == null ) throw new ArgumentNullException( "newRank" ); - if( changer == null ) throw new ArgumentNullException( "changer" ); + if ( newRank == null ) + throw new ArgumentNullException( "newRank" ); + if ( changer == null ) + throw new ArgumentNullException( "changer" ); PreviousRank = Rank; Rank = newRank; RankChangeDate = DateTime.UtcNow; @@ -1260,9 +1312,8 @@ public void ProcessRankChange( [NotNull] Rank newRank, [NotNull] string changer, LastModified = DateTime.UtcNow; } - public void ProcessBlockPlaced( byte type ) { - if( type == 0 ) { // air + if ( type == 0 ) { // air Interlocked.Increment( ref BlocksDeleted ); } else { Interlocked.Increment( ref BlocksBuilt ); @@ -1270,27 +1321,27 @@ public void ProcessBlockPlaced( byte type ) { LastModified = DateTime.UtcNow; } - public void ProcessDrawCommand( int blocksDrawn ) { Interlocked.Add( ref BlocksDrawn, blocksDrawn ); LastModified = DateTime.UtcNow; } - internal void ProcessKick( [NotNull] Player kickedBy, [CanBeNull] string reason ) { - if( kickedBy == null ) throw new ArgumentNullException( "kickedBy" ); - if( reason != null && reason.Trim().Length == 0 ) reason = null; + if ( kickedBy == null ) + throw new ArgumentNullException( "kickedBy" ); + if ( reason != null && reason.Trim().Length == 0 ) + reason = null; - lock( actionLock ) { + lock ( actionLock ) { Interlocked.Increment( ref TimesKicked ); Interlocked.Increment( ref kickedBy.Info.TimesKickedOthers ); LastKickDate = DateTime.UtcNow; LastKickBy = kickedBy.Name; LastKickReason = reason; - if( IsFrozen ) { + if ( IsFrozen ) { try { Unfreeze( kickedBy, false, true ); - } catch( PlayerOpException ex ) { + } catch ( PlayerOpException ex ) { Logger.Log( LogType.Warning, "PlayerInfo.ProcessKick: {0}", ex.Message ); } @@ -1299,88 +1350,78 @@ internal void ProcessKick( [NotNull] Player kickedBy, [CanBeNull] string reason } } - #endregion - + #endregion Update Handlers #region Utilities public static string Escape( [CanBeNull] string str ) { - if( String.IsNullOrEmpty( str ) ) { + if ( String.IsNullOrEmpty( str ) ) { return ""; - } else if( str.IndexOf( ',' ) > -1 ) { + } else if ( str.IndexOf( ',' ) > -1 ) { return str.Replace( ',', '\xFF' ); } else { return str; } } - public static string UnescapeOldFormat( [NotNull] string str ) { - if( str == null ) throw new ArgumentNullException( "str" ); + if ( str == null ) + throw new ArgumentNullException( "str" ); return str.Replace( '\xFF', ',' ).Replace( "\'", "'" ).Replace( @"\\", @"\" ); } - public static string Unescape( [NotNull] string str ) { - if( str == null ) throw new ArgumentNullException( "str" ); - if( str.IndexOf( '\xFF' ) > -1 ) { + if ( str == null ) + throw new ArgumentNullException( "str" ); + if ( str.IndexOf( '\xFF' ) > -1 ) { return str.Replace( '\xFF', ',' ); } else { return str; } } - // implements IClassy interface public string ClassyName { get { StringBuilder sb = new StringBuilder(); - if ( TitleName != null ) - { - if (ConfigKey.RankPrefixesInList.Enabled()) - { - sb.Append(Rank.Prefix + TitleName); + if ( TitleName != null ) { + if ( ConfigKey.RankPrefixesInList.Enabled() ) { + sb.Append( Rank.Prefix + TitleName ); } - if (ConfigKey.RankColorsInChat.Enabled()) - { - sb.Append(Rank.Color + TitleName); + if ( ConfigKey.RankColorsInChat.Enabled() ) { + sb.Append( Rank.Color + TitleName ); } } - if( ConfigKey.RankColorsInChat.Enabled() ) { + if ( ConfigKey.RankColorsInChat.Enabled() ) { sb.Append( Rank.Color ); } - if( DisplayedName != null ) { + if ( DisplayedName != null ) { sb.Append( DisplayedName ); } else { - if( ConfigKey.RankPrefixesInChat.Enabled() && TitleName != null ) { + if ( ConfigKey.RankPrefixesInChat.Enabled() && TitleName != null ) { sb.Append( Rank.Prefix ); } sb.Append( Name ); } - if (IsBanned) - { - sb.Append(Color.Warning).Append('*'); + if ( IsBanned ) { + sb.Append( Color.Warning ).Append( '*' ); } - if (IsFrozen) - { - sb.Append(Color.Blue).Append('*'); + if ( IsFrozen ) { + sb.Append( Color.Blue ).Append( '*' ); } - if (IsMuted) - { - sb.Append(Color.Olive).Append('*'); + if ( IsMuted ) { + sb.Append( Color.Olive ).Append( '*' ); } - if (IsWarned) - { - sb.Append(Color.Black).Append('*'); + if ( IsWarned ) { + sb.Append( Color.Black ).Append( '*' ); } return sb.ToString(); } } - #endregion - + #endregion Utilities #region TimeSince_____ shortcuts @@ -1420,8 +1461,7 @@ public TimeSpan TimeMutedLeft { get { return MutedUntil.Subtract( DateTime.UtcNow ); } } - #endregion - + #endregion TimeSince_____ shortcuts public override string ToString() { return String.Format( "PlayerInfo({0},{1})", Name, Rank.Name ); @@ -1435,7 +1475,6 @@ public bool Can( Permission permission, Rank rank ) { return Rank.Can( permission, rank ); } - #region Unfinished / Not Implemented /// Not implemented (IRC/server password hash). @@ -1448,12 +1487,11 @@ public bool Can( Permission permission, Rank rank ) { /// Not implemented (for temp bans). public DateTime BannedUntil; // TODO - #endregion + #endregion Unfinished / Not Implemented } - public sealed class PlayerInfoComparer : IComparer { - readonly Player observer; + private readonly Player observer; public PlayerInfoComparer( Player observer ) { this.observer = observer; @@ -1465,13 +1503,13 @@ public int Compare( PlayerInfo x, PlayerInfo y ) { bool xIsOnline = xPlayer != null && observer.CanSee( xPlayer ); bool yIsOnline = yPlayer != null && observer.CanSee( yPlayer ); - if( !xIsOnline && yIsOnline ) { + if ( !xIsOnline && yIsOnline ) { return 1; - } else if( xIsOnline && !yIsOnline ) { + } else if ( xIsOnline && !yIsOnline ) { return -1; } - if( x.Rank == y.Rank ) { + if ( x.Rank == y.Rank ) { return Math.Sign( y.LastSeen.Ticks - x.LastSeen.Ticks ); } else { return x.Rank.Index - y.Rank.Index; diff --git a/fCraft/Player/PlayerOpException.cs b/fCraft/Player/PlayerOpException.cs index 006987a..69e2284 100644 --- a/fCraft/Player/PlayerOpException.cs +++ b/fCraft/Player/PlayerOpException.cs @@ -4,14 +4,19 @@ using JetBrains.Annotations; namespace fCraft { + public sealed class PlayerOpException : Exception { + public PlayerOpException( [NotNull] Player player, PlayerInfo target, PlayerOpExceptionCode errorCode, [NotNull] string message, [NotNull] string messageColored ) : base( message ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( message == null ) throw new ArgumentNullException( "message" ); - if( messageColored == null ) throw new ArgumentNullException( "messageColored" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( messageColored == null ) + throw new ArgumentNullException( "messageColored" ); Player = player; Target = target; ErrorCode = errorCode; @@ -19,17 +24,20 @@ public PlayerOpException( [NotNull] Player player, PlayerInfo target, } public Player Player { get; private set; } + public PlayerInfo Target { get; private set; } + public PlayerOpExceptionCode ErrorCode { get; private set; } - public string MessageColored { get; private set; } + public string MessageColored { get; private set; } // Throws a PlayerOpException if reason is required but missing. internal static void CheckBanReason( [CanBeNull] string reason, [NotNull] Player player, PlayerInfo targetInfo, bool unban ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( ConfigKey.RequireBanReason.Enabled() && String.IsNullOrEmpty( reason ) ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( ConfigKey.RequireBanReason.Enabled() && String.IsNullOrEmpty( reason ) ) { string msg; - if( unban ) { + if ( unban ) { msg = "Please specify an unban reason."; } else { msg = "Please specify an ban reason."; @@ -39,13 +47,13 @@ internal static void CheckBanReason( [CanBeNull] string reason, [NotNull] Player } } - // Throws a PlayerOpException if reason is required but missing. internal static void CheckRankChangeReason( [CanBeNull] string reason, [NotNull] Player player, PlayerInfo targetInfo, bool promoting ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( ConfigKey.RequireRankChangeReason.Enabled() && String.IsNullOrEmpty( reason ) ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( ConfigKey.RequireRankChangeReason.Enabled() && String.IsNullOrEmpty( reason ) ) { string msg; - if( promoting ) { + if ( promoting ) { msg = "Please specify a promotion reason."; } else { msg = "Please specify a demotion reason."; @@ -55,35 +63,38 @@ internal static void CheckRankChangeReason( [CanBeNull] string reason, [NotNull] } } - // Throws a PlayerOpException if reason is required but missing. internal static void CheckKickReason( [CanBeNull] string reason, [NotNull] Player player, PlayerInfo targetInfo ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( ConfigKey.RequireKickReason.Enabled() && String.IsNullOrEmpty( reason ) ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( ConfigKey.RequireKickReason.Enabled() && String.IsNullOrEmpty( reason ) ) { const string msg = "Please specify a kick reason."; const string colorMsg = "&S" + msg; throw new PlayerOpException( player, targetInfo, PlayerOpExceptionCode.ReasonRequired, msg, colorMsg ); } } - internal static void ThrowCannotTargetSelf( [NotNull] Player player, [CanBeNull] PlayerInfo target, [NotNull] string action ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( action == null ) throw new ArgumentNullException( "action" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( action == null ) + throw new ArgumentNullException( "action" ); string msg = String.Format( "You cannot {0} yourself.", action ); string colorMsg = String.Format( "&SYou cannot {0} yourself.", action ); throw new PlayerOpException( player, target, PlayerOpExceptionCode.CannotTargetSelf, msg, colorMsg ); } - internal static void ThrowPermissionMissing( [NotNull] Player player, [CanBeNull] PlayerInfo target, [NotNull] string action, [NotNull] params Permission[] permissions ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( action == null ) throw new ArgumentNullException( "action" ); - if( permissions == null ) throw new ArgumentNullException( "permissions" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( action == null ) + throw new ArgumentNullException( "action" ); + if ( permissions == null ) + throw new ArgumentNullException( "permissions" ); Rank minRank = RankManager.GetMinRankWithAllPermissions( permissions ); string msg, colorMsg; - if( minRank != null ) { + if ( minRank != null ) { msg = String.Format( "You need to be ranked {0}+ to {1}.", minRank.Name, action ); colorMsg = String.Format( "&SYou need to be ranked {0}&S+ to {1}.", @@ -96,13 +107,15 @@ internal static void ThrowPermissionMissing( [NotNull] Player player, [CanBeNull throw new PlayerOpException( player, target, PlayerOpExceptionCode.PermissionMissing, msg, colorMsg ); } - internal static void ThrowPermissionLimitIP( [NotNull] Player player, [NotNull] PlayerInfo infoWhomPlayerCantBan, [NotNull] IPAddress targetAddress ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( infoWhomPlayerCantBan == null ) throw new ArgumentNullException( "infoWhomPlayerCantBan" ); - if( targetAddress == null ) throw new ArgumentNullException( "targetAddress" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( infoWhomPlayerCantBan == null ) + throw new ArgumentNullException( "infoWhomPlayerCantBan" ); + if ( targetAddress == null ) + throw new ArgumentNullException( "targetAddress" ); string msg, colorMsg; - if( player.Can( Permission.ViewPlayerIPs ) ) { + if ( player.Can( Permission.ViewPlayerIPs ) ) { msg = String.Format( "IP {0} is used by player {1}, ranked {2}. You may only ban players ranked {3} and below.", targetAddress, infoWhomPlayerCantBan.Name, infoWhomPlayerCantBan.Rank.Name, player.Info.Rank.GetLimit( Permission.Ban ).Name ); @@ -121,11 +134,13 @@ internal static void ThrowPermissionLimitIP( [NotNull] Player player, [NotNull] msg, colorMsg ); } - internal static void ThrowPermissionLimit( [NotNull] Player player, [NotNull] PlayerInfo targetInfo, [NotNull] string action, Permission permission ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( targetInfo == null ) throw new ArgumentNullException( "targetInfo" ); - if( action == null ) throw new ArgumentNullException( "action" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( targetInfo == null ) + throw new ArgumentNullException( "targetInfo" ); + if ( action == null ) + throw new ArgumentNullException( "action" ); string msg = String.Format( "Cannot {0} {1} (ranked {2}): you may only {0} players ranked {3} and below.", action, targetInfo.Name, targetInfo.Rank.Name, player.Info.Rank.GetLimit( permission ).Name ); @@ -136,13 +151,15 @@ internal static void ThrowPermissionLimit( [NotNull] Player player, [NotNull] Pl msg, colorMsg ); } - internal static void ThrowPlayerAndIPNotBanned( [NotNull] Player player, [NotNull] PlayerInfo targetInfo, [NotNull] IPAddress address ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( targetInfo == null ) throw new ArgumentNullException( "targetInfo" ); - if( address == null ) throw new ArgumentNullException( "address" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( targetInfo == null ) + throw new ArgumentNullException( "targetInfo" ); + if ( address == null ) + throw new ArgumentNullException( "address" ); string msg, colorMsg; - if( player.Can( Permission.ViewPlayerIPs ) ) { + if ( player.Can( Permission.ViewPlayerIPs ) ) { msg = String.Format( "Player {0} and their IP ({1}) are not currently banned.", targetInfo.Name, address ); colorMsg = String.Format( "&SPlayer {0}&S and their IP ({1}) are not currently banned.", @@ -156,13 +173,14 @@ internal static void ThrowPlayerAndIPNotBanned( [NotNull] Player player, [NotNul throw new PlayerOpException( player, targetInfo, PlayerOpExceptionCode.NoActionNeeded, msg, colorMsg ); } - internal static void ThrowNoOneToBan( [NotNull] Player player, [CanBeNull] PlayerInfo targetInfo, [NotNull] IPAddress address ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( address == null ) throw new ArgumentNullException( "address" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( address == null ) + throw new ArgumentNullException( "address" ); string msg, colorMsg; - if( targetInfo == null ) { - if( player.Can( Permission.ViewPlayerIPs ) ) { + if ( targetInfo == null ) { + if ( player.Can( Permission.ViewPlayerIPs ) ) { msg = String.Format( "Given IP ({0}) and all players who use it are already banned.", address ); } else { @@ -170,7 +188,7 @@ internal static void ThrowNoOneToBan( [NotNull] Player player, [CanBeNull] Playe } colorMsg = "&S" + msg; } else { - if( player.Can( Permission.ViewPlayerIPs ) ) { + if ( player.Can( Permission.ViewPlayerIPs ) ) { msg = String.Format( "Player {0}, their IP ({1}), and all players who use this IP are already banned.", targetInfo.Name, address ); colorMsg = String.Format( "&SPlayer {0}&S, their IP ({1}), and all players who use this IP are already banned.", @@ -185,12 +203,13 @@ internal static void ThrowNoOneToBan( [NotNull] Player player, [CanBeNull] Playe throw new PlayerOpException( player, targetInfo, PlayerOpExceptionCode.NoActionNeeded, msg, colorMsg ); } - internal static void ThrowNoOneToUnban( [NotNull] Player player, [CanBeNull] PlayerInfo targetInfo, [NotNull] IPAddress address ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( address == null ) throw new ArgumentNullException( "address" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( address == null ) + throw new ArgumentNullException( "address" ); string msg; - if( player.Can( Permission.ViewPlayerIPs ) ) { + if ( player.Can( Permission.ViewPlayerIPs ) ) { msg = String.Format( "None of the players who use given IP ({0}) are banned.", address ); } else { @@ -200,49 +219,55 @@ internal static void ThrowNoOneToUnban( [NotNull] Player player, [CanBeNull] Pla throw new PlayerOpException( player, targetInfo, PlayerOpExceptionCode.NoActionNeeded, msg, colorMsg ); } - internal static void ThrowPlayerAlreadyBanned( [NotNull] Player player, [NotNull] PlayerInfo target, [NotNull] string action ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( target == null ) throw new ArgumentNullException( "target" ); - if( action == null ) throw new ArgumentNullException( "action" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( target == null ) + throw new ArgumentNullException( "target" ); + if ( action == null ) + throw new ArgumentNullException( "action" ); string msg = String.Format( "Player {0} is already {1}.", target.Name, action ); string msgColored = String.Format( "&SPlayer {0}&S is already {1}.", target.ClassyName, action ); throw new PlayerOpException( player, target, PlayerOpExceptionCode.NoActionNeeded, msg, msgColored ); } - internal static void ThrowPlayerNotBanned( [NotNull] Player player, [NotNull] PlayerInfo target, [NotNull] string action ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( target == null ) throw new ArgumentNullException( "target" ); - if( action == null ) throw new ArgumentNullException( "action" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( target == null ) + throw new ArgumentNullException( "target" ); + if ( action == null ) + throw new ArgumentNullException( "action" ); string msg = String.Format( "Player {0} is not currently {1}.", target.Name, action ); string msgColored = String.Format( "&SPlayer {0}&S is not currently {1}.", target.ClassyName, action ); throw new PlayerOpException( player, target, PlayerOpExceptionCode.NoActionNeeded, msg, msgColored ); } - internal static void ThrowCancelled( [NotNull] Player player, [NotNull] PlayerInfo target ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( target == null ) throw new ArgumentNullException( "target" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( target == null ) + throw new ArgumentNullException( "target" ); const string msg = "Cancelled by plugin."; const string colorMsg = "&S" + msg; throw new PlayerOpException( player, target, PlayerOpExceptionCode.Cancelled, msg, colorMsg ); } - internal static void ThrowNoWorld( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); const string msg = "Player must be in a world to do this."; const string colorMsg = "&S" + msg; throw new PlayerOpException( player, null, PlayerOpExceptionCode.MustBeInAWorld, msg, colorMsg ); } - internal static void ThrowInvalidIP( [NotNull] Player player, [CanBeNull] PlayerInfo target, [NotNull] IPAddress ip ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( ip == null ) throw new ArgumentNullException( "ip" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( ip == null ) + throw new ArgumentNullException( "ip" ); string msg, msgColored; - if( target == null ) { + if ( target == null ) { msg = String.Format( "Cannot IP-ban {0}: invalid IP.", ip ); msgColored = String.Format( "&SCannot IP-ban {0}: invalid IP.", ip ); } else { @@ -253,8 +278,8 @@ internal static void ThrowInvalidIP( [NotNull] Player player, [CanBeNull] Player } } - public enum PlayerOpExceptionCode { + /// Other/unknown/unexpected error. Other, diff --git a/fCraft/Player/Position.cs b/fCraft/Player/Position.cs index 5d447b4..1786b97 100644 --- a/fCraft/Player/Position.cs +++ b/fCraft/Player/Position.cs @@ -21,9 +21,9 @@ public Position( short x, short y, short z, byte r, byte l ) { } public Position( int x, int y, int z ) { - X = (short)x; - Y = (short)y; - Z = (short)z; + X = ( short )x; + Y = ( short )y; + Z = ( short )z; R = 0; L = 0; } @@ -36,31 +36,27 @@ internal bool FitsIntoMoveRotatePacket { } } - public bool IsZero { get { return X == 0 && Y == 0 && Z == 0 && R == 0 && L == 0; } } - // adjust for bugs in position-reporting in Minecraft client public Position GetFixed() { return new Position { - X = (X), - Y = (Y), - Z = (short)(Z - 22), + X = ( X ), + Y = ( Y ), + Z = ( short )( Z - 22 ), R = R, L = L }; } - public int DistanceSquaredTo( Position other ) { - return (X - other.X) * (X - other.X) + (Y - other.Y) * (Y - other.Y) + (Z - other.Z) * (Z - other.Z); + return ( X - other.X ) * ( X - other.X ) + ( Y - other.Y ) * ( Y - other.Y ) + ( Z - other.Z ) * ( Z - other.Z ); } - #region Equality public static bool operator ==( Position a, Position b ) { @@ -72,19 +68,18 @@ public int DistanceSquaredTo( Position other ) { } public bool Equals( Position other ) { - return (X == other.X) && (Y == other.Y) && (Z == other.Z) && (R == other.R) && (L == other.L); + return ( X == other.X ) && ( Y == other.Y ) && ( Z == other.Z ) && ( R == other.R ) && ( L == other.L ); } public override bool Equals( object obj ) { - return (obj is Position) && Equals( (Position)obj ); + return ( obj is Position ) && Equals( ( Position )obj ); } public override int GetHashCode() { - return (X + Y * short.MaxValue) ^ (R + L * short.MaxValue) + Z; + return ( X + Y * short.MaxValue ) ^ ( R + L * short.MaxValue ) + Z; } - #endregion - + #endregion Equality public override string ToString() { return String.Format( "Position({0},{1},{2} @{3},{4})", X, Y, Z, R, L ); @@ -99,7 +94,7 @@ public Vector3I ToVector3I() { } public Vector3I ToBlockCoords() { - return new Vector3I( (X - 16) / 32, (Y - 16) / 32, (Z - 16) / 32 ); + return new Vector3I( ( X - 16 ) / 32, ( Y - 16 ) / 32, ( Z - 16 ) / 32 ); } } } \ No newline at end of file diff --git a/fCraft/Player/Rank.cs b/fCraft/Player/Rank.cs index 0dd0fa9..d79e713 100644 --- a/fCraft/Player/Rank.cs +++ b/fCraft/Player/Rank.cs @@ -6,6 +6,7 @@ using JetBrains.Annotations; namespace fCraft { + public sealed class Rank : IClassy, IComparable { /// Rank color code. Should not be left blank. @@ -49,7 +50,6 @@ public sealed class Rank : IClassy, IComparable { /// Subordinate ranks start at 1. Higher index = lower rank. public int Index; - [CanBeNull] public Rank NextRankUp { get; internal set; } @@ -59,7 +59,6 @@ public sealed class Rank : IClassy, IComparable { [CanBeNull] public World MainWorld { get; set; } - #region Constructors private Rank() { @@ -70,52 +69,48 @@ private Rank() { Prefix = ""; } - public Rank( [NotNull] string name, [NotNull] string id ) : this() { - if( name == null ) throw new ArgumentNullException( "name" ); - if( id == null ) throw new ArgumentNullException( "id" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( id == null ) + throw new ArgumentNullException( "id" ); Name = name; ID = id; FullName = Name + "#" + ID; } - public Rank( [NotNull] XElement el ) : this() { - if( el == null ) throw new ArgumentNullException( "el" ); + if ( el == null ) + throw new ArgumentNullException( "el" ); // Name XAttribute attr = el.Attribute( "name" ); - if( attr == null ) { + if ( attr == null ) { throw new RankDefinitionException( null, "Rank definition with no name was ignored." ); - - } else if( !IsValidRankName( attr.Value.Trim() ) ) { - throw new RankDefinitionException( Name, + } else if ( !IsValidRankName( attr.Value.Trim() ) ) { + throw new RankDefinitionException( Name, "Invalid name specified for rank \"{0}\". " + "Rank names can only contain letters, digits, and underscores. " + "Rank definition was ignored.", Name ); - } else { // duplicate Name check is done in RankManager.AddRank() Name = attr.Value.Trim(); } - // ID attr = el.Attribute( "id" ); - if( attr == null ) { + if ( attr == null ) { ID = RankManager.GenerateID(); Logger.Log( LogType.Warning, "Rank({0}): No ID specified; issued a new unique ID: {1}", Name, ID ); - - } else if( !IsValidID( attr.Value.Trim() ) ) { + } else if ( !IsValidID( attr.Value.Trim() ) ) { ID = RankManager.GenerateID(); Logger.Log( LogType.Warning, "Rank({0}): Invalid ID specified (must be alphanumeric, and exactly 16 characters long); issued a new unique ID: {1}", Name, ID ); - } else { ID = attr.Value.Trim(); // duplicate ID check is done in RankManager.AddRank() @@ -123,11 +118,10 @@ public Rank( [NotNull] XElement el ) FullName = Name + "#" + ID; - // Color (optional) - if( ( attr = el.Attribute( "color" ) ) != null ) { + if ( ( attr = el.Attribute( "color" ) ) != null ) { string color = fCraft.Color.Parse( attr.Value ); - if( color == null ) { + if ( color == null ) { Logger.Log( LogType.Warning, "Rank({0}): Could not parse rank color. Assuming default (none).", Name ); Color = fCraft.Color.White; @@ -139,7 +133,7 @@ public Rank( [NotNull] XElement el ) } if ( ( attr = el.Attribute( "hidden" ) ) != null ) { - bool hidden; + bool hidden; if ( bool.TryParse( attr.Value, out hidden ) ) { IsHidden = hidden; } else { @@ -149,27 +143,24 @@ public Rank( [NotNull] XElement el ) } } - // Prefix (optional) - if( ( attr = el.Attribute( "prefix" ) ) != null ) { - if( IsValidPrefix( attr.Value ) ) { + if ( ( attr = el.Attribute( "prefix" ) ) != null ) { + if ( IsValidPrefix( attr.Value ) ) { Prefix = attr.Value; } else { Logger.Log( LogType.Warning, - "Rank({0}): Invalid prefix format. Expecting 1 character.",Name ); + "Rank({0}): Invalid prefix format. Expecting 1 character.", Name ); } } - // AntiGrief block limit (assuming unlimited if not given) int value; XAttribute agBlocks = el.Attribute( "antiGriefBlocks" ); XAttribute agSeconds = el.Attribute( "antiGriefSeconds" ); - if( agBlocks != null && agSeconds != null ) { - if( Int32.TryParse( agBlocks.Value, out value ) ) { - if( value >= 0 && value < 1000 ) { + if ( agBlocks != null && agSeconds != null ) { + if ( Int32.TryParse( agBlocks.Value, out value ) ) { + if ( value >= 0 && value < 1000 ) { AntiGriefBlocks = value; - } else { Logger.Log( LogType.Warning, "Rank({0}): Value for antiGriefBlocks is not within valid range (0-1000). Assuming default ({1}).", @@ -181,8 +172,8 @@ public Rank( [NotNull] XElement el ) Name, AntiGriefBlocks ); } - if( Int32.TryParse( agSeconds.Value, out value ) ) { - if( value >= 0 && value < 100 ) { + if ( Int32.TryParse( agSeconds.Value, out value ) ) { + if ( value >= 0 && value < 100 ) { AntiGriefSeconds = value; } else { Logger.Log( LogType.Warning, @@ -196,11 +187,10 @@ public Rank( [NotNull] XElement el ) } } - // Draw command limit, in number-of-blocks (assuming unlimited if not given) - if( ( attr = el.Attribute( "drawLimit" ) ) != null ) { - if( Int32.TryParse( attr.Value, out value ) ) { - if( value >= 0 && value < 100000000 ) { + if ( ( attr = el.Attribute( "drawLimit" ) ) != null ) { + if ( Int32.TryParse( attr.Value, out value ) ) { + if ( value >= 0 && value < 100000000 ) { DrawLimit = value; } else { Logger.Log( LogType.Warning, @@ -214,10 +204,9 @@ public Rank( [NotNull] XElement el ) } } - // Idle kick timer, in minutes. (assuming 'never' if not given) - if( ( attr = el.Attribute( "idleKickAfter" ) ) != null ) { - if( !Int32.TryParse( attr.Value, out IdleKickTimer ) ) { + if ( ( attr = el.Attribute( "idleKickAfter" ) ) != null ) { + if ( !Int32.TryParse( attr.Value, out IdleKickTimer ) ) { Logger.Log( LogType.Warning, "Rank({0}): Could not parse the value for idleKickAfter. Assuming 0 (never).", Name ); @@ -227,10 +216,9 @@ public Rank( [NotNull] XElement el ) IdleKickTimer = 0; } - // Reserved slot. (assuming 'no' if not given) - if( ( attr = el.Attribute( "reserveSlot" ) ) != null ) { - if( !Boolean.TryParse( attr.Value, out ReservedSlot ) ) { + if ( ( attr = el.Attribute( "reserveSlot" ) ) != null ) { + if ( !Boolean.TryParse( attr.Value, out ReservedSlot ) ) { Logger.Log( LogType.Warning, "Rank({0}): Could not parse value for reserveSlot. Assuming \"false\".", Name ); ReservedSlot = false; @@ -239,10 +227,9 @@ public Rank( [NotNull] XElement el ) ReservedSlot = false; } - // Security circumvention. (assuming 'no' if not given) - if( ( attr = el.Attribute( "allowSecurityCircumvention" ) ) != null ) { - if( !Boolean.TryParse( attr.Value, out AllowSecurityCircumvention ) ) { + if ( ( attr = el.Attribute( "allowSecurityCircumvention" ) ) != null ) { + if ( !Boolean.TryParse( attr.Value, out AllowSecurityCircumvention ) ) { Logger.Log( LogType.Warning, "Rank({0}): Could not parse the value for allowSecurityCircumvention. Assuming \"false\".", Name ); @@ -252,11 +239,10 @@ public Rank( [NotNull] XElement el ) AllowSecurityCircumvention = false; } - // Copy slots (assuming default 2 if not given) - if( ( attr = el.Attribute( "copySlots" ) ) != null ) { - if( Int32.TryParse( attr.Value, out value ) ) { - if( value > 0 && value < 256 ) { + if ( ( attr = el.Attribute( "copySlots" ) ) != null ) { + if ( Int32.TryParse( attr.Value, out value ) ) { + if ( value > 0 && value < 256 ) { CopySlots = value; } else { Logger.Log( LogType.Warning, @@ -271,13 +257,13 @@ public Rank( [NotNull] XElement el ) } // Fill limit (assuming default 32 if not given) - if( ( attr = el.Attribute( "fillLimit" ) ) != null ) { - if( Int32.TryParse( attr.Value, out value ) ) { - if( value < 1 ) { + if ( ( attr = el.Attribute( "fillLimit" ) ) != null ) { + if ( Int32.TryParse( attr.Value, out value ) ) { + if ( value < 1 ) { Logger.Log( LogType.Warning, "Rank({0}): Value for fillLimit may not be negative. Assuming default ({1}).", Name, FillLimit ); - } else if( value > 2048 ) { + } else if ( value > 2048 ) { FillLimit = 2048; } else { FillLimit = value; @@ -291,71 +277,75 @@ public Rank( [NotNull] XElement el ) // Permissions XElement temp; - for( int i = 0; i < Enum.GetValues( typeof( Permission ) ).Length; i++ ) { - string permission = ( (Permission)i ).ToString(); - if( ( temp = el.Element( permission ) ) != null ) { + for ( int i = 0; i < Enum.GetValues( typeof( Permission ) ).Length; i++ ) { + string permission = ( ( Permission )i ).ToString(); + if ( ( temp = el.Element( permission ) ) != null ) { Permissions[i] = true; - if( ( attr = temp.Attribute( "max" ) ) != null ) { + if ( ( attr = temp.Attribute( "max" ) ) != null ) { PermissionLimitStrings[i] = attr.Value; } } } // check consistency of ban permissions - if( !Can( Permission.Ban ) && ( Can( Permission.BanAll ) || Can( Permission.BanIP ) ) ) { + if ( !Can( Permission.Ban ) && ( Can( Permission.BanAll ) || Can( Permission.BanIP ) ) ) { Logger.Log( LogType.Warning, "Rank({0}): Rank is allowed to BanIP and/or BanAll but not allowed to Ban. " + "Assuming that all ban permissions were meant to be off.", Name ); - Permissions[(int)Permission.BanIP] = false; - Permissions[(int)Permission.BanAll] = false; + Permissions[( int )Permission.BanIP] = false; + Permissions[( int )Permission.BanAll] = false; } // check consistency of patrol permissions - if( !Can( Permission.Teleport ) && Can( Permission.Patrol ) ) { + if ( !Can( Permission.Teleport ) && Can( Permission.Patrol ) ) { Logger.Log( LogType.Warning, "Rank({0}): Rank is allowed to Patrol but not allowed to Teleport. " + "Assuming that Patrol permission was meant to be off.", Name ); - Permissions[(int)Permission.Patrol] = false; + Permissions[( int )Permission.Patrol] = false; } // check consistency of draw permissions - if( !Can( Permission.Draw ) && Can( Permission.DrawAdvanced ) ) { + if ( !Can( Permission.Draw ) && Can( Permission.DrawAdvanced ) ) { Logger.Log( LogType.Warning, "Rank({0}): Rank is allowed to DrawAdvanced but not allowed to Draw. " + "Assuming that Draw permission were meant to be off.", Name ); - Permissions[(int)Permission.DrawAdvanced] = false; + Permissions[( int )Permission.DrawAdvanced] = false; } } - #endregion - + #endregion Constructors public XElement Serialize() { XElement rankTag = new XElement( "Rank" ); rankTag.Add( new XAttribute( "name", Name ) ); rankTag.Add( new XAttribute( "id", ID ) ); string colorName = fCraft.Color.GetName( Color ); - if( colorName != null ) { + if ( colorName != null ) { rankTag.Add( new XAttribute( "color", colorName ) ); } - if( Prefix.Length > 0 ) rankTag.Add( new XAttribute( "prefix", Prefix ) ); + if ( Prefix.Length > 0 ) + rankTag.Add( new XAttribute( "prefix", Prefix ) ); rankTag.Add( new XAttribute( "antiGriefBlocks", AntiGriefBlocks ) ); rankTag.Add( new XAttribute( "antiGriefSeconds", AntiGriefSeconds ) ); - if( DrawLimit > 0 ) rankTag.Add( new XAttribute( "drawLimit", DrawLimit ) ); - if( IdleKickTimer > 0 ) rankTag.Add( new XAttribute( "idleKickAfter", IdleKickTimer ) ); - if( ReservedSlot ) rankTag.Add( new XAttribute( "reserveSlot", ReservedSlot ) ); - if( AllowSecurityCircumvention ) rankTag.Add( new XAttribute( "allowSecurityCircumvention", AllowSecurityCircumvention ) ); + if ( DrawLimit > 0 ) + rankTag.Add( new XAttribute( "drawLimit", DrawLimit ) ); + if ( IdleKickTimer > 0 ) + rankTag.Add( new XAttribute( "idleKickAfter", IdleKickTimer ) ); + if ( ReservedSlot ) + rankTag.Add( new XAttribute( "reserveSlot", ReservedSlot ) ); + if ( AllowSecurityCircumvention ) + rankTag.Add( new XAttribute( "allowSecurityCircumvention", AllowSecurityCircumvention ) ); rankTag.Add( new XAttribute( "copySlots", CopySlots ) ); rankTag.Add( new XAttribute( "fillLimit", FillLimit ) ); rankTag.Add( new XAttribute( "hidden", IsHidden ) ); XElement temp; - for( int i = 0; i < Enum.GetValues( typeof( Permission ) ).Length; i++ ) { - if( Permissions[i] ) { - temp = new XElement( ( (Permission)i ).ToString() ); + for ( int i = 0; i < Enum.GetValues( typeof( Permission ) ).Length; i++ ) { + if ( Permissions[i] ) { + temp = new XElement( ( ( Permission )i ).ToString() ); - if( PermissionLimits[i] != null ) { - temp.Add( new XAttribute( "max", GetLimit( (Permission)i ).FullName ) ); + if ( PermissionLimits[i] != null ) { + temp.Add( new XAttribute( "max", GetLimit( ( Permission )i ).FullName ) ); } rankTag.Add( temp ); } @@ -363,13 +353,13 @@ public XElement Serialize() { return rankTag; } - #region Rank Comparison Operators // Somewhat counterintuitive, but lower index number = higher up on the list = higher rank public int CompareTo( [NotNull] Rank other ) { - if( other == null ) throw new ArgumentNullException( "other" ); + if ( other == null ) + throw new ArgumentNullException( "other" ); return other.Index - Index; } @@ -389,28 +379,27 @@ public int CompareTo( [NotNull] Rank other ) { return a.Index >= b.Index; } - #endregion - + #endregion Rank Comparison Operators #region Permissions public bool Can( Permission permission ) { - return Permissions[(int)permission]; + return Permissions[( int )permission]; } public bool Can( Permission permission, [NotNull] Rank other ) { - if( other == null ) throw new ArgumentNullException( "other" ); - return Permissions[(int)permission] && GetLimit( permission ) >= other; + if ( other == null ) + throw new ArgumentNullException( "other" ); + return Permissions[( int )permission] && GetLimit( permission ) >= other; } - public bool CanSee( [NotNull] Rank other ) { - if( other == null ) throw new ArgumentNullException( "other" ); + if ( other == null ) + throw new ArgumentNullException( "other" ); return this > other.GetLimit( Permission.Hide ); } - #endregion - + #endregion Permissions #region Permission Limits @@ -418,43 +407,42 @@ public Rank[] PermissionLimits { get; private set; } + public readonly string[] PermissionLimitStrings; public Rank GetLimit( Permission permission ) { - return PermissionLimits[(int)permission] ?? this; + return PermissionLimits[( int )permission] ?? this; } - public void SetLimit( Permission permission, [CanBeNull] Rank limit ) { - PermissionLimits[(int)permission] = limit; + PermissionLimits[( int )permission] = limit; } - public void ResetLimit( Permission permission ) { SetLimit( permission, null ); } - public int GetLimitIndex( Permission permission ) { - if( PermissionLimits[(int)permission] == null ) { + if ( PermissionLimits[( int )permission] == null ) { return 0; } else { - return PermissionLimits[(int)permission].Index + 1; + return PermissionLimits[( int )permission].Index + 1; } } - #endregion - + #endregion Permission Limits #region Validation public static bool IsValidRankName( [NotNull] string rankName ) { - if( rankName == null ) throw new ArgumentNullException( "rankName" ); - if( rankName.Length < 1 || rankName.Length > 16 ) return false; + if ( rankName == null ) + throw new ArgumentNullException( "rankName" ); + if ( rankName.Length < 1 || rankName.Length > 16 ) + return false; // ReSharper disable LoopCanBeConvertedToQuery - for( int i = 0; i < rankName.Length; i++ ) { + for ( int i = 0; i < rankName.Length; i++ ) { char ch = rankName[i]; - if( ch < '0' || ( ch > '9' && ch < 'A' ) || ( ch > 'Z' && ch < '_' ) || ( ch > '_' && ch < 'a' ) || + if ( ch < '0' || ( ch > '9' && ch < 'A' ) || ( ch > 'Z' && ch < '_' ) || ( ch > '_' && ch < 'a' ) || ch > 'z' ) { return false; } @@ -463,14 +451,15 @@ public static bool IsValidRankName( [NotNull] string rankName ) { return true; } - public static bool IsValidID( [NotNull] string id ) { - if( id == null ) throw new ArgumentNullException( "id" ); - if( id.Length != 16 ) return false; + if ( id == null ) + throw new ArgumentNullException( "id" ); + if ( id.Length != 16 ) + return false; // ReSharper disable LoopCanBeConvertedToQuery - for( int i = 0; i < id.Length; i++ ) { + for ( int i = 0; i < id.Length; i++ ) { char ch = id[i]; - if( ch < '0' || ( ch > '9' && ch < 'A' ) || ( ch > 'Z' && ch < 'a' ) || ch > 'z' ) { + if ( ch < '0' || ( ch > '9' && ch < 'A' ) || ( ch > 'Z' && ch < 'a' ) || ch > 'z' ) { return false; } } @@ -478,49 +467,48 @@ public static bool IsValidID( [NotNull] string id ) { return true; } - public static bool IsValidPrefix( [NotNull] string prefix ) { - if( prefix == null ) throw new ArgumentNullException( "prefix" ); - if( prefix.Length == 0 ) return true; - if( prefix.Length > 1 ) return false; + if ( prefix == null ) + throw new ArgumentNullException( "prefix" ); + if ( prefix.Length == 0 ) + return true; + if ( prefix.Length > 1 ) + return false; return !Chat.ContainsInvalidChars( prefix ); } - #endregion - + #endregion Validation public override string ToString() { return String.Format( "Rank({0})", Name ); } - /// Fully qualified name of the rank. Format: "Name#ID". /// Should be used whereever rank name needs to be serialized. public string FullName { get; internal set; } - /// Decorated name of the rank, including color and prefix /// (if enabled by the configuration). public string ClassyName { get { string displayedName = Name; - if( ConfigKey.RankPrefixesInChat.Enabled() ) { + if ( ConfigKey.RankPrefixesInChat.Enabled() ) { displayedName = Prefix + displayedName; } - if( ConfigKey.RankColorsInChat.Enabled() ) { + if ( ConfigKey.RankColorsInChat.Enabled() ) { displayedName = Color + displayedName; } return displayedName; } } - internal bool ParsePermissionLimits() { bool ok = true; - for( int i = 0; i < PermissionLimits.Length; i++ ) { - if( PermissionLimitStrings[i] == null ) continue; - SetLimit( (Permission)i, Parse( PermissionLimitStrings[i] ) ); - ok &= ( GetLimit( (Permission)i ) != null ); + for ( int i = 0; i < PermissionLimits.Length; i++ ) { + if ( PermissionLimitStrings[i] == null ) + continue; + SetLimit( ( Permission )i, Parse( PermissionLimitStrings[i] ) ); + ok &= ( GetLimit( ( Permission )i ) != null ); } return ok; } @@ -540,7 +528,6 @@ public int PlayerCount { } } - /// Parses serialized rank. Accepts either the "name" or "name#ID" format. /// Uses legacy rank mapping table for unrecognized ranks. Does not autocomple. /// Name part is case-insensitive. ID part is case-sensitive. @@ -548,31 +535,31 @@ public int PlayerCount { /// If name could be parsed, returns the corresponding Rank object. Otherwise returns null. [CanBeNull] public static Rank Parse( string name ) { - if( name == null ) return null; + if ( name == null ) + return null; - if( RankManager.RanksByFullName.ContainsKey( name ) ) { + if ( RankManager.RanksByFullName.ContainsKey( name ) ) { return RankManager.RanksByFullName[name]; } - if( name.Contains( "#" ) ) { + if ( name.Contains( "#" ) ) { // new format string id = name.Substring( name.IndexOf( "#" ) + 1 ); - if( RankManager.RanksByID.ContainsKey( id ) ) { + if ( RankManager.RanksByID.ContainsKey( id ) ) { // current class return RankManager.RanksByID[id]; - } else { // unknown class int tries = 0; - while( RankManager.LegacyRankMapping.ContainsKey( id ) ) { + while ( RankManager.LegacyRankMapping.ContainsKey( id ) ) { id = RankManager.LegacyRankMapping[id]; - if( RankManager.RanksByID.ContainsKey( id ) ) { + if ( RankManager.RanksByID.ContainsKey( id ) ) { return RankManager.RanksByID[id]; } // avoid infinite loops due to recursive definitions tries++; - if( tries > 100 ) { + if ( tries > 100 ) { throw new RankDefinitionException( name, "Recursive legacy rank definition" ); } } @@ -581,11 +568,9 @@ public static Rank Parse( string name ) { return RankManager.RanksByName.ContainsKey( plainName ) ? RankManager.RanksByName[plainName] : null; } - - } else if( RankManager.RanksByName.ContainsKey( name.ToLower() ) ) { + } else if ( RankManager.RanksByName.ContainsKey( name.ToLower() ) ) { // old format return RankManager.RanksByName[name.ToLower()]; // LEGACY - } else { // totally unknown rank return null; @@ -593,8 +578,8 @@ public static Rank Parse( string name ) { } } - public sealed class RankDefinitionException : Exception { + public RankDefinitionException( string rankName, string message ) : base( message ) { RankName = rankName; @@ -603,10 +588,9 @@ public RankDefinitionException( string rankName, string message ) [StringFormatMethod( "message" )] public RankDefinitionException( string rankName, string message, params object[] args ) : base( String.Format( message, args ) ) { - RankName=rankName; + RankName = rankName; } - public string RankName { get; private set; } } } \ No newline at end of file diff --git a/fCraft/Player/RankManager.cs b/fCraft/Player/RankManager.cs index d058c99..72ee0e0 100644 --- a/fCraft/Player/RankManager.cs +++ b/fCraft/Player/RankManager.cs @@ -5,12 +5,19 @@ using JetBrains.Annotations; namespace fCraft { + public static class RankManager { + public static Dictionary RanksByName { get; private set; } + public static Dictionary RanksByFullName { get; private set; } + public static Dictionary RanksByID { get; private set; } + public static Dictionary LegacyRankMapping { get; private set; } + public static List Ranks { get; private set; } + public static Rank DefaultRank, LowestRank, HighestRank, @@ -18,16 +25,14 @@ public static class RankManager { DefaultBuildRank, BlockDBAutoEnableRank; - static RankManager() { Reset(); LegacyRankMapping = new Dictionary(); } - /// Clears the list of ranks. internal static void Reset() { - if( PlayerDB.IsLoaded ) { + if ( PlayerDB.IsLoaded ) { throw new InvalidOperationException( "You may not reset ranks after PlayerDB has already been loaded." ); } RanksByName = new Dictionary(); @@ -40,21 +45,21 @@ internal static void Reset() { BlockDBAutoEnableRank = null; } - /// Adds a new rank to the list. Checks for duplicates. public static void AddRank( [NotNull] Rank rank ) { - if( rank == null ) throw new ArgumentNullException( "rank" ); - if( PlayerDB.IsLoaded ) { + if ( rank == null ) + throw new ArgumentNullException( "rank" ); + if ( PlayerDB.IsLoaded ) { throw new InvalidOperationException( "You may not add ranks after PlayerDB has already been loaded." ); } // check for duplicate rank names - if( RanksByName.ContainsKey( rank.Name.ToLower() ) ) { + if ( RanksByName.ContainsKey( rank.Name.ToLower() ) ) { throw new RankDefinitionException( rank.Name, "Duplicate definition for rank \"{0}\" (by Name) was ignored.", rank.Name ); } - if( RanksByID.ContainsKey( rank.ID ) ) { + if ( RanksByID.ContainsKey( rank.ID ) ) { throw new RankDefinitionException( rank.Name, "Duplicate definition for rank \"{0}\" (by ID) was ignored.", rank.Name ); @@ -67,21 +72,21 @@ public static void AddRank( [NotNull] Rank rank ) { RebuildIndex(); } - /// Parses rank name (without the ID) using autocompletion. /// Full or partial rank name. /// If name could be parsed, returns the corresponding Rank object. Otherwise returns null. [CanBeNull] public static Rank FindRank( string name ) { - if( name == null ) return null; + if ( name == null ) + return null; Rank result = null; - foreach( string rankName in RanksByName.Keys ) { - if( rankName.Equals( name, StringComparison.OrdinalIgnoreCase ) ) { + foreach ( string rankName in RanksByName.Keys ) { + if ( rankName.Equals( name, StringComparison.OrdinalIgnoreCase ) ) { return RanksByName[rankName]; } - if( rankName.StartsWith( name, StringComparison.OrdinalIgnoreCase ) ) { - if( result == null ) { + if ( rankName.StartsWith( name, StringComparison.OrdinalIgnoreCase ) ) { + if ( result == null ) { result = RanksByName[rankName]; } else { return null; @@ -91,27 +96,26 @@ public static Rank FindRank( string name ) { return result; } - /// Finds rank by index. Rank at index 0 is the highest. /// If name could be parsed, returns the corresponding Rank object. Otherwise returns null. [CanBeNull] public static Rank FindRank( int index ) { - if( index < 0 || index >= Ranks.Count ) { + if ( index < 0 || index >= Ranks.Count ) { return null; } return Ranks[index]; } - public static int GetIndex( Rank rank ) { - return (rank == null) ? 0 : (rank.Index + 1); + return ( rank == null ) ? 0 : ( rank.Index + 1 ); } - public static bool DeleteRank( [NotNull] Rank deletedRank, [NotNull] Rank replacementRank ) { - if( deletedRank == null ) throw new ArgumentNullException( "deletedRank" ); - if( replacementRank == null ) throw new ArgumentNullException( "replacementRank" ); - if( PlayerDB.IsLoaded ) { + if ( deletedRank == null ) + throw new ArgumentNullException( "deletedRank" ); + if ( replacementRank == null ) + throw new ArgumentNullException( "replacementRank" ); + if ( PlayerDB.IsLoaded ) { throw new InvalidOperationException( "You may not modify ranks after PlayerDB has been loaded." ); } bool rankLimitsChanged = false; @@ -120,10 +124,10 @@ public static bool DeleteRank( [NotNull] Rank deletedRank, [NotNull] Rank replac RanksByID.Remove( deletedRank.ID ); RanksByFullName.Remove( deletedRank.FullName ); LegacyRankMapping.Add( deletedRank.ID, replacementRank.ID ); - foreach( Rank rank in Ranks ) { - for( int i = 0; i < rank.PermissionLimits.Length; i++ ) { - if( rank.GetLimit( (Permission)i ) == deletedRank ) { - rank.ResetLimit( (Permission)i ); + foreach ( Rank rank in Ranks ) { + for ( int i = 0; i < rank.PermissionLimits.Length; i++ ) { + if ( rank.GetLimit( ( Permission )i ) == deletedRank ) { + rank.ResetLimit( ( Permission )i ); rankLimitsChanged = true; } } @@ -132,9 +136,8 @@ public static bool DeleteRank( [NotNull] Rank deletedRank, [NotNull] Rank replac return rankLimitsChanged; } - - static void RebuildIndex() { - if( Ranks.Count == 0 ) { + private static void RebuildIndex() { + if ( Ranks.Count == 0 ) { LowestRank = null; HighestRank = null; DefaultRank = null; @@ -146,13 +149,13 @@ static void RebuildIndex() { LowestRank = Ranks.Last(); // assign indices - for( int i = 0; i < Ranks.Count; i++ ) { + for ( int i = 0; i < Ranks.Count; i++ ) { Ranks[i].Index = i; } // assign nextRankUp/nextRankDown - if( Ranks.Count > 1 ) { - for( int i = 0; i < Ranks.Count - 1; i++ ) { + if ( Ranks.Count > 1 ) { + for ( int i = 0; i < Ranks.Count - 1; i++ ) { Ranks[i + 1].NextRankUp = Ranks[i]; Ranks[i].NextRankDown = Ranks[i + 1]; } @@ -162,31 +165,33 @@ static void RebuildIndex() { } } - public static bool CanRenameRank( [NotNull] Rank rank, [NotNull] string newName ) { - if( rank == null ) throw new ArgumentNullException( "rank" ); - if( newName == null ) throw new ArgumentNullException( "newName" ); - if( rank.Name.Equals( newName, StringComparison.OrdinalIgnoreCase ) ) { + if ( rank == null ) + throw new ArgumentNullException( "rank" ); + if ( newName == null ) + throw new ArgumentNullException( "newName" ); + if ( rank.Name.Equals( newName, StringComparison.OrdinalIgnoreCase ) ) { return true; } else { return !RanksByName.ContainsKey( newName.ToLower() ); } } - public static void RenameRank( [NotNull] Rank rank, [NotNull] string newName ) { - if( rank == null ) throw new ArgumentNullException( "rank" ); - if( newName == null ) throw new ArgumentNullException( "newName" ); + if ( rank == null ) + throw new ArgumentNullException( "rank" ); + if ( newName == null ) + throw new ArgumentNullException( "newName" ); RanksByName.Remove( rank.Name.ToLower() ); rank.Name = newName; rank.FullName = rank.Name + "#" + rank.ID; RanksByName.Add( rank.Name.ToLower(), rank ); } - public static bool RaiseRank( [NotNull] Rank rank ) { - if( rank == null ) throw new ArgumentNullException( "rank" ); - if( rank == Ranks.First() ) { + if ( rank == null ) + throw new ArgumentNullException( "rank" ); + if ( rank == Ranks.First() ) { return false; } Rank nextRankUp = Ranks[rank.Index - 1]; @@ -196,10 +201,10 @@ public static bool RaiseRank( [NotNull] Rank rank ) { return true; } - public static bool LowerRank( [NotNull] Rank rank ) { - if( rank == null ) throw new ArgumentNullException( "rank" ); - if( rank == Ranks.Last() ) { + if ( rank == null ) + throw new ArgumentNullException( "rank" ); + if ( rank == Ranks.Last() ) { return false; } Rank nextRankDown = Ranks[rank.Index + 1]; @@ -209,10 +214,9 @@ public static bool LowerRank( [NotNull] Rank rank ) { return true; } - internal static void ParsePermissionLimits() { - foreach( Rank rank in Ranks ) { - if( !rank.ParsePermissionLimits() ) { + foreach ( Rank rank in Ranks ) { + if ( !rank.ParsePermissionLimits() ) { Logger.Log( LogType.Warning, "Could not parse one of the rank-limits for kick, ban, promote, and/or demote permissions for {0}. " + "Any unrecognized limits were reset to defaults (own rank).", @@ -221,21 +225,20 @@ internal static void ParsePermissionLimits() { } } - public static string GenerateID() { return Server.GetRandomString( 16 ); } - /// Finds the lowest rank that has all the required permissions. /// One or more permissions to check for. /// A relevant Rank object, or null of none were found. [CanBeNull] public static Rank GetMinRankWithAllPermissions( [NotNull] params Permission[] permissions ) { - if( permissions == null ) throw new ArgumentNullException( "permissions" ); - for( int r = Ranks.Count - 1; r >= 0; r-- ) { + if ( permissions == null ) + throw new ArgumentNullException( "permissions" ); + for ( int r = Ranks.Count - 1; r >= 0; r-- ) { int r1 = r; - if( permissions.All( t => Ranks[r1].Can( t ) ) ) { + if ( permissions.All( t => Ranks[r1].Can( t ) ) ) { return Ranks[r]; } } @@ -247,10 +250,11 @@ public static Rank GetMinRankWithAllPermissions( [NotNull] params Permission[] p /// A relevant Rank object, or null of none were found. [CanBeNull] public static Rank GetMinRankWithAnyPermission( [NotNull] params Permission[] permissions ) { - if( permissions == null ) throw new ArgumentNullException( "permissions" ); - for( int r = Ranks.Count - 1; r >= 0; r-- ) { + if ( permissions == null ) + throw new ArgumentNullException( "permissions" ); + for ( int r = Ranks.Count - 1; r >= 0; r-- ) { int r1 = r; - if( permissions.Any( t => Ranks[r1].Can( t ) ) ) { + if ( permissions.Any( t => Ranks[r1].Can( t ) ) ) { return Ranks[r]; } } diff --git a/fCraft/Plugins/Plugin.cs b/fCraft/Plugins/Plugin.cs index 4adb39e..01db7fd 100644 --- a/fCraft/Plugins/Plugin.cs +++ b/fCraft/Plugins/Plugin.cs @@ -24,18 +24,17 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace fCraft -{ - public interface Plugin - { + +namespace fCraft { + + public interface Plugin { + String Name { get; set; } + String Version { get; set; } void Initialize(); } -} +} \ No newline at end of file diff --git a/fCraft/Plugins/PluginConfig.cs b/fCraft/Plugins/PluginConfig.cs index 0a4bdc3..d5f1121 100644 --- a/fCraft/Plugins/PluginConfig.cs +++ b/fCraft/Plugins/PluginConfig.cs @@ -1,36 +1,29 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.IO; -namespace fCraft -{ - public abstract class PluginConfig - { - public virtual void Save(Plugin plugin, String file) - { +namespace fCraft { + + public abstract class PluginConfig { + + public virtual void Save( Plugin plugin, String file ) { // Append plugin directory String realFile = "plugins/" + plugin.Name + "/" + file; - PluginConfigSerializer.Serialize(realFile, this); + PluginConfigSerializer.Serialize( realFile, this ); } - public virtual PluginConfig Load(Plugin plugin, String file, Type type) - { + public virtual PluginConfig Load( Plugin plugin, String file, Type type ) { // Append plugin directory String realFile = "plugins/" + plugin.Name + "/" + file; - if (!Directory.Exists("plugins/" + plugin.Name)) - { - Directory.CreateDirectory("plugins/" + plugin.Name); + if ( !Directory.Exists( "plugins/" + plugin.Name ) ) { + Directory.CreateDirectory( "plugins/" + plugin.Name ); } - if (!File.Exists(realFile)) - { - Save(plugin, file); + if ( !File.Exists( realFile ) ) { + Save( plugin, file ); } - return PluginConfigSerializer.Deserialize(realFile, type); + return PluginConfigSerializer.Deserialize( realFile, type ); } } -} +} \ No newline at end of file diff --git a/fCraft/Plugins/PluginConfigSerializer.cs b/fCraft/Plugins/PluginConfigSerializer.cs index e56e762..f41baec 100644 --- a/fCraft/Plugins/PluginConfigSerializer.cs +++ b/fCraft/Plugins/PluginConfigSerializer.cs @@ -1,30 +1,25 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml.Serialization; using System.IO; +using System.Xml.Serialization; + +namespace fCraft { + + public class PluginConfigSerializer { -namespace fCraft -{ - public class PluginConfigSerializer - { - public static void Serialize(String configFile, PluginConfig config) - { - XmlSerializer xs = new XmlSerializer(config.GetType()); - StreamWriter writer = File.CreateText(configFile); - xs.Serialize(writer, config); + public static void Serialize( String configFile, PluginConfig config ) { + XmlSerializer xs = new XmlSerializer( config.GetType() ); + StreamWriter writer = File.CreateText( configFile ); + xs.Serialize( writer, config ); writer.Flush(); writer.Close(); } - public static PluginConfig Deserialize(String configFile, Type type) - { - XmlSerializer xs = new XmlSerializer(type); - StreamReader reader = File.OpenText(configFile); - PluginConfig c = (PluginConfig)xs.Deserialize(reader); + public static PluginConfig Deserialize( String configFile, Type type ) { + XmlSerializer xs = new XmlSerializer( type ); + StreamReader reader = File.OpenText( configFile ); + PluginConfig c = ( PluginConfig )xs.Deserialize( reader ); reader.Close(); return c; } } -} +} \ No newline at end of file diff --git a/fCraft/Plugins/PluginManager.cs b/fCraft/Plugins/PluginManager.cs index 0b0b2db..39af783 100644 --- a/fCraft/Plugins/PluginManager.cs +++ b/fCraft/Plugins/PluginManager.cs @@ -24,25 +24,23 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.IO; using System.Reflection; -using System.Collections; -using System.Security.Policy; namespace fCraft { - class PluginManager { + + internal class PluginManager { private static PluginManager instance; public List Plugins = new List(); - private PluginManager () { + private PluginManager() { // Empty bitch } - public static PluginManager GetInstance () { + public static PluginManager GetInstance() { if ( instance == null ) { instance = new PluginManager(); instance.Initialize(); @@ -51,7 +49,7 @@ public static PluginManager GetInstance () { return instance; } - private void Initialize () { + private void Initialize() { try { if ( !Directory.Exists( "plugins" ) ) { Directory.CreateDirectory( "plugins" ); @@ -92,7 +90,7 @@ private void Initialize () { LoadPlugins(); } - private void LoadPlugins () { + private void LoadPlugins() { if ( Plugins.Count > 0 ) { foreach ( Plugin plugin in Plugins ) { Logger.Log( LogType.ConsoleOutput, "PluginManager: Loading plugin " + plugin.Name ); diff --git a/fCraft/Plugins/Plugins/TrollPlugin.cs b/fCraft/Plugins/Plugins/TrollPlugin.cs index 87960e2..5763d1b 100644 --- a/fCraft/Plugins/Plugins/TrollPlugin.cs +++ b/fCraft/Plugins/Plugins/TrollPlugin.cs @@ -1,21 +1,15 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft; +using fCraft; -namespace TrollPlugin -{ - public class Init : Plugin - { - public void Initialize() - { - Logger.Log(LogType.ConsoleOutput, Name + "(v " + Version + "): Registering TrollPlugin"); - CommandManager.RegisterCustomCommand(CdTroll); +namespace TrollPlugin { + + public class Init : Plugin { + + public void Initialize() { + Logger.Log( LogType.ConsoleOutput, Name + "(v " + Version + "): Registering TrollPlugin" ); + CommandManager.RegisterCustomCommand( CdTroll ); } - static CommandDescriptor CdTroll = new CommandDescriptor - { + private static CommandDescriptor CdTroll = new CommandDescriptor { Name = "Troll", Category = CommandCategory.Chat | CommandCategory.Fun, Permissions = new[] { Permission.Troll }, @@ -28,90 +22,84 @@ public void Initialize() }; //your plugin name - public string Name - { - get - { + public string Name { + get { return "TrollPlugin"; } - set - { + set { Name = value; } } //your plugin version - public string Version - { - get - { + public string Version { + get { return "1.0"; } - set - { + set { Version = value; } } - static void TrollHandler(Player player, Command cmd) - { + private static void TrollHandler( Player player, Command cmd ) { string Name = cmd.Next(); - if (Name == null) - { - player.Message("Player not found. Please specify valid name."); + if ( Name == null ) { + player.Message( "Player not found. Please specify valid name." ); return; } - if (!Player.IsValidName(Name)) + if ( !Player.IsValidName( Name ) ) return; - Player target = Server.FindPlayerOrPrintMatches(player, Name, true, true); - if (target == null) + Player target = Server.FindPlayerOrPrintMatches( player, Name, true, true ); + if ( target == null ) return; string options = cmd.Next(); - if (options == null) - { - CdTroll.PrintUsage(player); + if ( options == null ) { + CdTroll.PrintUsage( player ); return; } string Message = cmd.NextAll(); - if (Message.Length < 1 && options.ToLower() != "leave") - { - player.Message("&WError: Please enter a message for {0}.", target.ClassyName); + if ( Message.Length < 1 && options.ToLower() != "leave" ) { + player.Message( "&WError: Please enter a message for {0}.", target.ClassyName ); return; } - switch (options.ToLower()) - { + switch ( options.ToLower() ) { case "pm": - if (player.Can(Permission.UseColorCodes) && Message.Contains("%")) - { - Message = Color.ReplacePercentCodes(Message); + if ( player.Can( Permission.UseColorCodes ) && Message.Contains( "%" ) ) { + Message = Color.ReplacePercentCodes( Message ); } - Server.Players.Message("&Pfrom {0}: {1}", - target.Name, Message); + Server.Players.Message( "&Pfrom {0}: {1}", + target.Name, Message ); break; + case "ac": - Chat.SendAdmin(target, Message); + Chat.SendAdmin( target, Message ); break; + case "st": case "staff": - Chat.SendStaff(target, Message); + Chat.SendStaff( target, Message ); break; + case "i": case "impersonate": case "msg": case "message": case "m": - Server.Message("{0}&S&F: {1}", - target.ClassyName, Message); + Server.Message( "{0}&S&F: {1}", + target.ClassyName, Message ); break; + case "leave": case "disconnect": case "gtfo": - Server.Players.Message("&SPlayer {0}&S left the server.", - target.ClassyName); + Server.Players.Message( "&SPlayer {0}&S left the server.", + target.ClassyName ); break; - default: player.Message("Invalid option. Please choose st, ac, pm, message or leave"); + + default: + player.Message( "Invalid option. Please choose st, ac, pm, message or leave" ); break; } } } -} +} \ No newline at end of file diff --git a/fCraft/Plugins/SecurityController.cs b/fCraft/Plugins/SecurityController.cs index 63fbbbd..38cf55c 100644 --- a/fCraft/Plugins/SecurityController.cs +++ b/fCraft/Plugins/SecurityController.cs @@ -11,15 +11,15 @@ namespace fCraft { /// Controller for setting and checking per-rank permissions and per-player exceptions. /// Used by World.AccessSecurity, World.BuildSecurity, and Zone. public sealed class SecurityController : ICloneable, INotifiesOnChange { - - readonly Dictionary includedPlayers = new Dictionary(); - readonly Dictionary excludedPlayers = new Dictionary(); + private readonly Dictionary includedPlayers = new Dictionary(); + private readonly Dictionary excludedPlayers = new Dictionary(); public PlayerExceptions ExceptionList { get; private set; } - readonly object locker = new object(); - + + private readonly object locker = new object(); + [CanBeNull] - Rank minRank; + private Rank minRank; /// Lowest allowed player rank. [NotNull] @@ -28,8 +28,9 @@ public Rank MinRank { return minRank ?? RankManager.LowestRank; } set { - if( value == null ) throw new ArgumentNullException( "value" ); - if( minRank != value ) { + if ( value == null ) + throw new ArgumentNullException( "value" ); + if ( minRank != value ) { minRank = value; RaiseChangedEvent(); } @@ -37,21 +38,19 @@ public Rank MinRank { } public void ResetMinRank() { - if( minRank != null ) { + if ( minRank != null ) { minRank = null; RaiseChangedEvent(); } } - /// True if a rank restriction is in effect. /// This property is used to distinguish cases of no MinRank set /// vs. cases of MinRank set to LowestRank. public bool HasRankRestriction { - get { return (minRank != null); } + get { return ( minRank != null ); } } - /// True if this controller has any restrictions /// (per-rank or per-player). public bool HasRestrictions { @@ -61,31 +60,29 @@ public bool HasRestrictions { } } - /// Creates a new controller with no restrictions. public SecurityController() { UpdatePlayerListCache(); } - - void UpdatePlayerListCache() { - lock( locker ) { + private void UpdatePlayerListCache() { + lock ( locker ) { ExceptionList = new PlayerExceptions( includedPlayers.Values.ToArray(), excludedPlayers.Values.ToArray() ); } } - /// Either specially includes a player (if their state /// was previously neutral), or removes a specific exclusion. /// Player's info. /// Previous exception state of the player. public PermissionOverride Include( [NotNull] PlayerInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); - lock( locker ) { - if( includedPlayers.ContainsValue( info ) ) { + if ( info == null ) + throw new ArgumentNullException( "info" ); + lock ( locker ) { + if ( includedPlayers.ContainsValue( info ) ) { return PermissionOverride.Allow; - } else if( excludedPlayers.ContainsValue( info ) ) { + } else if ( excludedPlayers.ContainsValue( info ) ) { excludedPlayers.Remove( info.Name.ToLower() ); UpdatePlayerListCache(); RaiseChangedEvent(); @@ -99,17 +96,17 @@ public PermissionOverride Include( [NotNull] PlayerInfo info ) { } } - /// Either specially excludes a player (if their state /// was previously neutral), or removes a specific inclusion. /// Player's info. /// Previous exception state of the player. public PermissionOverride Exclude( [NotNull] PlayerInfo info ) { - if( info == null ) throw new ArgumentNullException( "info" ); - lock( locker ) { - if( excludedPlayers.ContainsValue( info ) ) { + if ( info == null ) + throw new ArgumentNullException( "info" ); + lock ( locker ) { + if ( excludedPlayers.ContainsValue( info ) ) { return PermissionOverride.Deny; - } else if( includedPlayers.ContainsValue( info ) ) { + } else if ( includedPlayers.ContainsValue( info ) ) { includedPlayers.Remove( info.Name.ToLower() ); UpdatePlayerListCache(); RaiseChangedEvent(); @@ -123,24 +120,25 @@ public PermissionOverride Exclude( [NotNull] PlayerInfo info ) { } } - /// Checks whether a player is allowed by this controller. /// Player to check. /// True if player is allowed. public bool Check( [NotNull] PlayerInfo info ) { // ReSharper disable LoopCanBeConvertedToQuery - if( info == null ) throw new ArgumentNullException( "info" ); + if ( info == null ) + throw new ArgumentNullException( "info" ); PlayerExceptions listCache = ExceptionList; - for( int i = 0; i < listCache.Excluded.Length; i++ ) { - if( listCache.Excluded[i] == info ) { + for ( int i = 0; i < listCache.Excluded.Length; i++ ) { + if ( listCache.Excluded[i] == info ) { return false; } } - if( info.Rank >= MinRank /*&& player.info.rank <= maxRank*/ ) return true; // TODO: implement maxrank + if ( info.Rank >= MinRank /*&& player.info.rank <= maxRank*/ ) + return true; // TODO: implement maxrank - for( int i = 0; i < listCache.Included.Length; i++ ) { - if( listCache.Included[i] == info ) { + for ( int i = 0; i < listCache.Included.Length; i++ ) { + if ( listCache.Included[i] == info ) { return true; } } @@ -149,25 +147,25 @@ public bool Check( [NotNull] PlayerInfo info ) { // ReSharper restore LoopCanBeConvertedToQuery } - /// Checks player's permission status with this controller, in detail. /// Player to check. /// Security check result. public SecurityCheckResult CheckDetailed( [NotNull] PlayerInfo info ) { // ReSharper disable LoopCanBeConvertedToQuery - if( info == null ) throw new ArgumentNullException( "info" ); + if ( info == null ) + throw new ArgumentNullException( "info" ); PlayerExceptions listCache = ExceptionList; - for( int i = 0; i < listCache.Excluded.Length; i++ ) { - if( listCache.Excluded[i] == info ) { + for ( int i = 0; i < listCache.Excluded.Length; i++ ) { + if ( listCache.Excluded[i] == info ) { return SecurityCheckResult.BlackListed; } } - if( info.Rank >= MinRank /*&& player.info.rank <= maxRank*/ ) // TODO: implement maxrank + if ( info.Rank >= MinRank /*&& player.info.rank <= maxRank*/ ) // TODO: implement maxrank return SecurityCheckResult.Allowed; - for( int i = 0; i < listCache.Included.Length; i++ ) { - if( listCache.Included[i] == info ) { + for ( int i = 0; i < listCache.Included.Length; i++ ) { + if ( listCache.Included[i] == info ) { return SecurityCheckResult.WhiteListed; } } @@ -176,22 +174,24 @@ public SecurityCheckResult CheckDetailed( [NotNull] PlayerInfo info ) { // ReSharper restore LoopCanBeConvertedToQuery } - /// Creates a description string of the controller. /// Name of the object that owns this controller. /// The type of target (e.g. "world" or "zone"). /// The action, in past tense, that this /// controller manages (e.g. "accessed" or "modified"). public string GetDescription( [NotNull] IClassy target, [NotNull] string noun, [NotNull] string verb ) { - if( target == null ) throw new ArgumentNullException( "target" ); - if( noun == null ) throw new ArgumentNullException( "noun" ); - if( verb == null ) throw new ArgumentNullException( "verb" ); + if ( target == null ) + throw new ArgumentNullException( "target" ); + if ( noun == null ) + throw new ArgumentNullException( "noun" ); + if ( verb == null ) + throw new ArgumentNullException( "verb" ); PlayerExceptions list = ExceptionList; StringBuilder message = new StringBuilder( noun ); message[0] = Char.ToUpper( message[0] ); // capitalize first letter. - if( HasRankRestriction ) { + if ( HasRankRestriction ) { message.AppendFormat( " {0}&S can only be {1} by {2}+&S", target.ClassyName, verb, @@ -202,11 +202,11 @@ public string GetDescription( [NotNull] IClassy target, [NotNull] string noun, [ verb ); } - if( list.Included.Length > 0 ) { + if ( list.Included.Length > 0 ) { message.AppendFormat( " and {0}&S", list.Included.JoinToClassyString() ); } - if( list.Excluded.Length > 0 ) { + if ( list.Excluded.Length > 0 ) { message.AppendFormat( ", except {0}&S", list.Excluded.JoinToClassyString() ); } @@ -214,16 +214,16 @@ public string GetDescription( [NotNull] IClassy target, [NotNull] string noun, [ return message.ToString(); } - #region XML Serialization public const string XmlRootElementName = "PermissionController"; - readonly XElement[] rawExceptions; + private readonly XElement[] rawExceptions; public SecurityController( [NotNull] XContainer el, bool parseExceptions ) { - if( el == null ) throw new ArgumentNullException( "el" ); - if( el.Element( "minRank" ) != null ) { + if ( el == null ) + throw new ArgumentNullException( "el" ); + if ( el.Element( "minRank" ) != null ) { // ReSharper disable PossibleNullReferenceException minRank = Rank.Parse( el.Element( "minRank" ).Value ); // ReSharper restore PossibleNullReferenceException @@ -231,18 +231,22 @@ public SecurityController( [NotNull] XContainer el, bool parseExceptions ) { minRank = null; } - if( parseExceptions ) { + if ( parseExceptions ) { //maxRank = Rank.Parse( root.Element( "maxRank" ).Value ); - foreach( XElement player in el.Elements( "included" ) ) { - if( !Player.IsValidName( player.Value ) ) continue; + foreach ( XElement player in el.Elements( "included" ) ) { + if ( !Player.IsValidName( player.Value ) ) + continue; PlayerInfo info = PlayerDB.FindPlayerInfoExact( player.Value ); - if( info != null ) Include( info ); + if ( info != null ) + Include( info ); } - foreach( XElement player in el.Elements( "excluded" ) ) { - if( !Player.IsValidName( player.Value ) ) continue; + foreach ( XElement player in el.Elements( "excluded" ) ) { + if ( !Player.IsValidName( player.Value ) ) + continue; PlayerInfo info = PlayerDB.FindPlayerInfoExact( player.Value ); - if( info != null ) Exclude( info ); + if ( info != null ) + Exclude( info ); } } else { rawExceptions = el.Elements( "included" ).Union( el.Elements( "excluded" ) ).ToArray(); @@ -250,30 +254,29 @@ public SecurityController( [NotNull] XContainer el, bool parseExceptions ) { UpdatePlayerListCache(); } - public XElement Serialize() { return Serialize( XmlRootElementName ); } - public XElement Serialize( [NotNull] string tagName ) { - if( tagName == null ) throw new ArgumentNullException( "tagName" ); + if ( tagName == null ) + throw new ArgumentNullException( "tagName" ); XElement root = new XElement( tagName ); - if( HasRankRestriction ) { + if ( HasRankRestriction ) { root.Add( new XElement( "minRank", MinRank.FullName ) ); } //root.Add( new XElement( "maxRank", maxRank ) ); - lock( locker ) { - foreach( string playerName in includedPlayers.Keys ) { + lock ( locker ) { + foreach ( string playerName in includedPlayers.Keys ) { root.Add( new XElement( "included", playerName ) ); } - foreach( string playerName in excludedPlayers.Keys ) { + foreach ( string playerName in excludedPlayers.Keys ) { root.Add( new XElement( "excluded", playerName ) ); } - if( rawExceptions != null ) { - foreach( XElement exception in rawExceptions ) { + if ( rawExceptions != null ) { + foreach ( XElement exception in rawExceptions ) { root.Add( exception ); } } @@ -281,29 +284,26 @@ public XElement Serialize( [NotNull] string tagName ) { return root; } - #endregion - + #endregion XML Serialization #region Resetting /// Clears the list of specifically included players. public void ResetIncludedList() { - lock( locker ) { + lock ( locker ) { includedPlayers.Clear(); UpdatePlayerListCache(); } } - /// Clears the list of specifically excluded players. public void ResetExcludedList() { - lock( locker ) { + lock ( locker ) { excludedPlayers.Clear(); UpdatePlayerListCache(); } } - /// Resets all permissions: minimum rank, /// excluded player list, and included player list. public void Reset() { @@ -312,45 +312,47 @@ public void Reset() { ResetExcludedList(); } - #endregion - + #endregion Resetting #region Cloning /// Creates a copy of an existing controller. public SecurityController( [NotNull] SecurityController other ) { - if( other == null ) throw new ArgumentNullException( "other" ); + if ( other == null ) + throw new ArgumentNullException( "other" ); minRank = other.minRank; rawExceptions = other.rawExceptions; - lock( other.locker ) { + lock ( other.locker ) { includedPlayers = new Dictionary( other.includedPlayers ); excludedPlayers = new Dictionary( other.excludedPlayers ); } UpdatePlayerListCache(); } - /// Creates a copy of an existing controller. public object Clone() { return new SecurityController( this ); } - #endregion + #endregion Cloning public event EventHandler Changed; - void RaiseChangedEvent() { + private void RaiseChangedEvent() { var h = Changed; - if( h != null ) h( null, EventArgs.Empty ); + if ( h != null ) + h( null, EventArgs.Empty ); } } - /// List of included and excluded players. public struct PlayerExceptions { + public PlayerExceptions( [NotNull] PlayerInfo[] included, [NotNull] PlayerInfo[] excluded ) { - if( included == null ) throw new ArgumentNullException( "included" ); - if( excluded == null ) throw new ArgumentNullException( "excluded" ); + if ( included == null ) + throw new ArgumentNullException( "included" ); + if ( excluded == null ) + throw new ArgumentNullException( "excluded" ); Included = included; Excluded = excluded; } @@ -361,11 +363,11 @@ public PlayerExceptions( [NotNull] PlayerInfo[] included, [NotNull] PlayerInfo[] public readonly PlayerInfo[] Excluded; } - #region Enums /// Indicates what kind of per-entity override/exception is defined in a security controller. public enum PermissionOverride { + /// No permission exception. None, @@ -376,9 +378,9 @@ public enum PermissionOverride { Deny } - /// Possible results of a SecurityController permission check. public enum SecurityCheckResult { + /// Allowed, no permission involved. Allowed, @@ -395,5 +397,5 @@ public enum SecurityCheckResult { BlackListed } - #endregion + #endregion Enums } \ No newline at end of file diff --git a/fCraft/Portals/Portal.cs b/fCraft/Portals/Portal.cs index 681c785..3edcf43 100644 --- a/fCraft/Portals/Portal.cs +++ b/fCraft/Portals/Portal.cs @@ -24,35 +24,46 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft.Drawing; -using System.Threading; using System.Runtime.Serialization; +using fCraft.Drawing; namespace fCraft.Portals { + public class Portal { + public String Name { get; set; } + public String Creator { get; set; } + public DateTime Created { get; set; } + public String World { get; set; } + public Vector3I[] AffectedBlocks { get; set; } + public PortalRange Range { get; set; } + public String Place { get; set; } + public int DesiredOutputX { get; set; } + public int DesiredOutputY { get; set; } + public int DesiredOutputZ { get; set; } + public byte DesiredOutputR { get; set; } + public byte DesiredOutputL { get; set; } + public bool HasDesiredOutput = false; - public Portal () { + public Portal() { //empty } - public Portal ( String world, Vector3I[] affectedBlocks, String Name, String Creator, String Place, bool CustomOutput ) { + public Portal( String world, Vector3I[] affectedBlocks, String Name, String Creator, String Place, bool CustomOutput ) { this.World = world; this.AffectedBlocks = affectedBlocks; this.Range = Portal.CalculateRange( this ); @@ -63,7 +74,7 @@ public Portal ( String world, Vector3I[] affectedBlocks, String Name, String Cre this.HasDesiredOutput = CustomOutput; } - public static PortalRange CalculateRange ( Portal portal ) { + public static PortalRange CalculateRange( Portal portal ) { PortalRange range = new PortalRange( 0, 0, 0, 0, 0, 0 ); foreach ( Vector3I block in portal.AffectedBlocks ) { @@ -119,7 +130,7 @@ public static PortalRange CalculateRange ( Portal portal ) { return range; } - public bool IsInRange ( Player player ) { + public bool IsInRange( Player player ) { if ( ( player.Position.X / 32 ) <= Range.Xmax && ( player.Position.X / 32 ) >= Range.Xmin ) { if ( ( player.Position.Y / 32 ) <= Range.Ymax && ( player.Position.Y / 32 ) >= Range.Ymin ) { if ( ( ( player.Position.Z / 32 ) - 1 ) <= Range.Zmax && ( ( player.Position.Z / 32 ) - 1 ) >= Range.Zmin ) { @@ -131,7 +142,7 @@ public bool IsInRange ( Player player ) { return false; } - public bool IsInRange ( Vector3I vector ) { + public bool IsInRange( Vector3I vector ) { if ( vector.X <= Range.Xmax && vector.X >= Range.Xmin ) { if ( vector.Y <= Range.Ymax && vector.Y >= Range.Ymin ) { if ( vector.Z <= Range.Zmax && vector.Z >= Range.Zmin ) { @@ -143,7 +154,7 @@ public bool IsInRange ( Vector3I vector ) { return false; } - public static String GenerateName ( string World, bool Custom ) { + public static String GenerateName( string World, bool Custom ) { World world = WorldManager.FindWorldExact( World ); if ( Custom ) { if ( !world.IsLoaded ) { @@ -184,7 +195,7 @@ public static String GenerateName ( string World, bool Custom ) { return "portal1"; } - public static bool DoesNameExist ( World world, String name ) { + public static bool DoesNameExist( World world, String name ) { if ( world.Map.Portals != null ) { if ( world.Map.Portals.Count > 0 ) { foreach ( Portal portal in world.Map.Portals ) { @@ -198,7 +209,7 @@ public static bool DoesNameExist ( World world, String name ) { return false; } - public void Remove ( Player requester ) { + public void Remove( Player requester ) { NormalBrush brush = new NormalBrush( Block.Air, Block.Air ); DrawOperation removeOperation = new CuboidDrawOperation( requester ); removeOperation.AnnounceCompletion = false; @@ -222,7 +233,7 @@ public void Remove ( Player requester ) { } } - public string Serialize () { + public string Serialize() { SerializedData data = new SerializedData( this ); DataContractSerializer serializer = new DataContractSerializer( typeof( SerializedData ) ); System.IO.MemoryStream s = new System.IO.MemoryStream(); @@ -230,7 +241,7 @@ public string Serialize () { return Convert.ToBase64String( s.ToArray() ); } - public static Portal Deserialize ( string name, string sdata, Map map ) { + public static Portal Deserialize( string name, string sdata, Map map ) { byte[] bdata = Convert.FromBase64String( sdata ); Portal portal = new Portal(); DataContractSerializer serializer = new DataContractSerializer( typeof( SerializedData ) ); @@ -240,44 +251,62 @@ public static Portal Deserialize ( string name, string sdata, Map map ) { data.UpdatePortal( portal ); return portal; } + [DataContract] private class SerializedData { + [DataMember] public String Name; + [DataMember] public String Creator; + [DataMember] public DateTime Created; + [DataMember] public String World; + [DataMember] public int XMin; + [DataMember] public int XMax; + [DataMember] public int YMin; + [DataMember] public int YMax; + [DataMember] public int ZMin; + [DataMember] public int ZMax; + [DataMember] public String Place; + [DataMember] public int DesiredOutputX; + [DataMember] public int DesiredOutputY; + [DataMember] public int DesiredOutputZ; + [DataMember] public byte DesiredOutputR; + [DataMember] public byte DesiredOutputL; + [DataMember] public bool HasDesiredOutput; - public SerializedData ( Portal portal ) { + public SerializedData( Portal portal ) { lock ( portal ) { Name = portal.Name; Creator = portal.Creator; @@ -299,7 +328,7 @@ public SerializedData ( Portal portal ) { } } - public void UpdatePortal ( Portal portal ) { + public void UpdatePortal( Portal portal ) { portal.Name = Name; portal.Creator = Creator; portal.Created = Created; @@ -315,4 +344,4 @@ public void UpdatePortal ( Portal portal ) { } } } -} +} \ No newline at end of file diff --git a/fCraft/Portals/PortalException.cs b/fCraft/Portals/PortalException.cs index 7b8774b..290c976 100644 --- a/fCraft/Portals/PortalException.cs +++ b/fCraft/Portals/PortalException.cs @@ -24,19 +24,16 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -namespace fCraft.Portals -{ - class PortalException : Exception - { - public PortalException(String message) - : base(message) - { +namespace fCraft.Portals { + + internal class PortalException : Exception { + + public PortalException( String message ) + : base( message ) { // Do nothing } } -} +} \ No newline at end of file diff --git a/fCraft/Portals/PortalHandler.cs b/fCraft/Portals/PortalHandler.cs index 943e2ab..7e37fb7 100644 --- a/fCraft/Portals/PortalHandler.cs +++ b/fCraft/Portals/PortalHandler.cs @@ -24,22 +24,21 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----*/ + using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Collections; +using System.Linq; namespace fCraft.Portals { - class PortalHandler { + internal class PortalHandler { private static PortalHandler instance; - private PortalHandler () { + private PortalHandler() { // Empty, singleton } - public static PortalHandler GetInstance () { + public static PortalHandler GetInstance() { if ( instance == null ) { instance = new PortalHandler(); Player.Moved += new EventHandler( Player_Moved ); @@ -50,11 +49,10 @@ public static PortalHandler GetInstance () { return instance; } - static void Player_PlacingBlock ( object sender, Events.PlayerPlacingBlockEventArgs e ) { + private static void Player_PlacingBlock( object sender, Events.PlayerPlacingBlockEventArgs e ) { try { if ( e.Player.World.Map.Portals != null && e.Player.World.Map.Portals.Count > 0 && e.Context != BlockChangeContext.Portal ) { lock ( e.Player.World.Map.Portals.SyncRoot ) { - foreach ( Portal portal in e.Player.World.Map.Portals ) { if ( portal.IsInRange( e.Coords ) ) { e.Result = CanPlaceResult.Revert; @@ -77,8 +75,8 @@ static void Player_PlacingBlock ( object sender, Events.PlayerPlacingBlockEventA e.Player.PortalCache.DesiredOutputX = e.Coords.ToPlayerCoords().X; e.Player.PortalCache.DesiredOutputY = e.Coords.ToPlayerCoords().Y; e.Player.PortalCache.DesiredOutputZ = ( e.Coords.Z + 2 ) * 32; - e.Player.PortalCache.DesiredOutputR = e.Player.Position.R; - e.Player.PortalCache.DesiredOutputL = e.Player.Position.L; + e.Player.PortalCache.DesiredOutputR = e.Player.Position.R; + e.Player.PortalCache.DesiredOutputL = e.Player.Position.L; e.Player.PortalCache.Name = Portal.GenerateName( e.Player.PortalCache.World, true ); string oldWorld = e.Player.PortalCache.World; @@ -96,7 +94,7 @@ static void Player_PlacingBlock ( object sender, Events.PlayerPlacingBlockEventA } } - static void Player_JoinedWorld ( object sender, Events.PlayerJoinedWorldEventArgs e ) { + private static void Player_JoinedWorld( object sender, Events.PlayerJoinedWorldEventArgs e ) { try { // Player can use portals again e.Player.CanUsePortal = true; @@ -106,7 +104,7 @@ static void Player_JoinedWorld ( object sender, Events.PlayerJoinedWorldEventArg } } - static void Player_Moved ( object sender, Events.PlayerMovedEventArgs e ) { + private static void Player_Moved( object sender, Events.PlayerMovedEventArgs e ) { try { if ( e.Player.PortalsEnabled ) { lock ( e.Player.PortalLock ) { @@ -130,7 +128,8 @@ static void Player_Moved ( object sender, Events.PlayerMovedEventArgs e ) { Portal portal = PortalHandler.GetInstance().GetPortal( e.Player ); World world = WorldManager.FindWorldExact( portal.World ); - if ( world == null ) return; + if ( world == null ) + return; // Teleport player, portal protection switch ( world.AccessSecurity.CheckDetailed( e.Player.Info ) ) { case SecurityCheckResult.Allowed: @@ -144,7 +143,7 @@ static void Player_Moved ( object sender, Events.PlayerMovedEventArgs e ) { if ( !portal.HasDesiredOutput ) { e.Player.TeleportTo( e.Player.World.Map.Spawn ); } else { - e.Player.TeleportTo( new Position((short)portal.DesiredOutputX, (short)portal.DesiredOutputY, (short)portal.DesiredOutputZ, portal.DesiredOutputR, portal.DesiredOutputL) ); + e.Player.TeleportTo( new Position( ( short )portal.DesiredOutputX, ( short )portal.DesiredOutputY, ( short )portal.DesiredOutputZ, portal.DesiredOutputR, portal.DesiredOutputL ) ); } e.Player.LastWarnedPortal = DateTime.UtcNow; e.Player.StandingInPortal = false; @@ -164,6 +163,7 @@ static void Player_Moved ( object sender, Events.PlayerMovedEventArgs e ) { e.Player.Message( "Cannot join world {0}&S: you are blacklisted.", world.ClassyName ); break; + case SecurityCheckResult.RankTooLow: e.Player.Message( "Cannot join world {0}&S: must be {1}+", world.ClassyName, world.AccessSecurity.MinRank.ClassyName ); @@ -182,7 +182,7 @@ static void Player_Moved ( object sender, Events.PlayerMovedEventArgs e ) { } } - public Portal GetPortal ( Player player ) { + public Portal GetPortal( Player player ) { Portal portal = null; try { @@ -202,7 +202,7 @@ public Portal GetPortal ( Player player ) { return portal; } - public Portal GetPortal ( World world, Vector3I block ) { + public Portal GetPortal( World world, Vector3I block ) { Portal portal = null; try { @@ -222,7 +222,7 @@ public Portal GetPortal ( World world, Vector3I block ) { return portal; } - public static void CreatePortal ( Portal portal, World source, bool Custom ) { + public static void CreatePortal( Portal portal, World source, bool Custom ) { try { if ( Custom ) { if ( !source.IsLoaded ) { @@ -246,7 +246,7 @@ public static void CreatePortal ( Portal portal, World source, bool Custom ) { } } - public static bool IsInRangeOfSpawnpoint ( World world, Vector3I block ) { + public static bool IsInRangeOfSpawnpoint( World world, Vector3I block ) { try { int Xdistance = ( world.Map.Spawn.X / 32 ) - block.X; int Ydistance = ( world.Map.Spawn.Y / 32 ) - block.Y; @@ -266,4 +266,4 @@ public static bool IsInRangeOfSpawnpoint ( World world, Vector3I block ) { return false; } } -} +} \ No newline at end of file diff --git a/fCraft/Portals/PortalRange.cs b/fCraft/Portals/PortalRange.cs index 432c627..6a62487 100644 --- a/fCraft/Portals/PortalRange.cs +++ b/fCraft/Portals/PortalRange.cs @@ -26,27 +26,27 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ----*/ //Copyright (C) <2011 - 2013> Glenn Mariën (http://project-vanilla.com) -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -namespace fCraft.Portals -{ +namespace fCraft.Portals { + /// /// Class used for rapid check if user is in range of portal /// - public class PortalRange - { + public class PortalRange { + public int Xmin { get; set; } + public int Xmax { get; set; } + public int Ymin { get; set; } + public int Ymax { get; set; } + public int Zmin { get; set; } + public int Zmax { get; set; } - public PortalRange(int Xmin, int Xmax, int Ymin, int Ymax, int Zmin, int Zmax) - { + public PortalRange( int Xmin, int Xmax, int Ymin, int Ymax, int Zmin, int Zmax ) { this.Xmin = Xmin; this.Xmax = Xmax; this.Ymin = Ymin; @@ -55,4 +55,4 @@ public PortalRange(int Xmin, int Xmax, int Ymin, int Ymax, int Zmin, int Zmax) this.Zmax = Zmax; } } -} +} \ No newline at end of file diff --git a/fCraft/Portals/PortalSerialization.cs b/fCraft/Portals/PortalSerialization.cs index 8c35dc3..e4c33cb 100644 --- a/fCraft/Portals/PortalSerialization.cs +++ b/fCraft/Portals/PortalSerialization.cs @@ -27,24 +27,20 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY //Copyright (C) <2011 - 2013> Glenn Mariën (http://project-vanilla.com) using System; +using System.Collections; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; using System.IO; -using System.Collections; -using System.Runtime.Serialization; using fCraft.MapConversion; -namespace fCraft.Portals -{ - public class PortalSerialization : IConverterExtension - { +namespace fCraft.Portals { + + public class PortalSerialization : IConverterExtension { private static readonly object SaveLoadLock = new object(); private static List _group = new List { "portal" }; - public IEnumerable AcceptedGroups { get { return _group; } } - public int Serialize ( Map map, Stream stream, IMapConverterEx converter ) { + public IEnumerable AcceptedGroups { get { return _group; } } + + public int Serialize( Map map, Stream stream, IMapConverterEx converter ) { BinaryWriter writer = new BinaryWriter( stream ); int count = 0; if ( map.Portals != null ) { @@ -58,24 +54,21 @@ public int Serialize ( Map map, Stream stream, IMapConverterEx converter ) { return count; } - public void Deserialize(string group, string key, string value, Map map) - { - try - { - Portal portal = Portal.Deserialize(key, value, map); - if ( map.Portals == null ) map.Portals = new ArrayList(); + public void Deserialize( string group, string key, string value, Map map ) { + try { + Portal portal = Portal.Deserialize( key, value, map ); + if ( map.Portals == null ) + map.Portals = new ArrayList(); if ( map.Portals.Count >= 1 ) { if ( map.Portals.Contains( key ) ) { - Logger.Log( LogType.Error, "Map loading warning: duplicate portal name found: " + key + ", ignored" ); - return; + Logger.Log( LogType.Error, "Map loading warning: duplicate portal name found: " + key + ", ignored" ); + return; } } - map.Portals.Add(portal); - } - catch (Exception ex) - { - Logger.Log(LogType.Error, "Portal.Deserialize: Error deserializing portal {0}: {1}", key, ex); - } + map.Portals.Add( portal ); + } catch ( Exception ex ) { + Logger.Log( LogType.Error, "Portal.Deserialize: Error deserializing portal {0}: {1}", key, ex ); + } } } -} +} \ No newline at end of file diff --git a/fCraft/Properties/AssemblyInfo.cs b/fCraft/Properties/AssemblyInfo.cs index cfe9d3a..2636c0d 100644 --- a/fCraft/Properties/AssemblyInfo.cs +++ b/fCraft/Properties/AssemblyInfo.cs @@ -3,20 +3,20 @@ using System.Resources; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("800Craft")] -[assembly: AssemblyDescription("A better Minecraft server, based on fCraft.")] +[assembly: AssemblyTitle( "800Craft" )] +[assembly: AssemblyDescription( "A better Minecraft server, based on fCraft." )] [assembly: AssemblyConfiguration( "" )] -[assembly: AssemblyCompany("au70.net")] -[assembly: AssemblyProduct("800Craft")] -[assembly: AssemblyCopyright("")] +[assembly: AssemblyCompany( "au70.net" )] +[assembly: AssemblyProduct( "800Craft" )] +[assembly: AssemblyCopyright( "" )] [assembly: AssemblyTrademark( "" )] [assembly: AssemblyCulture( "" )] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible( false )] @@ -26,15 +26,14 @@ // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -// You can specify all the values or you can default the Build and Revision Numbers +// You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion( "0.6.1.7" )] [assembly: AssemblyFileVersion( "0.6.1.7" )] - [assembly: CLSCompliant( false )] [assembly: NeutralResourcesLanguage( "en-US" )] \ No newline at end of file diff --git a/fCraft/System/ArgKey.cs b/fCraft/System/ArgKey.cs index 41043ac..b634fa6 100644 --- a/fCraft/System/ArgKey.cs +++ b/fCraft/System/ArgKey.cs @@ -1,9 +1,11 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft { + /// Enumerates the recognized command-line switches/arguments. /// Args are parsed in Server.InitLibrary public enum ArgKey { + /// Working path (directory) that fCraft should use. /// If the path is relative, it's computed against the location of fCraft.dll Path, @@ -34,4 +36,4 @@ public enum ArgKey { /// Disables colors in CLI frontends. NoConsoleColor }; -} +} \ No newline at end of file diff --git a/fCraft/System/Config.cs b/fCraft/System/Config.cs index f5d32c4..4747e84 100644 --- a/fCraft/System/Config.cs +++ b/fCraft/System/Config.cs @@ -9,7 +9,6 @@ using JetBrains.Annotations; namespace fCraft { - /* * Config format-version changelog: * 100 - r1-r133 @@ -30,7 +29,7 @@ namespace fCraft { * Removed PolicyColorCodesInChat, PolicyIllegalCharacters, and RunOnStartup * * 106 - r212 - Added IRCDelay key - * + * * 107 - r214 - Added ShowJoinedWorldMessages and ClassColorsInWorldNames keys * Removed ChangeName permission * @@ -42,7 +41,7 @@ namespace fCraft { * * 110 - r227 - Added ShutdownServer and Mute permissions. * NOTE: This build does not support loading config.xml of this or earlier versions. - * + * * 111 - r231 - Renamed config keys: * DefaultClass -> DefaultRank * ClassColorsInChat -> RankColorsInChat @@ -63,99 +62,99 @@ namespace fCraft { * Removed inactive ControlPhysics and AddLandmarks permissions * * 113 - r243 - Removed IRCBotQuitMsg config key - * + * * 114 - r244 - Added IRCRegisteredNick, IRCNickServ, and IRCNickServMessage keys - * + * * 115 - r265 - Added IRCThreads keys - * + * * 116 - r272 - Added AutoRankEnabled keys - * + * * 117 - r280 - Added MaxUndo keys - * + * * 118 - r318 - Added MeColor and WarningColor keys - * + * * 119 - r331 - Added LogPath and MapPath keys - * + * * 120 - r332 - Added DataPath key - * + * * 121 - r335 - Renamed SendRedundantBlockUpdates key to RelayAllBlockUpdates - * + * * 122 - r341 - Added IRCUseColor key - * + * * 123 - r346 - Added IRCBotAnnounceServerEvents - * + * * 124 - r354 - Added HeartbeatEnabled - * + * * 125 - r356 - Removed LogPath and DataPath keys - * + * * 126 - r366 - Added PreventSecurityCircumvention key - * + * * 127 - r368 - Removed PreventSecurityCircumvention key * Added per-rank AllowSecurityCircumvention setting instead - * + * * 128 - r379 - Added ConsoleName - * + * * 129 - r405 - Added ShowConnectedMessages - * + * * 130 - r413 - Added ShowBannedConnectionMessages - * + * * 131 - r460 - Changed default for IRCNick from "fBot" to "MinecraftBot" * Relaxed range limits on many integer keys. - * Renamed ProcessPriority value "Low" to "Idle", to match WinAPI - * + * Renamed ProcessPriority value "Low" to "Idle", to match WinAPI + * * 132 - r477 - Added BackupBeforeUpdate, RunBeforeUpdate, and RunAfterUpdate config keys * Renamed UpdateMode to UpdaterMode - * + * * 133 - r517 - Added UseColorCodes permission - * + * * 134 - r520 - Removed LimitOneConnectionPerIP key * Added MaxConnectionsPerIP key - * + * * 135 - r526 - Added RequireKickReason and AnnounceRankChangeReasons keys * Added ViewPlayerIPs permission - * + * * 136 - r528 - Added BringAll permission. - * + * * 137 - r556 - Added BandwidthUseMode key. - * + * * 138 - r578 - Removed SaveOnShutdown key. * Tweaked range checks on some keys. * Grouped key tags into section tags. * When saving, keys with default values are now commented out. * CONFIGS SAVED WITH THIS VERSION ARE NOT LOADABLE. It is obsolete. - * + * * 139 - r579 - Fixed XML structure messed up by 138. Sections are now saved into
elements. - * + * * 140 - r616 - Added Spectate permission. - * + * * 141 - r622 - Added RestartInterval key. - * + * * 142 - r638 - Added BackupDataOnStartup key. - * + * * 143 - r676 - Added LoadPlugins key (currently unused). - * + * * 144 - r787 - Added DrawAdvanced permission. - * + * * 145 - r794 - Added UndoOthersActions permission. - * + * * 146 - r910 - Renamed BackupInterval to DefaultBackupInterval - * + * * 147 - r926 - Renamed EnableBlockDB to BlockDBEnabled - * + * * 148 - r1014 - Added BlockDBAutoEnable and BlockDBAutoEnableRank keys * Moved BlockDBEnabled to Security ConfigSection - * + * * 149 - r1061 - Added HeartbeatToWoMDirect, WoMDirectDescription, and WoMEnableEnvExtensions keys - * + * * 150 - r1066 - Removed WoMDirectDescription key - * + * * 151 - r1169 - Added MaxUndoStates key * Added fillLimit rank attribute. * Changed defaults for some keys: * BlockDBEnabled to "true" * WomEnableEnvExtensions to "false" * IRCBotAnnounceServerEvents to "true" - * + * * 152 - r1243 - Changed the way fCraft stores config keys. * Before:
Value
* After: @@ -164,6 +163,7 @@ namespace fCraft { /// Static class that handles loading/saving configuration, contains config defaults, /// and various configuration-related utilities. public static class Config { + /// Supported version of the Minecraft classic protocol. public const int ProtocolVersion = 7; @@ -171,32 +171,32 @@ public static class Config { /// Config.xml files saved with this build will have this version number embedded. public const int CurrentVersion = 158; - const int LowestSupportedVersion = 111, + private const int LowestSupportedVersion = 111, FirstVersionWithMaxPlayersKey = 134, // LEGACY FirstVersionWithSectionTags = 139, // LEGACY FirstVersionWithSettingsTag = 152; // LEGACY - const string ConfigXmlRootName = "fCraftConfig"; + private const string ConfigXmlRootName = "fCraftConfig"; // Mapping of keys to their values - static readonly string[] Settings; - static readonly bool[] SettingsEnabledCache; // cached .Enabled() calls - static readonly bool[] SettingsUseEnabledCache; // cached .Enabled() calls + private static readonly string[] Settings; + + private static readonly bool[] SettingsEnabledCache; // cached .Enabled() calls + private static readonly bool[] SettingsUseEnabledCache; // cached .Enabled() calls // Mapping of keys to their metadata containers. - static readonly ConfigKeyAttribute[] KeyMetadata; + private static readonly ConfigKeyAttribute[] KeyMetadata; // Keys organized by sections - static readonly Dictionary KeySections = new Dictionary(); + private static readonly Dictionary KeySections = new Dictionary(); // List of renamed/remapped keys. - static readonly Dictionary LegacyConfigKeys = new Dictionary(); // LEGACY + private static readonly Dictionary LegacyConfigKeys = new Dictionary(); // LEGACY // List of renamed/remapped key values. - static readonly Dictionary> LegacyConfigValues = + private static readonly Dictionary> LegacyConfigValues = new Dictionary>(); // LEGACY - static Config() { int keyCount = Enum.GetValues( typeof( ConfigKey ) ).Length; Settings = new string[keyCount]; @@ -205,20 +205,20 @@ static Config() { KeyMetadata = new ConfigKeyAttribute[keyCount]; // gather metadata for ConfigKeys - foreach( var keyField in typeof( ConfigKey ).GetFields() ) { - foreach( var attribute in (ConfigKeyAttribute[])keyField.GetCustomAttributes( typeof( ConfigKeyAttribute ), false ) ) { + foreach ( var keyField in typeof( ConfigKey ).GetFields() ) { + foreach ( var attribute in ( ConfigKeyAttribute[] )keyField.GetCustomAttributes( typeof( ConfigKeyAttribute ), false ) ) { // ReSharper disable AssignNullToNotNullAttribute - ConfigKey key = (ConfigKey)keyField.GetValue( null ); + ConfigKey key = ( ConfigKey )keyField.GetValue( null ); // ReSharper restore AssignNullToNotNullAttribute attribute.Key = key; - KeyMetadata[(int)key] = attribute; + KeyMetadata[( int )key] = attribute; } } // organize ConfigKeys into categories, based on metadata - foreach( ConfigSection section in Enum.GetValues( typeof( ConfigSection ) ) ) { + foreach ( ConfigSection section in Enum.GetValues( typeof( ConfigSection ) ) ) { ConfigSection sec = section; - KeySections.Add( section, KeyMetadata.Where( meta => (meta.Section == sec) ) + KeySections.Add( section, KeyMetadata.Where( meta => ( meta.Section == sec ) ) .Select( meta => meta.Key ) .ToArray() ); } @@ -238,7 +238,6 @@ static Config() { new KeyValuePair( "Low", ProcessPriorityClass.Idle.ToString() ) ); } - #if DEBUG // Makes sure that defaults and metadata containers are set. // This is invoked by Server.InitServer() if built with DEBUG flag. @@ -255,48 +254,42 @@ internal static void RunSelfTest() { } #endif - #region Defaults /// Overwrites current settings with defaults. public static void LoadDefaults() { - for( int i = 0; i < KeyMetadata.Length; i++ ) { - SetValue( (ConfigKey)i, KeyMetadata[i].DefaultValue ); + for ( int i = 0; i < KeyMetadata.Length; i++ ) { + SetValue( ( ConfigKey )i, KeyMetadata[i].DefaultValue ); } } - /// Loads defaults for keys in a given ConfigSection. public static void LoadDefaults( ConfigSection section ) { - foreach( var key in KeySections[section] ) { - SetValue( key, KeyMetadata[(int)key].DefaultValue ); + foreach ( var key in KeySections[section] ) { + SetValue( key, KeyMetadata[( int )key].DefaultValue ); } } - /// Checks whether given ConfigKey still has its default value. public static bool IsDefault( this ConfigKey key ) { - return (KeyMetadata[(int)key].DefaultValue.ToString() == Settings[(int)key]); + return ( KeyMetadata[( int )key].DefaultValue.ToString() == Settings[( int )key] ); } - /// Provides the default value for a given ConfigKey. public static object GetDefault( this ConfigKey key ) { - return KeyMetadata[(int)key].DefaultValue; + return KeyMetadata[( int )key].DefaultValue; } - public static void ResetLogOptions() { - for( int i = 0; i < Logger.ConsoleOptions.Length; i++ ) { + for ( int i = 0; i < Logger.ConsoleOptions.Length; i++ ) { Logger.ConsoleOptions[i] = true; Logger.LogFileOptions[i] = true; } - Logger.ConsoleOptions[(int)LogType.ConsoleInput] = false; - Logger.ConsoleOptions[(int)LogType.Debug] = false; + Logger.ConsoleOptions[( int )LogType.ConsoleInput] = false; + Logger.ConsoleOptions[( int )LogType.Debug] = false; } - #endregion - + #endregion Defaults #region Loading @@ -309,10 +302,10 @@ public static bool Load( bool skipRankList, bool raiseReloadedEvent ) { // try to load config file (XML) XDocument file; - if( File.Exists( Paths.ConfigFileName ) ) { + if ( File.Exists( Paths.ConfigFileName ) ) { try { file = XDocument.Load( Paths.ConfigFileName ); - if( file.Root == null || file.Root.Name != ConfigXmlRootName ) { + if ( file.Root == null || file.Root.Name != ConfigXmlRootName ) { Logger.Log( LogType.Warning, "Config.Load: Malformed or incompatible config file {0}. Loading defaults.", Paths.ConfigFileName ); @@ -324,7 +317,7 @@ public static bool Load( bool skipRankList, bool raiseReloadedEvent ) { Paths.ConfigFileName ); fromFile = true; } - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.LogAndReportCrash( "Config failed to load", "fCraft", ex, true ); return false; } @@ -335,18 +328,19 @@ public static bool Load( bool skipRankList, bool raiseReloadedEvent ) { } XElement config = file.Root; - if( config == null ) throw new Exception( "Config.xml has no root. Never happens." ); + if ( config == null ) + throw new Exception( "Config.xml has no root. Never happens." ); int version = 0; - if( fromFile ) { + if ( fromFile ) { XAttribute attr = config.Attribute( "version" ); - if( attr != null && Int32.TryParse( attr.Value, out version ) ) { - if( version < LowestSupportedVersion ) { + if ( attr != null && Int32.TryParse( attr.Value, out version ) ) { + if ( version < LowestSupportedVersion ) { Logger.Log( LogType.Warning, "Config.Load: Your copy of config.xml is too old to be loaded properly. " + "Some settings will be lost or replaced with defaults. " + "Please run ConfigGUI to make sure that everything is in order." ); - } else if( version != CurrentVersion ) { + } else if ( version != CurrentVersion ) { Logger.Log( LogType.Warning, "Config.Load: Your config.xml was made for a different version of 800Craft / fCraft. " + "Some obsolete settings might be ignored, and some recently-added settings will be set to defaults. " + @@ -360,44 +354,43 @@ public static bool Load( bool skipRankList, bool raiseReloadedEvent ) { } // read rank definitions - if( !skipRankList ) { + if ( !skipRankList ) { LoadRankList( config, fromFile ); } - + ResetLogOptions(); // read log options for console XElement consoleOptions = config.Element( "ConsoleOptions" ); - if( consoleOptions != null ){ + if ( consoleOptions != null ) { LoadLogOptions( consoleOptions, Logger.ConsoleOptions ); - }else if(fromFile){ + } else if ( fromFile ) { Logger.Log( LogType.Warning, "Config.Load: using default console options." ); } // read log options for logfiles XElement logFileOptions = config.Element( "LogFileOptions" ); - if( logFileOptions != null ){ + if ( logFileOptions != null ) { LoadLogOptions( logFileOptions, Logger.LogFileOptions ); - }else if(fromFile){ + } else if ( fromFile ) { Logger.Log( LogType.Warning, "Config.Load: using default log file options." ); } - // read the rest of the keys - if( version < FirstVersionWithSectionTags ) { - foreach( XElement element in config.Elements() ) { + if ( version < FirstVersionWithSectionTags ) { + foreach ( XElement element in config.Elements() ) { ParseKeyElementPreSettings( element ); } - } else if( version < FirstVersionWithSettingsTag ) { - foreach( XElement section in config.Elements( "Section" ) ) { - foreach( XElement keyElement in section.Elements() ) { + } else if ( version < FirstVersionWithSettingsTag ) { + foreach ( XElement section in config.Elements( "Section" ) ) { + foreach ( XElement keyElement in section.Elements() ) { ParseKeyElementPreSettings( keyElement ); } } } else { XElement settings = config.Element( "Settings" ); - if( settings != null ) { - foreach( XElement pair in settings.Elements( "ConfigKey" ) ) { + if ( settings != null ) { + foreach ( XElement pair in settings.Elements( "ConfigKey" ) ) { ParseKeyElement( pair ); } } else { @@ -406,7 +399,7 @@ public static bool Load( bool skipRankList, bool raiseReloadedEvent ) { } } - if( !skipRankList ) { + if ( !skipRankList ) { RankManager.DefaultRank = Rank.Parse( ConfigKey.DefaultRank.GetString() ); RankManager.DefaultBuildRank = Rank.Parse( ConfigKey.DefaultBuildRank.GetString() ); RankManager.PatrolledRank = Rank.Parse( ConfigKey.PatrolledRank.GetString() ); @@ -414,10 +407,10 @@ public static bool Load( bool skipRankList, bool raiseReloadedEvent ) { } // key relation validation - if( version < FirstVersionWithMaxPlayersKey ) { + if ( version < FirstVersionWithMaxPlayersKey ) { ConfigKey.MaxPlayersPerWorld.TrySetValue( ConfigKey.MaxPlayers.GetInt() ); } - if( ConfigKey.MaxPlayersPerWorld.GetInt() > ConfigKey.MaxPlayers.GetInt() ) { + if ( ConfigKey.MaxPlayersPerWorld.GetInt() > ConfigKey.MaxPlayers.GetInt() ) { Logger.Log( LogType.Warning, "Value of MaxPlayersPerWorld ({0}) was lowered to match MaxPlayers ({1}).", ConfigKey.MaxPlayersPerWorld.GetInt(), @@ -425,32 +418,30 @@ public static bool Load( bool skipRankList, bool raiseReloadedEvent ) { ConfigKey.MaxPlayersPerWorld.TrySetValue( ConfigKey.MaxPlayers.GetInt() ); } - if( raiseReloadedEvent ) RaiseReloadedEvent(); + if ( raiseReloadedEvent ) + RaiseReloadedEvent(); return true; } - - static void ParseKeyElementPreSettings( [NotNull] XElement element ) { - if( element == null ) throw new ArgumentNullException( "element" ); + private static void ParseKeyElementPreSettings( [NotNull] XElement element ) { + if ( element == null ) + throw new ArgumentNullException( "element" ); string keyName = element.Name.ToString().ToLower(); ConfigKey key; - if(EnumUtil.TryParse(keyName,out key,true)){ + if ( EnumUtil.TryParse( keyName, out key, true ) ) { // known key TrySetValue( key, element.Value ); - - } else if( LegacyConfigKeys.ContainsKey( keyName ) ) { // LEGACY + } else if ( LegacyConfigKeys.ContainsKey( keyName ) ) { // LEGACY // renamed/legacy key TrySetValue( LegacyConfigKeys[keyName], element.Value ); - - } else if( keyName == "limitoneconnectionperip" ) { // LEGACY + } else if ( keyName == "limitoneconnectionperip" ) { // LEGACY Logger.Log( LogType.Warning, "Config: LimitOneConnectionPerIP (bool) was replaced by MaxConnectionsPerIP (int). " + "Adjust your configuration accordingly." ); ConfigKey.MaxConnectionsPerIP.TrySetValue( 1 ); - - } else if( keyName != "consoleoptions" && + } else if ( keyName != "consoleoptions" && keyName != "logfileoptions" && keyName != "ranks" && keyName != "legacyrankmapping" ) { @@ -461,21 +452,19 @@ static void ParseKeyElementPreSettings( [NotNull] XElement element ) { } } - - static void ParseKeyElement( [NotNull] XElement element ) { - if( element == null ) throw new ArgumentNullException( "element" ); + private static void ParseKeyElement( [NotNull] XElement element ) { + if ( element == null ) + throw new ArgumentNullException( "element" ); string keyName = element.Attribute( "key" ).Value; string value = element.Attribute( "value" ).Value; ConfigKey key; - if( EnumUtil.TryParse( keyName, out key, true ) ) { + if ( EnumUtil.TryParse( keyName, out key, true ) ) { // known key TrySetValue( key, value ); - - } else if( LegacyConfigKeys.ContainsKey( keyName ) ) { // LEGACY + } else if ( LegacyConfigKeys.ContainsKey( keyName ) ) { // LEGACY // renamed/legacy key TrySetValue( LegacyConfigKeys[keyName], value ); - } else { // unknown key Logger.Log( LogType.Warning, @@ -484,12 +473,14 @@ static void ParseKeyElement( [NotNull] XElement element ) { } } - static void LoadLogOptions( [NotNull] XContainer el, [NotNull] IList list ) { - if( el == null ) throw new ArgumentNullException( "el" ); - if( list == null ) throw new ArgumentNullException( "list" ); + private static void LoadLogOptions( [NotNull] XContainer el, [NotNull] IList list ) { + if ( el == null ) + throw new ArgumentNullException( "el" ); + if ( list == null ) + throw new ArgumentNullException( "list" ); - for( int i = 0; i < list.Count; i++ ) { - if( el.Element( ((LogType)i).ToString() ) != null ) { + for ( int i = 0; i < list.Count; i++ ) { + if ( el.Element( ( ( LogType )i ).ToString() ) != null ) { list[i] = true; } else { list[i] = false; @@ -497,9 +488,8 @@ static void LoadLogOptions( [NotNull] XContainer el, [NotNull] IList list } } - - static void ApplyKeyChange( ConfigKey key ) { - switch( key ) { + private static void ApplyKeyChange( ConfigKey key ) { + switch ( key ) { case ConfigKey.AnnouncementColor: Color.Announcement = Color.Parse( key.GetString() ); break; @@ -522,9 +512,9 @@ static void ApplyKeyChange( ConfigKey key ) { case ConfigKey.BandwidthUseMode: Player[] playerListCache = Server.Players; - if( playerListCache != null ) { - foreach( Player p in playerListCache ) { - if( p.BandwidthUseMode == BandwidthUseMode.Default ) { + if ( playerListCache != null ) { + foreach ( Player p in playerListCache ) { + if ( p.BandwidthUseMode == BandwidthUseMode.Default ) { // resets the use tweaks p.BandwidthUseMode = BandwidthUseMode.Default; } @@ -534,11 +524,11 @@ static void ApplyKeyChange( ConfigKey key ) { case ConfigKey.BlockDBAutoEnableRank: RankManager.BlockDBAutoEnableRank = Rank.Parse( key.GetString() ); - if( BlockDB.IsEnabledGlobally ) { + if ( BlockDB.IsEnabledGlobally ) { World[] worldListCache = WorldManager.Worlds; - foreach( World world in worldListCache ) { - if( world.BlockDB.AutoToggleIfNeeded() ) { - if( world.BlockDB.IsEnabled ) { + foreach ( World world in worldListCache ) { + if ( world.BlockDB.AutoToggleIfNeeded() ) { + if ( world.BlockDB.IsEnabled ) { Logger.Log( LogType.SystemActivity, "BlockDB is now auto-enabled on world {0}", world.Name ); } else { @@ -555,7 +545,7 @@ static void ApplyKeyChange( ConfigKey key ) { break; case ConfigKey.ConsoleName: - if( Player.Console != null ) { + if ( Player.Console != null ) { Player.Console.Info.Name = key.GetString(); } break; @@ -582,8 +572,8 @@ static void ApplyKeyChange( ConfigKey key ) { break; case ConfigKey.MapPath: - if( !Paths.IgnoreMapPathConfigKey && GetString( ConfigKey.MapPath ).Length > 0 ) { - if( Paths.TestDirectory( "MapPath", GetString( ConfigKey.MapPath ), true ) ) { + if ( !Paths.IgnoreMapPathConfigKey && GetString( ConfigKey.MapPath ).Length > 0 ) { + if ( Paths.TestDirectory( "MapPath", GetString( ConfigKey.MapPath ), true ) ) { Paths.MapPath = Path.GetFullPath( GetString( ConfigKey.MapPath ) ); } } @@ -598,7 +588,7 @@ static void ApplyKeyChange( ConfigKey key ) { break; case ConfigKey.NoPartialPositionUpdates: - if( key.Enabled() ) { + if ( key.Enabled() ) { Player.FullPositionUpdateInterval = 0; } else { Player.FullPositionUpdateInterval = Player.FullPositionUpdateIntervalDefault; @@ -626,11 +616,11 @@ static void ApplyKeyChange( ConfigKey key ) { break; case ConfigKey.CustomChatColor: - Color.Custom = Color.Parse(key.GetString()); + Color.Custom = Color.Parse( key.GetString() ); break; case ConfigKey.TickInterval: - Server.TicksPerSecond = 1000 / (float)key.GetInt(); + Server.TicksPerSecond = 1000 / ( float )key.GetInt(); break; case ConfigKey.UploadBandwidth: @@ -643,8 +633,7 @@ static void ApplyKeyChange( ConfigKey key ) { } } - #endregion - + #endregion Loading #region Saving @@ -657,12 +646,12 @@ public static bool Save() { XElement settings = new XElement( "Settings" ); // save general settings - foreach( ConfigSection section in Enum.GetValues( typeof( ConfigSection ) ) ) { + foreach ( ConfigSection section in Enum.GetValues( typeof( ConfigSection ) ) ) { settings.Add( new XComment( section.ToString() ) ); - foreach( ConfigKey key in KeySections[section] ) { + foreach ( ConfigKey key in KeySections[section] ) { XElement keyPairEl = new XElement( "ConfigKey" ); keyPairEl.Add( new XAttribute( "key", key ) ); - keyPairEl.Add( new XAttribute( "value", Settings[(int)key] ) ); + keyPairEl.Add( new XAttribute( "value", Settings[( int )key] ) ); keyPairEl.Add( new XAttribute( "default", key.GetDefault() ) ); settings.Add( keyPairEl ); } @@ -671,34 +660,34 @@ public static bool Save() { // save console options XElement consoleOptions = new XElement( "ConsoleOptions" ); - for( int i = 0; i < Logger.ConsoleOptions.Length; i++ ) { - if( Logger.ConsoleOptions[i] ) { - consoleOptions.Add( new XElement( ((LogType)i).ToString() ) ); + for ( int i = 0; i < Logger.ConsoleOptions.Length; i++ ) { + if ( Logger.ConsoleOptions[i] ) { + consoleOptions.Add( new XElement( ( ( LogType )i ).ToString() ) ); } } config.Add( consoleOptions ); // save logfile options XElement logFileOptions = new XElement( "LogFileOptions" ); - for( int i = 0; i < Logger.LogFileOptions.Length; i++ ) { - if( Logger.LogFileOptions[i] ) { - logFileOptions.Add( new XElement( ((LogType)i).ToString() ) ); + for ( int i = 0; i < Logger.LogFileOptions.Length; i++ ) { + if ( Logger.LogFileOptions[i] ) { + logFileOptions.Add( new XElement( ( ( LogType )i ).ToString() ) ); } } config.Add( logFileOptions ); // save ranks XElement ranksTag = new XElement( "Ranks" ); - foreach( Rank rank in RankManager.Ranks ) { + foreach ( Rank rank in RankManager.Ranks ) { ranksTag.Add( rank.Serialize() ); } config.Add( ranksTag ); - if( RankManager.LegacyRankMapping.Count > 0 ) { + if ( RankManager.LegacyRankMapping.Count > 0 ) { // save legacy rank mapping XElement legacyRankMappingTag = new XElement( "LegacyRankMapping" ); legacyRankMappingTag.Add( new XComment( "Legacy rank mapping is used for compatibility if cases when ranks are renamed or deleted." ) ); - foreach( KeyValuePair pair in RankManager.LegacyRankMapping ) { + foreach ( KeyValuePair pair in RankManager.LegacyRankMapping ) { XElement rankPair = new XElement( "LegacyRankPair" ); rankPair.Add( new XAttribute( "from", pair.Key ), new XAttribute( "to", pair.Value ) ); legacyRankMappingTag.Add( rankPair ); @@ -706,7 +695,6 @@ public static bool Save() { config.Add( legacyRankMappingTag ); } - file.Add( config ); try { // write out the changes @@ -714,36 +702,32 @@ public static bool Save() { file.Save( tempFileName ); Paths.MoveOrReplace( tempFileName, Paths.ConfigFileName ); return true; - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.LogAndReportCrash( "Config failed to save", "fCraft", ex, true ); return false; } } - #endregion - + #endregion Saving #region Getters /// Checks whether any value has been set for a given key. public static bool IsBlank( this ConfigKey key ) { - return (Settings[(int)key].Length == 0); + return ( Settings[( int )key].Length == 0 ); } - /// Returns raw value for the given key. public static string GetString( this ConfigKey key ) { - return KeyMetadata[(int)key].Process( Settings[(int)key] ); + return KeyMetadata[( int )key].Process( Settings[( int )key] ); } - /// Attempts to parse given key's value as an integer. /// Throws a FormatException on failure. public static int GetInt( this ConfigKey key ) { return Int32.Parse( GetString( key ) ); } - /// Attempts to parse a given key's value as an integer. /// ConfigKey to get value from. /// Will be set to the value on success, or to 0 on failure. @@ -752,36 +736,34 @@ public static bool TryGetInt( this ConfigKey key, out int result ) { return Int32.TryParse( GetString( key ), out result ); } - /// Attempts to parse a given key's value as an enumeration. /// An ArgumentException is thrown if value could not be parsed. /// Note the parsing is done in a case-insensitive way. /// Enum to use for parsing. /// An ArgumentException will be thrown if this is not an enum. public static TEnum GetEnum( this ConfigKey key ) where TEnum : struct { - if( !typeof( TEnum ).IsEnum ) throw new ArgumentException( "Enum type required" ); - return (TEnum)Enum.Parse( typeof( TEnum ), GetString( key ), true ); + if ( !typeof( TEnum ).IsEnum ) + throw new ArgumentException( "Enum type required" ); + return ( TEnum )Enum.Parse( typeof( TEnum ), GetString( key ), true ); } - /// Attempts to parse given key's value as a boolean. /// Throws a FormatException on failure. public static bool Enabled( this ConfigKey key ) { - if( SettingsUseEnabledCache[(int)key] ) { - return SettingsEnabledCache[(int)key]; + if ( SettingsUseEnabledCache[( int )key] ) { + return SettingsEnabledCache[( int )key]; } else { return Boolean.Parse( GetString( key ) ); } } - /// Attempts to parse a given key's value as a boolean. /// ConfigKey to get value from. /// Will be set to the value on success, or to false on failure. /// Whether parsing succeeded. public static bool TryGetBool( this ConfigKey key, out bool result ) { - if( SettingsUseEnabledCache[(int)key] ) { - result = SettingsEnabledCache[(int)key]; + if ( SettingsUseEnabledCache[( int )key] ) { + result = SettingsEnabledCache[( int )key]; return true; } else { result = false; @@ -789,32 +771,27 @@ public static bool TryGetBool( this ConfigKey key, out bool result ) { } } - /// Returns the expected Type of the key's value, as specified in key metadata. public static Type GetValueType( this ConfigKey key ) { - return KeyMetadata[(int)key].ValueType; + return KeyMetadata[( int )key].ValueType; } - /// Returns the metadata container (ConfigKeyAttribute object) for a given key. public static ConfigKeyAttribute GetMetadata( this ConfigKey key ) { - return KeyMetadata[(int)key]; + return KeyMetadata[( int )key]; } - /// Returns the ConfigSection that a given key is associated with. public static ConfigSection GetSection( this ConfigKey key ) { - return KeyMetadata[(int)key].Section; + return KeyMetadata[( int )key].Section; } - /// Returns the description text for a given config key. public static string GetDescription( this ConfigKey key ) { - return KeyMetadata[(int)key].Description; + return KeyMetadata[( int )key].Description; } - #endregion - + #endregion Getters #region Setters @@ -825,7 +802,6 @@ public static bool ResetValue( this ConfigKey key ) { return key.TrySetValue( key.GetDefault() ); } - /// Sets value of a given config key. /// Note that this method may throw exceptions if the given value is not acceptible. /// Use Config.TrySetValue() if you'd like to suppress exceptions in favor of a boolean return value. @@ -836,19 +812,19 @@ public static bool ResetValue( this ConfigKey key ) { /// True if value is valid and has been assigned. /// False if value is valid, but assignment was cancelled by an event handler/plugin. public static bool SetValue( this ConfigKey key, object rawValue ) { - if( rawValue == null ) { + if ( rawValue == null ) { throw new ArgumentNullException( "rawValue", key + ": ConfigKey values cannot be null. Use an empty string to indicate unset value." ); } - string value = (rawValue as string ?? rawValue.ToString()); + string value = ( rawValue as string ?? rawValue.ToString() ); - if( value == null ) { + if ( value == null ) { throw new NullReferenceException( key + ": rawValue.ToString() returned null." ); } - if( LegacyConfigValues.ContainsKey( key ) ) { - foreach( var pair in LegacyConfigValues.Values ) { - if( pair.Key.Equals( value, StringComparison.OrdinalIgnoreCase ) ) { + if ( LegacyConfigValues.ContainsKey( key ) ) { + foreach ( var pair in LegacyConfigValues.Values ) { + if ( pair.Key.Equals( value, StringComparison.OrdinalIgnoreCase ) ) { value = pair.Value; break; } @@ -856,12 +832,11 @@ public static bool SetValue( this ConfigKey key, object rawValue ) { } // throws various exceptions (most commonly FormatException) if invalid - KeyMetadata[(int)key].Validate( value ); + KeyMetadata[( int )key].Validate( value ); return DoSetValue( key, value ); } - /// Attempts to set the value of a given config key. /// Check the return value to make sure that the given value was acceptible. /// Config key to set. @@ -872,7 +847,7 @@ public static bool SetValue( this ConfigKey key, object rawValue ) { public static bool TrySetValue( this ConfigKey key, object rawValue ) { try { return SetValue( key, rawValue ); - } catch( FormatException ex ) { + } catch ( FormatException ex ) { Logger.Log( LogType.Error, "{0}.TrySetValue: {1}", key, ex.Message ); @@ -880,20 +855,20 @@ public static bool TrySetValue( this ConfigKey key, object rawValue ) { } } - - static bool DoSetValue( ConfigKey key, string newValue ) { - string oldValue = Settings[(int)key]; - if( oldValue != newValue ) { - if( RaiseKeyChangingEvent( key, oldValue, ref newValue ) ) return false; - Settings[(int)key] = newValue; + private static bool DoSetValue( ConfigKey key, string newValue ) { + string oldValue = Settings[( int )key]; + if ( oldValue != newValue ) { + if ( RaiseKeyChangingEvent( key, oldValue, ref newValue ) ) + return false; + Settings[( int )key] = newValue; bool enabledCache; - if( Boolean.TryParse( newValue, out enabledCache ) ) { - SettingsUseEnabledCache[(int)key] = true; - SettingsEnabledCache[(int)key] = enabledCache; + if ( Boolean.TryParse( newValue, out enabledCache ) ) { + SettingsUseEnabledCache[( int )key] = true; + SettingsEnabledCache[( int )key] = enabledCache; } else { - SettingsUseEnabledCache[(int)key] = false; - SettingsEnabledCache[(int)key] = false; + SettingsUseEnabledCache[( int )key] = false; + SettingsEnabledCache[( int )key] = false; } ApplyKeyChange( key ); @@ -902,20 +877,20 @@ static bool DoSetValue( ConfigKey key, string newValue ) { return true; } - #endregion - + #endregion Setters #region Ranks - static void LoadRankList( [NotNull] XContainer el, bool fromFile ) { - if( el == null ) throw new ArgumentNullException( "el" ); + private static void LoadRankList( [NotNull] XContainer el, bool fromFile ) { + if ( el == null ) + throw new ArgumentNullException( "el" ); XElement legacyRankMappingTag = el.Element( "LegacyRankMapping" ); - if( legacyRankMappingTag != null ) { - foreach( XElement rankPair in legacyRankMappingTag.Elements( "LegacyRankPair" ) ) { + if ( legacyRankMappingTag != null ) { + foreach ( XElement rankPair in legacyRankMappingTag.Elements( "LegacyRankPair" ) ) { XAttribute fromRankID = rankPair.Attribute( "from" ); XAttribute toRankID = rankPair.Attribute( "to" ); - if( fromRankID == null || String.IsNullOrEmpty( fromRankID.Value ) || + if ( fromRankID == null || String.IsNullOrEmpty( fromRankID.Value ) || toRankID == null || String.IsNullOrEmpty( toRankID.Value ) ) { Logger.Log( LogType.Error, "Config.Load: Could not parse a LegacyRankMapping entry: {0}", rankPair ); @@ -927,27 +902,27 @@ static void LoadRankList( [NotNull] XContainer el, bool fromFile ) { XElement rankList = el.Element( "Ranks" ); - if( rankList != null ) { + if ( rankList != null ) { XElement[] rankDefinitionList = rankList.Elements( "Rank" ).ToArray(); - foreach( XElement rankDefinition in rankDefinitionList ) { + foreach ( XElement rankDefinition in rankDefinitionList ) { try { RankManager.AddRank( new Rank( rankDefinition ) ); - } catch( RankDefinitionException ex ) { + } catch ( RankDefinitionException ex ) { Logger.Log( LogType.Error, ex.Message ); } } - if( RankManager.RanksByName.Count == 0 ) { + if ( RankManager.RanksByName.Count == 0 ) { Logger.Log( LogType.Warning, - "Config.Load: No ranks were defined, or none were defined correctly. "+ + "Config.Load: No ranks were defined, or none were defined correctly. " + "Using default ranks (guest, builder, op, and owner)." ); rankList.Remove(); el.Add( DefineDefaultRanks() ); } - } else { - if( fromFile ) Logger.Log( LogType.Warning, "Config.Load: using default player ranks." ); + if ( fromFile ) + Logger.Log( LogType.Warning, "Config.Load: using default player ranks." ); el.Add( DefineDefaultRanks() ); } @@ -955,7 +930,6 @@ static void LoadRankList( [NotNull] XContainer el, bool fromFile ) { RankManager.ParsePermissionLimits(); } - /// Resets the list of ranks to defaults (guest/builder/op/owner). /// Warning: This method is not thread-safe, and should never be used on a live server. public static void ResetRanks() { @@ -964,8 +938,7 @@ public static void ResetRanks() { RankManager.ParsePermissionLimits(); } - - static XElement DefineDefaultRanks() { + private static XElement DefineDefaultRanks() { XElement permissions = new XElement( "Ranks" ); XElement owner = new XElement( "Rank" ); @@ -1040,47 +1013,46 @@ static XElement DefineDefaultRanks() { owner.Add( new XElement( Permission.ReloadConfig.ToString() ) ); owner.Add( new XElement( Permission.ShutdownServer.ToString() ) ); - owner.Add( new XElement(Permission.Basscannon.ToString() ) ); - owner.Add( new XElement(Permission.UsePortal.ToString() ) ); - owner.Add( new XElement(Permission.ManagePortal.ToString() ) ); - owner.Add( new XElement(Permission.HighFive.ToString() ) ); - owner.Add( new XElement(Permission.ChatWithCaps.ToString() ) ); - - owner.Add( new XElement(Permission.Swear.ToString() ) ); - owner.Add( new XElement(Permission.MakeVotes.ToString() ) ); - owner.Add( new XElement(Permission.MakeVoteKicks.ToString() ) ); - owner.Add( new XElement(Permission.BroMode.ToString() ) ); - owner.Add( new XElement(Permission.Troll.ToString() ) ); - owner.Add( new XElement(Permission.HideRanks.ToString() ) ); - owner.Add( new XElement(Permission.ReadAdminChat.ToString() ) ); - - owner.Add( new XElement(Permission.ReadCustomChat.ToString() ) ); - owner.Add( new XElement(Permission.Realm.ToString() ) ); - owner.Add( new XElement(Permission.Possess.ToString() ) ); - owner.Add( new XElement(Permission.Gtfo.ToString() ) ); - owner.Add( new XElement(Permission.RageQuit.ToString() ) ); - owner.Add( new XElement(Permission.Tower.ToString() ) ); - - owner.Add( new XElement(Permission.TempBan.ToString() ) ); - owner.Add( new XElement(Permission.Warn.ToString() ) ); - owner.Add( new XElement(Permission.Slap.ToString() ) ); - owner.Add( new XElement(Permission.Kill.ToString() ) ); - owner.Add( new XElement(Permission.Physics.ToString() ) ); - - owner.Add( new XElement(Permission.Fireworks.ToString() ) ); - owner.Add( new XElement(Permission.Gun.ToString() ) ); - owner.Add( new XElement(Permission.Games.ToString() ) ); - owner.Add( new XElement(Permission.Moderation.ToString() ) ); - owner.Add( new XElement(Permission.Immortal.ToString() ) ); + owner.Add( new XElement( Permission.Basscannon.ToString() ) ); + owner.Add( new XElement( Permission.UsePortal.ToString() ) ); + owner.Add( new XElement( Permission.ManagePortal.ToString() ) ); + owner.Add( new XElement( Permission.HighFive.ToString() ) ); + owner.Add( new XElement( Permission.ChatWithCaps.ToString() ) ); + + owner.Add( new XElement( Permission.Swear.ToString() ) ); + owner.Add( new XElement( Permission.MakeVotes.ToString() ) ); + owner.Add( new XElement( Permission.MakeVoteKicks.ToString() ) ); + owner.Add( new XElement( Permission.BroMode.ToString() ) ); + owner.Add( new XElement( Permission.Troll.ToString() ) ); + owner.Add( new XElement( Permission.HideRanks.ToString() ) ); + owner.Add( new XElement( Permission.ReadAdminChat.ToString() ) ); + + owner.Add( new XElement( Permission.ReadCustomChat.ToString() ) ); + owner.Add( new XElement( Permission.Realm.ToString() ) ); + owner.Add( new XElement( Permission.Possess.ToString() ) ); + owner.Add( new XElement( Permission.Gtfo.ToString() ) ); + owner.Add( new XElement( Permission.RageQuit.ToString() ) ); + owner.Add( new XElement( Permission.Tower.ToString() ) ); + + owner.Add( new XElement( Permission.TempBan.ToString() ) ); + owner.Add( new XElement( Permission.Warn.ToString() ) ); + owner.Add( new XElement( Permission.Slap.ToString() ) ); + owner.Add( new XElement( Permission.Kill.ToString() ) ); + owner.Add( new XElement( Permission.Physics.ToString() ) ); + + owner.Add( new XElement( Permission.Fireworks.ToString() ) ); + owner.Add( new XElement( Permission.Gun.ToString() ) ); + owner.Add( new XElement( Permission.Games.ToString() ) ); + owner.Add( new XElement( Permission.Moderation.ToString() ) ); + owner.Add( new XElement( Permission.Immortal.ToString() ) ); owner.Add( new XElement( Permission.UndoAll.ToString() ) ); permissions.Add( owner ); try { RankManager.AddRank( new Rank( owner ) ); - } catch( RankDefinitionException ex ) { + } catch ( RankDefinitionException ex ) { Logger.Log( LogType.Error, ex.Message ); } - XElement op = new XElement( "Rank" ); op.Add( new XAttribute( "id", RankManager.GenerateID() ) ); op.Add( new XAttribute( "name", "op" ) ); @@ -1144,11 +1116,10 @@ static XElement DefineDefaultRanks() { permissions.Add( op ); try { RankManager.AddRank( new Rank( op ) ); - } catch( RankDefinitionException ex ) { + } catch ( RankDefinitionException ex ) { Logger.Log( LogType.Error, ex.Message ); } - XElement builder = new XElement( "Rank" ); builder.Add( new XAttribute( "id", RankManager.GenerateID() ) ); builder.Add( new XAttribute( "name", "builder" ) ); @@ -1183,11 +1154,10 @@ static XElement DefineDefaultRanks() { permissions.Add( builder ); try { RankManager.AddRank( new Rank( builder ) ); - } catch( RankDefinitionException ex ) { + } catch ( RankDefinitionException ex ) { Logger.Log( LogType.Error, ex.Message ); } - XElement guest = new XElement( "Rank" ); guest.Add( new XAttribute( "id", RankManager.GenerateID() ) ); guest.Add( new XAttribute( "name", "guest" ) ); @@ -1205,55 +1175,51 @@ static XElement DefineDefaultRanks() { permissions.Add( guest ); try { RankManager.AddRank( new Rank( guest ) ); - } catch( RankDefinitionException ex ) { + } catch ( RankDefinitionException ex ) { Logger.Log( LogType.Error, ex.Message ); } return permissions; } - #endregion - + #endregion Ranks #region Events /// Occurs after the entire configuration has been reloaded from file. public static event EventHandler Reloaded; - /// Occurs when a config key is about to be changed (cancellable). /// The new value may be replaced by the callback. public static event EventHandler KeyChanging; - /// Occurs after a config key has been changed. public static event EventHandler KeyChanged; - - static void RaiseReloadedEvent() { + private static void RaiseReloadedEvent() { var h = Reloaded; - if( h != null ) h( null, EventArgs.Empty ); + if ( h != null ) + h( null, EventArgs.Empty ); } - - static bool RaiseKeyChangingEvent( ConfigKey key, string oldValue, ref string newValue ) { + private static bool RaiseKeyChangingEvent( ConfigKey key, string oldValue, ref string newValue ) { var h = KeyChanging; - if( h == null ) return false; + if ( h == null ) + return false; var e = new ConfigKeyChangingEventArgs( key, oldValue, newValue ); h( null, e ); newValue = e.NewValue; return e.Cancel; } - - static void RaiseKeyChangedEvent( ConfigKey key, string oldValue, string newValue ) { + private static void RaiseKeyChangedEvent( ConfigKey key, string oldValue, string newValue ) { var h = KeyChanged; var args = new ConfigKeyChangedEventArgs( key, oldValue, newValue ); - if( h != null ) h( null, args ); + if ( h != null ) + h( null, args ); } - #endregion - + #endregion Events /// Returns a list of all keys in a section. public static ConfigKey[] GetKeys( this ConfigSection section ) { @@ -1262,13 +1228,16 @@ public static ConfigKey[] GetKeys( this ConfigSection section ) { } } - namespace fCraft.Events { public sealed class ConfigKeyChangingEventArgs : EventArgs, ICancellableEvent { + public ConfigKey Key { get; private set; } + public string OldValue { get; private set; } + public string NewValue { get; set; } + public bool Cancel { get; set; } public ConfigKeyChangingEventArgs( ConfigKey key, string oldValue, string newValue ) { @@ -1279,10 +1248,12 @@ public ConfigKeyChangingEventArgs( ConfigKey key, string oldValue, string newVal } } - public sealed class ConfigKeyChangedEventArgs : EventArgs { + public ConfigKey Key { get; private set; } + public string OldValue { get; private set; } + public string NewValue { get; private set; } public ConfigKeyChangedEventArgs( ConfigKey key, string oldValue, string newValue ) { @@ -1291,5 +1262,4 @@ public ConfigKeyChangedEventArgs( ConfigKey key, string oldValue, string newValu NewValue = newValue; } } - } \ No newline at end of file diff --git a/fCraft/System/ConfigKey.Metadata.cs b/fCraft/System/ConfigKey.Metadata.cs index 4c3ccd0..fad5881 100644 --- a/fCraft/System/ConfigKey.Metadata.cs +++ b/fCraft/System/ConfigKey.Metadata.cs @@ -12,85 +12,94 @@ namespace fCraft { /// Describes attributes and metadata of a configuration key. [AttributeUsage( AttributeTargets.Field )] public class ConfigKeyAttribute : DescriptionAttribute { + protected ConfigKeyAttribute( ConfigSection section, [NotNull] Type valueType, object defaultValue, [NotNull] string description ) : base( description ) { - if( valueType == null ) throw new ArgumentNullException( "valueType" ); - if( description == null ) throw new ArgumentNullException( "description" ); + if ( valueType == null ) + throw new ArgumentNullException( "valueType" ); + if ( description == null ) + throw new ArgumentNullException( "description" ); ValueType = valueType; DefaultValue = defaultValue; Section = section; NotBlank = false; } + public Type ValueType { get; protected set; } + public object DefaultValue { get; protected set; } + public ConfigSection Section { get; private set; } + // ReSharper disable MemberCanBeProtected.Global public bool NotBlank { get; set; } + // ReSharper restore MemberCanBeProtected.Global public ConfigKey Key { get; internal set; } - public bool TryValidate( string value ) { try { Validate( value ); return true; - } catch( ArgumentException ) { + } catch ( ArgumentException ) { return false; } } - public virtual void Validate( [NotNull] string value ) { - if( value == null ) throw new ArgumentNullException( "value" ); - if( NotBlank && value.Length == 0 ) { + if ( value == null ) + throw new ArgumentNullException( "value" ); + if ( NotBlank && value.Length == 0 ) { throw new FormatException( "Value cannot be blank or null." ); } } - [DebuggerStepThrough] public virtual string Process( string value ) { return value; } } - internal sealed class StringKeyAttribute : ConfigKeyAttribute { public const int NoLengthRestriction = -1; + public StringKeyAttribute( ConfigSection section, object defaultValue, string description ) : base( section, typeof( string ), defaultValue, description ) { MinLength = NoLengthRestriction; MaxLength = NoLengthRestriction; Regex = null; } + public int MinLength { get; set; } + public int MaxLength { get; set; } + public Regex Regex { get; set; } - public bool RestrictedChars { get; set; } + public bool RestrictedChars { get; set; } public override void Validate( string value ) { base.Validate( value ); - if( MinLength != NoLengthRestriction && value.Length < MinLength ) { + if ( MinLength != NoLengthRestriction && value.Length < MinLength ) { throw new FormatException( String.Format( "Value string is too short; expected at least {0} characters.", MinLength ) ); } - if( MaxLength != NoLengthRestriction && value.Length > MaxLength ) { + if ( MaxLength != NoLengthRestriction && value.Length > MaxLength ) { throw new FormatException( String.Format( "Value string too long; expected at most {0} characters.", MaxLength ) ); } - if( RestrictedChars && Chat.ContainsInvalidChars( value ) ) { + if ( RestrictedChars && Chat.ContainsInvalidChars( value ) ) { throw new FormatException( String.Format( "Value contains restricted characters." ) ); } - if( Regex != null && !Regex.IsMatch( value ) ) { + if ( Regex != null && !Regex.IsMatch( value ) ) { throw new FormatException( String.Format( "Value does not match the expected format: /{0}/.", Regex ) ); } } } - internal sealed class IntKeyAttribute : ConfigKeyAttribute { + public IntKeyAttribute( ConfigSection section, int defaultValue, string description ) : base( section, typeof( int ), defaultValue, description ) { MinValue = int.MinValue; @@ -100,64 +109,70 @@ public IntKeyAttribute( ConfigSection section, int defaultValue, string descript ValidValues = null; InvalidValues = null; } + public int MinValue { get; set; } + public int MaxValue { get; set; } + public bool PowerOfTwo { get; set; } + public int MultipleOf { get; set; } + public int[] ValidValues { get; set; } + public int[] InvalidValues { get; set; } - public bool AlwaysAllowZero { get; set; } + public bool AlwaysAllowZero { get; set; } public override void Validate( string value ) { base.Validate( value ); int parsedValue; - if( !Int32.TryParse( value, out parsedValue ) ) { + if ( !Int32.TryParse( value, out parsedValue ) ) { throw new FormatException( "Value cannot be parsed as an integer." ); } - if( AlwaysAllowZero && parsedValue == 0 ) { + if ( AlwaysAllowZero && parsedValue == 0 ) { return; } - if( MinValue != int.MinValue && parsedValue < MinValue ) { + if ( MinValue != int.MinValue && parsedValue < MinValue ) { throw new FormatException( String.Format( "Value is too low ({0}); expected at least {1}.", parsedValue, MinValue ) ); } - if( MaxValue != int.MaxValue && parsedValue > MaxValue ) { + if ( MaxValue != int.MaxValue && parsedValue > MaxValue ) { throw new FormatException( String.Format( "Value is too high ({0}); expected at most {1}.", parsedValue, MaxValue ) ); } - if( MultipleOf != 0 && (parsedValue % MultipleOf != 0) ) { + if ( MultipleOf != 0 && ( parsedValue % MultipleOf != 0 ) ) { throw new FormatException( String.Format( "Value ({0}) is not a multiple of {1}.", parsedValue, MultipleOf ) ); } - if( PowerOfTwo ) { + if ( PowerOfTwo ) { bool found = false; - for( int i = 0; i < 31; i++ ) { - if( parsedValue == (1 << i) ) { + for ( int i = 0; i < 31; i++ ) { + if ( parsedValue == ( 1 << i ) ) { found = true; break; } } - if( !found && parsedValue != 0 ) { + if ( !found && parsedValue != 0 ) { throw new FormatException( String.Format( "Value ({0}) is not a power of two.", parsedValue ) ); } } - if( ValidValues != null ) { - if( !ValidValues.Any( t => parsedValue == t ) ) { + if ( ValidValues != null ) { + if ( !ValidValues.Any( t => parsedValue == t ) ) { throw new FormatException( String.Format( "Value ({0}) is not on the list of valid values.", parsedValue ) ); } } - if( InvalidValues != null ) { - if( !InvalidValues.All( t => parsedValue != t ) ) { + if ( InvalidValues != null ) { + if ( !InvalidValues.All( t => parsedValue != t ) ) { throw new FormatException( String.Format( "Value ({0}) is on the list of invalid values.", parsedValue ) ); } } } } - internal sealed class RankKeyAttribute : ConfigKeyAttribute { + public RankKeyAttribute( ConfigSection section, BlankValueMeaning blankMeaning, string description ) : base( section, typeof( Rank ), "", description ) { CanBeLowest = true; @@ -165,37 +180,39 @@ public RankKeyAttribute( ConfigSection section, BlankValueMeaning blankMeaning, BlankMeaning = blankMeaning; NotBlank = false; } + public bool CanBeLowest { get; set; } + public bool CanBeHighest { get; set; } - public BlankValueMeaning BlankMeaning { get; set; } + public BlankValueMeaning BlankMeaning { get; set; } public override void Validate( string value ) { base.Validate( value ); Rank rank; - if( value.Length == 0 ) { + if ( value.Length == 0 ) { rank = GetBlankValueSubstitute(); - if( rank == null ) return; // ranks must not have loaded yet; can't validate + if ( rank == null ) + return; // ranks must not have loaded yet; can't validate } else { rank = Rank.Parse( value ); - if( rank == null ) { + if ( rank == null ) { throw new FormatException( "Value cannot be parsed as a rank." ); } } - if( !CanBeLowest && rank == RankManager.LowestRank ) { + if ( !CanBeLowest && rank == RankManager.LowestRank ) { throw new FormatException( "Value may not be the lowest rank." ); } - if( !CanBeHighest && rank == RankManager.HighestRank ) { + if ( !CanBeHighest && rank == RankManager.HighestRank ) { throw new FormatException( "Value may not be the highest rank." ); } } - public override string Process( string value ) { - if( value.Length == 0 ) { + if ( value.Length == 0 ) { Rank defaultRank = GetBlankValueSubstitute(); - if( defaultRank == null ) { + if ( defaultRank == null ) { return ""; } else { return defaultRank.FullName; @@ -205,9 +222,8 @@ public override string Process( string value ) { } } - - Rank GetBlankValueSubstitute() { - switch( BlankMeaning ) { + private Rank GetBlankValueSubstitute() { + switch ( BlankMeaning ) { case BlankValueMeaning.DefaultRank: return RankManager.DefaultRank; case BlankValueMeaning.HighestRank: @@ -221,7 +237,6 @@ Rank GetBlankValueSubstitute() { } } - public enum BlankValueMeaning { Invalid, LowestRank, @@ -230,23 +245,22 @@ public enum BlankValueMeaning { } } - internal sealed class BoolKeyAttribute : ConfigKeyAttribute { + public BoolKeyAttribute( ConfigSection section, bool defaultValue, string description ) : base( section, typeof( bool ), defaultValue, description ) { } - public override void Validate( string value ) { base.Validate( value ); bool test; - if( !Boolean.TryParse( value, out test ) ) { + if ( !Boolean.TryParse( value, out test ) ) { throw new FormatException( "Value cannot be parsed as a boolean." ); } } public override string Process( string value ) { - if( value.Length == 0 ) { + if ( value.Length == 0 ) { return DefaultValue.ToString(); } else { return value; @@ -254,18 +268,20 @@ public override string Process( string value ) { } } - internal sealed class IPKeyAttribute : ConfigKeyAttribute { + public IPKeyAttribute( ConfigSection section, BlankValueMeaning defaultMeaning, string description ) : base( section, typeof( IPAddress ), "", description ) { BlankMeaning = defaultMeaning; - switch( BlankMeaning ) { + switch ( BlankMeaning ) { case BlankValueMeaning.Any: DefaultValue = IPAddress.Any; break; + case BlankValueMeaning.Loopback: DefaultValue = IPAddress.Loopback; break; + default: DefaultValue = IPAddress.None; break; @@ -273,38 +289,40 @@ public IPKeyAttribute( ConfigSection section, BlankValueMeaning defaultMeaning, } public bool NotAny { get; set; } + public bool NotNone { get; set; } + public bool NotLAN { get; set; } + public bool NotLoopback { get; set; } - public BlankValueMeaning BlankMeaning { get; set; } + public BlankValueMeaning BlankMeaning { get; set; } public override void Validate( string value ) { base.Validate( value ); IPAddress test; - if( value.Length == 0 ) { + if ( value.Length == 0 ) { test = GetBlankValueSubstitute(); - } else if( !IPAddress.TryParse( value, out test ) ) { + } else if ( !IPAddress.TryParse( value, out test ) ) { throw new FormatException( "Value cannot be parsed as an IP Address." ); } - if( NotAny && test.Equals( IPAddress.Any ) ) { + if ( NotAny && test.Equals( IPAddress.Any ) ) { throw new FormatException( String.Format( "Value cannot be {0}", IPAddress.Any ) ); } - if( NotNone && test.Equals( IPAddress.None ) ) { + if ( NotNone && test.Equals( IPAddress.None ) ) { throw new FormatException( String.Format( "Value cannot be {0}", IPAddress.None ) ); } - if( NotLAN && test.IsLAN() ) { + if ( NotLAN && test.IsLAN() ) { throw new FormatException( "Value cannot be a LAN address." ); } - if( NotLoopback && IPAddress.IsLoopback( test ) ) { + if ( NotLoopback && IPAddress.IsLoopback( test ) ) { throw new FormatException( "Value cannot be a loopback address." ); } } - - IPAddress GetBlankValueSubstitute() { - switch( BlankMeaning ) { + private IPAddress GetBlankValueSubstitute() { + switch ( BlankMeaning ) { case BlankValueMeaning.Any: return IPAddress.Any; case BlankValueMeaning.Loopback: @@ -316,16 +334,14 @@ IPAddress GetBlankValueSubstitute() { } } - public override string Process( string value ) { - if( value.Length == 0 ) { + if ( value.Length == 0 ) { return GetBlankValueSubstitute().ToString(); } else { return value; } } - public enum BlankValueMeaning { Any, Loopback, @@ -333,47 +349,46 @@ public enum BlankValueMeaning { } } - internal sealed class ColorKeyAttribute : ConfigKeyAttribute { + public ColorKeyAttribute( ConfigSection section, string defaultColor, string description ) : base( section, typeof( string ), Color.GetName( defaultColor ), description ) { } - public override void Validate( string value ) { base.Validate( value ); string parsedValue = Color.Parse( value ); - if( parsedValue == null ) { + if ( parsedValue == null ) { throw new FormatException( "Value cannot be parsed as a color." ); - } else if( parsedValue.Length == 0 && NotBlank ) { + } else if ( parsedValue.Length == 0 && NotBlank ) { throw new FormatException( "Value may not represent absence of color." ); } } } - internal sealed class EnumKeyAttribute : ConfigKeyAttribute { + public EnumKeyAttribute( ConfigSection section, object defaultValue, string description ) : base( section, defaultValue.GetType(), defaultValue, description ) { ValueType = defaultValue.GetType(); } - public override void Validate( string value ) { base.Validate( value ); - if( !NotBlank && String.IsNullOrEmpty( value ) ) return; + if ( !NotBlank && String.IsNullOrEmpty( value ) ) + return; try { Enum.Parse( ValueType, value, true ); - } catch( ArgumentException ) { + } catch ( ArgumentException ) { string message = String.Format( "Could not parse value as {0}. Valid values are: {1}", ValueType.Name, - Enum.GetNames(ValueType).JoinToString() ); + Enum.GetNames( ValueType ).JoinToString() ); throw new FormatException( message ); } } public override string Process( string value ) { - if( value.Length == 0 ) { + if ( value.Length == 0 ) { return DefaultValue.ToString(); } else { return value; diff --git a/fCraft/System/ConfigKey.cs b/fCraft/System/ConfigKey.cs index e952248..7bc9752 100644 --- a/fCraft/System/ConfigKey.cs +++ b/fCraft/System/ConfigKey.cs @@ -2,9 +2,11 @@ using System.Diagnostics; namespace fCraft { + /// Enumeration of available configuration keys. See comments /// at the top of Config.cs for a history of changes. public enum ConfigKey { + #region General [StringKey( ConfigSection.General, "Custom Minecraft Server (800Craft)", @@ -13,29 +15,28 @@ official server list (if server is public).", MinLength = 1, MaxLength = 64 )] ServerName, - [StringKey(ConfigSection.General, "EngineerChat", + [StringKey( ConfigSection.General, "EngineerChat", @"The name of the custom chat channel", - MinLength = 1, MaxLength = 12)] + MinLength = 1, MaxLength = 12 )] CustomChatName, - [StringKey(ConfigSection.General, "En", + + [StringKey( ConfigSection.General, "En", @"The name of the custom chat alias", - MinLength = 1, MaxLength = 12)] + MinLength = 1, MaxLength = 12 )] CustomAliasName, - [StringKey(ConfigSection.General, "%CBlock", + [StringKey( ConfigSection.General, "%CBlock", @"The word which swears will be replaced with", - MinLength = 1, MaxLength = 12)] + MinLength = 1, MaxLength = 12 )] SwearName, - [StringKey( ConfigSection.General, "Welcome to the server!", -@"MOTD (Message Of The Day) is a message shown to connecting players +@"MOTD (Message Of The Day) is a message shown to connecting players right under the server name. May be left blank. Note: If WoM extensions are enabled, non-WoM users will not see this.", MinLength = 0, MaxLength = 64 )] MOTD, - [IntKey( ConfigSection.General, 20, @"Maximum number of players on the server. Having more players uses more RAM and more bandwidth. If a player's rank is given a @@ -43,12 +44,11 @@ uses more RAM and more bandwidth. If a player's rank is given a MinValue = 1, MaxValue = 1000 )] MaxPlayers, - [IntKey(ConfigSection.General, 8, + [IntKey( ConfigSection.General, 8, @"Maximum number Caps a player is allowed to chat with.", - MinValue = 1, MaxValue = 12)] + MinValue = 1, MaxValue = 12 )] MaxCaps, - [IntKey( ConfigSection.General, 20, @"Maximum number of players allowed to be on the same world at the same time. Minecraft protocol limits total number of players per world to 128. @@ -56,14 +56,12 @@ Minecraft protocol limits total number of players per world to 128. MinValue = 1, MaxValue = 128 )] MaxPlayersPerWorld, - [RankKey( ConfigSection.General, RankKeyAttribute.BlankValueMeaning.LowestRank, @"New players will be assigned this rank by default. It's generally a good idea not to give new players many powers until they prove themselves trustworthy." )] DefaultRank, - [BoolKey( ConfigSection.General, false, @"Public servers are listed on minecraft.net server list, so expect random players to join. Private servers can only be joined by players @@ -71,7 +69,6 @@ who already know the server port/address or URL. Note that the URL changes if your computer's IP or server's port change." )] IsPublic, - [IntKey( ConfigSection.General, 25565, @"Port number on your local machine that 800Craft uses to listen for incoming connections. If you are behind a router, you may need @@ -88,8 +85,7 @@ is used to pace drawing commands to prevent server from MinValue = 1, MaxValue = short.MaxValue )] UploadBandwidth, - #endregion - + #endregion General #region Chat @@ -122,8 +118,9 @@ is used to pace drawing commands to prevent server from [ColorKey( ConfigSection.Chat, Color.SysDefault, @"Color of normal system messages." )] SystemMessageColor, - [ColorKey(ConfigSection.Chat, Color.CustomDefault, -@"Color of custom chat channel.")] + + [ColorKey( ConfigSection.Chat, Color.CustomDefault, +@"Color of custom chat channel." )] CustomChatColor, [ColorKey( ConfigSection.Chat, Color.HelpDefault, @@ -158,8 +155,7 @@ is used to pace drawing commands to prevent server from MinValue = 0 )] AnnouncementInterval, - #endregion - + #endregion Chat #region Worlds @@ -173,8 +169,7 @@ is used to pace drawing commands to prevent server from make sure to move the map files before starting the server again." )] MapPath, - #endregion - + #endregion Worlds #region Security @@ -230,14 +225,12 @@ Set this to 0 to disable automatic mute (and only leave the warning).", AlwaysAllowZero = true, MinValue = 0, MaxValue = 64 )] AntispamMaxWarnings, - [BoolKey( ConfigSection.Security, false, @"Only allow players who have a paid Minecraft account (not recommended). This will help filter out griefers with throwaway accounts, but will also prevent many legitimate players from joining." )] PaidPlayersOnly, - [BoolKey( ConfigSection.Security, false, @"Require players to specify a reason/memo when banning or unbanning someone." )] RequireBanReason, @@ -250,7 +243,6 @@ Set this to 0 to disable automatic mute (and only leave the warning).", @"Require players to specify a reason/memo when promoting or demoting someone." )] RequireRankChangeReason, - [BoolKey( ConfigSection.Security, true, @"Announce the reason/memo in chat when someone gets kicked/banned/unbanned." )] AnnounceKickAndBanReasons, @@ -276,8 +268,7 @@ Set this to 0 to disable automatic mute (and only leave the warning).", Has no effect until BlockDBAutoEnable key is set." )] BlockDBAutoEnableRank, - #endregion - + #endregion Security #region Saving and Backup @@ -324,16 +315,16 @@ This setting can be overridden on a per-world basis. [BoolKey( ConfigSection.SavingAndBackup, true, @"Create backups of server data (PlayerDB and IPBanList) on startup." )] BackupDataOnStartup, - [BoolKey(ConfigSection.SavingAndBackup, true, -@"Starts the heartbeatsaver on shutdown")] + + [BoolKey( ConfigSection.SavingAndBackup, true, +@"Starts the heartbeatsaver on shutdown" )] HbSaverKey, - [BoolKey(ConfigSection.Chat, true, -@"Enables Global Chat (/Global) for IRC channel #800Craft esper.net")] + [BoolKey( ConfigSection.Chat, true, +@"Enables Global Chat (/Global) for IRC channel #800Craft esper.net" )] GCKey, - #endregion - + #endregion Saving and Backup #region Logging @@ -347,8 +338,7 @@ This setting can be overridden on a per-world basis. MinValue = 0 )] MaxLogs, - #endregion - + #endregion Logging #region IRC @@ -435,11 +425,10 @@ Using multiple bots helps bypass message rate limits on some servers. Note that some networks frown upon having multiple connections from one IP. It is recommended to leave this at 1 unless you are having specific issues with IRC bots falling behind on messages.", - MinValue = 1, MaxValue=3 )] + MinValue = 1, MaxValue = 3 )] IRCThreads, - #endregion - + #endregion IRC #region Advanced @@ -557,6 +546,6 @@ limit also depends on rank draw limits. Saving undo information @"Automatically restarts the server after a given number of seconds." )] RestartInterval - #endregion + #endregion Advanced } } \ No newline at end of file diff --git a/fCraft/System/ConfigSection.cs b/fCraft/System/ConfigSection.cs index f466818..650eb74 100644 --- a/fCraft/System/ConfigSection.cs +++ b/fCraft/System/ConfigSection.cs @@ -1,6 +1,7 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft { + /// ConfigKey section/category. public enum ConfigSection { diff --git a/fCraft/System/Logger.cs b/fCraft/System/Logger.cs index 4f76f58..45bea78 100644 --- a/fCraft/System/Logger.cs +++ b/fCraft/System/Logger.cs @@ -6,143 +6,127 @@ using System.Linq; using System.Net; using System.Net.Cache; -using System.Reflection; using System.Text; using fCraft.Events; using JetBrains.Annotations; + #if DEBUG_EVENTS using System.Reflection.Emit; #endif -namespace fCraft -{ +namespace fCraft { + /// Central logging class. Logs to file, relays messages to the frontend, submits crash reports. - public static class Logger - { - static readonly object LogLock = new object(); + public static class Logger { + private static readonly object LogLock = new object(); + public static bool Enabled { get; set; } + public static readonly bool[] ConsoleOptions; public static readonly bool[] LogFileOptions; - const string DefaultLogFileName = "800Craft.log", + private const string DefaultLogFileName = "800Craft.log", LongDateFormat = "yyyy'-'MM'-'dd'_'HH'-'mm'-'ss", ShortDateFormat = "yyyy'-'MM'-'dd"; - static readonly Uri CrashReportUri = new Uri("http://800craft.webuda.com/crashreport.php"); + + private static readonly Uri CrashReportUri = new Uri( "http://800craft.webuda.com/crashreport.php" ); public static LogSplittingType SplittingType = LogSplittingType.OneFile; - static readonly string SessionStart = DateTime.Now.ToString(LongDateFormat); // localized - static readonly Queue RecentMessages = new Queue(); - const int MaxRecentMessages = 25; + private static readonly string SessionStart = DateTime.Now.ToString( LongDateFormat ); // localized + private static readonly Queue RecentMessages = new Queue(); + private const int MaxRecentMessages = 25; - public static string CurrentLogFileName - { - get - { - switch (SplittingType) - { + public static string CurrentLogFileName { + get { + switch ( SplittingType ) { case LogSplittingType.SplitBySession: return SessionStart + ".log"; case LogSplittingType.SplitByDay: - return DateTime.Now.ToString(ShortDateFormat) + ".log"; // localized + return DateTime.Now.ToString( ShortDateFormat ) + ".log"; // localized default: return DefaultLogFileName; } } } - - static Logger() - { + static Logger() { Enabled = true; - int typeCount = Enum.GetNames(typeof(LogType)).Length; + int typeCount = Enum.GetNames( typeof( LogType ) ).Length; ConsoleOptions = new bool[typeCount]; LogFileOptions = new bool[typeCount]; - for (int i = 0; i < typeCount; i++) - { + for ( int i = 0; i < typeCount; i++ ) { ConsoleOptions[i] = true; LogFileOptions[i] = true; } } - - internal static void MarkLogStart() - { + internal static void MarkLogStart() { // Mark start of logging - Log(LogType.SystemActivity, "------ Log Starts {0} ({1}) ------", - DateTime.Now.ToLongDateString(), DateTime.Now.ToShortDateString()); // localized + Log( LogType.SystemActivity, "------ Log Starts {0} ({1}) ------", + DateTime.Now.ToLongDateString(), DateTime.Now.ToShortDateString() ); // localized } - public static void LogToConsole([NotNull] string message) - { - if (message == null) throw new ArgumentNullException("message"); - if (message.Contains('\n')) - { - foreach (string line in message.Split('\n')) - { - LogToConsole(line); + public static void LogToConsole( [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( message.Contains( '\n' ) ) { + foreach ( string line in message.Split( '\n' ) ) { + LogToConsole( line ); } return; } string processedMessage = "# "; - for (int i = 0; i < message.Length; i++) - { - if (message[i] == '&') i++; - else processedMessage += message[i]; + for ( int i = 0; i < message.Length; i++ ) { + if ( message[i] == '&' ) + i++; + else + processedMessage += message[i]; } - Log(LogType.ConsoleOutput, processedMessage); + Log( LogType.ConsoleOutput, processedMessage ); } - [DebuggerStepThrough] - [StringFormatMethod("message")] - public static void Log(LogType type, [NotNull] string message, [NotNull] params object[] values) - { - if (message == null) throw new ArgumentNullException("message"); - if (values == null) throw new ArgumentNullException("values"); - Log(type, String.Format(message, values)); + [StringFormatMethod( "message" )] + public static void Log( LogType type, [NotNull] string message, [NotNull] params object[] values ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( values == null ) + throw new ArgumentNullException( "values" ); + Log( type, String.Format( message, values ) ); } - [DebuggerStepThrough] - public static void Log(LogType type, [NotNull] string message) - { - if (message == null) throw new ArgumentNullException("message"); - if (!Enabled) return; - string line = DateTime.Now.ToLongTimeString() + " > " + GetPrefix(type) + message; // localized - - lock (LogLock) - { - RaiseLoggedEvent(message, line, type); - - RecentMessages.Enqueue(line); - while (RecentMessages.Count > MaxRecentMessages) - { + public static void Log( LogType type, [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( !Enabled ) + return; + string line = DateTime.Now.ToLongTimeString() + " > " + GetPrefix( type ) + message; // localized + + lock ( LogLock ) { + RaiseLoggedEvent( message, line, type ); + + RecentMessages.Enqueue( line ); + while ( RecentMessages.Count > MaxRecentMessages ) { RecentMessages.Dequeue(); } - if (LogFileOptions[(int)type]) - { - try - { - File.AppendAllText(Path.Combine(Paths.LogPath, CurrentLogFileName), line + Environment.NewLine); - } - catch (Exception ex) - { + if ( LogFileOptions[( int )type] ) { + try { + File.AppendAllText( Path.Combine( Paths.LogPath, CurrentLogFileName ), line + Environment.NewLine ); + } catch ( Exception ex ) { string errorMessage = "Logger.Log: " + ex.Message; - RaiseLoggedEvent(errorMessage, - DateTime.Now.ToLongTimeString() + " > " + GetPrefix(LogType.Error) + errorMessage, // localized - LogType.Error); + RaiseLoggedEvent( errorMessage, + DateTime.Now.ToLongTimeString() + " > " + GetPrefix( LogType.Error ) + errorMessage, // localized + LogType.Error ); } } } } - [DebuggerStepThrough] - public static string GetPrefix(LogType level) - { - switch (level) - { + public static string GetPrefix( LogType level ) { + switch ( level ) { case LogType.SeriousError: case LogType.Error: return "ERROR: "; @@ -155,125 +139,107 @@ public static string GetPrefix(LogType level) } } - #region Crash Handling - static readonly object CrashReportLock = new object(); // mutex to prevent simultaneous reports (messes up the timers/requests) - static DateTime lastCrashReport = DateTime.MinValue; - const int MinCrashReportInterval = 61; // minimum interval between submitting crash reports, in seconds - + private static readonly object CrashReportLock = new object(); // mutex to prevent simultaneous reports (messes up the timers/requests) + private static DateTime lastCrashReport = DateTime.MinValue; + private const int MinCrashReportInterval = 61; // minimum interval between submitting crash reports, in seconds - public static void LogAndReportCrash([CanBeNull] string message, [CanBeNull] string assembly, - [CanBeNull] Exception exception, bool shutdownImminent) - { - if (message == null) message = "(null)"; - if (assembly == null) assembly = "(null)"; - if (exception == null) exception = new Exception("(null)"); + public static void LogAndReportCrash( [CanBeNull] string message, [CanBeNull] string assembly, + [CanBeNull] Exception exception, bool shutdownImminent ) { + if ( message == null ) + message = "(null)"; + if ( assembly == null ) + assembly = "(null)"; + if ( exception == null ) + exception = new Exception( "(null)" ); - Log(LogType.SeriousError, "{0}: {1}", message, exception); + Log( LogType.SeriousError, "{0}: {1}", message, exception ); bool submitCrashReport = ConfigKey.SubmitCrashReports.Enabled(); - bool isCommon = CheckForCommonErrors(exception); + bool isCommon = CheckForCommonErrors( exception ); // ReSharper disable EmptyGeneralCatchClause - try - { - var eventArgs = new CrashedEventArgs(message, + try { + var eventArgs = new CrashedEventArgs( message, assembly, exception, submitCrashReport && !isCommon, isCommon, - shutdownImminent); - RaiseCrashedEvent(eventArgs); + shutdownImminent ); + RaiseCrashedEvent( eventArgs ); isCommon = eventArgs.IsCommonProblem; - } - catch { } + } catch { } // ReSharper restore EmptyGeneralCatchClause - if (!submitCrashReport || isCommon) - { + if ( !submitCrashReport || isCommon ) { return; } - lock (CrashReportLock) - { - if (DateTime.UtcNow.Subtract(lastCrashReport).TotalSeconds < MinCrashReportInterval) - { - Log(LogType.Warning, "Logger.SubmitCrashReport: Could not submit crash report, reports too frequent."); + lock ( CrashReportLock ) { + if ( DateTime.UtcNow.Subtract( lastCrashReport ).TotalSeconds < MinCrashReportInterval ) { + Log( LogType.Warning, "Logger.SubmitCrashReport: Could not submit crash report, reports too frequent." ); return; } lastCrashReport = DateTime.UtcNow; - try - { + try { StringBuilder sb = new StringBuilder(); - sb.Append("version=").Append(Uri.EscapeDataString(Updater.CurrentRelease.VersionString)); - sb.Append("&message=").Append(Uri.EscapeDataString(message)); - sb.Append("&assembly=").Append(Uri.EscapeDataString(assembly)); - sb.Append("&runtime="); - if (MonoCompat.IsMono) - { - sb.Append(Uri.EscapeDataString("Mono " + MonoCompat.MonoVersionString)); - } - else - { - sb.Append(Uri.EscapeDataString("CLR " + Environment.Version)); - } - sb.Append("&os=").Append(Environment.OSVersion.Platform + " / " + Environment.OSVersion.VersionString); - - sb.Append("&exceptiontype=").Append(Uri.EscapeDataString(exception.GetType().ToString())); - sb.Append("&exceptionmessage=").Append(Uri.EscapeDataString(exception.Message)); - sb.Append("&exceptionstacktrace="); - if (exception.StackTrace != null) - { - sb.Append(Uri.EscapeDataString(exception.StackTrace)); + sb.Append( "version=" ).Append( Uri.EscapeDataString( Updater.CurrentRelease.VersionString ) ); + sb.Append( "&message=" ).Append( Uri.EscapeDataString( message ) ); + sb.Append( "&assembly=" ).Append( Uri.EscapeDataString( assembly ) ); + sb.Append( "&runtime=" ); + if ( MonoCompat.IsMono ) { + sb.Append( Uri.EscapeDataString( "Mono " + MonoCompat.MonoVersionString ) ); + } else { + sb.Append( Uri.EscapeDataString( "CLR " + Environment.Version ) ); } - else - { - sb.Append("(none)"); + sb.Append( "&os=" ).Append( Environment.OSVersion.Platform + " / " + Environment.OSVersion.VersionString ); + + sb.Append( "&exceptiontype=" ).Append( Uri.EscapeDataString( exception.GetType().ToString() ) ); + sb.Append( "&exceptionmessage=" ).Append( Uri.EscapeDataString( exception.Message ) ); + sb.Append( "&exceptionstacktrace=" ); + if ( exception.StackTrace != null ) { + sb.Append( Uri.EscapeDataString( exception.StackTrace ) ); + } else { + sb.Append( "(none)" ); } - sb.Append("&config="); - if (File.Exists(Paths.ConfigFileName)) - { - sb.Append(Uri.EscapeDataString(File.ReadAllText(Paths.ConfigFileName))); + sb.Append( "&config=" ); + if ( File.Exists( Paths.ConfigFileName ) ) { + sb.Append( Uri.EscapeDataString( File.ReadAllText( Paths.ConfigFileName ) ) ); } string assemblies = AppDomain.CurrentDomain .GetAssemblies() - .JoinToString(Environment.NewLine, asm => asm.FullName); - sb.Append("&asm=").Append(Uri.EscapeDataString(assemblies)); + .JoinToString( Environment.NewLine, asm => asm.FullName ); + sb.Append( "&asm=" ).Append( Uri.EscapeDataString( assemblies ) ); string[] lastFewLines; - lock (LogLock) - { + lock ( LogLock ) { lastFewLines = RecentMessages.ToArray(); } - sb.Append("&log=").Append(Uri.EscapeDataString(String.Join(Environment.NewLine, lastFewLines))); + sb.Append( "&log=" ).Append( Uri.EscapeDataString( String.Join( Environment.NewLine, lastFewLines ) ) ); - byte[] formData = Encoding.UTF8.GetBytes(sb.ToString()); - HttpWebRequest request = (HttpWebRequest)WebRequest.Create(CrashReportUri); + byte[] formData = Encoding.UTF8.GetBytes( sb.ToString() ); + HttpWebRequest request = ( HttpWebRequest )WebRequest.Create( CrashReportUri ); request.Method = "POST"; request.Timeout = 15000; // 15s timeout request.ContentType = "application/x-www-form-urlencoded"; - request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); + request.CachePolicy = new RequestCachePolicy( RequestCacheLevel.NoCacheNoStore ); request.ContentLength = formData.Length; request.UserAgent = Updater.UserAgent; - using (Stream requestStream = request.GetRequestStream()) - { - requestStream.Write(formData, 0, formData.Length); + using ( Stream requestStream = request.GetRequestStream() ) { + requestStream.Write( formData, 0, formData.Length ); requestStream.Flush(); } string responseString; - using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) - { - using (Stream responseStream = response.GetResponseStream()) - { + using ( HttpWebResponse response = ( HttpWebResponse )request.GetResponse() ) { + using ( Stream responseStream = response.GetResponseStream() ) { // ReSharper disable AssignNullToNotNullAttribute - using (StreamReader reader = new StreamReader(responseStream)) - { + using ( StreamReader reader = new StreamReader( responseStream ) ) { // ReSharper restore AssignNullToNotNullAttribute responseString = reader.ReadLine(); } @@ -281,118 +247,84 @@ public static void LogAndReportCrash([CanBeNull] string message, [CanBeNull] str } request.Abort(); - if (responseString != null && responseString.StartsWith("ERROR")) - { - Log(LogType.Error, "Crash report could not be processed by 800Craft.net."); - } - else - { + if ( responseString != null && responseString.StartsWith( "ERROR" ) ) { + Log( LogType.Error, "Crash report could not be processed by 800Craft.net." ); + } else { int referenceNumber; - if (responseString != null && Int32.TryParse(responseString, out referenceNumber)) - { - Log(LogType.SystemActivity, "Crash report submitted (Reference #{0})", referenceNumber); - } - else - { - Log(LogType.SystemActivity, "Crash report submitted."); + if ( responseString != null && Int32.TryParse( responseString, out referenceNumber ) ) { + Log( LogType.SystemActivity, "Crash report submitted (Reference #{0})", referenceNumber ); + } else { + Log( LogType.SystemActivity, "Crash report submitted." ); } } - } - catch (Exception ex) - { - Log(LogType.Warning, "Logger.SubmitCrashReport: {0}", ex); + } catch ( Exception ex ) { + Log( LogType.Warning, "Logger.SubmitCrashReport: {0}", ex ); } } } - // Called by the Logger in case of serious errors to print troubleshooting advice. // Returns true if this type of error is common, and crash report should NOT be submitted. - public static bool CheckForCommonErrors([CanBeNull] Exception ex) - { - if (ex == null) throw new ArgumentNullException("ex"); + public static bool CheckForCommonErrors( [CanBeNull] Exception ex ) { + if ( ex == null ) + throw new ArgumentNullException( "ex" ); string message = null; - try - { - if ((ex is FileNotFoundException && ex.Message.Contains("Version=3.5")) || (ex is FileNotFoundException && ex.Message.Contains("Version=3.5"))) - { + try { + if ( ( ex is FileNotFoundException && ex.Message.Contains( "Version=3.5" ) ) || ( ex is FileNotFoundException && ex.Message.Contains( "Version=3.5" ) ) ) { message = "Your crash was likely caused by using a wrong version of .NET or Mono runtime. " + "Please update to Microsoft .NET Framework 4 (Windows) OR Mono 2.8+ (Linux, Unix, Mac OS X)."; return true; - } - else if (ex.Message.Contains("libMonoPosixHelper") || - ex is EntryPointNotFoundException && ex.Message.Contains("CreateZStream")) - { + } else if ( ex.Message.Contains( "libMonoPosixHelper" ) || + ex is EntryPointNotFoundException && ex.Message.Contains( "CreateZStream" ) ) { message = "800Craft could not locate Mono's compression functionality. " + "Please make sure that you have zlib (sometimes called \"libz\" or just \"z\") installed. " + "Some versions of Mono may also require \"libmono-posix-2.0-cil\" package to be installed."; return true; - } - else if (ex is MissingMemberException || ex is TypeLoadException) - { + } else if ( ex is MissingMemberException || ex is TypeLoadException ) { message = "Something is incompatible with the current revision of 800Craft. " + "If you installed third-party modifications, " + "make sure to use the correct revision (as specified by mod developers). " + "If your own modifications stopped working, your may need to make some updates."; return true; - } - else if (ex is UnauthorizedAccessException) - { + } else if ( ex is UnauthorizedAccessException ) { message = "800Craft was blocked from accessing a file or resource. " + "Make sure that correct permissions are set for the 800Craft files, folders, and processes."; return true; - } - else if (ex is OutOfMemoryException) - { + } else if ( ex is OutOfMemoryException ) { message = "800Craft ran out of memory. Make sure there is enough RAM to run."; return true; - } - else if (ex is SystemException && ex.Message == "Can't find current process") - { + } else if ( ex is SystemException && ex.Message == "Can't find current process" ) { // Ignore Mono-specific bug in MonitorProcessorUsage() return true; - - } - else if (ex is InvalidOperationException && ex.StackTrace.Contains("MD5CryptoServiceProvider")) - { + } else if ( ex is InvalidOperationException && ex.StackTrace.Contains( "MD5CryptoServiceProvider" ) ) { message = "Some Windows settings are preventing 800Craft from doing player name verification. " + "See http://support.microsoft.com/kb/811833"; return true; - } - else if (ex.StackTrace.Contains("__Error.WinIOError")) - { + } else if ( ex.StackTrace.Contains( "__Error.WinIOError" ) ) { message = "A filesystem-related error has occured. Make sure that only one instance of 800Craft is running, " + "and that no other processes are using server's files or directories."; return true; - } - else if (ex.Message.Contains("UNSTABLE")) - { + } else if ( ex.Message.Contains( "UNSTABLE" ) ) { return true; - } - else - { + } else { return false; } - } - finally - { - if (message != null) - { - Log(LogType.Warning, message); + } finally { + if ( message != null ) { + Log( LogType.Warning, message ); } } } - #endregion - + #endregion Crash Handling #region Event Tracing + #if DEBUG_EVENTS // list of events in this assembly static readonly Dictionary eventsMap = new Dictionary(); - static List eventWhitelist = new List(); static List eventBlacklist = new List(); const string TraceWhitelistFile = "traceonly.txt", @@ -409,10 +341,8 @@ static void LoadTracingSettings() { } } - // adds hooks to all compliant events in current assembly internal static void PrepareEventTracing() { - LoadTracingSettings(); // create a dynamic type to hold our handler methods @@ -435,7 +365,6 @@ internal static void PrepareEventTracing() { } if( eventInfo.EventHandlerType.FullName.StartsWith( typeof( EventHandler<> ).FullName ) || eventInfo.EventHandlerType.FullName.StartsWith( typeof( EventHandler ).FullName ) ) { - if( useEventWhitelist && !eventWhitelist.Contains( type.Name + "." + eventInfo.Name, StringComparer.OrdinalIgnoreCase ) || useEventBlacklist && eventBlacklist.Contains( type.Name + "." + eventInfo.Name, StringComparer.OrdinalIgnoreCase ) ) continue; @@ -464,7 +393,6 @@ internal static void PrepareEventTracing() { } } - // create a static handler method that matches the given signature, and calls EventTraceNotifier static void AddEventHook( TypeBuilder typeBuilder, Type[] methodParams, Type returnType, int eventIndex ) { string methodName = "EventHook" + eventIndex; @@ -481,7 +409,6 @@ static void AddEventHook( TypeBuilder typeBuilder, Type[] methodParams, Type ret generator.Emit( OpCodes.Ret ); } - // Invoked when events fire public static void EventTraceNotifier( int eventIndex, EventArgs e ) { if( (e is LogEventArgs) && ((LogEventArgs)e).MessageType == LogType.Trace ) return; @@ -508,53 +435,51 @@ public static void EventTraceNotifier( int eventIndex, EventArgs e ) { Log( LogType.Trace, "TraceEvent: {0}.{1}( {2} )", eventInfo.DeclaringType.Name, eventInfo.Name, sb.ToString() ); - } #endif - #endregion + #endregion Event Tracing #region Events /// Occurs after a message has been logged. public static event EventHandler Logged; - /// Occurs when the server "crashes" (has an unhandled exception). /// Note that such occurences will not always cause shutdowns - check ShutdownImminent property. /// Reporting of the crash may be suppressed. public static event EventHandler Crashed; - [DebuggerStepThrough] - static void RaiseLoggedEvent([NotNull] string rawMessage, [NotNull] string line, LogType logType) - { - if (rawMessage == null) throw new ArgumentNullException("rawMessage"); - if (line == null) throw new ArgumentNullException("line"); + private static void RaiseLoggedEvent( [NotNull] string rawMessage, [NotNull] string line, LogType logType ) { + if ( rawMessage == null ) + throw new ArgumentNullException( "rawMessage" ); + if ( line == null ) + throw new ArgumentNullException( "line" ); var h = Logged; - if (h != null) h(null, new LogEventArgs(rawMessage, - line, - logType, - LogFileOptions[(int)logType], - ConsoleOptions[(int)logType])); + if ( h != null ) + h( null, new LogEventArgs( rawMessage, + line, + logType, + LogFileOptions[( int )logType], + ConsoleOptions[( int )logType] ) ); } - - static void RaiseCrashedEvent(CrashedEventArgs e) - { + private static void RaiseCrashedEvent( CrashedEventArgs e ) { var h = Crashed; - if (h != null) h(null, e); + if ( h != null ) + h( null, e ); } - #endregion + #endregion Events } #region Enums /// Category of a log event. - public enum LogType - { + public enum LogType { + /// System activity (loading/saving of data, shutdown and startup events, etc). SystemActivity, @@ -604,10 +529,9 @@ public enum LogType Trace } - /// Log splitting type. - public enum LogSplittingType - { + public enum LogSplittingType { + /// All logs are written to one file. OneFile, @@ -618,35 +542,36 @@ public enum LogSplittingType SplitByDay } - #endregion + #endregion Enums } +namespace fCraft.Events { + + public sealed class LogEventArgs : EventArgs { -namespace fCraft.Events -{ - public sealed class LogEventArgs : EventArgs - { [DebuggerStepThrough] - internal LogEventArgs(string rawMessage, string message, LogType messageType, bool writeToFile, bool writeToConsole) - { + internal LogEventArgs( string rawMessage, string message, LogType messageType, bool writeToFile, bool writeToConsole ) { RawMessage = rawMessage; Message = message; MessageType = messageType; WriteToFile = writeToFile; WriteToConsole = writeToConsole; } + public string RawMessage { get; private set; } + public string Message { get; private set; } + public LogType MessageType { get; private set; } + public bool WriteToFile { get; private set; } + public bool WriteToConsole { get; private set; } } + public sealed class CrashedEventArgs : EventArgs { - public sealed class CrashedEventArgs : EventArgs - { - internal CrashedEventArgs(string message, string location, Exception exception, bool submitCrashReport, bool isCommonProblem, bool shutdownImminent) - { + internal CrashedEventArgs( string message, string location, Exception exception, bool submitCrashReport, bool isCommonProblem, bool shutdownImminent ) { Message = message; Location = location; Exception = exception; @@ -654,11 +579,17 @@ internal CrashedEventArgs(string message, string location, Exception exception, IsCommonProblem = isCommonProblem; ShutdownImminent = shutdownImminent; } + public string Message { get; private set; } + public string Location { get; private set; } + public Exception Exception { get; private set; } + public bool SubmitCrashReport { get; set; } + public bool IsCommonProblem { get; private set; } + public bool ShutdownImminent { get; private set; } } } \ No newline at end of file diff --git a/fCraft/System/Scheduler.cs b/fCraft/System/Scheduler.cs index a66f149..d316788 100644 --- a/fCraft/System/Scheduler.cs +++ b/fCraft/System/Scheduler.cs @@ -1,24 +1,25 @@ // Copyright 2009-2013 Matvei Stefarov using System; using System.Collections.Generic; +using System.Diagnostics; +using System.IO; using System.Threading; using JetBrains.Annotations; -using System.IO; -using System.Diagnostics; namespace fCraft { + /// A general-purpose task scheduler. public static class Scheduler { - static readonly HashSet Tasks = new HashSet(); - static SchedulerTask[] taskCache; - static readonly Queue BackgroundTasks = new Queue(); - static readonly object TaskListLock = new object(), + private static readonly HashSet Tasks = new HashSet(); + private static SchedulerTask[] taskCache; + private static readonly Queue BackgroundTasks = new Queue(); + + private static readonly object TaskListLock = new object(), BackgroundTaskListLock = new object(); - static Thread schedulerThread, + private static Thread schedulerThread, backgroundThread; - internal static void Start() { #if DEBUG_SCHEDULER Logger.Log( LogType.Debug, "Scheduler: Starting..." ); @@ -33,22 +34,22 @@ internal static void Start() { backgroundThread.Start(); } - - static void MainLoop() { - while( !Server.IsShuttingDown ) { + private static void MainLoop() { + while ( !Server.IsShuttingDown ) { DateTime ticksNow = DateTime.UtcNow; SchedulerTask[] taskListCache = taskCache; - for( int i = 0; i < taskListCache.Length && !Server.IsShuttingDown; i++ ) { + for ( int i = 0; i < taskListCache.Length && !Server.IsShuttingDown; i++ ) { SchedulerTask task = taskListCache[i]; - if( task.IsStopped || task.NextTime > ticksNow ) continue; - if( task.IsRecurring && task.AdjustForExecutionTime ) { + if ( task.IsStopped || task.NextTime > ticksNow ) + continue; + if ( task.IsRecurring && task.AdjustForExecutionTime ) { task.NextTime += task.Interval; } - if( task.IsBackground ) { - lock( BackgroundTaskListLock ) { + if ( task.IsBackground ) { + lock ( BackgroundTaskListLock ) { BackgroundTasks.Enqueue( task ); } } else { @@ -64,7 +65,7 @@ static void MainLoop() { #else try { task.Callback( task ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.LogAndReportCrash( "Exception thrown by ScheduledTask callback", "fCraft", ex, false ); } finally { task.IsExecuting = false; @@ -76,14 +77,14 @@ static void MainLoop() { #endif } - if( !task.IsRecurring || task.MaxRepeats == 1 ) { + if ( !task.IsRecurring || task.MaxRepeats == 1 ) { task.Stop(); continue; } task.MaxRepeats--; ticksNow = DateTime.UtcNow; - if( !task.AdjustForExecutionTime ) { + if ( !task.AdjustForExecutionTime ) { task.NextTime = ticksNow.Add( task.Interval ); } } @@ -92,12 +93,11 @@ static void MainLoop() { } } - - static void BackgroundLoop() { - while( !Server.IsShuttingDown ) { - if( BackgroundTasks.Count > 0 ) { + private static void BackgroundLoop() { + while ( !Server.IsShuttingDown ) { + if ( BackgroundTasks.Count > 0 ) { SchedulerTask task; - lock( BackgroundTaskListLock ) { + lock ( BackgroundTaskListLock ) { task = BackgroundTasks.Dequeue(); } task.IsExecuting = true; @@ -110,7 +110,7 @@ static void BackgroundLoop() { #else try { task.Callback( task ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.LogAndReportCrash( "Exception thrown by ScheduledTask callback", "fCraft", ex, false ); } finally { task.IsExecuting = false; @@ -125,13 +125,14 @@ static void BackgroundLoop() { } } - /// Schedules a given task for execution. /// Task to schedule. internal static void AddTask( [NotNull] SchedulerTask task ) { - if( task == null ) throw new ArgumentNullException( "task" ); - lock( TaskListLock ) { - if( Server.IsShuttingDown ) return; + if ( task == null ) + throw new ArgumentNullException( "task" ); + lock ( TaskListLock ) { + if ( Server.IsShuttingDown ) + return; task.IsStopped = false; #if DEBUG_SCHEDULER FireEvent( TaskAdded, task ); @@ -144,14 +145,13 @@ internal static void AddTask( [NotNull] SchedulerTask task ) { "Scheduler.AddTask: Added duplicate {0}", task ); } #else - if( Tasks.Add( task ) ) { + if ( Tasks.Add( task ) ) { UpdateCache(); } #endif } } - /// Creates a new SchedulerTask object to run in the main thread. /// Use this if your task is time-sensitive or frequent, and your callback won't take too long to execute. /// Method to call when the task is triggered. @@ -160,7 +160,6 @@ public static SchedulerTask NewTask( [NotNull] SchedulerCallback callback ) { return new SchedulerTask( callback, false ); } - /// Creates a new SchedulerTask object to run in the background thread. /// Use this if your task is not very time-sensitive or frequent, or if your callback is resource-intensive. /// Method to call when the task is triggered. @@ -169,7 +168,6 @@ public static SchedulerTask NewBackgroundTask( [NotNull] SchedulerCallback callb return new SchedulerTask( callback, true ); } - /// Creates a new SchedulerTask object to run in the main thread. /// Use this if your task is time-sensitive or frequent, and your callback won't take too long to execute. /// Method to call when the task is triggered. @@ -179,7 +177,6 @@ public static SchedulerTask NewTask( [NotNull] SchedulerCallback callback, [CanB return new SchedulerTask( callback, false, userState ); } - /// Creates a new SchedulerTask object to run in the background thread. /// Use this if your task is not very time-sensitive or frequent, or if your callback is resource-intensive. /// Method to call when the task is triggered. @@ -189,20 +186,19 @@ public static SchedulerTask NewBackgroundTask( [NotNull] SchedulerCallback callb return new SchedulerTask( callback, true, userState ); } - // Removes stopped tasks from the list internal static void UpdateCache() { List newList = new List(); List deletionList = new List(); - lock( TaskListLock ) { - foreach( SchedulerTask task in Tasks ) { - if( task.IsStopped ) { + lock ( TaskListLock ) { + foreach ( SchedulerTask task in Tasks ) { + if ( task.IsStopped ) { deletionList.Add( task ); } else { newList.Add( task ); } } - for( int i = 0; i < deletionList.Count; i++ ) { + for ( int i = 0; i < deletionList.Count; i++ ) { Tasks.Remove( deletionList[i] ); #if DEBUG_SCHEDULER FireEvent( TaskRemoved, deletionList[i] ); @@ -214,40 +210,32 @@ internal static void UpdateCache() { taskCache = newList.ToArray(); } - // Clears the task list internal static void BeginShutdown() { #if DEBUG_SCHEDULER Logger.Log( LogType.Debug, "Scheduler: BeginShutdown..." ); #endif - if ( ConfigKey.HbSaverKey.Enabled() && ConfigKey.IsPublic.Enabled() ) - { - if (!Server.IsRestarting) - { - try - { - if (!File.Exists("heartbeatsaver.exe")) - { - Logger.Log(LogType.Warning, "heartbeatsaver.exe does not exist and failed to launch"); + if ( ConfigKey.HbSaverKey.Enabled() && ConfigKey.IsPublic.Enabled() ) { + if ( !Server.IsRestarting ) { + try { + if ( !File.Exists( "heartbeatsaver.exe" ) ) { + Logger.Log( LogType.Warning, "heartbeatsaver.exe does not exist and failed to launch" ); return; } //start the heartbeat saver Process HeartbeatSaver = new Process(); - Logger.Log(LogType.SystemActivity, "Starting the HeartBeat Saver"); + Logger.Log( LogType.SystemActivity, "Starting the HeartBeat Saver" ); HeartbeatSaver.StartInfo.FileName = "heartbeatsaver.exe"; HeartbeatSaver.Start(); + } catch ( Exception ex ) { + Logger.Log( LogType.Error, "HeartBeatSaver: " + ex ); } - catch (Exception ex) - { - Logger.Log(LogType.Error, "HeartBeatSaver: " + ex); - } - } - else - Logger.Log(LogType.SystemActivity, "HeartBeat Saver was not launched"); + } else + Logger.Log( LogType.SystemActivity, "HeartBeat Saver was not launched" ); } - lock( TaskListLock ) { - foreach( SchedulerTask task in Tasks ) { + lock ( TaskListLock ) { + foreach ( SchedulerTask task in Tasks ) { task.Stop(); } Tasks.Clear(); @@ -255,29 +243,27 @@ internal static void BeginShutdown() { } } - // Makes sure that both scheduler threads finish and quit. internal static void EndShutdown() { #if DEBUG_SCHEDULER Logger.Log( LogType.Debug, "Scheduler: EndShutdown..." ); #endif try { - if( schedulerThread != null && schedulerThread.IsAlive ) { + if ( schedulerThread != null && schedulerThread.IsAlive ) { schedulerThread.Join(); } schedulerThread = null; - } catch( ThreadStateException ) { } + } catch ( ThreadStateException ) { } try { - if( backgroundThread != null && backgroundThread.IsAlive ) { + if ( backgroundThread != null && backgroundThread.IsAlive ) { backgroundThread.Join(); } backgroundThread = null; - } catch( ThreadStateException ) { } + } catch ( ThreadStateException ) { } } - #if DEBUG_SCHEDULER - + public static void PrintTasks( [NotNull] Player player ) { if( player == null ) throw new ArgumentNullException( "player" ); lock( TaskListLock ) { @@ -287,7 +273,6 @@ public static void PrintTasks( [NotNull] Player player ) { } } - public static event EventHandler TaskAdded; public static event EventHandler TaskExecuting; @@ -296,7 +281,6 @@ public static void PrintTasks( [NotNull] Player player ) { public static event EventHandler TaskRemoved; - static void FireEvent( EventHandler eventToFire, SchedulerTask task ) { var h = eventToFire; if( h != null ) h( null, new SchedulerTaskEventArgs( task ) ); diff --git a/fCraft/System/SchedulerTask.cs b/fCraft/System/SchedulerTask.cs index 8aee976..ec5ece7 100644 --- a/fCraft/System/SchedulerTask.cs +++ b/fCraft/System/SchedulerTask.cs @@ -4,30 +4,31 @@ using JetBrains.Annotations; namespace fCraft { + /// A task to be executed by the Scheduler. /// Stores timing information and state. public sealed class SchedulerTask { - static readonly TimeSpan DefaultInterval = TimeSpan.FromMinutes( 1 ); + private static readonly TimeSpan DefaultInterval = TimeSpan.FromMinutes( 1 ); - SchedulerTask() { + private SchedulerTask() { AdjustForExecutionTime = true; Delay = TimeSpan.Zero; Interval = DefaultInterval; MaxRepeats = -1; } - internal SchedulerTask( [NotNull] SchedulerCallback callback, bool isBackground ) : this() { - if( callback == null ) throw new ArgumentNullException( "callback" ); + if ( callback == null ) + throw new ArgumentNullException( "callback" ); Callback = callback; IsBackground = isBackground; } - internal SchedulerTask( [NotNull] SchedulerCallback callback, bool isBackground, [CanBeNull] object userState ) : this() { - if( callback == null ) throw new ArgumentNullException( "callback" ); + if ( callback == null ) + throw new ArgumentNullException( "callback" ); Callback = callback; IsBackground = isBackground; UserState = userState; @@ -76,7 +77,6 @@ internal SchedulerTask( [NotNull] SchedulerCallback callback, bool isBackground, /// can be used for anything you want. public object UserState { get; set; } - #region Run Once /// Runs the task once, as quickly as possible. @@ -88,14 +88,12 @@ public SchedulerTask RunOnce() { return this; } - /// Runs the task once, after a given delay. public SchedulerTask RunOnce( TimeSpan delay ) { Delay = delay; return RunOnce(); } - /// Runs the task once at a given date. /// If the given date is in the past, the task is ran immediately. public SchedulerTask RunOnce( DateTime time ) { @@ -106,14 +104,12 @@ public SchedulerTask RunOnce( DateTime time ) { return this; } - /// Runs the task once, after a given delay. public SchedulerTask RunOnce( object userState, TimeSpan delay ) { UserState = userState; return RunOnce( delay ); } - /// Runs the task once at a given date. /// If the given date is in the past, the task is ran immediately. public SchedulerTask RunOnce( object userState, DateTime time ) { @@ -121,69 +117,66 @@ public SchedulerTask RunOnce( object userState, DateTime time ) { return RunOnce( time ); } - #endregion - + #endregion Run Once #region Run Forever - SchedulerTask RunForever() { + private SchedulerTask RunForever() { IsRecurring = true; NextTime = DateTime.UtcNow.Add( Delay ); Scheduler.AddTask( this ); return this; } - /// Runs the task forever at a given interval, until manually stopped. public SchedulerTask RunForever( TimeSpan interval ) { - if( interval.Ticks < 0 ) throw new ArgumentException( "Interval must be positive", "interval" ); + if ( interval.Ticks < 0 ) + throw new ArgumentException( "Interval must be positive", "interval" ); Interval = interval; return RunForever(); } - /// Runs the task forever at a given interval after an initial delay, until manually stopped. public SchedulerTask RunForever( TimeSpan interval, TimeSpan delay ) { - if( interval.Ticks < 0 ) throw new ArgumentException( "Interval must be positive", "interval" ); + if ( interval.Ticks < 0 ) + throw new ArgumentException( "Interval must be positive", "interval" ); Interval = interval; Delay = delay; return RunForever(); } - /// Runs the task forever at a given interval after an initial delay, until manually stopped. public SchedulerTask RunForever( object userState, TimeSpan interval, TimeSpan delay ) { UserState = userState; return RunForever( interval, delay ); } - #endregion - + #endregion Run Forever #region Run Repeating /// Runs the task a given number of times, at a given interval after an initial delay. public SchedulerTask RunRepeating( TimeSpan delay, TimeSpan interval, int times ) { - if( times < 1 ) throw new ArgumentException( "Must be ran at least 1 time.", "times" ); + if ( times < 1 ) + throw new ArgumentException( "Must be ran at least 1 time.", "times" ); MaxRepeats = times; return RunForever( interval, delay ); } - /// Runs the task a given number of times, at a given interval after an initial delay. public SchedulerTask RunRepeating( [CanBeNull] object userState, TimeSpan delay, TimeSpan interval, int times ) { - if( times < 1 ) throw new ArgumentException( "Must be ran at least 1 time.", "times" ); + if ( times < 1 ) + throw new ArgumentException( "Must be ran at least 1 time.", "times" ); UserState = userState; MaxRepeats = times; return RunForever( interval, delay ); } - #endregion - + #endregion Run Repeating #region Run Manual - static readonly TimeSpan CloseEnoughToForever = TimeSpan.FromDays( 36525 ); // >100 years + private static readonly TimeSpan CloseEnoughToForever = TimeSpan.FromDays( 36525 ); // >100 years /// Executes the task once immediately, and suspends (but does not stop). /// A SchedulerTask object can be reused many times if ran manually. @@ -221,8 +214,7 @@ public SchedulerTask RunManual( DateTime time ) { return this; } - #endregion - + #endregion Run Manual /// Stops the task, and removes it from the schedule. public SchedulerTask Stop() { @@ -230,15 +222,14 @@ public SchedulerTask Stop() { return this; } - public override string ToString() { StringBuilder sb = new StringBuilder( "Task(" ); - if( IsStopped ) { + if ( IsStopped ) { sb.Append( "STOPPED " ); } - if( Callback.Target != null ) { + if ( Callback.Target != null ) { sb.Append( Callback.Target ).Append( "::" ); } sb.Append( Callback.Method.DeclaringType.Name ); @@ -246,12 +237,12 @@ public override string ToString() { sb.Append( Callback.Method.Name ); sb.Append( " @ " ); - if( IsRecurring ) { + if ( IsRecurring ) { sb.Append( Interval.ToCompactString() ); } sb.Append( "+" ).Append( Delay.ToCompactString() ); - if( UserState != null ) { + if ( UserState != null ) { sb.Append( " -> " ); sb.Append( UserState ); } @@ -260,10 +251,8 @@ public override string ToString() { } } - public delegate void SchedulerCallback( [NotNull] SchedulerTask task ); - #if DEBUG_SCHEDULER public class SchedulerTaskEventArgs : EventArgs { public SchedulerTaskEventArgs( SchedulerTask task ) { @@ -272,4 +261,4 @@ public SchedulerTaskEventArgs( SchedulerTask task ) { public SchedulerTask Task { get; private set; } } #endif -} +} \ No newline at end of file diff --git a/fCraft/System/Server.Events.cs b/fCraft/System/Server.Events.cs index 88b688c..cde2b22 100644 --- a/fCraft/System/Server.Events.cs +++ b/fCraft/System/Server.Events.cs @@ -1,11 +1,12 @@ // Copyright 2009-2013 Matvei Stefarov using System; -using System.Net; using System.Collections.Generic; +using System.Net; using fCraft.Events; using JetBrains.Annotations; namespace fCraft { + partial class Server { /// Occurs when the server is about to be initialized. @@ -29,80 +30,80 @@ partial class Server { /// Occurs when the player list has just changed (any time players connected or disconnected). public static event EventHandler PlayerListChanged; - /// Occurs when a player is searching for players (with autocompletion). /// The list of players in the search results may be replaced. public static event EventHandler SearchingForPlayer; - - static void RaiseEvent( EventHandler h ) { - if( h != null ) h( null, EventArgs.Empty ); + private static void RaiseEvent( EventHandler h ) { + if ( h != null ) + h( null, EventArgs.Empty ); } - static void RaiseShutdownBeganEvent( ShutdownParams shutdownParams ) { + private static void RaiseShutdownBeganEvent( ShutdownParams shutdownParams ) { var h = ShutdownBegan; - if( h != null ) h( null, new ShutdownEventArgs( shutdownParams ) ); + if ( h != null ) + h( null, new ShutdownEventArgs( shutdownParams ) ); } - static void RaiseShutdownEndedEvent( ShutdownParams shutdownParams ) { + private static void RaiseShutdownEndedEvent( ShutdownParams shutdownParams ) { var h = ShutdownEnded; - if( h != null ) h( null, new ShutdownEventArgs( shutdownParams ) ); + if ( h != null ) + h( null, new ShutdownEventArgs( shutdownParams ) ); } internal static void RaisePlayerListChangedEvent() { RaiseEvent( PlayerListChanged ); } - #region Session-related /// Occurs any time the server receives an incoming connection (cancellable). public static event EventHandler SessionConnecting; - /// Occurs any time a new session has connected, but before any communication is done. public static event EventHandler SessionConnected; - /// Occurs when a connection is closed or lost. public static event EventHandler SessionDisconnected; - - internal static bool RaiseSessionConnectingEvent( [NotNull] IPAddress ip ) { - if( ip == null ) throw new ArgumentNullException( "ip" ); + if ( ip == null ) + throw new ArgumentNullException( "ip" ); var h = SessionConnecting; - if( h == null ) return false; + if ( h == null ) + return false; var e = new SessionConnectingEventArgs( ip ); h( null, e ); return e.Cancel; } - internal static void RaiseSessionConnectedEvent( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); var h = SessionConnected; - if( h != null ) h( null, new PlayerEventArgs( player ) ); + if ( h != null ) + h( null, new PlayerEventArgs( player ) ); } - internal static void RaiseSessionDisconnectedEvent( [NotNull] Player player, LeaveReason leaveReason ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); var h = SessionDisconnected; - if( h != null ) h( null, new SessionDisconnectedEventArgs( player, leaveReason ) ); + if ( h != null ) + h( null, new SessionDisconnectedEventArgs( player, leaveReason ) ); } - #endregion - + #endregion Session-related } } - namespace fCraft.Events { public sealed class ShutdownEventArgs : EventArgs { + internal ShutdownEventArgs( [NotNull] ShutdownParams shutdownParams ) { - if( shutdownParams == null ) throw new ArgumentNullException( "shutdownParams" ); + if ( shutdownParams == null ) + throw new ArgumentNullException( "shutdownParams" ); ShutdownParams = shutdownParams; } @@ -110,10 +111,11 @@ internal ShutdownEventArgs( [NotNull] ShutdownParams shutdownParams ) { public ShutdownParams ShutdownParams { get; private set; } } - public sealed class SearchingForPlayerEventArgs : EventArgs, IPlayerEvent { + internal SearchingForPlayerEventArgs( [CanBeNull] Player player, [NotNull] string searchTerm, List matches ) { - if( searchTerm == null ) throw new ArgumentNullException( "searchTerm" ); + if ( searchTerm == null ) + throw new ArgumentNullException( "searchTerm" ); Player = player; SearchTerm = searchTerm; Matches = matches; @@ -121,7 +123,9 @@ internal SearchingForPlayerEventArgs( [CanBeNull] Player player, [NotNull] strin [CanBeNull] public Player Player { get; private set; } + public string SearchTerm { get; private set; } + public List Matches { get; set; } public bool CheckVisibility { diff --git a/fCraft/System/Server.cs b/fCraft/System/Server.cs index ff5af41..531e04b 100644 --- a/fCraft/System/Server.cs +++ b/fCraft/System/Server.cs @@ -16,11 +16,12 @@ using fCraft.AutoRank; using fCraft.Drawing; using fCraft.Events; +using fCraft.Portals; using JetBrains.Annotations; using ThreadState = System.Threading.ThreadState; -using fCraft.Portals; namespace fCraft { + /// Core of an fCraft server. Manages startup/shutdown, online player /// sessions, and global events and scheduled tasks. public static partial class Server { @@ -33,6 +34,7 @@ public static partial class Server { internal const int MaxSessionPacketsPerTick = 128, // used when there are no players in a world MaxBlockUpdatesPerTick = 100000; // used when there are no players in a world + internal static float TicksPerSecond; public static bool IsRestarting = false; @@ -43,26 +45,28 @@ public static partial class Server { public static List VoicedPlayers = new List(); public static SchedulerTask TempbanTask; + // networking - static TcpListener listener; + private static TcpListener listener; + public static IPAddress InternalIP { get; private set; } + public static IPAddress ExternalIP { get; private set; } public static int Port { get; private set; } public static Uri Uri { get; set; } - #region Command-line args - static readonly Dictionary Args = new Dictionary(); + private static readonly Dictionary Args = new Dictionary(); /// Returns value of a given command-line argument (if present). Use HasArg to check flag arguments. /// Command-line argument name (enumerated) /// Value of the command-line argument, or null if this argument was not set or argument is a flag. [CanBeNull] public static string GetArg( ArgKey key ) { - if( Args.ContainsKey( key ) ) { + if ( Args.ContainsKey( key ) ) { return Args[key]; } else { return null; @@ -76,21 +80,19 @@ public static bool HasArg( ArgKey key ) { return Args.ContainsKey( key ); } - /// Produces a string containing all recognized arguments that wereset/passed to this instance of fCraft. /// A string containing all given arguments, or an empty string if none were set. public static string GetArgString() { return String.Join( " ", GetArgList() ); } - /// Produces a list of arguments that were passed to this instance of fCraft. /// An array of strings, formatted as --key="value" (or, for flag arguments, --key). /// Returns an empty string array if no arguments were set. public static string[] GetArgList() { List argList = new List(); - foreach( var pair in Args ) { - if( pair.Value != null ) { + foreach ( var pair in Args ) { + if ( pair.Value != null ) { argList.Add( String.Format( "--{0}=\"{1}\"", pair.Key.ToString().ToLower(), pair.Value ) ); } else { argList.Add( String.Format( "--{0}", pair.Key.ToString().ToLower() ) ); @@ -99,14 +101,14 @@ public static string[] GetArgList() { return argList.ToArray(); } - #endregion - + #endregion Command-line args #region Initialization and Startup // flags used to ensure proper initialization order - static bool libraryInitialized, + private static bool libraryInitialized, serverInitialized; + public static bool IsRunning { get; private set; } /// Reads command-line switches and sets up paths and logging. @@ -118,30 +120,30 @@ public static string[] GetArgList() { /// If library is already initialized. /// Working path, log path, or map path could not be set. public static void InitLibrary( [NotNull] IEnumerable rawArgs ) { - if( rawArgs == null ) throw new ArgumentNullException( "rawArgs" ); - if( libraryInitialized ) { + if ( rawArgs == null ) + throw new ArgumentNullException( "rawArgs" ); + if ( libraryInitialized ) { throw new InvalidOperationException( "800Craft library is already initialized" ); } ServicePointManager.Expect100Continue = false; // try to parse arguments - foreach( string arg in rawArgs ) { - if( arg.StartsWith( "--" ) ) { + foreach ( string arg in rawArgs ) { + if ( arg.StartsWith( "--" ) ) { string argKeyName, argValue; - if( arg.Contains( '=' ) ) { + if ( arg.Contains( '=' ) ) { argKeyName = arg.Substring( 2, arg.IndexOf( '=' ) - 2 ).ToLower().Trim(); argValue = arg.Substring( arg.IndexOf( '=' ) + 1 ).Trim(); - if( argValue.StartsWith( "\"" ) && argValue.EndsWith( "\"" ) ) { + if ( argValue.StartsWith( "\"" ) && argValue.EndsWith( "\"" ) ) { argValue = argValue.Substring( 1, argValue.Length - 2 ); } - } else { argKeyName = arg.Substring( 2 ); argValue = null; } ArgKey key; - if( EnumUtil.TryParse( argKeyName, out key, true ) ) { + if ( EnumUtil.TryParse( argKeyName, out key, true ) ) { Args.Add( key, argValue ); } else { Console.Error.WriteLine( "Unknown argument: {0}", arg ); @@ -156,10 +158,10 @@ public static void InitLibrary( [NotNull] IEnumerable rawArgs ) { // set custom working path (if specified) string path = GetArg( ArgKey.Path ); - if( path != null && Paths.TestDirectory( "WorkingPath", path, true ) ) { + if ( path != null && Paths.TestDirectory( "WorkingPath", path, true ) ) { Paths.WorkingPath = Path.GetFullPath( path ); Directory.SetCurrentDirectory( Paths.WorkingPath ); - } else if( Paths.TestDirectory( "WorkingPath", Paths.WorkingPathDefault, true ) ) { + } else if ( Paths.TestDirectory( "WorkingPath", Paths.WorkingPathDefault, true ) ) { Paths.WorkingPath = Path.GetFullPath( Paths.WorkingPathDefault ); Directory.SetCurrentDirectory( Paths.WorkingPath ); } else { @@ -168,15 +170,15 @@ public static void InitLibrary( [NotNull] IEnumerable rawArgs ) { // set log path string logPath = GetArg( ArgKey.LogPath ); - if( logPath != null && Paths.TestDirectory( "LogPath", logPath, true ) ) { + if ( logPath != null && Paths.TestDirectory( "LogPath", logPath, true ) ) { Paths.LogPath = Path.GetFullPath( logPath ); - } else if( Paths.TestDirectory( "LogPath", Paths.LogPathDefault, true ) ) { + } else if ( Paths.TestDirectory( "LogPath", Paths.LogPathDefault, true ) ) { Paths.LogPath = Path.GetFullPath( Paths.LogPathDefault ); } else { throw new IOException( "Could not set the log path." ); } - if( HasArg( ArgKey.NoLog ) ) { + if ( HasArg( ArgKey.NoLog ) ) { Logger.Enabled = false; } else { Logger.MarkLogStart(); @@ -184,10 +186,10 @@ public static void InitLibrary( [NotNull] IEnumerable rawArgs ) { // set map path string mapPath = GetArg( ArgKey.MapPath ); - if( mapPath != null && Paths.TestDirectory( "MapPath", mapPath, true ) ) { + if ( mapPath != null && Paths.TestDirectory( "MapPath", mapPath, true ) ) { Paths.MapPath = Path.GetFullPath( mapPath ); Paths.IgnoreMapPathConfigKey = true; - } else if( Paths.TestDirectory( "MapPath", Paths.MapPathDefault, true ) ) { + } else if ( Paths.TestDirectory( "MapPath", Paths.MapPathDefault, true ) ) { Paths.MapPath = Path.GetFullPath( Paths.MapPathDefault ); } else { throw new IOException( "Could not set the map path." ); @@ -196,13 +198,13 @@ public static void InitLibrary( [NotNull] IEnumerable rawArgs ) { // set config path Paths.ConfigFileName = Paths.ConfigFileNameDefault; string configFile = GetArg( ArgKey.Config ); - if( configFile != null ) { - if( Paths.TestFile( "config.xml", configFile, false, FileAccess.Read ) ) { + if ( configFile != null ) { + if ( Paths.TestFile( "config.xml", configFile, false, FileAccess.Read ) ) { Paths.ConfigFileName = new FileInfo( configFile ).FullName; } } - if( MonoCompat.IsMono ) { + if ( MonoCompat.IsMono ) { Logger.Log( LogType.Debug, "Running on Mono {0}", MonoCompat.MonoVersion ); } @@ -218,37 +220,36 @@ public static void InitLibrary( [NotNull] IEnumerable rawArgs ) { libraryInitialized = true; } - /// Initialized various server subsystems. This should be called after InitLibrary and before StartServer. /// Loads config, PlayerDB, IP bans, AutoRank settings, builds a list of commands, and prepares the IRC bot. /// Raises Server.Initializing and Server.Initialized events, and possibly Logger.Logged events. /// Throws exceptions on failure. /// Library is not initialized, or server is already initialzied. public static void InitServer() { - if( serverInitialized ) { + if ( serverInitialized ) { throw new InvalidOperationException( "Server is already initialized" ); } - if( !libraryInitialized ) { + if ( !libraryInitialized ) { throw new InvalidOperationException( "Server.InitLibrary must be called before Server.InitServer" ); } RaiseEvent( Initializing ); // Instantiate DeflateStream to make sure that libMonoPosix is present. // This allows catching misconfigured Mono installs early, and stopping the server. - using( var testMemStream = new MemoryStream() ) { - using( new DeflateStream( testMemStream, CompressionMode.Compress ) ) { + using ( var testMemStream = new MemoryStream() ) { + using ( new DeflateStream( testMemStream, CompressionMode.Compress ) ) { } } // warnings/disclaimers - if( Updater.CurrentRelease.IsFlagged( ReleaseFlags.Dev ) ) { + if ( Updater.CurrentRelease.IsFlagged( ReleaseFlags.Dev ) ) { Logger.Log( LogType.Warning, "You are using an unreleased developer version of 800Craft. " + "Do not use this version unless you are ready to deal with bugs and potential data loss. " + "Consider using the lastest stable version instead, available from http://github.com/glennmr/800craft" ); } - if( Updater.CurrentRelease.IsFlagged( ReleaseFlags.Unstable ) ) { + if ( Updater.CurrentRelease.IsFlagged( ReleaseFlags.Unstable ) ) { const string unstableMessage = "This build has been marked as UNSTABLE. " + "Do not use except for debugging purposes. " + "Latest non-broken build is " + Updater.LatestStable; @@ -259,7 +260,7 @@ public static void InitServer() { #endif } - if( MonoCompat.IsMono && !MonoCompat.IsSGenCapable ) { + if ( MonoCompat.IsMono && !MonoCompat.IsSGenCapable ) { Logger.Log( LogType.Warning, "You are using a relatively old version of the Mono runtime ({0}). " + "It is recommended that you upgrade to at least 2.8+", @@ -275,11 +276,11 @@ public static void InitServer() { #endif // try to load the config - if( !Config.Load( false, false ) ) { + if ( !Config.Load( false, false ) ) { throw new Exception( "800Craft Config failed to initialize" ); } - if( ConfigKey.VerifyNames.GetEnum() == NameVerificationMode.Never ) { + if ( ConfigKey.VerifyNames.GetEnum() == NameVerificationMode.Never ) { Logger.Log( LogType.Warning, "Name verification is currently OFF. Your server is at risk of being hacked. " + "Enable name verification as soon as possible." ); @@ -301,7 +302,7 @@ public static void InitServer() { Physics.Load(); HeartbeatSaverUtil.Init(); - if( ConfigKey.AutoRankEnabled.Enabled() ) { + if ( ConfigKey.AutoRankEnabled.Enabled() ) { AutoRankManager.Init(); } @@ -310,7 +311,6 @@ public static void InitServer() { serverInitialized = true; } - /// Starts the server: /// Creates Console pseudoplayer, loads the world list, starts listening for incoming connections, /// sets up scheduled tasks and starts the scheduler, starts the heartbeat, and connects to IRC. @@ -319,10 +319,10 @@ public static void InitServer() { /// True if server started normally, false on soft failure. /// Server is already running, or server/library have not been initailized. public static bool StartServer() { - if( IsRunning ) { + if ( IsRunning ) { throw new InvalidOperationException( "Server is already running" ); } - if( !libraryInitialized || !serverInitialized ) { + if ( !libraryInitialized || !serverInitialized ) { throw new InvalidOperationException( "Server.InitLibrary and Server.InitServer must be called before Server.StartServer" ); } @@ -332,17 +332,19 @@ public static bool StartServer() { RaiseEvent( Starting ); - if( ConfigKey.BackupDataOnStartup.Enabled() ) { + if ( ConfigKey.BackupDataOnStartup.Enabled() ) { BackupData(); } Player.Console = new Player( ConfigKey.ConsoleName.GetString() ); Player.AutoRank = new Player( "(AutoRank)" ); - if( ConfigKey.BlockDBEnabled.Enabled() ) BlockDB.Init(); + if ( ConfigKey.BlockDBEnabled.Enabled() ) + BlockDB.Init(); // try to load the world list - if( !WorldManager.LoadWorldList() ) return false; + if ( !WorldManager.LoadWorldList() ) + return false; WorldManager.SaveWorldList(); // open the port @@ -352,23 +354,22 @@ public static bool StartServer() { try { listener = new TcpListener( InternalIP, Port ); listener.Start(); - - } catch( Exception ex ) { + } catch ( Exception ex ) { // if the port is unavailable, try next one Logger.Log( LogType.Error, "Could not start listening on port {0}, stopping. ({1})", Port, ex.Message ); - if( !ConfigKey.IP.IsDefault() ) { + if ( !ConfigKey.IP.IsDefault() ) { Logger.Log( LogType.Warning, "Do not use the \"Designated IP\" setting unless you have multiple NICs or IPs." ); } return false; } - InternalIP = ((IPEndPoint)listener.LocalEndpoint).Address; + InternalIP = ( ( IPEndPoint )listener.LocalEndpoint ).Address; ExternalIP = CheckExternalIP(); - if( ExternalIP == null ) { + if ( ExternalIP == null ) { Logger.Log( LogType.SystemActivity, "Server.Run: now accepting connections on port {0}", Port ); } else { @@ -377,7 +378,6 @@ public static bool StartServer() { ExternalIP, Port ); } - // list loaded worlds WorldManager.UpdateWorldList(); Logger.Log( LogType.SystemActivity, @@ -399,16 +399,15 @@ public static bool StartServer() { MonitorProcessorUsage( null ); Scheduler.NewTask( MonitorProcessorUsage ).RunForever( MonitorProcessorUsageInterval, MonitorProcessorUsageInterval ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.Log( LogType.Error, "Server.StartServer: Could not start monitoring CPU use: {0}", ex ); } - PlayerDB.StartSaveTask(); // Announcements - if( ConfigKey.AnnouncementInterval.GetInt() > 0 ) { + if ( ConfigKey.AnnouncementInterval.GetInt() > 0 ) { TimeSpan announcementInterval = TimeSpan.FromMinutes( ConfigKey.AnnouncementInterval.GetInt() ); Scheduler.NewTask( ShowRandomAnnouncement ).RunForever( announcementInterval ); } @@ -418,13 +417,14 @@ public static bool StartServer() { Heartbeat.Start(); - if( ConfigKey.RestartInterval.GetInt() > 0 ) { + if ( ConfigKey.RestartInterval.GetInt() > 0 ) { TimeSpan restartIn = TimeSpan.FromSeconds( ConfigKey.RestartInterval.GetInt() ); Shutdown( new ShutdownParams( ShutdownReason.Restarting, restartIn, true, true ), false ); ChatTimer.Start( restartIn, "Automatic Server Restart", Player.Console.Name ); } - if( ConfigKey.IRCBotEnabled.Enabled() ) IRC.Start(); + if ( ConfigKey.IRCBotEnabled.Enabled() ) + IRC.Start(); Scheduler.NewTask( AutoRankManager.TaskCallback ).RunForever( AutoRankManager.TickInterval ); @@ -439,21 +439,21 @@ public static bool StartServer() { return true; } - #endregion - + #endregion Initialization and Startup #region Shutdown - static readonly object ShutdownLock = new object(); + private static readonly object ShutdownLock = new object(); public static bool IsShuttingDown; - static readonly AutoResetEvent ShutdownWaiter = new AutoResetEvent( false ); - static Thread shutdownThread; - static ChatTimer shutdownTimer; - - - static void ShutdownNow( [NotNull] ShutdownParams shutdownParams ) { - if( shutdownParams == null ) throw new ArgumentNullException( "shutdownParams" ); - if( IsShuttingDown ) return; // to avoid starting shutdown twice + private static readonly AutoResetEvent ShutdownWaiter = new AutoResetEvent( false ); + private static Thread shutdownThread; + private static ChatTimer shutdownTimer; + + private static void ShutdownNow( [NotNull] ShutdownParams shutdownParams ) { + if ( shutdownParams == null ) + throw new ArgumentNullException( "shutdownParams" ); + if ( IsShuttingDown ) + return; // to avoid starting shutdown twice IsShuttingDown = true; #if !DEBUG try { @@ -467,16 +467,16 @@ static void ShutdownNow( [NotNull] ShutdownParams shutdownParams ) { shutdownParams.ReasonString ); // stop accepting new players - if( listener != null ) { + if ( listener != null ) { listener.Stop(); listener = null; } // kick all players - lock( SessionLock ) { - if( Sessions.Count > 0 ) { + lock ( SessionLock ) { + if ( Sessions.Count > 0 ) { Logger.Log( LogType.SystemActivity, "Shutdown: Kicking {0} players...", Sessions.Count ); - foreach( Player p in Sessions ) { + foreach ( Player p in Sessions ) { // NOTE: kick packet delivery here is not currently guaranteed p.Kick( "Server shutting down (" + shutdownParams.ReasonString + Color.White + ")", LeaveReason.ServerShutdown ); } @@ -505,35 +505,38 @@ static void ShutdownNow( [NotNull] ShutdownParams shutdownParams ) { if ( IsRunning ) { Logger.Log( LogType.SystemActivity, "Shutdown: Saving databases... ({0} players and {1} IP bans)", PlayerDB.PlayerInfoList.Length, IPBanList.Count ); - if ( PlayerDB.IsLoaded ) PlayerDB.Save(); - if ( IPBanList.IsLoaded ) IPBanList.Save(); + if ( PlayerDB.IsLoaded ) + PlayerDB.Save(); + if ( IPBanList.IsLoaded ) + IPBanList.Save(); } RaiseShutdownEndedEvent( shutdownParams ); #if !DEBUG - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.LogAndReportCrash( "Error in Server.Shutdown", "800Craft", ex, true ); } #endif } - /// Initiates the server shutdown with given parameters. /// Shutdown parameters /// If true, blocks the calling thread until shutdown is complete or cancelled. public static void Shutdown( [NotNull] ShutdownParams shutdownParams, bool waitForShutdown ) { - if( shutdownParams == null ) throw new ArgumentNullException( "shutdownParams" ); - lock( ShutdownLock ) { - if( !CancelShutdown() ) return; + if ( shutdownParams == null ) + throw new ArgumentNullException( "shutdownParams" ); + lock ( ShutdownLock ) { + if ( !CancelShutdown() ) + return; shutdownThread = new Thread( ShutdownThread ) { Name = "800Craft.Shutdown" }; - if( shutdownParams.Delay >= ChatTimer.MinDuration ) { + if ( shutdownParams.Delay >= ChatTimer.MinDuration ) { string timerMsg = String.Format( "Server {0} ({1})", shutdownParams.Restart ? "restart" : "shutdown", shutdownParams.ReasonString ); string nameOnTimer; - if( shutdownParams.InitiatedBy == null ) { + if ( shutdownParams.InitiatedBy == null ) { nameOnTimer = Player.Console.Name; } else { nameOnTimer = shutdownParams.InitiatedBy.Name; @@ -542,22 +545,21 @@ public static void Shutdown( [NotNull] ShutdownParams shutdownParams, bool waitF } shutdownThread.Start( shutdownParams ); } - if( waitForShutdown ) { + if ( waitForShutdown ) { ShutdownWaiter.WaitOne(); } } - /// Attempts to cancel the shutdown timer. /// True if a shutdown timer was cancelled, false if no shutdown is in progress. /// Also returns false if it's too late to cancel (shutdown has begun). public static bool CancelShutdown() { - lock( ShutdownLock ) { - if( shutdownThread != null ) { - if( IsShuttingDown || shutdownThread.ThreadState != ThreadState.WaitSleepJoin ) { + lock ( ShutdownLock ) { + if ( shutdownThread != null ) { + if ( IsShuttingDown || shutdownThread.ThreadState != ThreadState.WaitSleepJoin ) { return false; } - if( shutdownTimer != null ) { + if ( shutdownTimer != null ) { shutdownTimer.Stop(); shutdownTimer = null; } @@ -569,125 +571,132 @@ public static bool CancelShutdown() { return true; } - - static void ShutdownThread( [NotNull] object obj ) { - if( obj == null ) throw new ArgumentNullException( "obj" ); - ShutdownParams param = (ShutdownParams)obj; + private static void ShutdownThread( [NotNull] object obj ) { + if ( obj == null ) + throw new ArgumentNullException( "obj" ); + ShutdownParams param = ( ShutdownParams )obj; Thread.Sleep( param.Delay ); ShutdownNow( param ); ShutdownWaiter.Set(); - bool doRestart = (param.Restart && !HasArg( ArgKey.NoRestart )); + bool doRestart = ( param.Restart && !HasArg( ArgKey.NoRestart ) ); string assemblyExecutable = Assembly.GetEntryAssembly().Location; - if( Updater.RunAtShutdown && doRestart ) { + if ( Updater.RunAtShutdown && doRestart ) { string args = String.Format( "--restart=\"{0}\" {1}", MonoCompat.PrependMono( assemblyExecutable ), GetArgString() ); MonoCompat.StartDotNetProcess( Paths.UpdaterFileName, args, true ); - - } else if( Updater.RunAtShutdown ) { + } else if ( Updater.RunAtShutdown ) { MonoCompat.StartDotNetProcess( Paths.UpdaterFileName, GetArgString(), true ); - - } else if( doRestart ) { + } else if ( doRestart ) { MonoCompat.StartDotNetProcess( assemblyExecutable, GetArgString(), true ); } - if( param.KillProcess ) { + if ( param.KillProcess ) { Process.GetCurrentProcess().Kill(); } } - #endregion - + #endregion Shutdown #region Messaging / Packet Sending /// Broadcasts a message to all online players. /// Shorthand for Server.Players.Message public static void Message( [NotNull] string message ) { - if( message == null ) throw new ArgumentNullException( "message" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); Players.Message( message ); } - /// Broadcasts a message to all online players. /// Shorthand for Server.Players.Message [StringFormatMethod( "message" )] public static void Message( [NotNull] string message, [NotNull] params object[] formatArgs ) { - if( message == null ) throw new ArgumentNullException( "message" ); - if( formatArgs == null ) throw new ArgumentNullException( "formatArgs" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( formatArgs == null ) + throw new ArgumentNullException( "formatArgs" ); Players.Message( message, formatArgs ); } - /// Broadcasts a message to all online players except one. /// Shorthand for Server.Players.Except(except).Message public static void Message( [CanBeNull] Player except, [NotNull] string message ) { - if( message == null ) throw new ArgumentNullException( "message" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); Players.Except( except ).Message( message ); } - /// Broadcasts a message to all online players except one. /// Shorthand for Server.Players.Except(except).Message [StringFormatMethod( "message" )] public static void Message( [CanBeNull] Player except, [NotNull] string message, [NotNull] params object[] formatArgs ) { - if( message == null ) throw new ArgumentNullException( "message" ); - if( formatArgs == null ) throw new ArgumentNullException( "formatArgs" ); + if ( message == null ) + throw new ArgumentNullException( "message" ); + if ( formatArgs == null ) + throw new ArgumentNullException( "formatArgs" ); Players.Except( except ).Message( message, formatArgs ); } - #endregion - + #endregion Messaging / Packet Sending #region Scheduled Tasks // checks for incoming connections - static SchedulerTask checkConnectionsTask; - static TimeSpan checkConnectionsInterval = TimeSpan.FromMilliseconds( 250 ); + private static SchedulerTask checkConnectionsTask; + + private static TimeSpan checkConnectionsInterval = TimeSpan.FromMilliseconds( 250 ); + public static TimeSpan CheckConnectionsInterval { get { return checkConnectionsInterval; } set { - if( value.Ticks < 0 ) throw new ArgumentException( "CheckConnectionsInterval may not be negative." ); + if ( value.Ticks < 0 ) + throw new ArgumentException( "CheckConnectionsInterval may not be negative." ); checkConnectionsInterval = value; - if( checkConnectionsTask != null ) checkConnectionsTask.Interval = value; + if ( checkConnectionsTask != null ) + checkConnectionsTask.Interval = value; } } - static void CheckConnections( SchedulerTask param ) { + private static void CheckConnections( SchedulerTask param ) { TcpListener listenerCache = listener; - if( listenerCache != null && listenerCache.Pending() ) { + if ( listenerCache != null && listenerCache.Pending() ) { try { Player.StartSession( listenerCache.AcceptTcpClient() ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.Log( LogType.Error, "Server.CheckConnections: Could not accept incoming connection: {0}", ex ); } } } - // checks for idle players - static SchedulerTask checkIdlesTask; - static TimeSpan checkIdlesInterval = TimeSpan.FromSeconds( 30 ); + private static SchedulerTask checkIdlesTask; + + private static TimeSpan checkIdlesInterval = TimeSpan.FromSeconds( 30 ); + public static TimeSpan CheckIdlesInterval { get { return checkIdlesInterval; } set { - if( value.Ticks < 0 ) throw new ArgumentException( "CheckIdlesInterval may not be negative." ); + if ( value.Ticks < 0 ) + throw new ArgumentException( "CheckIdlesInterval may not be negative." ); checkIdlesInterval = value; - if( checkIdlesTask != null ) checkIdlesTask.Interval = checkIdlesInterval; + if ( checkIdlesTask != null ) + checkIdlesTask.Interval = checkIdlesInterval; } } - static void CheckIdles( SchedulerTask task ) { + private static void CheckIdles( SchedulerTask task ) { Player[] tempPlayerList = Players; - for( int i = 0; i < tempPlayerList.Length; i++ ) { + for ( int i = 0; i < tempPlayerList.Length; i++ ) { Player player = tempPlayerList[i]; - if( player.Info.Rank.IdleKickTimer <= 0 ) continue; + if ( player.Info.Rank.IdleKickTimer <= 0 ) + continue; - if( player.IdleTime.TotalMinutes >= player.Info.Rank.IdleKickTimer ) { + if ( player.IdleTime.TotalMinutes >= player.Info.Rank.IdleKickTimer ) { Message( "{0}&S was kicked for being idle for {1} min", player.ClassyName, player.Info.Rank.IdleKickTimer ); @@ -698,109 +707,118 @@ static void CheckIdles( SchedulerTask task ) { } } - // collects garbage (forced collection is necessary under Mono) - static SchedulerTask gcTask; - static TimeSpan gcInterval = TimeSpan.FromSeconds( 60 ); + private static SchedulerTask gcTask; + + private static TimeSpan gcInterval = TimeSpan.FromSeconds( 60 ); + public static TimeSpan GCInterval { get { return gcInterval; } set { - if( value.Ticks < 0 ) throw new ArgumentException( "GCInterval may not be negative." ); + if ( value.Ticks < 0 ) + throw new ArgumentException( "GCInterval may not be negative." ); gcInterval = value; - if( gcTask != null ) gcTask.Interval = gcInterval; + if ( gcTask != null ) + gcTask.Interval = gcInterval; } } - static void DoGC( SchedulerTask task ) { - if( !gcRequested ) return; + private static void DoGC( SchedulerTask task ) { + if ( !gcRequested ) + return; gcRequested = false; Process proc = Process.GetCurrentProcess(); proc.Refresh(); - long usageBefore = proc.PrivateMemorySize64 / (1024 * 1024); + long usageBefore = proc.PrivateMemorySize64 / ( 1024 * 1024 ); GC.Collect( GC.MaxGeneration, GCCollectionMode.Forced ); proc.Refresh(); - long usageAfter = proc.PrivateMemorySize64 / (1024 * 1024); + long usageAfter = proc.PrivateMemorySize64 / ( 1024 * 1024 ); Logger.Log( LogType.Debug, "Server.DoGC: Collected on schedule ({0}->{1} MB).", usageBefore, usageAfter ); } - // shows announcements - static void ShowRandomAnnouncement( SchedulerTask task ) { - if( !File.Exists( Paths.AnnouncementsFileName ) ) return; + private static void ShowRandomAnnouncement( SchedulerTask task ) { + if ( !File.Exists( Paths.AnnouncementsFileName ) ) + return; string[] lines = File.ReadAllLines( Paths.AnnouncementsFileName ); - if( lines.Length == 0 ) return; + if ( lines.Length == 0 ) + return; string line = lines[new Random().Next( 0, lines.Length )].Trim(); - if( line.Length == 0 ) return; - foreach( Player player in Players.Where( player => player.World != null ) ) { + if ( line.Length == 0 ) + return; + foreach ( Player player in Players.Where( player => player.World != null ) ) { player.Message( "&R" + ReplaceTextKeywords( player, line ) ); } } - // measures CPU usage public static bool IsMonitoringCPUUsage { get; private set; } - static TimeSpan cpuUsageStartingOffset; + + private static TimeSpan cpuUsageStartingOffset; + public static double CPUUsageTotal { get; private set; } + public static double CPUUsageLastMinute { get; private set; } - static TimeSpan oldCPUTime = new TimeSpan( 0 ); - static readonly TimeSpan MonitorProcessorUsageInterval = TimeSpan.FromSeconds( 30 ); - static DateTime lastMonitorTime = DateTime.UtcNow; + private static TimeSpan oldCPUTime = new TimeSpan( 0 ); + private static readonly TimeSpan MonitorProcessorUsageInterval = TimeSpan.FromSeconds( 30 ); + private static DateTime lastMonitorTime = DateTime.UtcNow; - static void MonitorProcessorUsage( SchedulerTask task ) { + private static void MonitorProcessorUsage( SchedulerTask task ) { TimeSpan newCPUTime = Process.GetCurrentProcess().TotalProcessorTime - cpuUsageStartingOffset; - CPUUsageLastMinute = (newCPUTime - oldCPUTime).TotalSeconds / - (Environment.ProcessorCount * DateTime.UtcNow.Subtract( lastMonitorTime ).TotalSeconds); + CPUUsageLastMinute = ( newCPUTime - oldCPUTime ).TotalSeconds / + ( Environment.ProcessorCount * DateTime.UtcNow.Subtract( lastMonitorTime ).TotalSeconds ); lastMonitorTime = DateTime.UtcNow; CPUUsageTotal = newCPUTime.TotalSeconds / - (Environment.ProcessorCount * DateTime.UtcNow.Subtract( StartTime ).TotalSeconds); + ( Environment.ProcessorCount * DateTime.UtcNow.Subtract( StartTime ).TotalSeconds ); oldCPUTime = newCPUTime; IsMonitoringCPUUsage = true; } - #endregion - + #endregion Scheduled Tasks #region Utilities - static bool gcRequested; + private static bool gcRequested; public static void RequestGC() { gcRequested = true; } - public static bool VerifyName( [NotNull] string name, [NotNull] string hash, [NotNull] string salt ) { - if( name == null ) throw new ArgumentNullException( "name" ); - if( hash == null ) throw new ArgumentNullException( "hash" ); - if( salt == null ) throw new ArgumentNullException( "salt" ); - while( hash.Length < 32 ) { + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( hash == null ) + throw new ArgumentNullException( "hash" ); + if ( salt == null ) + throw new ArgumentNullException( "salt" ); + while ( hash.Length < 32 ) { hash = "0" + hash; } MD5 hasher = MD5.Create(); StringBuilder sb = new StringBuilder( 32 ); - foreach( byte b in hasher.ComputeHash( Encoding.ASCII.GetBytes( salt + name ) ) ) { + foreach ( byte b in hasher.ComputeHash( Encoding.ASCII.GetBytes( salt + name ) ) ) { sb.AppendFormat( "{0:x2}", b ); } return sb.ToString().Equals( hash, StringComparison.OrdinalIgnoreCase ); } - public static int CalculateMaxPacketsPerUpdate( [NotNull] World world ) { - if( world == null ) throw new ArgumentNullException( "world" ); - int packetsPerTick = (int)(BlockUpdateThrottling / TicksPerSecond); - int maxPacketsPerUpdate = (int)(MaxUploadSpeed / TicksPerSecond * 128); + if ( world == null ) + throw new ArgumentNullException( "world" ); + int packetsPerTick = ( int )( BlockUpdateThrottling / TicksPerSecond ); + int maxPacketsPerUpdate = ( int )( MaxUploadSpeed / TicksPerSecond * 128 ); int playerCount = world.Players.Length; - if( playerCount > 0 && !world.IsFlushing ) { + if ( playerCount > 0 && !world.IsFlushing ) { maxPacketsPerUpdate /= playerCount; - if( maxPacketsPerUpdate > packetsPerTick ) { + if ( maxPacketsPerUpdate > packetsPerTick ) { maxPacketsPerUpdate = packetsPerTick; } } else { @@ -810,73 +828,61 @@ public static int CalculateMaxPacketsPerUpdate( [NotNull] World world ) { return maxPacketsPerUpdate; } - - static readonly Regex RegexIP = new Regex( @"\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b", + private static readonly Regex RegexIP = new Regex( @"\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b", RegexOptions.Compiled ); public static bool IsIP( [NotNull] string ipString ) { - if( ipString == null ) throw new ArgumentNullException( "ipString" ); + if ( ipString == null ) + throw new ArgumentNullException( "ipString" ); return RegexIP.IsMatch( ipString ); } - - - public static void BackupData() - { - if (!Paths.TestDirectory("DataBackup", Paths.DataBackupDirectory, true)) - { - Logger.Log(LogType.Error, "Unable to create a data backup."); + public static void BackupData() { + if ( !Paths.TestDirectory( "DataBackup", Paths.DataBackupDirectory, true ) ) { + Logger.Log( LogType.Error, "Unable to create a data backup." ); return; } - string backupFileName = String.Format(Paths.DataBackupFileNameFormat, DateTime.Now); // localized - backupFileName = Path.Combine(Paths.DataBackupDirectory, backupFileName); - using (FileStream fs = File.Create(backupFileName)) - { - try - { - string fileComment = String.Format("Backup of 800Craft data for server \"{0}\", saved on {1}", + string backupFileName = String.Format( Paths.DataBackupFileNameFormat, DateTime.Now ); // localized + backupFileName = Path.Combine( Paths.DataBackupDirectory, backupFileName ); + using ( FileStream fs = File.Create( backupFileName ) ) { + try { + string fileComment = String.Format( "Backup of 800Craft data for server \"{0}\", saved on {1}", ConfigKey.ServerName.GetString(), - DateTime.Now); - using (ZipStorer backupZip = ZipStorer.Create(fs, fileComment)) - { - foreach (string dataFileName in Paths.DataFilesToBackup) - { - if (File.Exists(dataFileName)) - { - backupZip.AddFile(ZipStorer.Compression.Deflate, + DateTime.Now ); + using ( ZipStorer backupZip = ZipStorer.Create( fs, fileComment ) ) { + foreach ( string dataFileName in Paths.DataFilesToBackup ) { + if ( File.Exists( dataFileName ) ) { + backupZip.AddFile( ZipStorer.Compression.Deflate, dataFileName, dataFileName, - ""); + "" ); } } } - } - catch (IOException) - { - Logger.Log(LogType.Error, "Unable to create a data backup."); + } catch ( IOException ) { + Logger.Log( LogType.Error, "Unable to create a data backup." ); return; - } - finally - { - if (fs != null) + } finally { + if ( fs != null ) fs.Close(); } - Logger.Log(LogType.SystemActivity, + Logger.Log( LogType.SystemActivity, "Backed up server data to \"{0}\"", - backupFileName); + backupFileName ); } } - public static string ReplaceTextKeywords( [NotNull] Player player, [NotNull] string input ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( input == null ) throw new ArgumentNullException( "input" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( input == null ) + throw new ArgumentNullException( "input" ); StringBuilder sb = new StringBuilder( input ); sb.Replace( "{SERVER_NAME}", ConfigKey.ServerName.GetString() ); sb.Replace( "{RANK}", player.Info.Rank.ClassyName ); sb.Replace( "{PLAYER_NAME}", player.ClassyName ); sb.Replace( "{TIME}", DateTime.Now.ToShortTimeString() ); // localized - if( player.World == null ) { + if ( player.World == null ) { sb.Replace( "{WORLD}", "(No World)" ); } else { sb.Replace( "{WORLD}", player.World.ClassyName ); @@ -888,52 +894,50 @@ public static string ReplaceTextKeywords( [NotNull] Player player, [NotNull] str return sb.ToString(); } - - public static string GetRandomString( int chars ) { RandomNumberGenerator prng = RandomNumberGenerator.Create(); StringBuilder sb = new StringBuilder(); byte[] oneChar = new byte[1]; - while( sb.Length < chars ) { + while ( sb.Length < chars ) { prng.GetBytes( oneChar ); - if( oneChar[0] >= 48 && oneChar[0] <= 57 || + if ( oneChar[0] >= 48 && oneChar[0] <= 57 || oneChar[0] >= 65 && oneChar[0] <= 90 || oneChar[0] >= 97 && oneChar[0] <= 122 ) { //if( oneChar[0] >= 33 && oneChar[0] <= 126 ) { - sb.Append( (char)oneChar[0] ); + sb.Append( ( char )oneChar[0] ); } } return sb.ToString(); } - static readonly Uri IPCheckUri = new Uri( "http://checkip.dyndns.org/" ); - const int IPCheckTimeout = 30000; + private static readonly Uri IPCheckUri = new Uri( "http://checkip.dyndns.org/" ); + private const int IPCheckTimeout = 30000; /// Checks server's external IP, as reported by checkip.dyndns.org. [CanBeNull] - static IPAddress CheckExternalIP() { - HttpWebRequest request = (HttpWebRequest)WebRequest.Create( IPCheckUri ); + private static IPAddress CheckExternalIP() { + HttpWebRequest request = ( HttpWebRequest )WebRequest.Create( IPCheckUri ); request.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint( BindIPEndPointCallback ); request.Timeout = IPCheckTimeout; request.CachePolicy = new RequestCachePolicy( RequestCacheLevel.NoCacheNoStore ); try { - using( WebResponse response = request.GetResponse() ) { + using ( WebResponse response = request.GetResponse() ) { // ReSharper disable AssignNullToNotNullAttribute - using( StreamReader responseReader = new StreamReader( response.GetResponseStream() ) ) { + using ( StreamReader responseReader = new StreamReader( response.GetResponseStream() ) ) { // ReSharper restore AssignNullToNotNullAttribute string responseString = responseReader.ReadToEnd(); int startIndex = responseString.IndexOf( ":" ) + 2; int endIndex = responseString.IndexOf( '<', startIndex ) - startIndex; IPAddress result; - if( IPAddress.TryParse( responseString.Substring( startIndex, endIndex ), out result ) ) { + if ( IPAddress.TryParse( responseString.Substring( startIndex, endIndex ), out result ) ) { return result; } else { return null; } } } - } catch( WebException ex ) { + } catch ( WebException ex ) { Logger.Log( LogType.Warning, "Could not check external IP: {0}", ex ); return null; @@ -945,35 +949,37 @@ public static IPEndPoint BindIPEndPointCallback( ServicePoint servicePoint, IPEn return new IPEndPoint( InternalIP, 0 ); } - #endregion - + #endregion Utilities #region Player and Session Management // list of registered players - static readonly SortedDictionary PlayerIndex = new SortedDictionary(); + private static readonly SortedDictionary PlayerIndex = new SortedDictionary(); + public static Player[] Players { get; private set; } - static readonly object PlayerListLock = new object(); + + private static readonly object PlayerListLock = new object(); // list of all connected sessions - static readonly List Sessions = new List(); - static readonly object SessionLock = new object(); + private static readonly List Sessions = new List(); + private static readonly object SessionLock = new object(); // Registers a new session, and checks the number of connections from this IP. // Returns true if the session was registered succesfully. // Returns false if the max number of connections was reached. internal static bool RegisterSession( [NotNull] Player session ) { - if( session == null ) throw new ArgumentNullException( "session" ); + if ( session == null ) + throw new ArgumentNullException( "session" ); int maxSessions = ConfigKey.MaxConnectionsPerIP.GetInt(); - lock( SessionLock ) { - if( !session.IP.Equals( IPAddress.Loopback ) && maxSessions > 0 ) { + lock ( SessionLock ) { + if ( !session.IP.Equals( IPAddress.Loopback ) && maxSessions > 0 ) { int sessionCount = 0; - for( int i = 0; i < Sessions.Count; i++ ) { + for ( int i = 0; i < Sessions.Count; i++ ) { Player p = Sessions[i]; - if( p.IP.Equals( session.IP ) ) { + if ( p.IP.Equals( session.IP ) ) { sessionCount++; - if( sessionCount >= maxSessions ) { + if ( sessionCount >= maxSessions ) { return false; } } @@ -984,20 +990,21 @@ internal static bool RegisterSession( [NotNull] Player session ) { return true; } - // Registers a player and checks if the server is full. // Also kicks any existing connections for this player account. // Returns true if player was registered succesfully. // Returns false if the server was full. internal static bool RegisterPlayer( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); // Kick other sessions with same player name List sessionsToKick = new List(); - lock( SessionLock ) { - foreach( Player s in Sessions ) { - if( s == player ) continue; - if( s.Name.Equals( player.Name, StringComparison.OrdinalIgnoreCase ) ) { + lock ( SessionLock ) { + foreach ( Player s in Sessions ) { + if ( s == player ) + continue; + if ( s.Name.Equals( player.Name, StringComparison.OrdinalIgnoreCase ) ) { sessionsToKick.Add( s ); Logger.Log( LogType.SuspiciousActivity, "Server.RegisterPlayer: Player {0} logged in twice. Ghost from {1} was kicked.", @@ -1008,13 +1015,13 @@ internal static bool RegisterPlayer( [NotNull] Player player ) { } // Wait for other sessions to exit/unregister (if any) - foreach( Player ses in sessionsToKick ) { + foreach ( Player ses in sessionsToKick ) { ses.WaitForDisconnect(); } // Add player to the list - lock( PlayerListLock ) { - if( PlayerIndex.Count >= ConfigKey.MaxPlayers.GetInt() && !player.Info.Rank.ReservedSlot ) { + lock ( PlayerListLock ) { + if ( PlayerIndex.Count >= ConfigKey.MaxPlayers.GetInt() && !player.Info.Rank.ReservedSlot ) { return false; } PlayerIndex.Add( player.Name, player ); @@ -1023,47 +1030,48 @@ internal static bool RegisterPlayer( [NotNull] Player player ) { return true; } - public static string MakePlayerConnectedMessage( [NotNull] Player player, bool firstTime, [NotNull] World world ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( world == null ) throw new ArgumentNullException( "world" ); - if (firstTime){ - return String.Format("&S{0} &Sconnected, joined {1}", + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( world == null ) + throw new ArgumentNullException( "world" ); + if ( firstTime ) { + return String.Format( "&S{0} &Sconnected, joined {1}", player.ClassyName, - world.ClassyName); + world.ClassyName ); } //use this if you want to show original names for people with displayednames - if (!firstTime && player.Info.DisplayedName != null){ - - return String.Format("&S{0} &S({1}&S) connected again, joined {2}", + if ( !firstTime && player.Info.DisplayedName != null ) { + return String.Format( "&S{0} &S({1}&S) connected again, joined {2}", player.ClassyName, player.Name, - world.ClassyName); - }else{ - return String.Format("&S{0} &Sconnected again, joined {1}", + world.ClassyName ); + } else { + return String.Format( "&S{0} &Sconnected again, joined {1}", player.ClassyName, - world.ClassyName); + world.ClassyName ); } } - // Removes player from the list, and announced them leaving public static void UnregisterPlayer( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); - lock( PlayerListLock ) { - if( !player.HasRegistered ) return; + lock ( PlayerListLock ) { + if ( !player.HasRegistered ) + return; player.Info.ProcessLogout( player ); Logger.Log( LogType.UserActivity, "{0} left the server ({1}).", player.Name, player.LeaveReason ); - if( player.HasRegistered && ConfigKey.ShowConnectionMessages.Enabled() ) { - Players.CanSee(player).Message("&SPlayer {0}&S {1}.", - player.ClassyName, player.Info.LeaveMsg); + if ( player.HasRegistered && ConfigKey.ShowConnectionMessages.Enabled() ) { + Players.CanSee( player ).Message( "&SPlayer {0}&S {1}.", + player.ClassyName, player.Info.LeaveMsg ); player.Info.LeaveMsg = "left the server"; } - if( player.World != null ) { + if ( player.World != null ) { player.World.ReleasePlayer( player ); } PlayerIndex.Remove( player.Name ); @@ -1071,18 +1079,17 @@ public static void UnregisterPlayer( [NotNull] Player player ) { } } - // Removes a session from the list internal static void UnregisterSession( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); - lock( SessionLock ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + lock ( SessionLock ) { Sessions.Remove( player ); } } - internal static void UpdatePlayerList() { - lock( PlayerListLock ) { + lock ( PlayerListLock ) { Players = PlayerIndex.Values.Where( p => p.IsOnline ) .OrderBy( player => player.Name ) .ToArray(); @@ -1090,28 +1097,29 @@ internal static void UpdatePlayerList() { } } - /// Finds a player by name, using autocompletion. /// Returns ALL matching players, including hidden ones. /// An array of matches. List length of 0 means "no matches"; /// 1 is an exact match; over 1 for multiple matches. public static Player[] FindPlayers( [NotNull] string name, bool raiseEvent ) { - if( name == null ) throw new ArgumentNullException( "name" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); Player[] tempList = Players; List results = new List(); - for( int i = 0; i < tempList.Length; i++ ) { - if( tempList[i] == null ) continue; - if( tempList[i].Name.Equals( name, StringComparison.OrdinalIgnoreCase ) ) { + for ( int i = 0; i < tempList.Length; i++ ) { + if ( tempList[i] == null ) + continue; + if ( tempList[i].Name.Equals( name, StringComparison.OrdinalIgnoreCase ) ) { results.Clear(); results.Add( tempList[i] ); break; - } else if( tempList[i].Name.StartsWith( name, StringComparison.OrdinalIgnoreCase ) ) { + } else if ( tempList[i].Name.StartsWith( name, StringComparison.OrdinalIgnoreCase ) ) { results.Add( tempList[i] ); } } - if( raiseEvent ) { + if ( raiseEvent ) { var h = SearchingForPlayer; - if( h != null ) { + if ( h != null ) { var e = new SearchingForPlayerEventArgs( null, name, results ); h( null, e ); } @@ -1119,7 +1127,6 @@ public static Player[] FindPlayers( [NotNull] string name, bool raiseEvent ) { return results.ToArray(); } - /// Finds a player by name, using autocompletion. Does not include hidden players. /// Player who initiated the search. /// Used to determine whether others are hidden or not. @@ -1128,10 +1135,12 @@ public static Player[] FindPlayers( [NotNull] string name, bool raiseEvent ) { /// An array of matches. List length of 0 means "no matches"; /// 1 is an exact match; over 1 for multiple matches. public static Player[] FindPlayers( [NotNull] Player player, [NotNull] string name, bool raiseEvent ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( name == null ) throw new ArgumentNullException( "name" ); - if( name == "-" ) { - if( player.LastUsedPlayerName != null ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( name == "-" ) { + if ( player.LastUsedPlayerName != null ) { name = player.LastUsedPlayerName; } else { return new Player[0]; @@ -1140,30 +1149,30 @@ public static Player[] FindPlayers( [NotNull] Player player, [NotNull] string na player.LastUsedPlayerName = name; List results = new List(); Player[] tempList = Players; - for( int i = 0; i < tempList.Length; i++ ) { - if( tempList[i] == null || !player.CanSee( tempList[i] ) ) continue; - if( tempList[i].Name.Equals( name, StringComparison.OrdinalIgnoreCase ) ) { + for ( int i = 0; i < tempList.Length; i++ ) { + if ( tempList[i] == null || !player.CanSee( tempList[i] ) ) + continue; + if ( tempList[i].Name.Equals( name, StringComparison.OrdinalIgnoreCase ) ) { results.Clear(); results.Add( tempList[i] ); break; - } else if( tempList[i].Name.StartsWith( name, StringComparison.OrdinalIgnoreCase ) ) { + } else if ( tempList[i].Name.StartsWith( name, StringComparison.OrdinalIgnoreCase ) ) { results.Add( tempList[i] ); } } - if( raiseEvent ) { + if ( raiseEvent ) { var h = SearchingForPlayer; - if( h != null ) { + if ( h != null ) { var e = new SearchingForPlayerEventArgs( player, name, results ); h( null, e ); } } - if( results.Count == 1 ) { + if ( results.Count == 1 ) { player.LastUsedPlayerName = results[0].Name; } return results.ToArray(); } - /// Find player by name using autocompletion. /// Returns null and prints message if none or multiple players matched. /// Raises Player.SearchingForPlayer event, which may modify search results. @@ -1174,10 +1183,12 @@ public static Player[] FindPlayers( [NotNull] Player player, [NotNull] string na /// Player object, or null if no player was found. [CanBeNull] public static Player FindPlayerOrPrintMatches( [NotNull] Player player, [NotNull] string name, bool includeHidden, bool raiseEvent ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( name == null ) throw new ArgumentNullException( "name" ); - if( name == "-" ) { - if( player.LastUsedPlayerName != null ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( name == "-" ) { + if ( player.LastUsedPlayerName != null ) { name = player.LastUsedPlayerName; } else { player.Message( "Cannot repeat player name: you haven't used any names yet." ); @@ -1185,49 +1196,46 @@ public static Player FindPlayerOrPrintMatches( [NotNull] Player player, [NotNull } } Player[] matches; - if( includeHidden ) { + if ( includeHidden ) { matches = FindPlayers( name, raiseEvent ); } else { matches = FindPlayers( player, name, raiseEvent ); } - if( matches.Length == 0 ) { + if ( matches.Length == 0 ) { player.MessageNoPlayer( name ); return null; - - } else if( matches.Length > 1 ) { + } else if ( matches.Length > 1 ) { player.MessageManyMatches( "player", matches ); return null; - } else { player.LastUsedPlayerName = matches[0].Name; return matches[0]; } } - /// Counts online players, optionally including hidden ones. public static int CountPlayers( bool includeHiddenPlayers ) { - if( includeHiddenPlayers ) { + if ( includeHiddenPlayers ) { return Players.Length; } else { return Players.Count( player => !player.Info.IsHidden ); } } - /// Counts online players whom the given observer can see. public static int CountVisiblePlayers( [NotNull] Player observer ) { - if( observer == null ) throw new ArgumentNullException( "observer" ); + if ( observer == null ) + throw new ArgumentNullException( "observer" ); return Players.Count( observer.CanSee ); } - #endregion + #endregion Player and Session Management } - /// Describes the circumstances of server shutdown. public sealed class ShutdownParams { + public ShutdownParams( ShutdownReason reason, TimeSpan delay, bool killProcess, bool restart ) { Reason = reason; Delay = delay; @@ -1244,7 +1252,8 @@ public ShutdownParams( ShutdownReason reason, TimeSpan delay, bool killProcess, public ShutdownReason Reason { get; private set; } - readonly string customReasonString; + private readonly string customReasonString; + [NotNull] public string ReasonString { get { @@ -1266,7 +1275,6 @@ public string ReasonString { public Player InitiatedBy { get; private set; } } - /// Categorizes conditions that lead to server shutdowns. public enum ShutdownReason { Unknown, diff --git a/fCraft/Utils/BoundingBox.cs b/fCraft/Utils/BoundingBox.cs index 7a3e4f7..fdb5f94 100644 --- a/fCraft/Utils/BoundingBox.cs +++ b/fCraft/Utils/BoundingBox.cs @@ -14,8 +14,9 @@ public sealed class BoundingBox : IEquatable { public static readonly BoundingBox Empty = new BoundingBox( 0, 0, 0, 0, 0, 0 ); // ReSharper disable FieldCanBeMadeReadOnly.Global - [DataMember] + [DataMember] public int XMin, YMin, ZMin, XMax, YMax, ZMax; + // ReSharper restore FieldCanBeMadeReadOnly.Global /// Constructs a bounding box using two vectors as opposite corners. @@ -23,7 +24,6 @@ public BoundingBox( Vector3I p1, Vector3I p2 ) : this( p1.X, p1.Y, p1.Z, p2.X, p2.Y, p2.Z ) { } - /// Constructs a bounding box at a given origin, with given dimensions. /// Origin point of the bounding box. /// Width (X-axis, horizontal). May be negative. @@ -36,7 +36,6 @@ public BoundingBox( Vector3I origin, int width, int length, int height ) : origin.Z + height - 1 ) { } - /// Constructs a bounding box between two given coordinates. public BoundingBox( int x1, int y1, int z1, int x2, int y2, int z2 ) { XMin = Math.Min( x1, x2 ); @@ -47,27 +46,26 @@ public BoundingBox( int x1, int y1, int z1, int x2, int y2, int z2 ) { ZMax = Math.Max( z1, z2 ); } - #region Collision Detection /// Checks whether this bounding box intersects/touches another one. public bool Insersects( [NotNull] BoundingBox other ) { - if( other == null ) throw new ArgumentNullException( "other" ); - return !(XMax < other.XMin || XMin > other.XMax || + if ( other == null ) + throw new ArgumentNullException( "other" ); + return !( XMax < other.XMin || XMin > other.XMax || YMax < other.YMin || YMin > other.YMax || - ZMax < other.ZMin || ZMin > other.ZMax); + ZMax < other.ZMin || ZMin > other.ZMax ); } - /// Checks if another bounding box is wholly contained inside this one. public bool Contains( [NotNull] BoundingBox other ) { - if( other == null ) throw new ArgumentNullException( "other" ); + if ( other == null ) + throw new ArgumentNullException( "other" ); return XMin <= other.XMin && XMax >= other.XMax && YMin <= other.YMin && YMax >= other.YMax && ZMin <= other.ZMin && ZMax >= other.ZMax; } - /// Checks if a given point is inside this bounding box. public bool Contains( int x, int y, int z ) { return x >= XMin && x <= XMax && @@ -75,7 +73,6 @@ public bool Contains( int x, int y, int z ) { z >= ZMin && z <= ZMax; } - /// Checks if a given point is inside this bounding box. public bool Contains( Vector3I point ) { return point.X >= XMin && point.X <= XMax && @@ -83,16 +80,16 @@ public bool Contains( Vector3I point ) { point.Z >= ZMin && point.Z <= ZMax; } - /// Returns a BoundingBox object that describes the space shared between this and another box. /// Intersecting volume, or BoundingBox.Empty if there is no overlap. public BoundingBox GetIntersection( [NotNull] BoundingBox other ) { - if( other == null ) throw new ArgumentNullException( "other" ); - if( Contains( other ) ) { + if ( other == null ) + throw new ArgumentNullException( "other" ); + if ( Contains( other ) ) { return other; - } else if( other.Contains( this ) ) { + } else if ( other.Contains( this ) ) { return this; - } else if( Insersects( other ) ) { + } else if ( Insersects( other ) ) { return new BoundingBox( Math.Max( XMin, other.XMin ), Math.Max( YMin, other.YMin ), Math.Max( ZMin, other.ZMin ), @@ -104,14 +101,12 @@ public BoundingBox GetIntersection( [NotNull] BoundingBox other ) { } } - #endregion - + #endregion Collision Detection public int Volume { - get { return (XMax - XMin + 1) * (YMax - YMin + 1) * (ZMax - ZMin + 1); } + get { return ( XMax - XMin + 1 ) * ( YMax - YMin + 1 ) * ( ZMax - ZMin + 1 ); } } - public Vector3I Dimensions { get { return new Vector3I( XMax - XMin + 1, @@ -120,38 +115,35 @@ public Vector3I Dimensions { } } - public int Width { - get { return (XMax - XMin + 1); } + get { return ( XMax - XMin + 1 ); } } public int Length { - get { return (YMax - YMin + 1); } + get { return ( YMax - YMin + 1 ); } } public int Height { - get { return (ZMax - ZMin + 1); } + get { return ( ZMax - ZMin + 1 ); } } - /// Returns the vertex closest to the coordinate origin, opposite MaxVertex. public Vector3I MinVertex { get { return new Vector3I( XMin, YMin, ZMin ); } } - /// Returns the vertex farthest from the origin, opposite MinVertex. public Vector3I MaxVertex { get { return new Vector3I( XMax, YMax, ZMax ); } } - #region Serialization public const string XmlRootElementName = "BoundingBox"; public BoundingBox( [NotNull] XElement root ) { - if( root == null ) throw new ArgumentNullException( "root" ); + if ( root == null ) + throw new ArgumentNullException( "root" ); string[] coords = root.Value.Split( ' ' ); int x1 = Int32.Parse( coords[0] ); int x2 = Int32.Parse( coords[1] ); @@ -168,7 +160,8 @@ public BoundingBox( [NotNull] XElement root ) { } public XElement Serialize( [NotNull] string tagName ) { - if( tagName == null ) throw new ArgumentNullException( "tagName" ); + if ( tagName == null ) + throw new ArgumentNullException( "tagName" ); string data = String.Format( "{0} {1} {2} {3} {4} {5}", XMin, XMax, YMin, YMax, ZMin, ZMax ); return new XElement( tagName, data ); @@ -178,8 +171,7 @@ public XElement Serialize() { return Serialize( XmlRootElementName ); } - #endregion - + #endregion Serialization public bool Equals( BoundingBox other ) { return XMin == other.XMin && XMax == other.XMax && diff --git a/fCraft/Utils/Color.cs b/fCraft/Utils/Color.cs index 84a3833..f8bc0fb 100644 --- a/fCraft/Utils/Color.cs +++ b/fCraft/Utils/Color.cs @@ -4,13 +4,12 @@ using System.Text; using JetBrains.Annotations; -namespace fCraft -{ +namespace fCraft { /// Static class with definitions of Minecraft color codes, /// parsers, converters, and utilities. - public static class Color - { + public static class Color { + public const string Black = "&0", Navy = "&1", Green = "&2", @@ -61,275 +60,257 @@ public static class Color { 'f', "white" } }; - /// Gets color name for hex color code. /// Hexadecimal color code (between '0' and 'f'). /// Lowercase color name. [CanBeNull] - public static string GetName(char code) - { - code = Char.ToLower(code); - if (IsValidColorCode(code)) - { + public static string GetName( char code ) { + code = Char.ToLower( code ); + if ( IsValidColorCode( code ) ) { return ColorNames[code]; } - string color = Parse(code); - if (color == null) - { + string color = Parse( code ); + if ( color == null ) { return null; } return ColorNames[color[1]]; } - /// Gets color name for a numeric color code. /// Ordinal numeric color code (between 0 and 15). /// Lowercase color name. If input is out of range, returns null. [CanBeNull] - public static string GetName(int index) - { - if (index >= 0 && index <= 15) - { + public static string GetName( int index ) { + if ( index >= 0 && index <= 15 ) { return ColorNames.Values[index]; - } - else - { + } else { return null; } } - /// Gets color name for a string representation of a color. /// Any parsable string representation of a color. /// Lowercase color name. /// If input is an empty string, returns empty string. /// If input is null or cannot be parsed, returns null. [CanBeNull] - public static string GetName(string color) - { - if (color == null) - { + public static string GetName( string color ) { + if ( color == null ) { return null; - } - else if (color.Length == 0) - { + } else if ( color.Length == 0 ) { return ""; - } - else - { - string parsedColor = Parse(color); - if (parsedColor == null) - { + } else { + string parsedColor = Parse( color ); + if ( parsedColor == null ) { return null; - } - else - { - return GetName(parsedColor[1]); + } else { + return GetName( parsedColor[1] ); } } } - - - /// Parses a string to a format readable by Minecraft clients. + /// Parses a string to a format readable by Minecraft clients. /// an accept color names and color codes (with or without the ampersand). /// Color code character. /// Two-character color string, readable by Minecraft client. /// If input is null or cannot be parsed, returns null. [CanBeNull] - public static string Parse(char code) - { - code = Char.ToLower(code); - if (IsValidColorCode(code)) - { + public static string Parse( char code ) { + code = Char.ToLower( code ); + if ( IsValidColorCode( code ) ) { return "&" + code; - } - else - { - switch (code) - { - case 's': return Sys; - case 'y': return Say; - case 'p': return PM; - case 'r': return Announcement; - case 'h': return Help; - case 'w': return Warning; - case 'm': return Me; - case 'i': return IRC; + } else { + switch ( code ) { + case 's': + return Sys; + case 'y': + return Say; + case 'p': + return PM; + case 'r': + return Announcement; + case 'h': + return Help; + case 'w': + return Warning; + case 'm': + return Me; + case 'i': + return IRC; default: return null; } } } - /// Parses a numeric color code to a string readable by Minecraft clients /// Ordinal numeric color code (between 0 and 15). /// Two-character color string, readable by Minecraft client. /// If input cannot be parsed, returns null. [CanBeNull] - public static string Parse(int index) - { - if (index >= 0 && index <= 15) - { + public static string Parse( int index ) { + if ( index >= 0 && index <= 15 ) { return "&" + ColorNames.Keys[index]; - } - else - { + } else { return null; } } - - /// Parses a string to a format readable by Minecraft clients. + /// Parses a string to a format readable by Minecraft clients. /// an accept color names and color codes (with or without the ampersand). /// Ordinal numeric color code (between 0 and 15). /// Two-character color string, readable by Minecraft client. /// If input is an empty string, returns empty string. /// If input is null or cannot be parsed, returns null. [CanBeNull] - public static string Parse(string color) - { - if (color == null) - { + public static string Parse( string color ) { + if ( color == null ) { return null; } color = color.ToLower(); - switch (color.Length) - { + switch ( color.Length ) { case 2: - if (color[0] == '&' && IsValidColorCode(color[1])) - { + if ( color[0] == '&' && IsValidColorCode( color[1] ) ) { return color; } break; case 1: - return Parse(color[0]); + return Parse( color[0] ); case 0: return ""; } - if (ColorNames.ContainsValue(color)) - { - return "&" + ColorNames.Keys[ColorNames.IndexOfValue(color)]; - } - else - { + if ( ColorNames.ContainsValue( color ) ) { + return "&" + ColorNames.Keys[ColorNames.IndexOfValue( color )]; + } else { return null; } } - - public static int ParseToIndex([NotNull] string color) - { - if (color == null) throw new ArgumentNullException("color"); + public static int ParseToIndex( [NotNull] string color ) { + if ( color == null ) + throw new ArgumentNullException( "color" ); color = color.ToLower(); - if (color.Length == 2 && color[0] == '&') - { - if (ColorNames.ContainsKey(color[1])) - { - return ColorNames.IndexOfKey(color[1]); - } - else - { - switch (color) - { - case "&s": return ColorNames.IndexOfKey(Sys[1]); - case "&y": return ColorNames.IndexOfKey(Say[1]); - case "&p": return ColorNames.IndexOfKey(PM[1]); - case "&r": return ColorNames.IndexOfKey(Announcement[1]); - case "&h": return ColorNames.IndexOfKey(Help[1]); - case "&w": return ColorNames.IndexOfKey(Warning[1]); - case "&m": return ColorNames.IndexOfKey(Me[1]); - case "&i": return ColorNames.IndexOfKey(IRC[1]); - default: return 15; + if ( color.Length == 2 && color[0] == '&' ) { + if ( ColorNames.ContainsKey( color[1] ) ) { + return ColorNames.IndexOfKey( color[1] ); + } else { + switch ( color ) { + case "&s": + return ColorNames.IndexOfKey( Sys[1] ); + case "&y": + return ColorNames.IndexOfKey( Say[1] ); + case "&p": + return ColorNames.IndexOfKey( PM[1] ); + case "&r": + return ColorNames.IndexOfKey( Announcement[1] ); + case "&h": + return ColorNames.IndexOfKey( Help[1] ); + case "&w": + return ColorNames.IndexOfKey( Warning[1] ); + case "&m": + return ColorNames.IndexOfKey( Me[1] ); + case "&i": + return ColorNames.IndexOfKey( IRC[1] ); + default: + return 15; } } - } - else if (ColorNames.ContainsValue(color)) - { - return ColorNames.IndexOfValue(color); - } - else - { + } else if ( ColorNames.ContainsValue( color ) ) { + return ColorNames.IndexOfValue( color ); + } else { return 15; // white } } - - /// /// Checks whether a color code is valid (checks if it's hexadecimal char). /// /// True is char is valid, otherwise false - public static bool IsValidColorCode(char code) - { - return (code >= '0' && code <= '9') || (code >= 'a' && code <= 'f') || (code >= 'A' && code <= 'F'); + public static bool IsValidColorCode( char code ) { + return ( code >= '0' && code <= '9' ) || ( code >= 'a' && code <= 'f' ) || ( code >= 'A' && code <= 'F' ); } - public static void ReplacePercentCodes([NotNull] StringBuilder sb) - { - if (sb == null) throw new ArgumentNullException("sb"); - sb.Replace("%0", "&0"); - sb.Replace("%1", "&1"); - sb.Replace("%2", "&2"); - sb.Replace("%3", "&3"); - sb.Replace("%4", "&4"); - sb.Replace("%5", "&5"); - sb.Replace("%6", "&6"); - sb.Replace("%7", "&7"); - sb.Replace("%8", "&8"); - sb.Replace("%9", "&9"); - sb.Replace("%a", "&a"); - sb.Replace("%b", "&b"); - sb.Replace("%c", "&c"); - sb.Replace("%d", "&d"); - sb.Replace("%e", "&e"); - sb.Replace("%f", "&f"); - sb.Replace("%A", "&a"); - sb.Replace("%B", "&b"); - sb.Replace("%C", "&c"); - sb.Replace("%D", "&d"); - sb.Replace("%E", "&e"); - sb.Replace("%F", "&f"); + public static void ReplacePercentCodes( [NotNull] StringBuilder sb ) { + if ( sb == null ) + throw new ArgumentNullException( "sb" ); + sb.Replace( "%0", "&0" ); + sb.Replace( "%1", "&1" ); + sb.Replace( "%2", "&2" ); + sb.Replace( "%3", "&3" ); + sb.Replace( "%4", "&4" ); + sb.Replace( "%5", "&5" ); + sb.Replace( "%6", "&6" ); + sb.Replace( "%7", "&7" ); + sb.Replace( "%8", "&8" ); + sb.Replace( "%9", "&9" ); + sb.Replace( "%a", "&a" ); + sb.Replace( "%b", "&b" ); + sb.Replace( "%c", "&c" ); + sb.Replace( "%d", "&d" ); + sb.Replace( "%e", "&e" ); + sb.Replace( "%f", "&f" ); + sb.Replace( "%A", "&a" ); + sb.Replace( "%B", "&b" ); + sb.Replace( "%C", "&c" ); + sb.Replace( "%D", "&d" ); + sb.Replace( "%E", "&e" ); + sb.Replace( "%F", "&f" ); } - public static string ReplacePercentCodes([NotNull] string message) - { - if (message == null) throw new ArgumentNullException("message"); - StringBuilder sb = new StringBuilder(message); - ReplacePercentCodes(sb); + public static string ReplacePercentCodes( [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); + StringBuilder sb = new StringBuilder( message ); + ReplacePercentCodes( sb ); return sb.ToString(); } + public static string SubstituteSpecialColors( [NotNull] string input ) { + if ( input == null ) + throw new ArgumentNullException( "input" ); + StringBuilder sb = new StringBuilder( input ); + for ( int i = sb.Length - 1; i > 0; i-- ) { + if ( sb[i - 1] == '&' ) { + switch ( Char.ToLower( sb[i] ) ) { + case 's': + sb[i] = Sys[1]; + break; + + case 'y': + sb[i] = Say[1]; + break; + + case 'p': + sb[i] = PM[1]; + break; + + case 'r': + sb[i] = Announcement[1]; + break; + + case 'h': + sb[i] = Help[1]; + break; + + case 'w': + sb[i] = Warning[1]; + break; + + case 'm': + sb[i] = Me[1]; + break; + + case 'i': + sb[i] = IRC[1]; + break; - public static string SubstituteSpecialColors([NotNull] string input) - { - if (input == null) throw new ArgumentNullException("input"); - StringBuilder sb = new StringBuilder(input); - for (int i = sb.Length - 1; i > 0; i--) - { - if (sb[i - 1] == '&') - { - switch (Char.ToLower(sb[i])) - { - case 's': sb[i] = Sys[1]; break; - case 'y': sb[i] = Say[1]; break; - case 'p': sb[i] = PM[1]; break; - case 'r': sb[i] = Announcement[1]; break; - case 'h': sb[i] = Help[1]; break; - case 'w': sb[i] = Warning[1]; break; - case 'm': sb[i] = Me[1]; break; - case 'i': sb[i] = IRC[1]; break; default: - if (IsValidColorCode(sb[i])) - { + if ( IsValidColorCode( sb[i] ) ) { continue; - } - else - { - sb.Remove(i - 1, 1); + } else { + sb.Remove( i - 1, 1 ); } break; } @@ -338,65 +319,54 @@ public static string SubstituteSpecialColors([NotNull] string input) return sb.ToString(); } - /// Strips all ampersand color codes, and unescapes doubled-up ampersands. - public static string StripColors([NotNull] string input) - { - if (input == null) throw new ArgumentNullException("input"); - if (input.IndexOf('&') == -1) - { + public static string StripColors( [NotNull] string input ) { + if ( input == null ) + throw new ArgumentNullException( "input" ); + if ( input.IndexOf( '&' ) == -1 ) { return input; - } - else - { - StringBuilder output = new StringBuilder(input.Length); - for (int i = 0; i < input.Length; i++) - { - if (input[i] == '&') - { - if (i == input.Length - 1) - { + } else { + StringBuilder output = new StringBuilder( input.Length ); + for ( int i = 0; i < input.Length; i++ ) { + if ( input[i] == '&' ) { + if ( i == input.Length - 1 ) { break; - } - else if (input[i + 1] == '&') - { - output.Append('&'); + } else if ( input[i + 1] == '&' ) { + output.Append( '&' ); } i++; - } - else - { - output.Append(input[i]); + } else { + output.Append( input[i] ); } } return output.ToString(); } } - #region IRC Colors - /// Replaces IRC color codes with equivalent Minecraft color codes, in the given StringBuilder. + /// Replaces IRC color codes with equivalent Minecraft color codes, in the given StringBuilder. /// Opposite of MinecraftToIrcColors method. /// StringBuilder objects, the contents of which will be processed. /// sb is null. - public static void IrcToMinecraftColors ( [NotNull] StringBuilder sb ) { - if ( sb == null ) throw new ArgumentNullException( "sb" ); + public static void IrcToMinecraftColors( [NotNull] StringBuilder sb ) { + if ( sb == null ) + throw new ArgumentNullException( "sb" ); SubstituteSpecialColors( sb ); foreach ( var codePair in MinecraftToIRCColors ) { sb.Replace( codePair.Value, codePair.Key ); } } - /// Replaces IRC color codes with equivalent Minecraft color codes, in the given string. /// Opposite of MinecraftToIrcColors method. /// String to process. /// A processed string. /// input is null. [NotNull, Pure] - public static string IrcToMinecraftColors ( [NotNull] string input ) { - if ( input == null ) throw new ArgumentNullException( "input" ); + public static string IrcToMinecraftColors( [NotNull] string input ) { + if ( input == null ) + throw new ArgumentNullException( "input" ); StringBuilder sb = new StringBuilder( input ); IrcToMinecraftColors( sb ); return sb.ToString(); @@ -405,7 +375,7 @@ public static string IrcToMinecraftColors ( [NotNull] string input ) { public const string IRCReset = "\u0003\u000f"; public const string IRCBold = "\u0002"; - static readonly Dictionary MinecraftToIRCColors = new Dictionary { + private static readonly Dictionary MinecraftToIRCColors = new Dictionary { { White, "\u000300" }, { Black, "\u000301" }, { Navy, "\u000302" }, @@ -424,42 +394,39 @@ public static string IrcToMinecraftColors ( [NotNull] string input ) { { Silver, "\u000315" }, }; - - public static string EscapeAmpersands([NotNull] string input) - { - if (input == null) throw new ArgumentNullException("input"); - return input.Replace("&", "&&"); + public static string EscapeAmpersands( [NotNull] string input ) { + if ( input == null ) + throw new ArgumentNullException( "input" ); + return input.Replace( "&", "&&" ); } - /// Replaces Minecraft color codes with equivalent IRC color codes, in the given StringBuilder. /// Opposite of IrcToMinecraftColors method. /// StringBuilder objects, the contents of which will be processed. /// sb is null. - public static void MinecraftToIrcColors([NotNull] StringBuilder sb) - { - if (sb == null) throw new ArgumentNullException("sb"); - SubstituteSpecialColors(sb); - foreach (var codePair in MinecraftToIRCColors) - { - sb.Replace(codePair.Key, codePair.Value); + public static void MinecraftToIrcColors( [NotNull] StringBuilder sb ) { + if ( sb == null ) + throw new ArgumentNullException( "sb" ); + SubstituteSpecialColors( sb ); + foreach ( var codePair in MinecraftToIRCColors ) { + sb.Replace( codePair.Key, codePair.Value ); } } - /// Replaces Minecraft color codes with equivalent IRC color codes, in the given string. /// Opposite of IrcToMinecraftColors method. /// String to process. /// A processed string. /// input is null. [NotNull, Pure] - public static string MinecraftToIrcColors([NotNull] string input) - { - if (input == null) throw new ArgumentNullException("input"); - StringBuilder sb = new StringBuilder(input); - MinecraftToIrcColors(sb); + public static string MinecraftToIrcColors( [NotNull] string input ) { + if ( input == null ) + throw new ArgumentNullException( "input" ); + StringBuilder sb = new StringBuilder( input ); + MinecraftToIrcColors( sb ); return sb.ToString(); } + /// Substitutes all fCraft-specific ampersand color codes (like &S/Color.Sys) /// with the assigned Minecraft colors (like &E/Color.Yellow). /// Strips any unrecognized sequences. Does not replace percent-codes. @@ -467,43 +434,47 @@ public static string MinecraftToIrcColors([NotNull] string input) /// StringBuilder, contents of which will be processed. /// Processed string. /// sb is null. - public static void SubstituteSpecialColors([NotNull] StringBuilder sb) - { - if (sb == null) throw new ArgumentNullException("sb"); - for (int i = sb.Length - 1; i > 0; i--) - { - if (sb[i - 1] == '&') - { - switch (Char.ToLower(sb[i])) - { + public static void SubstituteSpecialColors( [NotNull] StringBuilder sb ) { + if ( sb == null ) + throw new ArgumentNullException( "sb" ); + for ( int i = sb.Length - 1; i > 0; i-- ) { + if ( sb[i - 1] == '&' ) { + switch ( Char.ToLower( sb[i] ) ) { case 's': sb[i] = Sys[1]; break; + case 'y': sb[i] = Say[1]; break; + case 'p': sb[i] = PM[1]; break; + case 'r': sb[i] = Announcement[1]; break; + case 'h': sb[i] = Help[1]; break; + case 'w': sb[i] = Warning[1]; break; + case 'm': sb[i] = Me[1]; break; + case 'i': sb[i] = IRC[1]; break; + default: - if (!IsValidColorCode(sb[i])) - { - sb.Remove(i - 1, 2); + if ( !IsValidColorCode( sb[i] ) ) { + sb.Remove( i - 1, 2 ); } break; } @@ -511,10 +482,7 @@ public static void SubstituteSpecialColors([NotNull] StringBuilder sb) } } - - - enum IRCColor - { + private enum IRCColor { White = 0, Black, Navy, @@ -534,4 +502,5 @@ enum IRCColor } } } -#endregion \ No newline at end of file + + #endregion IRC Colors \ No newline at end of file diff --git a/fCraft/Utils/Direction.cs b/fCraft/Utils/Direction.cs index bc1c4a1..edb792f 100644 --- a/fCraft/Utils/Direction.cs +++ b/fCraft/Utils/Direction.cs @@ -1,47 +1,32 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -namespace fCraft -{ - public enum Direction - { +namespace fCraft { + + public enum Direction { Null, one, two, three, four } - public class DirectionFinder - { - - public static Direction GetDirection(Vector3I[] marks) - { - if (Math.Abs(marks[1].X - marks[0].X) > Math.Abs(marks[1].Y - marks[0].Y)) - { - if (marks[0].X < marks[1].X) - { + + public class DirectionFinder { + + public static Direction GetDirection( Vector3I[] marks ) { + if ( Math.Abs( marks[1].X - marks[0].X ) > Math.Abs( marks[1].Y - marks[0].Y ) ) { + if ( marks[0].X < marks[1].X ) { return Direction.one; - } - else - { + } else { return Direction.two; } - } - else if (Math.Abs(marks[1].X - marks[0].X) < Math.Abs(marks[1].Y - marks[0].Y)) - { - if (marks[0].Y < marks[1].Y) - { + } else if ( Math.Abs( marks[1].X - marks[0].X ) < Math.Abs( marks[1].Y - marks[0].Y ) ) { + if ( marks[0].Y < marks[1].Y ) { return Direction.three; - } - else - { + } else { return Direction.four; } - } - else + } else return Direction.Null; } } -} +} \ No newline at end of file diff --git a/fCraft/Utils/EventInterfaces.cs b/fCraft/Utils/EventInterfaces.cs index 3659dae..d080540 100644 --- a/fCraft/Utils/EventInterfaces.cs +++ b/fCraft/Utils/EventInterfaces.cs @@ -3,28 +3,30 @@ using System; namespace fCraft { + /// An EventArgs for an event that can be cancelled. public interface ICancellableEvent { + bool Cancel { get; set; } } - /// An EventArgs for an event that directly relates to a particular player. public interface IPlayerEvent { + Player Player { get; } } - /// An EventArgs for an event that directly relates to a particular world. public interface IWorldEvent { + World World { get; } } - /// Simple interface for objects to notify of changes in their serializable state. /// This event is used to trigger saving things like Zone- and MetadataCollection. /// sender should be set for EventHandler, and e should be set to EventArgs.Empty - interface INotifiesOnChange { + internal interface INotifiesOnChange { + event EventHandler Changed; } } \ No newline at end of file diff --git a/fCraft/Utils/ExtensionMethods.cs b/fCraft/Utils/ExtensionMethods.cs index 63915b5..9ecbbdb 100644 --- a/fCraft/Utils/ExtensionMethods.cs +++ b/fCraft/Utils/ExtensionMethods.cs @@ -6,340 +6,268 @@ using System.Text; using JetBrains.Annotations; -namespace fCraft -{ +namespace fCraft { + + public static class IPAddressUtil { - public static class IPAddressUtil - { /// Checks whether an IP address may belong to LAN (192.168.0.0/16 or 10.0.0.0/24). - public static bool IsLAN([NotNull] this IPAddress addr) - { - if (addr == null) throw new ArgumentNullException("addr"); + public static bool IsLAN( [NotNull] this IPAddress addr ) { + if ( addr == null ) + throw new ArgumentNullException( "addr" ); byte[] bytes = addr.GetAddressBytes(); - return (bytes[0] == 192 && bytes[1] == 168) || - (bytes[0] == 10); + return ( bytes[0] == 192 && bytes[1] == 168 ) || + ( bytes[0] == 10 ); } - public static uint AsUInt([NotNull] this IPAddress thisAddr) - { - if (thisAddr == null) throw new ArgumentNullException("thisAddr"); - return (uint)IPAddress.HostToNetworkOrder(BitConverter.ToInt32(thisAddr.GetAddressBytes(), 0)); + public static uint AsUInt( [NotNull] this IPAddress thisAddr ) { + if ( thisAddr == null ) + throw new ArgumentNullException( "thisAddr" ); + return ( uint )IPAddress.HostToNetworkOrder( BitConverter.ToInt32( thisAddr.GetAddressBytes(), 0 ) ); } - public static int AsInt([NotNull] this IPAddress thisAddr) - { - if (thisAddr == null) throw new ArgumentNullException("thisAddr"); - return IPAddress.HostToNetworkOrder(BitConverter.ToInt32(thisAddr.GetAddressBytes(), 0)); + public static int AsInt( [NotNull] this IPAddress thisAddr ) { + if ( thisAddr == null ) + throw new ArgumentNullException( "thisAddr" ); + return IPAddress.HostToNetworkOrder( BitConverter.ToInt32( thisAddr.GetAddressBytes(), 0 ) ); } - public static bool Match([NotNull] this IPAddress thisAddr, uint otherAddr, uint mask) - { - if (thisAddr == null) throw new ArgumentNullException("thisAddr"); + public static bool Match( [NotNull] this IPAddress thisAddr, uint otherAddr, uint mask ) { + if ( thisAddr == null ) + throw new ArgumentNullException( "thisAddr" ); uint thisAsUInt = thisAddr.AsUInt(); - return (thisAsUInt & mask) == (otherAddr & mask); + return ( thisAsUInt & mask ) == ( otherAddr & mask ); } - public static IPAddress RangeMin([NotNull] this IPAddress thisAddr, byte range) - { - if (thisAddr == null) throw new ArgumentNullException("thisAddr"); - if (range > 32) throw new ArgumentOutOfRangeException("range"); + public static IPAddress RangeMin( [NotNull] this IPAddress thisAddr, byte range ) { + if ( thisAddr == null ) + throw new ArgumentNullException( "thisAddr" ); + if ( range > 32 ) + throw new ArgumentOutOfRangeException( "range" ); int thisAsInt = thisAddr.AsInt(); - int mask = (int)NetMask(range); - return new IPAddress(IPAddress.HostToNetworkOrder(thisAsInt & mask)); + int mask = ( int )NetMask( range ); + return new IPAddress( IPAddress.HostToNetworkOrder( thisAsInt & mask ) ); } - public static IPAddress RangeMax([NotNull] this IPAddress thisAddr, byte range) - { - if (thisAddr == null) throw new ArgumentNullException("thisAddr"); - if (range > 32) throw new ArgumentOutOfRangeException("range"); + public static IPAddress RangeMax( [NotNull] this IPAddress thisAddr, byte range ) { + if ( thisAddr == null ) + throw new ArgumentNullException( "thisAddr" ); + if ( range > 32 ) + throw new ArgumentOutOfRangeException( "range" ); int thisAsInt = thisAddr.AsInt(); - int mask = (int)~NetMask(range); - return new IPAddress((uint)IPAddress.HostToNetworkOrder(thisAsInt | mask)); + int mask = ( int )~NetMask( range ); + return new IPAddress( ( uint )IPAddress.HostToNetworkOrder( thisAsInt | mask ) ); } - public static uint NetMask(byte range) - { - if (range > 32) throw new ArgumentOutOfRangeException("range"); - if (range == 0) - { + public static uint NetMask( byte range ) { + if ( range > 32 ) + throw new ArgumentOutOfRangeException( "range" ); + if ( range == 0 ) { return 0; - } - else - { - return 0xffffffff << (32 - range); + } else { + return 0xffffffff << ( 32 - range ); } } } - - public static class DateTimeUtil - { - static readonly NumberFormatInfo NumberFormatter = CultureInfo.InvariantCulture.NumberFormat; - public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + public static class DateTimeUtil { + private static readonly NumberFormatInfo NumberFormatter = CultureInfo.InvariantCulture.NumberFormat; + public static readonly DateTime UnixEpoch = new DateTime( 1970, 1, 1, 0, 0, 0, DateTimeKind.Utc ); public static readonly long TicksToUnixEpoch; - const long TicksPerMillisecond = 10000; + private const long TicksPerMillisecond = 10000; - static DateTimeUtil() - { + static DateTimeUtil() { TicksToUnixEpoch = UnixEpoch.Ticks; } /// Creates a DateTime from a Utc Unix Timestamp. - public static DateTime TryParseDateTime ( long timestamp ) { + public static DateTime TryParseDateTime( long timestamp ) { return UnixEpoch.AddSeconds( timestamp ); } - #region To Unix Time /// Converts a DateTime to Utc Unix Timestamp. - public static long ToUnixTime(this DateTime date) - { - return (long)date.Subtract(UnixEpoch).TotalSeconds; + public static long ToUnixTime( this DateTime date ) { + return ( long )date.Subtract( UnixEpoch ).TotalSeconds; } - - public static long ToUnixTimeLegacy(this DateTime date) - { - return (date.Ticks - TicksToUnixEpoch) / TicksPerMillisecond; + public static long ToUnixTimeLegacy( this DateTime date ) { + return ( date.Ticks - TicksToUnixEpoch ) / TicksPerMillisecond; } - /// Converts a DateTime to a string containing the Utc Unix Timestamp. /// If the date equals DateTime.MinValue, returns an empty string. - public static string ToUnixTimeString(this DateTime date) - { - if (date == DateTime.MinValue) - { + public static string ToUnixTimeString( this DateTime date ) { + if ( date == DateTime.MinValue ) { return ""; - } - else - { - return date.ToUnixTime().ToString(NumberFormatter); + } else { + return date.ToUnixTime().ToString( NumberFormatter ); } } - /// Appends a Utc Unix Timestamp to the given StringBuilder. /// If the date equals DateTime.MinValue, nothing is appended. - public static StringBuilder ToUnixTimeString(this DateTime date, StringBuilder sb) - { - if (date != DateTime.MinValue) - { - sb.Append(date.ToUnixTime()); + public static StringBuilder ToUnixTimeString( this DateTime date, StringBuilder sb ) { + if ( date != DateTime.MinValue ) { + sb.Append( date.ToUnixTime() ); } return sb; } - #endregion - + #endregion To Unix Time #region To Date Time /// Creates a DateTime from a Utc Unix Timestamp. - public static DateTime ToDateTime(this long timestamp) - { - return UnixEpoch.AddSeconds(timestamp); + public static DateTime ToDateTime( this long timestamp ) { + return UnixEpoch.AddSeconds( timestamp ); } - /// Tries to create a DateTime from a string containing a Utc Unix Timestamp. /// If the string was empty, returns false and does not affect result. - public static bool ToDateTime(this string str, ref DateTime result) - { + public static bool ToDateTime( this string str, ref DateTime result ) { long t; - if (str.Length > 1 && Int64.TryParse(str, out t)) - { - result = UnixEpoch.AddSeconds(Int64.Parse(str)); + if ( str.Length > 1 && Int64.TryParse( str, out t ) ) { + result = UnixEpoch.AddSeconds( Int64.Parse( str ) ); return true; } return false; } - - public static DateTime ToDateTimeLegacy(long timestamp) - { - return new DateTime(timestamp * TicksPerMillisecond + TicksToUnixEpoch, DateTimeKind.Utc); + public static DateTime ToDateTimeLegacy( long timestamp ) { + return new DateTime( timestamp * TicksPerMillisecond + TicksToUnixEpoch, DateTimeKind.Utc ); } - - public static bool ToDateTimeLegacy(this string str, ref DateTime result) - { - if (str.Length <= 1) - { + public static bool ToDateTimeLegacy( this string str, ref DateTime result ) { + if ( str.Length <= 1 ) { return false; } - result = ToDateTimeLegacy(Int64.Parse(str)); + result = ToDateTimeLegacy( Int64.Parse( str ) ); return true; } - #endregion - + #endregion To Date Time /// Converts a TimeSpan to a string containing the number of seconds. /// If the timestamp is zero seconds, returns an empty string. - public static string ToTickString(this TimeSpan time) - { - if (time == TimeSpan.Zero) - { + public static string ToTickString( this TimeSpan time ) { + if ( time == TimeSpan.Zero ) { return ""; - } - else - { - return (time.Ticks / TimeSpan.TicksPerSecond).ToString(NumberFormatter); + } else { + return ( time.Ticks / TimeSpan.TicksPerSecond ).ToString( NumberFormatter ); } } - - public static long ToSeconds(this TimeSpan time) - { - return (time.Ticks / TimeSpan.TicksPerSecond); + public static long ToSeconds( this TimeSpan time ) { + return ( time.Ticks / TimeSpan.TicksPerSecond ); } - /// Tries to create a TimeSpan from a string containing the number of seconds. /// If the string was empty, returns false and sets result to TimeSpan.Zero - public static bool ToTimeSpan([NotNull] this string str, out TimeSpan result) - { - if (str == null) throw new ArgumentNullException("str"); - if (str.Length == 0) - { + public static bool ToTimeSpan( [NotNull] this string str, out TimeSpan result ) { + if ( str == null ) + throw new ArgumentNullException( "str" ); + if ( str.Length == 0 ) { result = TimeSpan.Zero; return true; } long ticks; - if (Int64.TryParse(str, out ticks)) - { - result = new TimeSpan(ticks * TimeSpan.TicksPerSecond); + if ( Int64.TryParse( str, out ticks ) ) { + result = new TimeSpan( ticks * TimeSpan.TicksPerSecond ); return true; - } - else - { + } else { result = TimeSpan.Zero; return false; } } - - public static bool ToTimeSpanLegacy(this string str, ref TimeSpan result) - { - if (str.Length > 1) - { - result = new TimeSpan(Int64.Parse(str) * TicksPerMillisecond); + public static bool ToTimeSpanLegacy( this string str, ref TimeSpan result ) { + if ( str.Length > 1 ) { + result = new TimeSpan( Int64.Parse( str ) * TicksPerMillisecond ); return true; - } - else - { + } else { return false; } } - #region MiniString - public static StringBuilder ToTickString(this TimeSpan time, StringBuilder sb) - { - if (time != TimeSpan.Zero) - { - sb.Append(time.Ticks / TimeSpan.TicksPerSecond); + public static StringBuilder ToTickString( this TimeSpan time, StringBuilder sb ) { + if ( time != TimeSpan.Zero ) { + sb.Append( time.Ticks / TimeSpan.TicksPerSecond ); } return sb; } - - public static string ToMiniString(this TimeSpan span) - { - if (span.TotalSeconds < 60) - { - return String.Format("{0}s", span.Seconds); - } - else if (span.TotalMinutes < 60) - { - return String.Format("{0}m{1}s", span.Minutes, span.Seconds); - } - else if (span.TotalHours < 48) - { - return String.Format("{0}h{1}m", (int)Math.Floor(span.TotalHours), span.Minutes); - } - else if (span.TotalDays < 15) - { - return String.Format("{0}d{1}h", span.Days, span.Hours); - } - else - { - return String.Format("{0:0}w{1:0}d", Math.Floor(span.TotalDays / 7), Math.Floor(span.TotalDays) % 7); + public static string ToMiniString( this TimeSpan span ) { + if ( span.TotalSeconds < 60 ) { + return String.Format( "{0}s", span.Seconds ); + } else if ( span.TotalMinutes < 60 ) { + return String.Format( "{0}m{1}s", span.Minutes, span.Seconds ); + } else if ( span.TotalHours < 48 ) { + return String.Format( "{0}h{1}m", ( int )Math.Floor( span.TotalHours ), span.Minutes ); + } else if ( span.TotalDays < 15 ) { + return String.Format( "{0}d{1}h", span.Days, span.Hours ); + } else { + return String.Format( "{0:0}w{1:0}d", Math.Floor( span.TotalDays / 7 ), Math.Floor( span.TotalDays ) % 7 ); } } - - public static bool TryParseMiniTimespan(this string text, out TimeSpan result) - { - try - { - result = ParseMiniTimespan(text); + public static bool TryParseMiniTimespan( this string text, out TimeSpan result ) { + try { + result = ParseMiniTimespan( text ); return true; - } - catch (ArgumentException) - { - } - catch (OverflowException) - { - } - catch (FormatException) { } + } catch ( ArgumentException ) { + } catch ( OverflowException ) { + } catch ( FormatException ) { } result = TimeSpan.Zero; return false; } + public static readonly TimeSpan MaxTimeSpan = TimeSpan.FromDays( 9999 ); - public static readonly TimeSpan MaxTimeSpan = TimeSpan.FromDays(9999); - - - public static TimeSpan ParseMiniTimespan([NotNull] this string text) - { - if (text == null) throw new ArgumentNullException("text"); + public static TimeSpan ParseMiniTimespan( [NotNull] this string text ) { + if ( text == null ) + throw new ArgumentNullException( "text" ); text = text.Trim(); bool expectingDigit = true; TimeSpan result = TimeSpan.Zero; int digitOffset = 0; - for (int i = 0; i < text.Length; i++) - { - if (expectingDigit) - { - if (text[i] < '0' || text[i] > '9') - { + for ( int i = 0; i < text.Length; i++ ) { + if ( expectingDigit ) { + if ( text[i] < '0' || text[i] > '9' ) { throw new FormatException(); } expectingDigit = false; - } - else - { - if (text[i] >= '0' && text[i] <= '9') - { + } else { + if ( text[i] >= '0' && text[i] <= '9' ) { continue; - } - else - { - string numberString = text.Substring(digitOffset, i - digitOffset); + } else { + string numberString = text.Substring( digitOffset, i - digitOffset ); digitOffset = i + 1; - int number = Int32.Parse(numberString); - switch (Char.ToLower(text[i])) - { + int number = Int32.Parse( numberString ); + switch ( Char.ToLower( text[i] ) ) { case 's': - result += TimeSpan.FromSeconds(number); + result += TimeSpan.FromSeconds( number ); break; + case 'm': - result += TimeSpan.FromMinutes(number); + result += TimeSpan.FromMinutes( number ); break; + case 'h': - result += TimeSpan.FromHours(number); + result += TimeSpan.FromHours( number ); break; + case 'd': - result += TimeSpan.FromDays(number); + result += TimeSpan.FromDays( number ); break; + case 'w': - result += TimeSpan.FromDays(number * 7); + result += TimeSpan.FromDays( number * 7 ); break; + default: throw new FormatException(); } @@ -349,27 +277,22 @@ public static TimeSpan ParseMiniTimespan([NotNull] this string text) return result; } - #endregion - + #endregion MiniString #region CompactString - public static string ToCompactString(this DateTime date) - { - return date.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ssK"); + public static string ToCompactString( this DateTime date ) { + return date.ToString( "yyyy'-'MM'-'dd'T'HH':'mm':'ssK" ); } - - public static string ToCompactString(this TimeSpan span) - { - return String.Format("{0}.{1:00}:{2:00}:{3:00}", - span.Days, span.Hours, span.Minutes, span.Seconds); + public static string ToCompactString( this TimeSpan span ) { + return String.Format( "{0}.{1:00}:{2:00}:{3:00}", + span.Days, span.Hours, span.Minutes, span.Seconds ); } - #endregion + #endregion CompactString - - static CultureInfo cultureInfo = CultureInfo.CurrentCulture; + private static CultureInfo cultureInfo = CultureInfo.CurrentCulture; /// Tries to parse a data in a culture-specific ways. /// This method is, unfortunately, necessary because in versions 0.520-0.522, @@ -379,338 +302,296 @@ public static string ToCompactString(this TimeSpan span) /// String to parse. /// Date to output. /// True if date string could be parsed and was not empty/MinValue. - public static bool TryParseLocalDate([NotNull] string dateString, out DateTime date) - { - if (dateString == null) throw new ArgumentNullException("dateString"); - if (dateString.Length <= 1) - { + public static bool TryParseLocalDate( [NotNull] string dateString, out DateTime date ) { + if ( dateString == null ) + throw new ArgumentNullException( "dateString" ); + if ( dateString.Length <= 1 ) { date = DateTime.MinValue; return false; - } - else - { - if (!DateTime.TryParse(dateString, cultureInfo, DateTimeStyles.None, out date)) - { - CultureInfo[] cultureList = CultureInfo.GetCultures(CultureTypes.FrameworkCultures); - foreach (CultureInfo otherCultureInfo in cultureList) - { + } else { + if ( !DateTime.TryParse( dateString, cultureInfo, DateTimeStyles.None, out date ) ) { + CultureInfo[] cultureList = CultureInfo.GetCultures( CultureTypes.FrameworkCultures ); + foreach ( CultureInfo otherCultureInfo in cultureList ) { cultureInfo = otherCultureInfo; - try - { - if (DateTime.TryParse(dateString, cultureInfo, DateTimeStyles.None, out date)) - { + try { + if ( DateTime.TryParse( dateString, cultureInfo, DateTimeStyles.None, out date ) ) { return true; } - } - catch (NotSupportedException) { } + } catch ( NotSupportedException ) { } } - throw new Exception("Could not find a culture that would be able to parse date/time formats."); - } - else - { + throw new Exception( "Could not find a culture that would be able to parse date/time formats." ); + } else { return true; } } } } + public static class EnumerableUtil { - public static class EnumerableUtil - { /// Joins all items in a collection into one comma-separated string. /// If the items are not strings, .ToString() is called on them. - public static string JoinToString([NotNull] this IEnumerable items) - { - if (items == null) throw new ArgumentNullException("items"); + public static string JoinToString( [NotNull] this IEnumerable items ) { + if ( items == null ) + throw new ArgumentNullException( "items" ); StringBuilder sb = new StringBuilder(); bool first = true; - foreach (T item in items) - { - if (!first) sb.Append(',').Append(' '); - sb.Append(item); + foreach ( T item in items ) { + if ( !first ) + sb.Append( ',' ).Append( ' ' ); + sb.Append( item ); first = false; } return sb.ToString(); } - /// Joins all items in a collection into one string separated with the given separator. /// If the items are not strings, .ToString() is called on them. - public static string JoinToString([NotNull] this IEnumerable items, [NotNull] string separator) - { - if (items == null) throw new ArgumentNullException("items"); - if (separator == null) throw new ArgumentNullException("separator"); + public static string JoinToString( [NotNull] this IEnumerable items, [NotNull] string separator ) { + if ( items == null ) + throw new ArgumentNullException( "items" ); + if ( separator == null ) + throw new ArgumentNullException( "separator" ); StringBuilder sb = new StringBuilder(); bool first = true; - foreach (T item in items) - { - if (!first) sb.Append(separator); - sb.Append(item); + foreach ( T item in items ) { + if ( !first ) + sb.Append( separator ); + sb.Append( item ); first = false; } return sb.ToString(); } - /// Joins all items in a collection into one string separated with the given separator. /// A specified string conversion function is called on each item before contactenation. - public static string JoinToString([NotNull] this IEnumerable items, [NotNull] Func stringConversionFunction) - { - if (items == null) throw new ArgumentNullException("items"); - if (stringConversionFunction == null) throw new ArgumentNullException("stringConversionFunction"); + public static string JoinToString( [NotNull] this IEnumerable items, [NotNull] Func stringConversionFunction ) { + if ( items == null ) + throw new ArgumentNullException( "items" ); + if ( stringConversionFunction == null ) + throw new ArgumentNullException( "stringConversionFunction" ); StringBuilder sb = new StringBuilder(); bool first = true; - foreach (T item in items) - { - if (!first) sb.Append(',').Append(' '); - sb.Append(stringConversionFunction(item)); + foreach ( T item in items ) { + if ( !first ) + sb.Append( ',' ).Append( ' ' ); + sb.Append( stringConversionFunction( item ) ); first = false; } return sb.ToString(); } - /// Joins all items in a collection into one string separated with the given separator. /// A specified string conversion function is called on each item before contactenation. - public static string JoinToString([NotNull] this IEnumerable items, [NotNull] string separator, [NotNull] Func stringConversionFunction) - { - if (items == null) throw new ArgumentNullException("items"); - if (separator == null) throw new ArgumentNullException("separator"); - if (stringConversionFunction == null) throw new ArgumentNullException("stringConversionFunction"); + public static string JoinToString( [NotNull] this IEnumerable items, [NotNull] string separator, [NotNull] Func stringConversionFunction ) { + if ( items == null ) + throw new ArgumentNullException( "items" ); + if ( separator == null ) + throw new ArgumentNullException( "separator" ); + if ( stringConversionFunction == null ) + throw new ArgumentNullException( "stringConversionFunction" ); StringBuilder sb = new StringBuilder(); bool first = true; - foreach (T item in items) - { - if (!first) sb.Append(separator); - sb.Append(stringConversionFunction(item)); + foreach ( T item in items ) { + if ( !first ) + sb.Append( separator ); + sb.Append( stringConversionFunction( item ) ); first = false; } return sb.ToString(); } - /// Joins formatted names of all IClassy objects in a collection into one comma-separated string. - public static string JoinToClassyString([NotNull] this IEnumerable items) - { - if (items == null) throw new ArgumentNullException("items"); - return items.JoinToString(" ", p => p.ClassyName); + public static string JoinToClassyString( [NotNull] this IEnumerable items ) { + if ( items == null ) + throw new ArgumentNullException( "items" ); + return items.JoinToString( " ", p => p.ClassyName ); } } + internal static unsafe class FormatUtil { - unsafe static class FormatUtil - { [NotNull] - public static string ToStringInvariant ( this int i ) { + public static string ToStringInvariant( this int i ) { return i.ToString( CultureInfo.InvariantCulture ); } - public static int IndexOfOrdinal ( [NotNull] this string haystack, [NotNull] string needle ) { + public static int IndexOfOrdinal( [NotNull] this string haystack, [NotNull] string needle ) { return haystack.IndexOf( needle, StringComparison.Ordinal ); } // Quicker StringBuilder.Append(int) by Sam Allen of http://www.dotnetperls.com - public static StringBuilder Digits([NotNull] this StringBuilder builder, int number) - { - if (builder == null) throw new ArgumentNullException("builder"); - if (number >= 100000000 || number < 0) - { + public static StringBuilder Digits( [NotNull] this StringBuilder builder, int number ) { + if ( builder == null ) + throw new ArgumentNullException( "builder" ); + if ( number >= 100000000 || number < 0 ) { // Use system ToString. - builder.Append(number); + builder.Append( number ); return builder; } int copy; int digit; - if (number >= 10000000) - { + if ( number >= 10000000 ) { // 8. copy = number % 100000000; digit = copy / 10000000; - builder.Append((char)(digit + 48)); + builder.Append( ( char )( digit + 48 ) ); } - if (number >= 1000000) - { + if ( number >= 1000000 ) { // 7. copy = number % 10000000; digit = copy / 1000000; - builder.Append((char)(digit + 48)); + builder.Append( ( char )( digit + 48 ) ); } - if (number >= 100000) - { + if ( number >= 100000 ) { // 6. copy = number % 1000000; digit = copy / 100000; - builder.Append((char)(digit + 48)); + builder.Append( ( char )( digit + 48 ) ); } - if (number >= 10000) - { + if ( number >= 10000 ) { // 5. copy = number % 100000; digit = copy / 10000; - builder.Append((char)(digit + 48)); + builder.Append( ( char )( digit + 48 ) ); } - if (number >= 1000) - { + if ( number >= 1000 ) { // 4. copy = number % 10000; digit = copy / 1000; - builder.Append((char)(digit + 48)); + builder.Append( ( char )( digit + 48 ) ); } - if (number >= 100) - { + if ( number >= 100 ) { // 3. copy = number % 1000; digit = copy / 100; - builder.Append((char)(digit + 48)); + builder.Append( ( char )( digit + 48 ) ); } - if (number >= 10) - { + if ( number >= 10 ) { // 2. copy = number % 100; digit = copy / 10; - builder.Append((char)(digit + 48)); + builder.Append( ( char )( digit + 48 ) ); } - if (number >= 0) - { + if ( number >= 0 ) { // 1. copy = number % 10; - builder.Append((char)(copy + 48)); + builder.Append( ( char )( copy + 48 ) ); } return builder; } // Quicker Int32.Parse(string) by Karl Seguin - public static int Parse([NotNull] string stringToConvert) - { - if (stringToConvert == null) throw new ArgumentNullException("stringToConvert"); + public static int Parse( [NotNull] string stringToConvert ) { + if ( stringToConvert == null ) + throw new ArgumentNullException( "stringToConvert" ); int value = 0; int length = stringToConvert.Length; - fixed (char* characters = stringToConvert) - { - for (int i = 0; i < length; ++i) - { - value = 10 * value + (characters[i] - 48); + fixed ( char* characters = stringToConvert ) { + for ( int i = 0; i < length; ++i ) { + value = 10 * value + ( characters[i] - 48 ); } } return value; } // UppercaseFirst by Sam Allen of http://www.dotnetperls.com - public static string UppercaseFirst(this string s) - { - if (string.IsNullOrEmpty(s)) - { + public static string UppercaseFirst( this string s ) { + if ( string.IsNullOrEmpty( s ) ) { return string.Empty; } char[] a = s.ToCharArray(); - a[0] = char.ToUpper(a[0]); - return new string(a); + a[0] = char.ToUpper( a[0] ); + return new string( a ); } } + public unsafe static class BufferUtil { - public unsafe static class BufferUtil - { - public static void MemSet([NotNull] this byte[] array, byte value) - { - if (array == null) throw new ArgumentNullException("array"); + public static void MemSet( [NotNull] this byte[] array, byte value ) { + if ( array == null ) + throw new ArgumentNullException( "array" ); byte[] rawValue = new[] { value, value, value, value, value, value, value, value }; - Int64 fillValue = BitConverter.ToInt64(rawValue, 0); + Int64 fillValue = BitConverter.ToInt64( rawValue, 0 ); - fixed (byte* ptr = array) - { - Int64* dest = (Int64*)ptr; + fixed ( byte* ptr = array ) { + Int64* dest = ( Int64* )ptr; int length = array.Length; - while (length >= 8) - { + while ( length >= 8 ) { *dest = fillValue; dest++; length -= 8; } - byte* bDest = (byte*)dest; - for (byte i = 0; i < length; i++) - { + byte* bDest = ( byte* )dest; + for ( byte i = 0; i < length; i++ ) { *bDest = value; bDest++; } } } - - public static void MemSet([NotNull] this byte[] array, byte value, int startIndex, int length) - { - if (array == null) throw new ArgumentNullException("array"); - if (length < 0 || length > array.Length) - { - throw new ArgumentOutOfRangeException("length"); + public static void MemSet( [NotNull] this byte[] array, byte value, int startIndex, int length ) { + if ( array == null ) + throw new ArgumentNullException( "array" ); + if ( length < 0 || length > array.Length ) { + throw new ArgumentOutOfRangeException( "length" ); } - if (startIndex < 0 || startIndex + length > array.Length) - { - throw new ArgumentOutOfRangeException("startIndex"); + if ( startIndex < 0 || startIndex + length > array.Length ) { + throw new ArgumentOutOfRangeException( "startIndex" ); } byte[] rawValue = new[] { value, value, value, value, value, value, value, value }; - Int64 fillValue = BitConverter.ToInt64(rawValue, 0); + Int64 fillValue = BitConverter.ToInt64( rawValue, 0 ); - fixed (byte* ptr = &array[startIndex]) - { - Int64* dest = (Int64*)ptr; - while (length >= 8) - { + fixed ( byte* ptr = &array[startIndex] ) { + Int64* dest = ( Int64* )ptr; + while ( length >= 8 ) { *dest = fillValue; dest++; length -= 8; } - byte* bDest = (byte*)dest; - for (byte i = 0; i < length; i++) - { + byte* bDest = ( byte* )dest; + for ( byte i = 0; i < length; i++ ) { *bDest = value; bDest++; } } } - - public static void MemCpy([NotNull] byte* src, [NotNull] byte* dest, int len) - { - if (src == null) throw new ArgumentNullException("src"); - if (dest == null) throw new ArgumentNullException("dest"); - if (len >= 0x10) - { - do - { - *((int*)dest) = *((int*)src); - *((int*)(dest + 4)) = *((int*)(src + 4)); - *((int*)(dest + 8)) = *((int*)(src + 8)); - *((int*)(dest + 12)) = *((int*)(src + 12)); + public static void MemCpy( [NotNull] byte* src, [NotNull] byte* dest, int len ) { + if ( src == null ) + throw new ArgumentNullException( "src" ); + if ( dest == null ) + throw new ArgumentNullException( "dest" ); + if ( len >= 0x10 ) { + do { + *( ( int* )dest ) = *( ( int* )src ); + *( ( int* )( dest + 4 ) ) = *( ( int* )( src + 4 ) ); + *( ( int* )( dest + 8 ) ) = *( ( int* )( src + 8 ) ); + *( ( int* )( dest + 12 ) ) = *( ( int* )( src + 12 ) ); dest += 0x10; src += 0x10; } - while ((len -= 0x10) >= 0x10); - } - if (len > 0) - { - if ((len & 8) != 0) - { - *((int*)dest) = *((int*)src); - *((int*)(dest + 4)) = *((int*)(src + 4)); + while ( ( len -= 0x10 ) >= 0x10 ); + } + if ( len > 0 ) { + if ( ( len & 8 ) != 0 ) { + *( ( int* )dest ) = *( ( int* )src ); + *( ( int* )( dest + 4 ) ) = *( ( int* )( src + 4 ) ); dest += 8; src += 8; } - if ((len & 4) != 0) - { - *((int*)dest) = *((int*)src); + if ( ( len & 4 ) != 0 ) { + *( ( int* )dest ) = *( ( int* )src ); dest += 4; src += 4; } - if ((len & 2) != 0) - { - *((short*)dest) = *((short*)src); + if ( ( len & 2 ) != 0 ) { + *( ( short* )dest ) = *( ( short* )src ); dest += 2; src += 2; } - if ((len & 1) != 0) - { + if ( ( len & 1 ) != 0 ) { dest++; src++; dest[0] = src[0]; @@ -718,27 +599,21 @@ public static void MemCpy([NotNull] byte* src, [NotNull] byte* dest, int len) } } - - public static int SizeOf(object obj) - { - return SizeOf(obj.GetType()); + public static int SizeOf( object obj ) { + return SizeOf( obj.GetType() ); } } + public static class EnumUtil { - public static class EnumUtil - { - public static bool TryParse([NotNull] string value, out TEnum output, bool ignoreCase) - { - if (value == null) throw new ArgumentNullException("value"); - try - { - output = (TEnum)Enum.Parse(typeof(TEnum), value, ignoreCase); - return Enum.IsDefined(typeof(TEnum), output); - } - catch (ArgumentException) - { - output = default(TEnum); + public static bool TryParse( [NotNull] string value, out TEnum output, bool ignoreCase ) { + if ( value == null ) + throw new ArgumentNullException( "value" ); + try { + output = ( TEnum )Enum.Parse( typeof( TEnum ), value, ignoreCase ); + return Enum.IsDefined( typeof( TEnum ), output ); + } catch ( ArgumentException ) { + output = default( TEnum ); return false; } } diff --git a/fCraft/Utils/HeartbeatSaverUtil.cs b/fCraft/Utils/HeartbeatSaverUtil.cs index 4181f47..7ee3604 100644 --- a/fCraft/Utils/HeartbeatSaverUtil.cs +++ b/fCraft/Utils/HeartbeatSaverUtil.cs @@ -26,32 +26,24 @@ DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ----*/ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using fCraft.Events; using System.Diagnostics; using System.IO; +using fCraft.Events; + +namespace fCraft { -namespace fCraft -{ - class HeartbeatSaverUtil - { - public static void Init() - { - EventHandler Crash = new EventHandler(HbCrashEvent); + internal class HeartbeatSaverUtil { + + public static void Init() { + EventHandler Crash = new EventHandler( HbCrashEvent ); } - public static void HbCrashEvent(object sender, CrashedEventArgs e) - { - if (e.ShutdownImminent.Equals(true)) - { - if (ConfigKey.HbSaverKey.Enabled()) - { - if (ConfigKey.HbSaverKey.Enabled()) - { - if (!File.Exists("heartbeatsaver.exe")) - { - Logger.Log(LogType.Warning, "heartbeatsaver.exe does not exist and failed to launch"); + + public static void HbCrashEvent( object sender, CrashedEventArgs e ) { + if ( e.ShutdownImminent.Equals( true ) ) { + if ( ConfigKey.HbSaverKey.Enabled() ) { + if ( ConfigKey.HbSaverKey.Enabled() ) { + if ( !File.Exists( "heartbeatsaver.exe" ) ) { + Logger.Log( LogType.Warning, "heartbeatsaver.exe does not exist and failed to launch" ); return; } @@ -64,4 +56,4 @@ public static void HbCrashEvent(object sender, CrashedEventArgs e) } } } -} +} \ No newline at end of file diff --git a/fCraft/Utils/IClassy.cs b/fCraft/Utils/IClassy.cs index 5df941d..2e88a8c 100644 --- a/fCraft/Utils/IClassy.cs +++ b/fCraft/Utils/IClassy.cs @@ -1,9 +1,11 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft { + /// Provides a way for printing an object's name beautified with Minecraft color codes. /// It was "classy" in a sense that it was colored based on "class" (rank) of a player/world/zone. public interface IClassy { + string ClassyName { get; } } -} +} \ No newline at end of file diff --git a/fCraft/Utils/JetBrains.Annotations.cs b/fCraft/Utils/JetBrains.Annotations.cs index eb5611d..af290f5 100644 --- a/fCraft/Utils/JetBrains.Annotations.cs +++ b/fCraft/Utils/JetBrains.Annotations.cs @@ -16,29 +16,27 @@ using System; -namespace JetBrains.Annotations -{ +namespace JetBrains.Annotations { + /// /// Indicates that marked element should be localized or not. /// - [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)] - public sealed class LocalizationRequiredAttribute : Attribute - { + [AttributeUsage( AttributeTargets.All, AllowMultiple = false, Inherited = true )] + public sealed class LocalizationRequiredAttribute : Attribute { + /// /// Initializes a new instance of the class with /// set to . /// public LocalizationRequiredAttribute() - : this(true) - { + : this( true ) { } /// /// Initializes a new instance of the class. /// /// true if a element should be localized; otherwise, false. - public LocalizationRequiredAttribute(bool required) - { + public LocalizationRequiredAttribute( bool required ) { Required = required; } @@ -56,8 +54,7 @@ public LocalizationRequiredAttribute(bool required) /// /// true if the value of the given object is equal to that of the current; otherwise, false. /// - public override bool Equals(object obj) - { + public override bool Equals( object obj ) { var attribute = obj as LocalizationRequiredAttribute; return attribute != null && attribute.Required == Required; } @@ -66,26 +63,24 @@ public override bool Equals(object obj) /// Returns the hash code for this instance. /// /// A hash code for the current . - public override int GetHashCode() - { + public override int GetHashCode() { return base.GetHashCode(); } } /// - /// Indicates that marked method builds string by format pattern and (optional) arguments. + /// Indicates that marked method builds string by format pattern and (optional) arguments. /// Parameter, which contains format string, should be given in constructor. /// The format string should be in -like form /// - [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] - public sealed class StringFormatMethodAttribute : Attribute - { + [AttributeUsage( AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = true )] + public sealed class StringFormatMethodAttribute : Attribute { + /// /// Initializes new instance of StringFormatMethodAttribute /// /// Specifies which parameter of an annotated method should be treated as format-string - public StringFormatMethodAttribute(string formatParameterName) - { + public StringFormatMethodAttribute( string formatParameterName ) { FormatParameterName = formatParameterName; } @@ -100,18 +95,19 @@ public StringFormatMethodAttribute(string formatParameterName) /// Indicates that the function argument should be string literal and match one of the parameters of the caller function. /// For example, has such parameter. /// - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] + [AttributeUsage( AttributeTargets.Parameter, AllowMultiple = false, Inherited = true )] public sealed class InvokerParameterNameAttribute : Attribute { } /// /// Indicates that the function is used to notify class type property value is changed. /// - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] - public sealed class NotifyPropertyChangedInvocatorAttribute : Attribute - { - public NotifyPropertyChangedInvocatorAttribute() { } - public NotifyPropertyChangedInvocatorAttribute(string parameterName) - { + [AttributeUsage( AttributeTargets.Method, AllowMultiple = false, Inherited = true )] + public sealed class NotifyPropertyChangedInvocatorAttribute : Attribute { + + public NotifyPropertyChangedInvocatorAttribute() { + } + + public NotifyPropertyChangedInvocatorAttribute( string parameterName ) { ParameterName = parameterName; } @@ -122,13 +118,13 @@ public NotifyPropertyChangedInvocatorAttribute(string parameterName) /// /// Indicates that the value of marked element could be null sometimes, so the check for null is necessary before its usage /// - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Field, AllowMultiple = false, Inherited = true)] + [AttributeUsage( AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Field, AllowMultiple = false, Inherited = true )] public sealed class CanBeNullAttribute : Attribute { } /// /// Indicates that the value of marked element could never be null /// - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Field, AllowMultiple = false, Inherited = true)] + [AttributeUsage( AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Field, AllowMultiple = false, Inherited = true )] public sealed class NotNullAttribute : Attribute { } /// @@ -157,21 +153,20 @@ public sealed class NotNullAttribute : Attribute { } /// [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")] public bool TryParse(string s, out Person result) /// /// - [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)] - public sealed class ContractAnnotationAttribute : Attribute - { - public ContractAnnotationAttribute([NotNull] string fdt) - : this(fdt, false) - { + [AttributeUsage( AttributeTargets.Method, AllowMultiple = true, Inherited = true )] + public sealed class ContractAnnotationAttribute : Attribute { + + public ContractAnnotationAttribute( [NotNull] string fdt ) + : this( fdt, false ) { } - public ContractAnnotationAttribute([NotNull] string fdt, bool forceFullStates) - { + public ContractAnnotationAttribute( [NotNull] string fdt, bool forceFullStates ) { FDT = fdt; ForceFullStates = forceFullStates; } public string FDT { get; private set; } + public bool ForceFullStates { get; private set; } } @@ -179,34 +174,33 @@ public ContractAnnotationAttribute([NotNull] string fdt, bool forceFullStates) /// Indicates that the value of marked type (or its derivatives) cannot be compared using '==' or '!=' operators. /// There is only exception to compare with null, it is permitted /// - [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)] + [AttributeUsage( AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true )] public sealed class CannotApplyEqualityOperatorAttribute : Attribute { } /// - /// When applied to target attribute, specifies a requirement for any type which is marked with + /// When applied to target attribute, specifies a requirement for any type which is marked with /// target attribute to implement or inherit specific type or types /// /// /// /// [BaseTypeRequired(typeof(IComponent)] // Specify requirement - /// public class ComponentAttribute : Attribute + /// public class ComponentAttribute : Attribute /// {} - /// + /// /// [Component] // ComponentAttribute requires implementing IComponent interface /// public class MyComponent : IComponent /// {} /// /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] - [BaseTypeRequired(typeof(Attribute))] - public sealed class BaseTypeRequiredAttribute : Attribute - { + [AttributeUsage( AttributeTargets.Class, AllowMultiple = true, Inherited = true )] + [BaseTypeRequired( typeof( Attribute ) )] + public sealed class BaseTypeRequiredAttribute : Attribute { + /// /// Initializes new instance of BaseTypeRequiredAttribute /// /// Specifies which types are required - public BaseTypeRequiredAttribute(Type baseType) - { + public BaseTypeRequiredAttribute( Type baseType ) { BaseTypes = new[] { baseType }; } @@ -220,27 +214,26 @@ public BaseTypeRequiredAttribute(Type baseType) /// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library), /// so this symbol will not be marked as unused (as well as by other usage inspections) /// - [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)] - public sealed class UsedImplicitlyAttribute : Attribute - { + [AttributeUsage( AttributeTargets.All, AllowMultiple = false, Inherited = true )] + public sealed class UsedImplicitlyAttribute : Attribute { + [UsedImplicitly] public UsedImplicitlyAttribute() - : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { } + : this( ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default ) { } [UsedImplicitly] - public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) - { + public UsedImplicitlyAttribute( ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags ) { UseKindFlags = useKindFlags; TargetFlags = targetFlags; } [UsedImplicitly] - public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags) - : this(useKindFlags, ImplicitUseTargetFlags.Default) { } + public UsedImplicitlyAttribute( ImplicitUseKindFlags useKindFlags ) + : this( useKindFlags, ImplicitUseTargetFlags.Default ) { } [UsedImplicitly] - public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags) - : this(ImplicitUseKindFlags.Default, targetFlags) { } + public UsedImplicitlyAttribute( ImplicitUseTargetFlags targetFlags ) + : this( ImplicitUseKindFlags.Default, targetFlags ) { } [UsedImplicitly] public ImplicitUseKindFlags UseKindFlags { get; private set; } @@ -255,29 +248,27 @@ public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags) /// /// Should be used on attributes and causes ReSharper to not mark symbols marked with such attributes as unused (as well as by other usage inspections) /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] - public sealed class MeansImplicitUseAttribute : Attribute - { + [AttributeUsage( AttributeTargets.Class, AllowMultiple = false, Inherited = true )] + public sealed class MeansImplicitUseAttribute : Attribute { + [UsedImplicitly] public MeansImplicitUseAttribute() - : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { } + : this( ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default ) { } [UsedImplicitly] - public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) - { + public MeansImplicitUseAttribute( ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags ) { UseKindFlags = useKindFlags; TargetFlags = targetFlags; } [UsedImplicitly] - public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags) - : this(useKindFlags, ImplicitUseTargetFlags.Default) - { + public MeansImplicitUseAttribute( ImplicitUseKindFlags useKindFlags ) + : this( useKindFlags, ImplicitUseTargetFlags.Default ) { } [UsedImplicitly] - public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags) - : this(ImplicitUseKindFlags.Default, targetFlags) { } + public MeansImplicitUseAttribute( ImplicitUseTargetFlags targetFlags ) + : this( ImplicitUseKindFlags.Default, targetFlags ) { } [UsedImplicitly] public ImplicitUseKindFlags UseKindFlags { get; private set; } @@ -290,8 +281,7 @@ public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags) } [Flags] - public enum ImplicitUseKindFlags - { + public enum ImplicitUseKindFlags { Default = Access | Assign | InstantiatedWithFixedConstructorSignature, /// @@ -320,8 +310,7 @@ public enum ImplicitUseKindFlags /// Specify what is considered used implicitly when marked with or /// [Flags] - public enum ImplicitUseTargetFlags - { + public enum ImplicitUseTargetFlags { Default = Itself, Itself = 1, @@ -341,23 +330,27 @@ public enum ImplicitUseTargetFlags /// This attribute is intended to mark publicly available API which should not be removed and so is treated as used. /// [MeansImplicitUse] - public sealed class PublicAPIAttribute : Attribute - { - public PublicAPIAttribute() { } + public sealed class PublicAPIAttribute : Attribute { + + public PublicAPIAttribute() { + } + // ReSharper disable UnusedParameter.Local - public PublicAPIAttribute(string comment) { } + public PublicAPIAttribute( string comment ) { + } + // ReSharper restore UnusedParameter.Local } /// - /// Tells code analysis engine if the parameter is completely handled when the invoked method is on stack. + /// Tells code analysis engine if the parameter is completely handled when the invoked method is on stack. /// If the parameter is delegate, indicates that delegate is executed while the method is executed. /// If the parameter is enumerable, indicates that it is enumerated while the method is executed. /// - [AttributeUsage(AttributeTargets.Parameter, Inherited = true)] + [AttributeUsage( AttributeTargets.Parameter, Inherited = true )] public sealed class InstantHandleAttribute : Attribute { } /// Indicates that method doesn't contain observable side effects. - [AttributeUsage(AttributeTargets.Method, Inherited = true)] + [AttributeUsage( AttributeTargets.Method, Inherited = true )] public sealed class PureAttribute : Attribute { } } \ No newline at end of file diff --git a/fCraft/Utils/LogRecorder.cs b/fCraft/Utils/LogRecorder.cs index e5b4ab8..9304ff2 100644 --- a/fCraft/Utils/LogRecorder.cs +++ b/fCraft/Utils/LogRecorder.cs @@ -1,63 +1,64 @@ // Copyright 2009-2013 Matvei Stefarov using System; using System.Collections.Generic; -using fCraft.Events; using System.Threading; +using fCraft.Events; using JetBrains.Annotations; namespace fCraft { + /// A simple way to temporarily hook into fCraft's Logger. /// Make sure to dispose this class when you are done recording. /// The easiest way to ensure that is with a using(){...} block. public sealed class LogRecorder : IDisposable { - readonly object locker = new object(); - readonly List messages = new List(); - readonly LogType[] thingsToLog; - bool disposed; - readonly Thread creatingThread; - + private readonly object locker = new object(); + private readonly List messages = new List(); + private readonly LogType[] thingsToLog; + private bool disposed; + private readonly Thread creatingThread; /// Creates a recorder for errors and warnings. public LogRecorder() : this( true, LogType.Error, LogType.Warning ) { } - /// Creates a custom recorder. /// Whether this log recorder should limit /// recording to messages emitted from the same thread that created this object. /// A list or array of LogTypes to record. public LogRecorder( bool restrictToThisThread, [NotNull] params LogType[] thingsToLog ) { - if( thingsToLog == null ) throw new ArgumentNullException( "thingsToLog" ); + if ( thingsToLog == null ) + throw new ArgumentNullException( "thingsToLog" ); Logger.Logged += HandleLog; this.thingsToLog = thingsToLog; - if( restrictToThisThread ) { + if ( restrictToThisThread ) { creatingThread = Thread.CurrentThread; } } - - void HandleLog( object sender, LogEventArgs e ) { - if( creatingThread != null && creatingThread != Thread.CurrentThread ) return; - for( int i = 0; i < thingsToLog.Length; i++ ) { - if( thingsToLog[i] != e.MessageType ) continue; - switch( e.MessageType ) { + private void HandleLog( object sender, LogEventArgs e ) { + if ( creatingThread != null && creatingThread != Thread.CurrentThread ) + return; + for ( int i = 0; i < thingsToLog.Length; i++ ) { + if ( thingsToLog[i] != e.MessageType ) + continue; + switch ( e.MessageType ) { case LogType.SeriousError: case LogType.Error: HasErrors = true; break; + case LogType.Warning: HasWarnings = true; break; } HasMessages = true; - lock( locker ) { + lock ( locker ) { messages.Add( e.MessageType + ": " + e.RawMessage ); } } } - /// Whether any messages have been recorded. public bool HasMessages { get; private set; } @@ -67,37 +68,34 @@ void HandleLog( object sender, LogEventArgs e ) { /// Whether any errors have been recorded. public bool HasWarnings { get; private set; } - /// An array of individual recorded messages. public string[] MessageList { get { - lock( locker ) { + lock ( locker ) { return messages.ToArray(); } } } - /// All messages in one block of text, separated by newlines. public string MessageString { get { - lock( locker ) { + lock ( locker ) { return String.Join( Environment.NewLine, messages.ToArray() ); } } } - /// Stops recording the messages (cannot be resumed). /// This method should be called when you are done with the object. /// If LogRecorder is in a using() block, this will be done for you. public void Dispose() { - lock( locker ) { - if( !disposed ) { + lock ( locker ) { + if ( !disposed ) { Logger.Logged -= HandleLog; disposed = true; } } } } -} +} \ No newline at end of file diff --git a/fCraft/Utils/MetadataCollection.cs b/fCraft/Utils/MetadataCollection.cs index a42c49c..6074f98 100644 --- a/fCraft/Utils/MetadataCollection.cs +++ b/fCraft/Utils/MetadataCollection.cs @@ -7,78 +7,86 @@ using JetBrains.Annotations; namespace fCraft { + /// A string metadata entry. /// Value type. Must be a reference type. [DebuggerDisplay( "Count = {Count}" )] public struct MetadataEntry where TValue : class { - string group; + private string group; + [NotNull] public string Group { get { return group; } set { - if( value == null ) throw new ArgumentNullException( "value" ); + if ( value == null ) + throw new ArgumentNullException( "value" ); group = value; } } - string key; + private string key; + [NotNull] public string Key { get { return key; } set { - if( value == null ) throw new ArgumentNullException( "value" ); + if ( value == null ) + throw new ArgumentNullException( "value" ); key = value; } } - TValue value; + private TValue value; + [NotNull] public TValue Value { get { return value; } set { - if( value == this.value ) throw new ArgumentNullException( "value" ); + if ( value == this.value ) + throw new ArgumentNullException( "value" ); this.value = value; } } } - /// A collection of metadata entries, addressable by pairs of string group/key names. /// Group names, key names, and values may not be null. /// Value type. Must be a reference type. public sealed class MetadataCollection : ICollection>, ICollection, ICloneable, INotifiesOnChange where TValue : class { - - readonly Dictionary> store = new Dictionary>(); + private readonly Dictionary> store = new Dictionary>(); /// Creates an empty MetadataCollection. - public MetadataCollection() { } - + public MetadataCollection() { + } /// Creates a copy of the given MetadataCollection. Copies all entries within. public MetadataCollection( [NotNull] MetadataCollection other ) : this() { - if( other == null ) throw new ArgumentNullException( "other" ); - lock( other.syncRoot ) { - foreach( var group in store ) { - foreach( var key in group.Value ) { + if ( other == null ) + throw new ArgumentNullException( "other" ); + lock ( other.syncRoot ) { + foreach ( var group in store ) { + foreach ( var key in group.Value ) { Add( group.Key, key.Key, key.Value ); } } } } - /// Adds a new entry to the collection. /// Throws ArgumentException if an entry with the same group/key already exists. /// Group name. Cannot be null. /// Key name. Cannot be null. /// Value. Cannot be null. public void Add( [NotNull] string group, [NotNull] string key, [NotNull] TValue value ) { - if( group == null ) throw new ArgumentNullException( "group" ); - if( key == null ) throw new ArgumentNullException( "key" ); - if( value == null ) throw new ArgumentNullException( "value" ); - lock( syncRoot ) { - if( !store.ContainsKey( group ) ) { + if ( group == null ) + throw new ArgumentNullException( "group" ); + if ( key == null ) + throw new ArgumentNullException( "key" ); + if ( value == null ) + throw new ArgumentNullException( "value" ); + lock ( syncRoot ) { + if ( !store.ContainsKey( group ) ) { store.Add( group, new Dictionary() ); } store[group].Add( key, value ); @@ -86,18 +94,20 @@ public void Add( [NotNull] string group, [NotNull] string key, [NotNull] TValue } } - /// Removes entry with the specified group/key from the collection. /// Group name. Cannot be null. /// Key name. Cannot be null. /// True if the entry was located and removed. False if no entry was found. public bool Remove( [NotNull] string group, [NotNull] string key ) { - if( group == null ) throw new ArgumentNullException( "group" ); - if( key == null ) throw new ArgumentNullException( "key" ); + if ( group == null ) + throw new ArgumentNullException( "group" ); + if ( key == null ) + throw new ArgumentNullException( "key" ); Dictionary pair; - lock( syncRoot ) { - if( !store.TryGetValue( group, out pair ) ) return false; - if( pair.Remove( key ) ) { + lock ( syncRoot ) { + if ( !store.TryGetValue( group, out pair ) ) + return false; + if ( pair.Remove( key ) ) { RaiseChangedEvent(); return true; } else { @@ -106,35 +116,32 @@ public bool Remove( [NotNull] string group, [NotNull] string key ) { } } - #region Count / Group Count / Key Count /// The total number of entries in this collection. public int Count { get { - lock( syncRoot ) { + lock ( syncRoot ) { return store.Sum( group => group.Value.Count ); } } } - /// Number of groups in this collection. public int GroupCount { get { return store.Count; } } - /// Number of keys within a given group. Throws KeyNotFoundException if no such group exists. /// Group name. Cannot be null. /// Number of keys within the specified group. public int GetKeyCount( [NotNull] string group ) { - if( group == null ) throw new ArgumentNullException( "group" ); + if ( group == null ) + throw new ArgumentNullException( "group" ); return store[group].Count; } - #endregion - + #endregion Count / Group Count / Key Count #region Index / Get / Set @@ -145,50 +152,59 @@ public int GetKeyCount( [NotNull] string group ) { /// The key of the value to get or set. public TValue this[[NotNull] string group, [NotNull] string key] { get { - if( group == null ) throw new ArgumentNullException( "group" ); - if( key == null ) throw new ArgumentNullException( "key" ); + if ( group == null ) + throw new ArgumentNullException( "group" ); + if ( key == null ) + throw new ArgumentNullException( "key" ); return GetValue( group, key ); } set { - if( group == null ) throw new ArgumentNullException( "group" ); - if( key == null ) throw new ArgumentNullException( "key" ); + if ( group == null ) + throw new ArgumentNullException( "group" ); + if ( key == null ) + throw new ArgumentNullException( "key" ); SetValue( group, key, value ); } } - - TValue GetValue( [NotNull] string group, [NotNull] string key ) { - if( group == null ) throw new ArgumentNullException( "group" ); - if( key == null ) throw new ArgumentNullException( "key" ); - lock( syncRoot ) { + private TValue GetValue( [NotNull] string group, [NotNull] string key ) { + if ( group == null ) + throw new ArgumentNullException( "group" ); + if ( key == null ) + throw new ArgumentNullException( "key" ); + lock ( syncRoot ) { return store[group][key]; } } - - void SetValue( [NotNull] string group, [NotNull] string key, [NotNull] TValue value ) { - if( group == null ) throw new ArgumentNullException( "group" ); - if( key == null ) throw new ArgumentNullException( "key" ); - if( value == null ) throw new ArgumentNullException( "value" ); - lock( syncRoot ) { + private void SetValue( [NotNull] string group, [NotNull] string key, [NotNull] TValue value ) { + if ( group == null ) + throw new ArgumentNullException( "group" ); + if ( key == null ) + throw new ArgumentNullException( "key" ); + if ( value == null ) + throw new ArgumentNullException( "value" ); + lock ( syncRoot ) { bool raiseChangedEvent = false; - if( !store.ContainsKey( group ) ) { + if ( !store.ContainsKey( group ) ) { store.Add( group, new Dictionary() ); raiseChangedEvent = true; } - if( !store[group].ContainsKey( key ) || store[group][key] != value ) { + if ( !store[group].ContainsKey( key ) || store[group][key] != value ) { raiseChangedEvent = true; } store[group][key] = value; - if( raiseChangedEvent ) RaiseChangedEvent(); + if ( raiseChangedEvent ) + RaiseChangedEvent(); } } - public MetadataEntry Get( [NotNull] string group, [NotNull] string key ) { - if( group == null ) throw new ArgumentNullException( "group" ); - if( key == null ) throw new ArgumentNullException( "key" ); - lock( syncRoot ) { + if ( group == null ) + throw new ArgumentNullException( "group" ); + if ( key == null ) + throw new ArgumentNullException( "key" ); + lock ( syncRoot ) { return new MetadataEntry { Group = group, Key = key, @@ -197,40 +213,39 @@ public MetadataEntry Get( [NotNull] string group, [NotNull] string key ) } } - public void Set( MetadataEntry entry ) { SetValue( entry.Group, entry.Key, entry.Value ); } - #endregion - + #endregion Index / Get / Set #region Contains Group / Key / Value public bool ContainsGroup( [NotNull] string group ) { - if( group == null ) throw new ArgumentNullException( "group" ); - lock( syncRoot ) { + if ( group == null ) + throw new ArgumentNullException( "group" ); + lock ( syncRoot ) { return store.ContainsKey( group ); } } - public bool ContainsKey( [NotNull] string group, [NotNull] string key ) { - if( group == null ) throw new ArgumentNullException( "group" ); - if( key == null ) throw new ArgumentNullException( "key" ); - lock( syncRoot ) { + if ( group == null ) + throw new ArgumentNullException( "group" ); + if ( key == null ) + throw new ArgumentNullException( "key" ); + lock ( syncRoot ) { return store.ContainsKey( group ) && store[group].ContainsKey( key ); } } - public bool ContainsValue( [NotNull] TValue value ) { - lock( syncRoot ) { + lock ( syncRoot ) { // ReSharper disable LoopCanBeConvertedToQuery - foreach( var group in store ) { - foreach( var key in group.Value ) { - if( value.Equals( key.Value ) ) { + foreach ( var group in store ) { + foreach ( var key in group.Value ) { + if ( value.Equals( key.Value ) ) { return true; } } @@ -240,13 +255,12 @@ public bool ContainsValue( [NotNull] TValue value ) { return false; } - public bool ContainsValue( [NotNull] TValue value, IEqualityComparer comparer ) { - lock( syncRoot ) { + lock ( syncRoot ) { // ReSharper disable LoopCanBeConvertedToQuery - foreach( var group in store ) { - foreach( var key in group.Value ) { - if( comparer.Equals( key.Value, value ) ) { + foreach ( var group in store ) { + foreach ( var key in group.Value ) { + if ( comparer.Equals( key.Value, value ) ) { return true; } } @@ -256,15 +270,16 @@ public bool ContainsValue( [NotNull] TValue value, IEqualityComparer com return false; } - #endregion - + #endregion Contains Group / Key / Value public bool TryGetValue( [NotNull] string group, [NotNull] string key, out TValue value ) { - if( group == null ) throw new ArgumentNullException( "group" ); - if( key == null ) throw new ArgumentNullException( "key" ); + if ( group == null ) + throw new ArgumentNullException( "group" ); + if ( key == null ) + throw new ArgumentNullException( "key" ); Dictionary pair; - lock( syncRoot ) { - if( !store.TryGetValue( group, out pair ) ) { + lock ( syncRoot ) { + if ( !store.TryGetValue( group, out pair ) ) { value = null; return false; } @@ -272,15 +287,15 @@ public bool TryGetValue( [NotNull] string group, [NotNull] string key, out TValu } } - /// Enumerates a group of keys. /// Lock SyncRoot if this is used in a loop. public IEnumerable> GetGroup( [NotNull] string group ) { - if( group == null ) throw new ArgumentNullException( "group" ); + if ( group == null ) + throw new ArgumentNullException( "group" ); Dictionary groupDic; - if( store.TryGetValue( group, out groupDic ) ) { - lock( syncRoot ) { - foreach( var key in groupDic ) { + if ( store.TryGetValue( group, out groupDic ) ) { + lock ( syncRoot ) { + foreach ( var key in groupDic ) { yield return new MetadataEntry { Group = group, Key = key.Key, @@ -293,43 +308,41 @@ public IEnumerable> GetGroup( [NotNull] string group ) { } } - #region ICollection Members public void Add( MetadataEntry item ) { Add( item.Group, item.Key, item.Value ); } - public void Clear() { - lock( syncRoot ) { - bool raiseEvent = (store.Count > 0); + lock ( syncRoot ) { + bool raiseEvent = ( store.Count > 0 ); store.Clear(); - if( raiseEvent ) RaiseChangedEvent(); + if ( raiseEvent ) + RaiseChangedEvent(); } } - public bool Contains( [NotNull] MetadataEntry item ) { return ContainsKey( item.Group, item.Key ); } - public void CopyTo( [NotNull] MetadataEntry[] array, int arrayIndex ) { - if( array == null ) throw new ArgumentNullException( "array" ); + if ( array == null ) + throw new ArgumentNullException( "array" ); - if( arrayIndex < 0 || arrayIndex >= array.Length ) { + if ( arrayIndex < 0 || arrayIndex >= array.Length ) { throw new ArgumentOutOfRangeException( "arrayIndex" ); } - lock( syncRoot ) { - if( array.Length < arrayIndex + Count ) { + lock ( syncRoot ) { + if ( array.Length < arrayIndex + Count ) { throw new ArgumentOutOfRangeException( "array" ); } int i = 0; - foreach( var group in store ) { - foreach( var pair in group.Value ) { + foreach ( var group in store ) { + foreach ( var pair in group.Value ) { array[i] = new MetadataEntry { Group = group.Key, Key = pair.Key, @@ -341,18 +354,15 @@ public void CopyTo( [NotNull] MetadataEntry[] array, int arrayIndex ) { } } - bool ICollection>.IsReadOnly { get { return false; } } - public bool Remove( MetadataEntry item ) { return Remove( item.Group, item.Key ); } - #endregion - + #endregion ICollection Members #region IEnumerable Members @@ -360,8 +370,8 @@ public bool Remove( MetadataEntry item ) { /// Lock SyncRoot if this is used in a loop. public IEnumerator> GetEnumerator() { // ReSharper disable LoopCanBeConvertedToQuery - foreach( var group in store ) { - foreach( var key in group.Value ) { + foreach ( var group in store ) { + foreach ( var key in group.Value ) { yield return new MetadataEntry { Group = group.Key, Key = key.Key, @@ -372,8 +382,7 @@ public IEnumerator> GetEnumerator() { // ReSharper restore LoopCanBeConvertedToQuery } - #endregion - + #endregion IEnumerable Members #region IEnumerable Members @@ -381,46 +390,43 @@ IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } - #endregion - + #endregion IEnumerable Members #region ICollection Members public void CopyTo( [NotNull] Array array, int index ) { - if( array == null ) throw new ArgumentNullException( "array" ); + if ( array == null ) + throw new ArgumentNullException( "array" ); var castArray = array as MetadataEntry[]; - if( castArray == null ) { + if ( castArray == null ) { throw new ArgumentException( "Array must be of type MetadataEntry[]", "array" ); } CopyTo( castArray, index ); } - public bool IsSynchronized { get { return true; } } + private readonly object syncRoot = new object(); - readonly object syncRoot = new object(); /// Internal lock object used by this collection to ensure thread safety. public object SyncRoot { get { return syncRoot; } } - #endregion - + #endregion ICollection Members public object Clone() { return new MetadataCollection( this ); } - public event EventHandler Changed; - - void RaiseChangedEvent() { + private void RaiseChangedEvent() { var h = Changed; - if( h != null ) h( null, EventArgs.Empty ); + if ( h != null ) + h( null, EventArgs.Empty ); } } } \ No newline at end of file diff --git a/fCraft/Utils/MonoCompat.cs b/fCraft/Utils/MonoCompat.cs index f9b69c5..141e4c9 100644 --- a/fCraft/Utils/MonoCompat.cs +++ b/fCraft/Utils/MonoCompat.cs @@ -5,11 +5,10 @@ using System.Text.RegularExpressions; using JetBrains.Annotations; -namespace fCraft -{ +namespace fCraft { + /// Class dedicated to solving Mono compatibility issues - public static class MonoCompat - { + public static class MonoCompat { /// Whether the current filesystem is case-sensitive. public static bool IsCaseSensitive { get; private set; } @@ -29,64 +28,53 @@ public static class MonoCompat /// Whether we are under a Windows OS (under either .NET or Mono). public static bool IsWindows { get; private set; } + private const string UnsupportedMessage = "Your Mono version is not supported. Update to at least Mono 2.6+ (recommended 2.10+)"; + private static readonly Regex VersionRegex = new Regex( @"^(\d)+\.(\d+)\.(\d)\D" ); - const string UnsupportedMessage = "Your Mono version is not supported. Update to at least Mono 2.6+ (recommended 2.10+)"; - static readonly Regex VersionRegex = new Regex(@"^(\d)+\.(\d+)\.(\d)\D"); + private const BindingFlags MonoMethodFlags = BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.ExactBinding; - const BindingFlags MonoMethodFlags = BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.ExactBinding; - static MonoCompat() - { - Type monoRuntimeType = typeof(object).Assembly.GetType("Mono.Runtime"); + static MonoCompat() { + Type monoRuntimeType = typeof( object ).Assembly.GetType( "Mono.Runtime" ); - if (monoRuntimeType != null) - { + if ( monoRuntimeType != null ) { IsMono = true; - MethodInfo getDisplayNameMethod = monoRuntimeType.GetMethod("GetDisplayName", MonoMethodFlags, null, Type.EmptyTypes, null); - - if (getDisplayNameMethod != null) - { - MonoVersionString = (string)getDisplayNameMethod.Invoke(null, null); - - try - { - Match versionMatch = VersionRegex.Match(MonoVersionString); - int major = Int32.Parse(versionMatch.Groups[1].Value); - int minor = Int32.Parse(versionMatch.Groups[2].Value); - int revision = Int32.Parse(versionMatch.Groups[3].Value); - MonoVersion = new Version(major, minor, revision); - IsSGenCapable = (major == 2 && minor >= 8); - } - catch (Exception ex) - { - throw new Exception(UnsupportedMessage, ex); + MethodInfo getDisplayNameMethod = monoRuntimeType.GetMethod( "GetDisplayName", MonoMethodFlags, null, Type.EmptyTypes, null ); + + if ( getDisplayNameMethod != null ) { + MonoVersionString = ( string )getDisplayNameMethod.Invoke( null, null ); + + try { + Match versionMatch = VersionRegex.Match( MonoVersionString ); + int major = Int32.Parse( versionMatch.Groups[1].Value ); + int minor = Int32.Parse( versionMatch.Groups[2].Value ); + int revision = Int32.Parse( versionMatch.Groups[3].Value ); + MonoVersion = new Version( major, minor, revision ); + IsSGenCapable = ( major == 2 && minor >= 8 ); + } catch ( Exception ex ) { + throw new Exception( UnsupportedMessage, ex ); } - if (MonoVersion.Major < 2 && MonoVersion.Major < 6) - { - throw new Exception(UnsupportedMessage); + if ( MonoVersion.Major < 2 && MonoVersion.Major < 6 ) { + throw new Exception( UnsupportedMessage ); } - - } - else - { - throw new Exception(UnsupportedMessage); + } else { + throw new Exception( UnsupportedMessage ); } } - switch (Environment.OSVersion.Platform) - { + switch ( Environment.OSVersion.Platform ) { case PlatformID.MacOSX: case PlatformID.Unix: IsMono = true; IsWindows = false; break; + default: IsWindows = true; break; } IsCaseSensitive = !IsWindows; - } /// Starts a .NET process, using Mono if necessary. @@ -94,59 +82,45 @@ static MonoCompat() /// Arguments to pass to the executable. /// If true, new process will be detached under Mono. /// Process object - public static Process StartDotNetProcess([NotNull] string assemblyLocation, [NotNull] string assemblyArgs, bool detachIfMono) - { - if (assemblyLocation == null) throw new ArgumentNullException("assemblyLocation"); - if (assemblyArgs == null) throw new ArgumentNullException("assemblyArgs"); + public static Process StartDotNetProcess( [NotNull] string assemblyLocation, [NotNull] string assemblyArgs, bool detachIfMono ) { + if ( assemblyLocation == null ) + throw new ArgumentNullException( "assemblyLocation" ); + if ( assemblyArgs == null ) + throw new ArgumentNullException( "assemblyArgs" ); string binaryName, args; - if (IsMono) - { - if (IsSGenCapable) - { + if ( IsMono ) { + if ( IsSGenCapable ) { binaryName = "mono-sgen"; - } - else - { + } else { binaryName = "mono"; } args = "\"" + assemblyLocation + "\""; - if (!String.IsNullOrEmpty(assemblyArgs)) - { + if ( !String.IsNullOrEmpty( assemblyArgs ) ) { args += " " + assemblyArgs; } - if (detachIfMono) - { + if ( detachIfMono ) { args += " &"; } - } - else - { + } else { binaryName = assemblyLocation; args = assemblyArgs; } - return Process.Start(binaryName, args); + return Process.Start( binaryName, args ); } - /// Prepends the correct Mono name to the .NET executable, if needed. /// /// - public static string PrependMono([NotNull] string dotNetExecutable) - { - if (dotNetExecutable == null) throw new ArgumentNullException("dotNetExecutable"); - if (IsMono) - { - if (IsSGenCapable) - { + public static string PrependMono( [NotNull] string dotNetExecutable ) { + if ( dotNetExecutable == null ) + throw new ArgumentNullException( "dotNetExecutable" ); + if ( IsMono ) { + if ( IsSGenCapable ) { return "mono-sgen " + dotNetExecutable; - } - else - { + } else { return "mono " + dotNetExecutable; } - } - else - { + } else { return dotNetExecutable; } } diff --git a/fCraft/Utils/Noise.cs b/fCraft/Utils/Noise.cs index fe63675..c746fac 100644 --- a/fCraft/Utils/Noise.cs +++ b/fCraft/Utils/Noise.cs @@ -6,6 +6,7 @@ namespace fCraft { /// Interpolation mode for perlin noise. public enum NoiseInterpolationMode { + /// Bilinear (LERP) interpolation (fastest). Linear, @@ -19,7 +20,6 @@ public enum NoiseInterpolationMode { Spline } - /// Class for generating and filtering 2D noise, extensively used by MapGenerator. public sealed class Noise { public readonly int Seed; @@ -30,22 +30,19 @@ public Noise( int seed, NoiseInterpolationMode interpolationMode ) { InterpolationMode = interpolationMode; } - public static float InterpolateLinear( float v0, float v1, float x ) { - return v0 * (1 - x) + v1 * x; + return v0 * ( 1 - x ) + v1 * x; } - public static float InterpolateLinear( float v00, float v01, float v10, float v11, float x, float y ) { return InterpolateLinear( InterpolateLinear( v00, v10, x ), InterpolateLinear( v01, v11, x ), y ); } - public static float InterpolateCosine( float v0, float v1, float x ) { - double f = (1 - Math.Cos( x * Math.PI )) * .5; - return (float)(v0 * (1 - f) + v1 * f); + double f = ( 1 - Math.Cos( x * Math.PI ) ) * .5; + return ( float )( v0 * ( 1 - f ) + v1 * f ); } public static float InterpolateCosine( float v00, float v01, float v10, float v11, float x, float y ) { @@ -54,7 +51,6 @@ public static float InterpolateCosine( float v00, float v01, float v10, float v1 y ); } - // Cubic and Catmull-Rom Spline interpolation methods by Paul Bourke // http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/interpolation/ public static float InterpolateCubic( float v0, float v1, float v2, float v3, float mu ) { @@ -63,44 +59,42 @@ public static float InterpolateCubic( float v0, float v1, float v2, float v3, fl float a1 = v0 - v1 - a0; float a2 = v2 - v0; float a3 = v1; - return (a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3); + return ( a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3 ); } - public static float InterpolateSpline( float v0, float v1, float v2, float v3, float mu ) { float mu2 = mu * mu; float a0 = -0.5f * v0 + 1.5f * v1 - 1.5f * v2 + 0.5f * v3; float a1 = v0 - 2.5f * v1 + 2 * v2 - 0.5f * v3; float a2 = -0.5f * v0 + 0.5f * v2; float a3 = v1; - return (a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3); + return ( a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3 ); } - public float StaticNoise( int x, int y ) { int n = Seed + x + y * short.MaxValue; - n = (n << 13) ^ n; - return (float)(1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7FFFFFFF) / 1073741824d); + n = ( n << 13 ) ^ n; + return ( float )( 1.0 - ( ( n * ( n * n * 15731 + 789221 ) + 1376312589 ) & 0x7FFFFFFF ) / 1073741824d ); } public float StaticNoise( int x, int y, int z ) { int n = Seed + x + y * 1625 + z * 2642245; - n = (n << 13) ^ n; - return (float)(1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7FFFFFFF) / 1073741824d); + n = ( n << 13 ) ^ n; + return ( float )( 1.0 - ( ( n * ( n * n * 15731 + 789221 ) + 1376312589 ) & 0x7FFFFFFF ) / 1073741824d ); } + private readonly float[,] points = new float[4, 4]; - readonly float[,] points = new float[4, 4]; public float InterpolatedNoise( float x, float y ) { - int xInt = (int)Math.Floor( x ); + int xInt = ( int )Math.Floor( x ); float xFloat = x - xInt; - int yInt = (int)Math.Floor( y ); + int yInt = ( int )Math.Floor( y ); float yFloat = y - yInt; float p00, p01, p10, p11; - switch( InterpolationMode ) { + switch ( InterpolationMode ) { case NoiseInterpolationMode.Linear: p00 = StaticNoise( xInt, yInt ); p01 = StaticNoise( xInt, yInt + 1 ); @@ -116,8 +110,8 @@ public float InterpolatedNoise( float x, float y ) { return InterpolateCosine( InterpolateCosine( p00, p10, xFloat ), InterpolateCosine( p01, p11, xFloat ), yFloat ); case NoiseInterpolationMode.Bicubic: - for( int xOffset = -1; xOffset < 3; xOffset++ ) { - for( int yOffset = -1; yOffset < 3; yOffset++ ) { + for ( int xOffset = -1; xOffset < 3; xOffset++ ) { + for ( int yOffset = -1; yOffset < 3; yOffset++ ) { points[xOffset + 1, yOffset + 1] = StaticNoise( xInt + xOffset, yInt + yOffset ); } } @@ -128,8 +122,8 @@ public float InterpolatedNoise( float x, float y ) { return InterpolateCubic( p00, p01, p10, p11, yFloat ); case NoiseInterpolationMode.Spline: - for( int xOffset = -1; xOffset < 3; xOffset++ ) { - for( int yOffset = -1; yOffset < 3; yOffset++ ) { + for ( int xOffset = -1; xOffset < 3; xOffset++ ) { + for ( int yOffset = -1; yOffset < 3; yOffset++ ) { points[xOffset + 1, yOffset + 1] = StaticNoise( xInt + xOffset, yInt + yOffset ); } } @@ -146,25 +140,25 @@ public float InterpolatedNoise( float x, float y ) { //readonly float[, ,] points3D = new float[4, 4, 4]; public float InterpolatedNoise( float x, float y, float z ) { - int xInt = (int)Math.Floor( x ); + int xInt = ( int )Math.Floor( x ); float xFloat = x - xInt; - int yInt = (int)Math.Floor( y ); + int yInt = ( int )Math.Floor( y ); float yFloat = y - yInt; - int zInt = (int)Math.Floor( z ); + int zInt = ( int )Math.Floor( z ); float zFloat = z - zInt; float p000, p001, p010, p011, p100, p101, p110, p111; - switch( InterpolationMode ) { + switch ( InterpolationMode ) { case NoiseInterpolationMode.Linear: p000 = StaticNoise( xInt, yInt, zInt ); p001 = StaticNoise( xInt, yInt, zInt + 1 ); p010 = StaticNoise( xInt, yInt + 1, zInt ); p011 = StaticNoise( xInt, yInt + 1, zInt + 1 ); - p100 = StaticNoise( xInt+1, yInt, zInt ); + p100 = StaticNoise( xInt + 1, yInt, zInt ); p101 = StaticNoise( xInt + 1, yInt, zInt + 1 ); p110 = StaticNoise( xInt + 1, yInt + 1, zInt ); p111 = StaticNoise( xInt + 1, yInt + 1, zInt + 1 ); @@ -186,44 +180,43 @@ public float InterpolatedNoise( float x, float y, float z ) { InterpolateCosine( InterpolateCosine( p000, p100, xFloat ), InterpolateCosine( p010, p110, xFloat ), yFloat ), InterpolateCosine( InterpolateCosine( p001, p101, xFloat ), InterpolateCosine( p011, p111, xFloat ), yFloat ), zFloat ); - /* - case NoiseInterpolationMode.Bicubic: TODO - for( int xOffset = -1; xOffset < 3; xOffset++ ) { - for( int yOffset = -1; yOffset < 3; yOffset++ ) { - points[xOffset + 1, yOffset + 1] = StaticNoise( xInt + xOffset, yInt + yOffset ); - } + /* + case NoiseInterpolationMode.Bicubic: TODO + for( int xOffset = -1; xOffset < 3; xOffset++ ) { + for( int yOffset = -1; yOffset < 3; yOffset++ ) { + points[xOffset + 1, yOffset + 1] = StaticNoise( xInt + xOffset, yInt + yOffset ); } - p00 = InterpolateCubic( points[0, 0], points[1, 0], points[2, 0], points[3, 0], xFloat ); - p01 = InterpolateCubic( points[0, 1], points[1, 1], points[2, 1], points[3, 1], xFloat ); - p10 = InterpolateCubic( points[0, 2], points[1, 2], points[2, 2], points[3, 2], xFloat ); - p11 = InterpolateCubic( points[0, 3], points[1, 3], points[2, 3], points[3, 3], xFloat ); - return InterpolateCubic( p00, p01, p10, p11, yFloat ); - - case NoiseInterpolationMode.Spline: - for( int xOffset = -1; xOffset < 3; xOffset++ ) { - for( int yOffset = -1; yOffset < 3; yOffset++ ) { - points[xOffset + 1, yOffset + 1] = StaticNoise( xInt + xOffset, yInt + yOffset ); - } + } + p00 = InterpolateCubic( points[0, 0], points[1, 0], points[2, 0], points[3, 0], xFloat ); + p01 = InterpolateCubic( points[0, 1], points[1, 1], points[2, 1], points[3, 1], xFloat ); + p10 = InterpolateCubic( points[0, 2], points[1, 2], points[2, 2], points[3, 2], xFloat ); + p11 = InterpolateCubic( points[0, 3], points[1, 3], points[2, 3], points[3, 3], xFloat ); + return InterpolateCubic( p00, p01, p10, p11, yFloat ); + + case NoiseInterpolationMode.Spline: + for( int xOffset = -1; xOffset < 3; xOffset++ ) { + for( int yOffset = -1; yOffset < 3; yOffset++ ) { + points[xOffset + 1, yOffset + 1] = StaticNoise( xInt + xOffset, yInt + yOffset ); } - p00 = InterpolateSpline( points[0, 0], points[1, 0], points[2, 0], points[3, 0], xFloat ); - p01 = InterpolateSpline( points[0, 1], points[1, 1], points[2, 1], points[3, 1], xFloat ); - p10 = InterpolateSpline( points[0, 2], points[1, 2], points[2, 2], points[3, 2], xFloat ); - p11 = InterpolateSpline( points[0, 3], points[1, 3], points[2, 3], points[3, 3], xFloat ); - return InterpolateSpline( p00, p01, p10, p11, yFloat ); - */ + } + p00 = InterpolateSpline( points[0, 0], points[1, 0], points[2, 0], points[3, 0], xFloat ); + p01 = InterpolateSpline( points[0, 1], points[1, 1], points[2, 1], points[3, 1], xFloat ); + p10 = InterpolateSpline( points[0, 2], points[1, 2], points[2, 2], points[3, 2], xFloat ); + p11 = InterpolateSpline( points[0, 3], points[1, 3], points[2, 3], points[3, 3], xFloat ); + return InterpolateSpline( p00, p01, p10, p11, yFloat ); + */ default: throw new ArgumentException(); } } - public float PerlinNoise( float x, float y, int startOctave, int endOctave, float decay ) { float total = 0; - float frequency = (float)Math.Pow( 2, startOctave ); - float amplitude = (float)Math.Pow( decay, startOctave ); + float frequency = ( float )Math.Pow( 2, startOctave ); + float amplitude = ( float )Math.Pow( decay, startOctave ); - for( int n = startOctave; n <= endOctave; n++ ) { + for ( int n = startOctave; n <= endOctave; n++ ) { total += InterpolatedNoise( x * frequency + frequency, y * frequency + frequency ) * amplitude; frequency *= 2; amplitude *= decay; @@ -234,10 +227,10 @@ public float PerlinNoise( float x, float y, int startOctave, int endOctave, floa public float PerlinNoise( float x, float y, float z, int startOctave, int endOctave, float decay ) { float total = 0; - float frequency = (float)Math.Pow( 2, startOctave ); - float amplitude = (float)Math.Pow( decay, startOctave ); + float frequency = ( float )Math.Pow( 2, startOctave ); + float amplitude = ( float )Math.Pow( decay, startOctave ); - for( int n = startOctave; n <= endOctave; n++ ) { + for ( int n = startOctave; n <= endOctave; n++ ) { total += InterpolatedNoise( x * frequency + frequency, y * frequency + frequency, z * frequency + frequency ) * amplitude; @@ -247,24 +240,24 @@ public float PerlinNoise( float x, float y, float z, int startOctave, int endOct return total; } - public void PerlinNoise( [NotNull] float[,] map, int startOctave, int endOctave, float decay, int offsetX, int offsetY ) { - if( map == null ) throw new ArgumentNullException( "map" ); + if ( map == null ) + throw new ArgumentNullException( "map" ); float maxDim = 1f / Math.Max( map.GetLength( 0 ), map.GetLength( 1 ) ); - for( int x = map.GetLength( 0 ) - 1; x >= 0; x-- ) { - for( int y = map.GetLength( 1 ) - 1; y >= 0; y-- ) { + for ( int x = map.GetLength( 0 ) - 1; x >= 0; x-- ) { + for ( int y = map.GetLength( 1 ) - 1; y >= 0; y-- ) { map[x, y] += PerlinNoise( x * maxDim + offsetX, y * maxDim + offsetY, startOctave, endOctave, decay ); } } } - public void PerlinNoise( [NotNull] float[, ,] map, int startOctave, int endOctave, float decay, int offsetX, int offsetY, int offsetZ ) { - if( map == null ) throw new ArgumentNullException( "map" ); + if ( map == null ) + throw new ArgumentNullException( "map" ); float maxDim = 1f / Math.Max( map.GetLength( 0 ), Math.Max( map.GetLength( 2 ), map.GetLength( 1 ) ) ); - for( int x = map.GetLength( 0 ) - 1; x >= 0; x-- ) { - for( int y = map.GetLength( 1 ) - 1; y >= 0; y-- ) { - for( int z = map.GetLength( 2 ) - 1; z >= 0; z-- ) { + for ( int x = map.GetLength( 0 ) - 1; x >= 0; x-- ) { + for ( int y = map.GetLength( 1 ) - 1; y >= 0; y-- ) { + for ( int z = map.GetLength( 2 ) - 1; z >= 0; z-- ) { map[x, y, z] += PerlinNoise( x * maxDim + offsetX, y * maxDim + offsetY, z * maxDim + offsetZ, startOctave, endOctave, decay ); } @@ -272,224 +265,223 @@ public void PerlinNoise( [NotNull] float[, ,] map, int startOctave, int endOctav } } - #region Normalize public static void Normalize( float[,] map ) { Normalize( map, 0, 1 ); } - - public static void Normalize( float[,,] map ) { + public static void Normalize( float[, ,] map ) { Normalize( map, 0, 1 ); } - public static void Normalize( float[, ,] map, out float multiplier, out float constant ) { CalculateNormalizationParams( map, out multiplier, out constant, 0f, 1f ); } public unsafe static void CalculateNormalizationParams( float[, ,] map, out float multiplier, out float constant, float low, float high ) { - fixed( float* ptr = map ) { + fixed ( float* ptr = map ) { float min = float.MaxValue, max = float.MinValue; - for( int i = 0; i < map.Length; i++ ) { + for ( int i = 0; i < map.Length; i++ ) { min = Math.Min( min, ptr[i] ); max = Math.Max( max, ptr[i] ); } - multiplier = (high - low) / (max - min); - constant = -min * (high - low) / (max - min) + low; + multiplier = ( high - low ) / ( max - min ); + constant = -min * ( high - low ) / ( max - min ) + low; - for( int i = 0; i < map.Length; i++ ) { + for ( int i = 0; i < map.Length; i++ ) { ptr[i] = ptr[i] * multiplier + constant; } } } - public unsafe static void Normalize( float[,] map, float low, float high ) { int length = map.GetLength( 0 ) * map.GetLength( 1 ); - fixed( float* ptr = map ) { + fixed ( float* ptr = map ) { Normalize( ptr, length, low, high ); } } - - public unsafe static void Normalize( float[,,] map, float low, float high ) { + public unsafe static void Normalize( float[, ,] map, float low, float high ) { int length = map.GetLength( 0 ) * map.GetLength( 1 ) * map.GetLength( 2 ); - fixed( float* ptr = map ) { + fixed ( float* ptr = map ) { Normalize( ptr, length, low, high ); } } - - unsafe static void Normalize( float* ptr, int length, float low, float high ) { + private static unsafe void Normalize( float* ptr, int length, float low, float high ) { float min = float.MaxValue, max = float.MinValue; - for( int i = 0; i < length; i++ ) { - min = Math.Min( min, ptr[i] ); - max = Math.Max( max, ptr[i] ); - } + for ( int i = 0; i < length; i++ ) { + min = Math.Min( min, ptr[i] ); + max = Math.Max( max, ptr[i] ); + } - float multiplier = (high - low) / (max - min); - float constant = -min * (high - low) / (max - min) + low; + float multiplier = ( high - low ) / ( max - min ); + float constant = -min * ( high - low ) / ( max - min ) + low; - for( int i = 0; i < length; i++ ) { - ptr[i] = ptr[i] * multiplier + constant; - } + for ( int i = 0; i < length; i++ ) { + ptr[i] = ptr[i] * multiplier + constant; + } } - #endregion - + #endregion Normalize // assumes normalized input public unsafe static void Marble( [NotNull] float[,] map ) { - if( map == null ) throw new ArgumentNullException( "map" ); - fixed( float* ptr = map ) { - for( int i = 0; i < map.Length; i++ ) { + if ( map == null ) + throw new ArgumentNullException( "map" ); + fixed ( float* ptr = map ) { + for ( int i = 0; i < map.Length; i++ ) { ptr[i] = Math.Abs( ptr[i] * 2 - 1 ); } } } - - public unsafe static void Marble( [NotNull] float[,,] map ) { - if( map == null ) throw new ArgumentNullException( "map" ); - fixed( float* ptr = map ) { - for( int i = 0; i < map.Length; i++ ) { + public unsafe static void Marble( [NotNull] float[, ,] map ) { + if ( map == null ) + throw new ArgumentNullException( "map" ); + fixed ( float* ptr = map ) { + for ( int i = 0; i < map.Length; i++ ) { ptr[i] = Math.Abs( ptr[i] * 2 - 1 ); } } } - // assumes normalized input public unsafe static void Blend( [NotNull] float[,] data1, [NotNull] float[,] data2, [NotNull] float[,] blendMap ) { - if( data1 == null ) throw new ArgumentNullException( "data1" ); - if( data2 == null ) throw new ArgumentNullException( "data2" ); - if( blendMap == null ) throw new ArgumentNullException( "blendMap" ); - fixed( float* ptr1 = data1, ptr2 = data2, ptrBlend = blendMap ) { - for( int i = 0; i < data1.Length; i++ ) { - ptr1[i] += ptr1[i] * ptrBlend[i] + ptr2[i] * (1 - ptrBlend[i]); + if ( data1 == null ) + throw new ArgumentNullException( "data1" ); + if ( data2 == null ) + throw new ArgumentNullException( "data2" ); + if ( blendMap == null ) + throw new ArgumentNullException( "blendMap" ); + fixed ( float* ptr1 = data1, ptr2 = data2, ptrBlend = blendMap ) { + for ( int i = 0; i < data1.Length; i++ ) { + ptr1[i] += ptr1[i] * ptrBlend[i] + ptr2[i] * ( 1 - ptrBlend[i] ); } } } - public unsafe static void Add( [NotNull] float[,] data1, [NotNull] float[,] data2 ) { - if( data1 == null ) throw new ArgumentNullException( "data1" ); - if( data2 == null ) throw new ArgumentNullException( "data2" ); - if( data1.GetLength( 0 ) != data2.GetLength( 0 ) || + if ( data1 == null ) + throw new ArgumentNullException( "data1" ); + if ( data2 == null ) + throw new ArgumentNullException( "data2" ); + if ( data1.GetLength( 0 ) != data2.GetLength( 0 ) || data1.GetLength( 1 ) != data2.GetLength( 1 ) ) { throw new ArgumentException( "data1 and data2 dimension mismatch" ); } - fixed( float* ptr1 = data1, ptr2 = data2 ) { - for( int i = 0; i < data1.Length; i++ ) { + fixed ( float* ptr1 = data1, ptr2 = data2 ) { + for ( int i = 0; i < data1.Length; i++ ) { ptr1[i] += ptr2[i]; } } } - public static void ApplyBias( [NotNull] float[,] data, float c00, float c01, float c10, float c11, float midpoint ) { - if( data == null ) throw new ArgumentNullException( "data" ); + if ( data == null ) + throw new ArgumentNullException( "data" ); float maxX = 2f / data.GetLength( 0 ); float maxY = 2f / data.GetLength( 1 ); int offsetX = data.GetLength( 0 ) / 2; int offsetY = data.GetLength( 1 ) / 2; - for( int x = offsetX - 1; x >= 0; x-- ) { - for( int y = offsetY - 1; y >= 0; y-- ) { - data[x, y] += InterpolateCosine( c00, (c00 + c01) / 2, (c00 + c10) / 2, midpoint, x * maxX, y * maxY ); - data[x + offsetX, y] += InterpolateCosine( (c00 + c10) / 2, midpoint, c10, (c11 + c10) / 2, x * maxX, y * maxY ); - data[x, y + offsetY] += InterpolateCosine( (c00 + c01) / 2, c01, midpoint, (c01 + c11) / 2, x * maxX, y * maxY ); - data[x + offsetX, y + offsetY] += InterpolateCosine( midpoint, (c01 + c11) / 2, (c11 + c10) / 2, c11, x * maxX, y * maxY ); + for ( int x = offsetX - 1; x >= 0; x-- ) { + for ( int y = offsetY - 1; y >= 0; y-- ) { + data[x, y] += InterpolateCosine( c00, ( c00 + c01 ) / 2, ( c00 + c10 ) / 2, midpoint, x * maxX, y * maxY ); + data[x + offsetX, y] += InterpolateCosine( ( c00 + c10 ) / 2, midpoint, c10, ( c11 + c10 ) / 2, x * maxX, y * maxY ); + data[x, y + offsetY] += InterpolateCosine( ( c00 + c01 ) / 2, c01, midpoint, ( c01 + c11 ) / 2, x * maxX, y * maxY ); + data[x + offsetX, y + offsetY] += InterpolateCosine( midpoint, ( c01 + c11 ) / 2, ( c11 + c10 ) / 2, c11, x * maxX, y * maxY ); } } } - // assumes normalized input public unsafe static void ScaleAndClip( [NotNull] float[,] data, float steepness ) { - if( data == null ) throw new ArgumentNullException( "data" ); - fixed( float* ptr = data ) { - for( int i = 0; i < data.Length; i++ ) { + if ( data == null ) + throw new ArgumentNullException( "data" ); + fixed ( float* ptr = data ) { + for ( int i = 0; i < data.Length; i++ ) { ptr[i] = Math.Min( 1, Math.Max( 0, ptr[i] * steepness * 2 - steepness ) ); } } } - public unsafe static void Invert( [NotNull] float[,] data ) { - if( data == null ) throw new ArgumentNullException( "data" ); - fixed( float* ptr = data ) { - for( int i = 0; i < data.Length; i++ ) { + if ( data == null ) + throw new ArgumentNullException( "data" ); + fixed ( float* ptr = data ) { + for ( int i = 0; i < data.Length; i++ ) { ptr[i] = 1 - ptr[i]; } } } + private const float BoxBlurDivisor = 1 / 23f; - const float BoxBlurDivisor = 1 / 23f; public static float[,] BoxBlur( [NotNull] float[,] heightmap ) { - if( heightmap == null ) throw new ArgumentNullException( "heightmap" ); + if ( heightmap == null ) + throw new ArgumentNullException( "heightmap" ); float[,] output = new float[heightmap.GetLength( 0 ), heightmap.GetLength( 1 )]; - for( int x = heightmap.GetLength( 0 ) - 1; x >= 0; x-- ) { - for( int y = heightmap.GetLength( 1 ) - 1; y >= 0; y-- ) { - if( (x == 0) || (y == 0) || (x == heightmap.GetLength( 0 ) - 1) || (y == heightmap.GetLength( 1 ) - 1) ) { + for ( int x = heightmap.GetLength( 0 ) - 1; x >= 0; x-- ) { + for ( int y = heightmap.GetLength( 1 ) - 1; y >= 0; y-- ) { + if ( ( x == 0 ) || ( y == 0 ) || ( x == heightmap.GetLength( 0 ) - 1 ) || ( y == heightmap.GetLength( 1 ) - 1 ) ) { output[x, y] = heightmap[x, y]; } else { - output[x, y] = (heightmap[x - 1, y - 1] * 2 + heightmap[x - 1, y] * 3 + heightmap[x - 1, y + 1] * 2 + + output[x, y] = ( heightmap[x - 1, y - 1] * 2 + heightmap[x - 1, y] * 3 + heightmap[x - 1, y + 1] * 2 + heightmap[x, y - 1] * 3 + heightmap[x, y] * 3 + heightmap[x, y + 1] * 3 + - heightmap[x + 1, y - 1] * 2 + heightmap[x + 1, y] * 3 + heightmap[x + 1, y + 1] * 2) * BoxBlurDivisor; + heightmap[x + 1, y - 1] * 2 + heightmap[x + 1, y] * 3 + heightmap[x + 1, y + 1] * 2 ) * BoxBlurDivisor; } } } return output; } + private const float GaussianBlurDivisor = 1 / 273f; - const float GaussianBlurDivisor = 1 / 273f; public static float[,] GaussianBlur5X5( [NotNull] float[,] heightmap ) { - if( heightmap == null ) throw new ArgumentNullException( "heightmap" ); + if ( heightmap == null ) + throw new ArgumentNullException( "heightmap" ); float[,] output = new float[heightmap.GetLength( 0 ), heightmap.GetLength( 1 )]; - for( int x = heightmap.GetLength( 0 ) - 1; x >= 0; x-- ) { - for( int y = heightmap.GetLength( 1 ) - 1; y >= 0; y-- ) { - if( (x < 2) || (y < 2) || (x > heightmap.GetLength( 0 ) - 3) || (y > heightmap.GetLength( 1 ) - 3) ) { + for ( int x = heightmap.GetLength( 0 ) - 1; x >= 0; x-- ) { + for ( int y = heightmap.GetLength( 1 ) - 1; y >= 0; y-- ) { + if ( ( x < 2 ) || ( y < 2 ) || ( x > heightmap.GetLength( 0 ) - 3 ) || ( y > heightmap.GetLength( 1 ) - 3 ) ) { output[x, y] = heightmap[x, y]; } else { - output[x, y] = (heightmap[x - 2, y - 2] + heightmap[x - 1, y - 2] * 4 + heightmap[x, y - 2] * 7 + heightmap[x + 1, y - 2] * 4 + heightmap[x + 2, y - 2] + + output[x, y] = ( heightmap[x - 2, y - 2] + heightmap[x - 1, y - 2] * 4 + heightmap[x, y - 2] * 7 + heightmap[x + 1, y - 2] * 4 + heightmap[x + 2, y - 2] + heightmap[x - 1, y - 1] * 4 + heightmap[x - 1, y - 1] * 16 + heightmap[x, y - 1] * 26 + heightmap[x + 1, y - 1] * 16 + heightmap[x + 2, y - 1] * 4 + heightmap[x - 2, y] * 7 + heightmap[x - 1, y] * 26 + heightmap[x, y] * 41 + heightmap[x + 1, y] * 26 + heightmap[x + 2, y] * 7 + heightmap[x - 2, y + 1] * 4 + heightmap[x - 1, y + 1] * 16 + heightmap[x, y + 1] * 26 + heightmap[x + 1, y + 1] * 16 + heightmap[x + 2, y + 1] * 4 + - heightmap[x - 2, y + 2] + heightmap[x - 1, y + 2] * 4 + heightmap[x, y + 2] * 7 + heightmap[x + 1, y + 2] * 4 + heightmap[x + 2, y + 2]) * GaussianBlurDivisor; + heightmap[x - 2, y + 2] + heightmap[x - 1, y + 2] * 4 + heightmap[x, y + 2] * 7 + heightmap[x + 1, y + 2] * 4 + heightmap[x + 2, y + 2] ) * GaussianBlurDivisor; } } } return output; } - public static float[,] CalculateSlope( [NotNull] float[,] heightmap ) { - if( heightmap == null ) throw new ArgumentNullException( "heightmap" ); + if ( heightmap == null ) + throw new ArgumentNullException( "heightmap" ); float[,] output = new float[heightmap.GetLength( 0 ), heightmap.GetLength( 1 )]; - for( int x = heightmap.GetLength( 0 ) - 1; x >= 0; x-- ) { - for( int y = heightmap.GetLength( 1 ) - 1; y >= 0; y-- ) { - if( (x == 0) || (y == 0) || (x == heightmap.GetLength( 0 ) - 1) || (y == heightmap.GetLength( 1 ) - 1) ) { + for ( int x = heightmap.GetLength( 0 ) - 1; x >= 0; x-- ) { + for ( int y = heightmap.GetLength( 1 ) - 1; y >= 0; y-- ) { + if ( ( x == 0 ) || ( y == 0 ) || ( x == heightmap.GetLength( 0 ) - 1 ) || ( y == heightmap.GetLength( 1 ) - 1 ) ) { output[x, y] = 0; } else { - output[x, y] = (Math.Abs( heightmap[x, y - 1] - heightmap[x, y] ) * 3 + + output[x, y] = ( Math.Abs( heightmap[x, y - 1] - heightmap[x, y] ) * 3 + Math.Abs( heightmap[x, y + 1] - heightmap[x, y] ) * 3 + Math.Abs( heightmap[x - 1, y] - heightmap[x, y] ) * 3 + Math.Abs( heightmap[x + 1, y] - heightmap[x, y] ) * 3 + Math.Abs( heightmap[x - 1, y - 1] - heightmap[x, y] ) * 2 + Math.Abs( heightmap[x + 1, y - 1] - heightmap[x, y] ) * 2 + Math.Abs( heightmap[x - 1, y + 1] - heightmap[x, y] ) * 2 + - Math.Abs( heightmap[x + 1, y + 1] - heightmap[x, y] ) * 2) / 20f; + Math.Abs( heightmap[x + 1, y + 1] - heightmap[x, y] ) * 2 ) / 20f; } } } @@ -497,57 +489,61 @@ public unsafe static void Invert( [NotNull] float[,] data ) { return output; } - - - const int ThresholdSearchPasses = 10; + private const int ThresholdSearchPasses = 10; public unsafe static float FindThreshold( [NotNull] float[,] data, float desiredCoverage ) { - if( data == null ) throw new ArgumentNullException( "data" ); - if( desiredCoverage == 0 ) return 0; - if( desiredCoverage == 1 ) return 1; + if ( data == null ) + throw new ArgumentNullException( "data" ); + if ( desiredCoverage == 0 ) + return 0; + if ( desiredCoverage == 1 ) + return 1; float threshold = 0.5f; - fixed( float* ptr = data ) { - for( int i = 0; i < ThresholdSearchPasses; i++ ) { + fixed ( float* ptr = data ) { + for ( int i = 0; i < ThresholdSearchPasses; i++ ) { float coverage = CalculateCoverage( ptr, data.Length, threshold ); - if( coverage > desiredCoverage ) { - threshold = threshold - 1 / (float)(4 << i); + if ( coverage > desiredCoverage ) { + threshold = threshold - 1 / ( float )( 4 << i ); } else { - threshold = threshold + 1 / (float)(4 << i); + threshold = threshold + 1 / ( float )( 4 << i ); } } } return threshold; } - - public unsafe static float FindThreshold( [NotNull] float[,,] data, float desiredCoverage ) { - if( data == null ) throw new ArgumentNullException( "data" ); - if( desiredCoverage == 0 ) return 0; - if( desiredCoverage == 1 ) return 1; + public unsafe static float FindThreshold( [NotNull] float[, ,] data, float desiredCoverage ) { + if ( data == null ) + throw new ArgumentNullException( "data" ); + if ( desiredCoverage == 0 ) + return 0; + if ( desiredCoverage == 1 ) + return 1; float threshold = 0.5f; - fixed( float* ptr = data ) { - for( int i = 0; i < ThresholdSearchPasses; i++ ) { + fixed ( float* ptr = data ) { + for ( int i = 0; i < ThresholdSearchPasses; i++ ) { float coverage = CalculateCoverage( ptr, data.Length, threshold ); - if( coverage > desiredCoverage ) { - threshold = threshold - 1 / (float)(4 << i); + if ( coverage > desiredCoverage ) { + threshold = threshold - 1 / ( float )( 4 << i ); } else { - threshold = threshold + 1 / (float)(4 << i); + threshold = threshold + 1 / ( float )( 4 << i ); } } } return threshold; } - public unsafe static float CalculateCoverage( [NotNull] float* data, int length, float threshold ) { - if( data == null ) throw new ArgumentNullException( "data" ); + if ( data == null ) + throw new ArgumentNullException( "data" ); int coveredVoxels = 0; float* end = data + length; - while( data < end ) { - if( *data < threshold ) coveredVoxels++; + while ( data < end ) { + if ( *data < threshold ) + coveredVoxels++; data++; } - return coveredVoxels / (float)length; + return coveredVoxels / ( float )length; } } } \ No newline at end of file diff --git a/fCraft/Utils/PathFinding.cs b/fCraft/Utils/PathFinding.cs index cb4eec6..1011688 100644 --- a/fCraft/Utils/PathFinding.cs +++ b/fCraft/Utils/PathFinding.cs @@ -1,78 +1,79 @@ -using System; -using System.Collections; -using System.Threading; - -namespace fCraft -{ - public class Bot - { - public string name { get; protected set; } - public Position pos; - public byte playerID { get; protected set; } - public byte heading { get; protected set; } - public byte pitch { get; protected set; } - - public delegate void BotSpawnHandler(Bot sender); - public event BotSpawnHandler Spawn; - - public delegate void BotMoveHandler(Bot player, Position dest, byte heading, byte pitch); - public event BotMoveHandler Move; - - public delegate void BotDisconnectHandler(Bot sender); - public event BotDisconnectHandler Disconnect; - - private double time; - private bool update; +namespace fCraft { + + public class Bot { + + public string name { get; protected set; } + + public Position pos; + + public byte playerID { get; protected set; } + + public byte heading { get; protected set; } + + public byte pitch { get; protected set; } + + public delegate void BotSpawnHandler( Bot sender ); + + public event BotSpawnHandler Spawn; + + public delegate void BotMoveHandler( Bot player, Position dest, byte heading, byte pitch ); + + public event BotMoveHandler Move; + + public delegate void BotDisconnectHandler( Bot sender ); + + public event BotDisconnectHandler Disconnect; + + private double time; + private bool update; public Map map; - public Bot(string name, Position Pos) - { - this.name = name; + public Bot( string name, Position Pos ) { + this.name = name; this.playerID = 1; pos = Pos; - heading = 0; - pitch = 0; - time = 0; - update = true; - } - - ~Bot() { - //Player.InUseIDs.Remove(playerID); - } - - public void Start() - { - if(Spawn != null) { - Spawn(this); - } - } - - public void Stop() - { - if(Disconnect != null) { - Disconnect(this); - } - } - - public void Update() - { - update = !update; - if(!update) return; - - time += 0.03 / 2; - if (time >= 6) { - time = 0; - } - - if (time < 3) { - pos.X += 1; - heading = 64; - } else if (time < 6) { - pos.X -= 1; - heading = 196; - } - - if(Move != null) Move(this, pos, heading, pitch); - } - } + heading = 0; + pitch = 0; + time = 0; + update = true; + } + + ~Bot() { + //Player.InUseIDs.Remove(playerID); + } + + public void Start() { + if ( Spawn != null ) { + Spawn( this ); + } + } + + public void Stop() { + if ( Disconnect != null ) { + Disconnect( this ); + } + } + + public void Update() { + update = !update; + if ( !update ) + return; + + time += 0.03 / 2; + if ( time >= 6 ) { + time = 0; + } + + if ( time < 3 ) { + pos.X += 1; + heading = 64; + } else if ( time < 6 ) { + pos.X -= 1; + heading = 196; + } + + if ( Move != null ) + Move( this, pos, heading, pitch ); + } + } } \ No newline at end of file diff --git a/fCraft/Utils/Paths.cs b/fCraft/Utils/Paths.cs index b5e38a4..e50cb11 100644 --- a/fCraft/Utils/Paths.cs +++ b/fCraft/Utils/Paths.cs @@ -7,16 +7,16 @@ using JetBrains.Annotations; namespace fCraft { + /// Contains fCraft path settings, and some filesystem-related utilities. public static class Paths { - - static readonly string[] ProtectedFiles; + private static readonly string[] ProtectedFiles; internal static readonly string[] DataFilesToBackup; static Paths() { string assemblyDir = Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location ); - if( assemblyDir != null ) { + if ( assemblyDir != null ) { WorkingPathDefault = Path.GetFullPath( assemblyDir ); } else { WorkingPathDefault = Path.GetPathRoot( assemblyDir ); @@ -58,7 +58,6 @@ static Paths() { }; } - #region Paths & Properties public static bool IgnoreMapPathConfigKey { get; internal set; } @@ -86,7 +85,6 @@ static Paths() { /// Can be overridden at startup via command-line argument "--config=" public static string ConfigFileName { get; set; } - public const string PlayerDBFileName = "PlayerDB.txt"; public const string IPBanListFileName = "ipbans.txt"; @@ -117,7 +115,6 @@ static Paths() { public const string PortalDBFileName = "PortalDB.txt"; public const string SwearWordsFileName = "SwearWords.txt"; - public static string BlockDBPath { get { return Path.Combine( WorkingPath, BlockDBDirectory ); } } @@ -126,19 +123,16 @@ public static string RulesPath { get { return Path.Combine( WorkingPath, RulesDirectory ); } } - public static string FontsPath - { - get { return Path.Combine(WorkingPath, FontsDirectory); } + public static string FontsPath { + get { return Path.Combine( WorkingPath, FontsDirectory ); } } - public static string ReqPath - { - get { return Path.Combine(WorkingPath, ReqDirectory); } + public static string ReqPath { + get { return Path.Combine( WorkingPath, ReqDirectory ); } } - public static string ReqTextPath - { - get { return Path.Combine(ReqDirectory, "requirements.txt"); } + public static string ReqTextPath { + get { return Path.Combine( ReqDirectory, "requirements.txt" ); } } /// Path where map backups are stored @@ -148,20 +142,20 @@ public static string BackupPath { } } - public const string DataBackupDirectory = "databackups"; public const string DataBackupFileNameFormat = "800CraftData_{0:yyyyMMdd'_'HH'-'mm'-'ss}.zip"; - #endregion - + #endregion Paths & Properties #region Utility Methods public static void MoveOrReplace( [NotNull] string source, [NotNull] string destination ) { - if( source == null ) throw new ArgumentNullException( "source" ); - if( destination == null ) throw new ArgumentNullException( "destination" ); - if( File.Exists( destination ) ) { - if( Path.GetPathRoot( Path.GetFullPath( source ) ) == Path.GetPathRoot( Path.GetFullPath( destination ) ) ) { + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( destination == null ) + throw new ArgumentNullException( "destination" ); + if ( File.Exists( destination ) ) { + if ( Path.GetPathRoot( Path.GetFullPath( source ) ) == Path.GetPathRoot( Path.GetFullPath( destination ) ) ) { string backupFileName = destination + ".bak"; File.Replace( source, destination, backupFileName, true ); File.Delete( backupFileName ); @@ -173,41 +167,41 @@ public static void MoveOrReplace( [NotNull] string source, [NotNull] string dest } } - /// Makes sure that the path format is valid, that it exists, that it is accessible and writeable. /// Name of the path that's being tested (e.g. "map path"). Used for logging. /// Full or partial path. /// If set, tries to write to the given directory. /// Full path of the directory (on success) or null (on failure). public static bool TestDirectory( [NotNull] string pathLabel, [NotNull] string path, bool checkForWriteAccess ) { - if( pathLabel == null ) throw new ArgumentNullException( "pathLabel" ); - if( path == null ) throw new ArgumentNullException( "path" ); + if ( pathLabel == null ) + throw new ArgumentNullException( "pathLabel" ); + if ( path == null ) + throw new ArgumentNullException( "path" ); try { - if( !Directory.Exists( path ) ) { + if ( !Directory.Exists( path ) ) { Directory.CreateDirectory( path ); } DirectoryInfo info = new DirectoryInfo( path ); - if( checkForWriteAccess ) { + if ( checkForWriteAccess ) { string randomFileName = Path.Combine( info.FullName, "800Craft_write_test_" + Guid.NewGuid() ); - using( File.Create( randomFileName ) ) { } + using ( File.Create( randomFileName ) ) { } File.Delete( randomFileName ); } return true; - - } catch( Exception ex ) { - if( ex is ArgumentException || ex is NotSupportedException || ex is PathTooLongException ) { + } catch ( Exception ex ) { + if ( ex is ArgumentException || ex is NotSupportedException || ex is PathTooLongException ) { Logger.Log( LogType.Error, "Paths.TestDirectory: Specified path for {0} is invalid or incorrectly formatted ({1}: {2}).", pathLabel, ex.GetType().Name, ex.Message ); - } else if( ex is SecurityException || ex is UnauthorizedAccessException ) { + } else if ( ex is SecurityException || ex is UnauthorizedAccessException ) { Logger.Log( LogType.Error, "Paths.TestDirectory: Cannot create or write to file/path for {0}, please check permissions ({1}: {2}).", pathLabel, ex.GetType().Name, ex.Message ); - } else if( ex is DirectoryNotFoundException ) { + } else if ( ex is DirectoryNotFoundException ) { Logger.Log( LogType.Error, "Paths.TestDirectory: Drive/volume for {0} does not exist or is not mounted ({1}: {2}).", pathLabel, ex.GetType().Name, ex.Message ); - } else if( ex is IOException ) { + } else if ( ex is IOException ) { Logger.Log( LogType.Error, "Paths.TestDirectory: Specified directory for {0} is not readable/writable ({1}: {2}).", pathLabel, ex.GetType().Name, ex.Message ); @@ -218,7 +212,6 @@ public static bool TestDirectory( [NotNull] string pathLabel, [NotNull] string p return false; } - /// Makes sure that the path format is valid, and optionally whether it is readable/writeable. /// Name of the path that's being tested (e.g. "map path"). Used for logging. /// Full or partial path of the file. @@ -229,36 +222,37 @@ public static bool TestDirectory( [NotNull] string pathLabel, [NotNull] string p /// Whether target file passed all tests. public static bool TestFile( [NotNull] string fileLabel, [NotNull] string filename, bool createIfDoesNotExist, FileAccess neededAccess ) { - if( fileLabel == null ) throw new ArgumentNullException( "fileLabel" ); - if( filename == null ) throw new ArgumentNullException( "filename" ); + if ( fileLabel == null ) + throw new ArgumentNullException( "fileLabel" ); + if ( filename == null ) + throw new ArgumentNullException( "filename" ); try { new FileInfo( filename ); - if( File.Exists( filename ) ) { - if( (neededAccess & FileAccess.Read) == FileAccess.Read ) { - using( File.OpenRead( filename ) ) { } + if ( File.Exists( filename ) ) { + if ( ( neededAccess & FileAccess.Read ) == FileAccess.Read ) { + using ( File.OpenRead( filename ) ) { } } - if( (neededAccess & FileAccess.Write) == FileAccess.Write ) { - using( File.OpenWrite( filename ) ) { } + if ( ( neededAccess & FileAccess.Write ) == FileAccess.Write ) { + using ( File.OpenWrite( filename ) ) { } } - } else if( createIfDoesNotExist ) { - using( File.Create( filename ) ) { } + } else if ( createIfDoesNotExist ) { + using ( File.Create( filename ) ) { } } return true; - - } catch( Exception ex ) { - if( ex is ArgumentException || ex is NotSupportedException || ex is PathTooLongException ) { + } catch ( Exception ex ) { + if ( ex is ArgumentException || ex is NotSupportedException || ex is PathTooLongException ) { Logger.Log( LogType.Error, "Paths.TestFile: Specified path for {0} is invalid or incorrectly formatted ({1}: {2}).", fileLabel, ex.GetType().Name, ex.Message ); - } else if( ex is SecurityException || ex is UnauthorizedAccessException ) { + } else if ( ex is SecurityException || ex is UnauthorizedAccessException ) { Logger.Log( LogType.Error, "Paths.TestFile: Cannot create or write to {0}, please check permissions ({1}: {2}).", fileLabel, ex.GetType().Name, ex.Message ); - } else if( ex is DirectoryNotFoundException ) { + } else if ( ex is DirectoryNotFoundException ) { Logger.Log( LogType.Error, "Paths.TestFile: Drive/volume for {0} does not exist or is not mounted ({1}: {2}).", fileLabel, ex.GetType().Name, ex.Message ); - } else if( ex is IOException ) { + } else if ( ex is IOException ) { Logger.Log( LogType.Error, "Paths.TestFile: Specified file for {0} is not readable/writable ({1}: {2}).", fileLabel, ex.GetType().Name, ex.Message ); @@ -269,120 +263,124 @@ public static bool TestFile( [NotNull] string fileLabel, [NotNull] string filena return false; } - public static bool IsDefaultMapPath( [CanBeNull] string path ) { return String.IsNullOrEmpty( path ) || Compare( MapPathDefault, path ); } - /// Returns true if paths or filenames reference the same location (accounts for all the filesystem quirks). public static bool Compare( [NotNull] string p1, [NotNull] string p2 ) { - if( p1 == null ) throw new ArgumentNullException( "p1" ); - if( p2 == null ) throw new ArgumentNullException( "p2" ); + if ( p1 == null ) + throw new ArgumentNullException( "p1" ); + if ( p2 == null ) + throw new ArgumentNullException( "p2" ); return Compare( p1, p2, MonoCompat.IsCaseSensitive ); } - /// Returns true if paths or filenames reference the same location (accounts for all the filesystem quirks). public static bool Compare( [NotNull] string p1, [NotNull] string p2, bool caseSensitive ) { - if( p1 == null ) throw new ArgumentNullException( "p1" ); - if( p2 == null ) throw new ArgumentNullException( "p2" ); - StringComparison sc = (caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase); + if ( p1 == null ) + throw new ArgumentNullException( "p1" ); + if ( p2 == null ) + throw new ArgumentNullException( "p2" ); + StringComparison sc = ( caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase ); return String.Equals( Path.GetFullPath( p1 ).TrimEnd( Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar ), Path.GetFullPath( p2 ).TrimEnd( Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar ), sc ); } - public static bool IsValidPath( string path ) { try { new FileInfo( path ); return true; - } catch( ArgumentException ) { - } catch( PathTooLongException ) { - } catch( NotSupportedException ) { + } catch ( ArgumentException ) { + } catch ( PathTooLongException ) { + } catch ( NotSupportedException ) { } return false; } - /// Checks whether childPath is inside parentPath /// Path that is supposed to contain childPath /// Path that is supposed to be contained within parentPath /// true if childPath is contained within parentPath public static bool Contains( [NotNull] string parentPath, [NotNull] string childPath ) { - if( parentPath == null ) throw new ArgumentNullException( "parentPath" ); - if( childPath == null ) throw new ArgumentNullException( "childPath" ); + if ( parentPath == null ) + throw new ArgumentNullException( "parentPath" ); + if ( childPath == null ) + throw new ArgumentNullException( "childPath" ); return Contains( parentPath, childPath, MonoCompat.IsCaseSensitive ); } - /// Checks whether childPath is inside parentPath /// Path that is supposed to contain childPath /// Path that is supposed to be contained within parentPath /// Whether check should be case-sensitive or case-insensitive. /// true if childPath is contained within parentPath public static bool Contains( [NotNull] string parentPath, [NotNull] string childPath, bool caseSensitive ) { - if( parentPath == null ) throw new ArgumentNullException( "parentPath" ); - if( childPath == null ) throw new ArgumentNullException( "childPath" ); + if ( parentPath == null ) + throw new ArgumentNullException( "parentPath" ); + if ( childPath == null ) + throw new ArgumentNullException( "childPath" ); string fullParentPath = Path.GetFullPath( parentPath ).TrimEnd( Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar ); string fullChildPath = Path.GetFullPath( childPath ).TrimEnd( Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar ); - StringComparison sc = (caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase); + StringComparison sc = ( caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase ); return fullChildPath.StartsWith( fullParentPath, sc ); } - /// Checks whether the file exists in a specified way (case-sensitive or case-insensitive) /// filename in question /// Whether check should be case-sensitive or case-insensitive. /// true if file exists, otherwise false public static bool FileExists( [NotNull] string fileName, bool caseSensitive ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); - if( caseSensitive == MonoCompat.IsCaseSensitive ) { + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + if ( caseSensitive == MonoCompat.IsCaseSensitive ) { return File.Exists( fileName ); } else { return new FileInfo( fileName ).Exists( caseSensitive ); } } - /// Checks whether the file exists in a specified way (case-sensitive or case-insensitive) /// FileInfo object in question /// Whether check should be case-sensitive or case-insensitive. /// true if file exists, otherwise false public static bool Exists( [NotNull] this FileInfo fileInfo, bool caseSensitive ) { - if( fileInfo == null ) throw new ArgumentNullException( "fileInfo" ); - if( caseSensitive == MonoCompat.IsCaseSensitive ) { + if ( fileInfo == null ) + throw new ArgumentNullException( "fileInfo" ); + if ( caseSensitive == MonoCompat.IsCaseSensitive ) { return fileInfo.Exists; } else { DirectoryInfo parentDir = fileInfo.Directory; - StringComparison sc = (caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase); + StringComparison sc = ( caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase ); return parentDir.GetFiles( "*", SearchOption.TopDirectoryOnly ) .Any( file => file.Name.Equals( fileInfo.Name, sc ) ); } } - /// Allows making changes to filename capitalization on case-insensitive filesystems. /// Full path to the original filename /// New file name (do not include the full path) public static void ForceRename( [NotNull] string originalFullFileName, [NotNull] string newFileName ) { - if( originalFullFileName == null ) throw new ArgumentNullException( "originalFullFileName" ); - if( newFileName == null ) throw new ArgumentNullException( "newFileName" ); + if ( originalFullFileName == null ) + throw new ArgumentNullException( "originalFullFileName" ); + if ( newFileName == null ) + throw new ArgumentNullException( "newFileName" ); FileInfo originalFile = new FileInfo( originalFullFileName ); - if( originalFile.Name == newFileName ) return; + if ( originalFile.Name == newFileName ) + return; FileInfo newFile = new FileInfo( Path.Combine( originalFile.DirectoryName, newFileName ) ); string tempFileName = originalFile.FullName + Guid.NewGuid(); MoveOrReplace( originalFile.FullName, tempFileName ); MoveOrReplace( tempFileName, newFile.FullName ); } - /// Find files that match the name in a case-insensitive way. /// Case-insensitive filename to look for. /// Array of matches. Empty array if no files matches. public static FileInfo[] FindFiles( [NotNull] string fullFileName ) { - if( fullFileName == null ) throw new ArgumentNullException( "fullFileName" ); + if ( fullFileName == null ) + throw new ArgumentNullException( "fullFileName" ); FileInfo fi = new FileInfo( fullFileName ); DirectoryInfo parentDir = fi.Directory; return parentDir.GetFiles( "*", SearchOption.TopDirectoryOnly ) @@ -390,12 +388,12 @@ public static FileInfo[] FindFiles( [NotNull] string fullFileName ) { .ToArray(); } - public static bool IsProtectedFileName( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); return ProtectedFiles.Any( t => Compare( t, fileName ) ); } - #endregion + #endregion Utility Methods } } \ No newline at end of file diff --git a/fCraft/Utils/PerlinNoise3D.cs b/fCraft/Utils/PerlinNoise3D.cs index 6dcae0d..5e73380 100644 --- a/fCraft/Utils/PerlinNoise3D.cs +++ b/fCraft/Utils/PerlinNoise3D.cs @@ -4,7 +4,6 @@ Microsoft Public License (Ms-PL) [OSI Approved License] - This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. @@ -32,27 +31,33 @@ 3. Conditions and Limitations using JetBrains.Annotations; namespace fCraft { + /// Implementation of 3D Perlin Noise after Ken Perlin's reference implementation. public sealed class PerlinNoise3D { + #region Fields private readonly int[] permutation, p; - #endregion + #endregion Fields #region Properties public float Frequency { get; set; } + public float Amplitude { get; set; } + public float Persistence { get; set; } + public int Octaves { get; set; } - #endregion + #endregion Properties #region Contructors public PerlinNoise3D( [NotNull] Random rand ) { - if( rand == null ) throw new ArgumentNullException( "rand" ); + if ( rand == null ) + throw new ArgumentNullException( "rand" ); permutation = new int[256]; p = new int[permutation.Length * 2]; InitNoiseFunctions( rand ); @@ -64,23 +69,24 @@ public PerlinNoise3D( [NotNull] Random rand ) { Octaves = 2; } - #endregion + #endregion Contructors #region Methods public void InitNoiseFunctions( [NotNull] Random rand ) { - if( rand == null ) throw new ArgumentNullException( "rand" ); + if ( rand == null ) + throw new ArgumentNullException( "rand" ); // Fill empty - for( int i = 0; i < permutation.Length; i++ ) { + for ( int i = 0; i < permutation.Length; i++ ) { permutation[i] = -1; } // Generate random numbers - for( int i = 0; i < permutation.Length; i++ ) { - while( true ) { + for ( int i = 0; i < permutation.Length; i++ ) { + while ( true ) { int iP = rand.Next() % permutation.Length; - if( permutation[iP] == -1 ) { + if ( permutation[iP] == -1 ) { permutation[iP] = i; break; } @@ -88,17 +94,16 @@ public void InitNoiseFunctions( [NotNull] Random rand ) { } // Copy - for( int i = 0; i < permutation.Length; i++ ) { + for ( int i = 0; i < permutation.Length; i++ ) { p[permutation.Length + i] = p[i] = permutation[i]; } } - public float Compute( float x, float y, float z ) { float noise = 0; float amp = Amplitude; float freq = Frequency; - for( int i = 0; i < Octaves; i++ ) { + for ( int i = 0; i < Octaves; i++ ) { noise += Noise( x * freq, y * freq, z * freq ) * amp; freq *= 2; // octave is the double of the previous frequency amp *= Persistence; @@ -106,17 +111,16 @@ public float Compute( float x, float y, float z ) { return noise; } - private float Noise( float x, float y, float z ) { // Find unit cube that contains point - int iX = (int)Math.Floor( x ) & 255; - int iY = (int)Math.Floor( y ) & 255; - int iZ = (int)Math.Floor( z ) & 255; + int iX = ( int )Math.Floor( x ) & 255; + int iY = ( int )Math.Floor( y ) & 255; + int iZ = ( int )Math.Floor( z ) & 255; // Find relative x, y, z of the point in the cube. - x -= (float)Math.Floor( x ); - y -= (float)Math.Floor( y ); - z -= (float)Math.Floor( z ); + x -= ( float )Math.Floor( x ); + y -= ( float )Math.Floor( y ); + z -= ( float )Math.Floor( z ); // Compute fade curves for each of x, y, z float u = Fade( x ); @@ -142,27 +146,24 @@ private float Noise( float x, float y, float z ) { Grad( p[bb + 1], x - 1, y - 1, z - 1 ) ) ) ); } - private static float Fade( float t ) { // Smooth interpolation parameter - return (t * t * t * (t * (t * 6 - 15) + 10)); + return ( t * t * t * ( t * ( t * 6 - 15 ) + 10 ) ); } - private static float Lerp( float alpha, float a, float b ) { // Linear interpolation - return (a + alpha * (b - a)); + return ( a + alpha * ( b - a ) ); } - private static float Grad( int hashCode, float x, float y, float z ) { // Convert lower 4 bits of hash code into 12 gradient directions int h = hashCode & 15; float u = h < 8 ? x : y; float v = h < 4 ? y : h == 12 || h == 14 ? x : z; - return (((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v)); + return ( ( ( h & 1 ) == 0 ? u : -u ) + ( ( h & 2 ) == 0 ? v : -v ) ); } - #endregion + #endregion Methods } } \ No newline at end of file diff --git a/fCraft/Utils/RWLSExtension.cs b/fCraft/Utils/RWLSExtension.cs index 87c4a38..0049299 100644 --- a/fCraft/Utils/RWLSExtension.cs +++ b/fCraft/Utils/RWLSExtension.cs @@ -3,28 +3,30 @@ using System.Threading; namespace fCraft { - static class RWLSExtension { - public static ReadLockHelper ReadLock ( this ReaderWriterLockSlim readerWriterLock ) { + + internal static class RWLSExtension { + + public static ReadLockHelper ReadLock( this ReaderWriterLockSlim readerWriterLock ) { return new ReadLockHelper( readerWriterLock ); } - public static UpgradeableReadLockHelper UpgradableReadLock ( this ReaderWriterLockSlim readerWriterLock ) { + public static UpgradeableReadLockHelper UpgradableReadLock( this ReaderWriterLockSlim readerWriterLock ) { return new UpgradeableReadLockHelper( readerWriterLock ); } - public static WriteLockHelper WriteLock ( this ReaderWriterLockSlim readerWriterLock ) { + public static WriteLockHelper WriteLock( this ReaderWriterLockSlim readerWriterLock ) { return new WriteLockHelper( readerWriterLock ); } public struct ReadLockHelper : IDisposable { private readonly ReaderWriterLockSlim readerWriterLock; - public ReadLockHelper ( ReaderWriterLockSlim readerWriterLock ) { + public ReadLockHelper( ReaderWriterLockSlim readerWriterLock ) { readerWriterLock.EnterReadLock(); this.readerWriterLock = readerWriterLock; } - public void Dispose () { + public void Dispose() { readerWriterLock.ExitReadLock(); } } @@ -32,12 +34,12 @@ public void Dispose () { public struct UpgradeableReadLockHelper : IDisposable { private readonly ReaderWriterLockSlim readerWriterLock; - public UpgradeableReadLockHelper ( ReaderWriterLockSlim readerWriterLock ) { + public UpgradeableReadLockHelper( ReaderWriterLockSlim readerWriterLock ) { readerWriterLock.EnterUpgradeableReadLock(); this.readerWriterLock = readerWriterLock; } - public void Dispose () { + public void Dispose() { readerWriterLock.ExitUpgradeableReadLock(); } } @@ -45,12 +47,12 @@ public void Dispose () { public struct WriteLockHelper : IDisposable { private readonly ReaderWriterLockSlim readerWriterLock; - public WriteLockHelper ( ReaderWriterLockSlim readerWriterLock ) { + public WriteLockHelper( ReaderWriterLockSlim readerWriterLock ) { readerWriterLock.EnterWriteLock(); this.readerWriterLock = readerWriterLock; } - public void Dispose () { + public void Dispose() { readerWriterLock.ExitWriteLock(); } } diff --git a/fCraft/Utils/Trie.cs b/fCraft/Utils/Trie.cs index 3f04365..5f64161 100644 --- a/fCraft/Utils/Trie.cs +++ b/fCraft/Utils/Trie.cs @@ -2,52 +2,52 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using System.Diagnostics; +using System.Linq; using System.Text; using JetBrains.Annotations; - // ReSharper disable MemberCanBePrivate.Local namespace fCraft { + /// Specialized data structure for partial-matching of large sparse sets of words. /// Used as a searchable index of players for PlayerDB. /// Payload type (reference types only). [DebuggerDisplay( "Count = {Count}" )] public sealed class Trie : IDictionary, IDictionary, ICloneable where T : class { - const byte LeafNode = 254, - MultiNode = 255; - const string InconsistentStateMessage = "Inconsistent state"; + private const byte LeafNode = 254, + MultiNode = 255; - TrieNode root = new TrieNode(); + private const string InconsistentStateMessage = "Inconsistent state"; - int version; + private TrieNode root = new TrieNode(); + private int version; /// Creates a new empty trie. - public Trie () { + public Trie() { Count = 0; keys = new TrieKeyCollection( this ); values = new TrieValueCollection( this ); } - /// Creates a new trie from an existing dictionary. Values are shallowly copied. /// Source dictionary to copy from. - public Trie ( [NotNull] IEnumerable> dictionary ) + public Trie( [NotNull] IEnumerable> dictionary ) : this() { - if ( dictionary == null ) throw new ArgumentNullException( "dictionary" ); + if ( dictionary == null ) + throw new ArgumentNullException( "dictionary" ); foreach ( var pair in dictionary ) { Add( pair.Key, pair.Value ); } } - // Find a node that exactly matches the given key [CanBeNull] - TrieNode GetNode ( [NotNull] string key ) { - if ( key == null ) throw new ArgumentNullException( "key" ); + private TrieNode GetNode( [NotNull] string key ) { + if ( key == null ) + throw new ArgumentNullException( "key" ); TrieNode temp = root; for ( int i = 0; i < key.Length; i++ ) { @@ -76,17 +76,16 @@ TrieNode GetNode ( [NotNull] string key ) { return temp; } - /// Checks whether the trie contains a given value. /// This method uses the value enumerator and runs in O(n). /// Value to search for. /// True if the trie contains at least one copy of the value. - public bool ContainsValue ( [NotNull] T value ) { - if ( value == null ) throw new ArgumentNullException( "value" ); + public bool ContainsValue( [NotNull] T value ) { + if ( value == null ) + throw new ArgumentNullException( "value" ); return Values.Contains( value ); } - /// Searches for payloads with keys that start with keyPart, returning just one or none of the matches. /// Partial or full key. /// Payload object to output (will be set to null if no single match was found). @@ -95,8 +94,9 @@ public bool ContainsValue ( [NotNull] T value ) { /// If one match was found, returns true and sets payload to the value. /// If more than one match was found, returns false and sets payload to null. /// - public bool GetOneMatch ( [NotNull] string keyPart, out T payload ) { - if ( keyPart == null ) throw new ArgumentNullException( "keyPart" ); + public bool GetOneMatch( [NotNull] string keyPart, out T payload ) { + if ( keyPart == null ) + throw new ArgumentNullException( "keyPart" ); TrieNode node = GetNode( keyPart ); if ( node == null ) { @@ -107,7 +107,6 @@ public bool GetOneMatch ( [NotNull] string keyPart, out T payload ) { if ( node.Payload != null ) { payload = node.Payload; return true; // exact match - } else if ( node.Tag == MultiNode ) { payload = null; return false; // multiple matches @@ -134,13 +133,13 @@ public bool GetOneMatch ( [NotNull] string keyPart, out T payload ) { } } - /// Finds a list of payloads with keys that start with keyPart, up to a specified limit. Autocompletes. /// Partial or full key. /// Limit on the number of payloads to find/return. /// List of matches (if there are no matches, length is zero). - public List GetList ( [NotNull] string keyPart, int limit ) { - if ( keyPart == null ) throw new ArgumentNullException( "keyPart" ); + public List GetList( [NotNull] string keyPart, int limit ) { + if ( keyPart == null ) + throw new ArgumentNullException( "keyPart" ); List results = new List(); TrieNode startingNode = GetNode( keyPart ); @@ -151,15 +150,16 @@ public List GetList ( [NotNull] string keyPart, int limit ) { return results; } - /// Adds a new object by key. /// Full key. /// Object associated with the key. /// Whether to overwrite the value in case this key already exists. /// True if object was added, false if an entry for this key already exists. - public bool Add ( [NotNull] string key, [NotNull] T payload, bool overwriteOnDuplicate ) { - if ( key == null ) throw new ArgumentNullException( "key" ); - if ( payload == null ) throw new ArgumentNullException( "payload" ); + public bool Add( [NotNull] string key, [NotNull] T payload, bool overwriteOnDuplicate ) { + if ( key == null ) + throw new ArgumentNullException( "key" ); + if ( payload == null ) + throw new ArgumentNullException( "payload" ); if ( key.Length == 0 ) { if ( root.Payload != null ) { @@ -218,13 +218,13 @@ public bool Add ( [NotNull] string key, [NotNull] T payload, bool overwriteOnDup } } - /// Get payload for an exact key (no autocompletion). /// Full key. /// Payload object, if found. Null if not found. [CanBeNull] - public T Get ( [NotNull] string key ) { - if ( key == null ) throw new ArgumentNullException( "key" ); + public T Get( [NotNull] string key ) { + if ( key == null ) + throw new ArgumentNullException( "key" ); TrieNode node = GetNode( key ); if ( node != null ) { return node.Payload; @@ -233,11 +233,10 @@ public T Get ( [NotNull] string key ) { } } - #region Key Encoding / Decoding // Decodes ASCII into internal letter code. - static int CharToCode ( char ch ) { + private static int CharToCode( char ch ) { if ( ch >= 'a' && ch <= 'z' ) return ch - 'a'; else if ( ch >= 'A' && ch <= 'Z' ) @@ -248,8 +247,7 @@ static int CharToCode ( char ch ) { return 36; } - - static char CodeToChar ( int code ) { + private static char CodeToChar( int code ) { if ( code < 26 ) return ( char )( code + 'a' ); if ( code >= 26 && code < 36 ) @@ -258,8 +256,7 @@ static char CodeToChar ( int code ) { return '_'; } - - static char CanonicizeChar ( char ch ) { + private static char CanonicizeChar( char ch ) { if ( ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9' || ch == '_' ) return ch; else if ( ch >= 'A' && ch <= 'Z' ) @@ -268,8 +265,7 @@ static char CanonicizeChar ( char ch ) { return '_'; } - - static string CanonicizeKey ( string key ) { + private static string CanonicizeKey( string key ) { StringBuilder sb = new StringBuilder( key ); for ( int i = 0; i < sb.Length; i++ ) { sb[i] = CanonicizeChar( sb[i] ); @@ -277,63 +273,56 @@ static string CanonicizeKey ( string key ) { return sb.ToString(); } - #endregion - + #endregion Key Encoding / Decoding #region Subset Enumerators /// Finds a subset of values whose keys start with a given prefix. /// Key prefix. /// Enumeration of values. - public IEnumerable ValuesStartingWith ( string prefix ) { + public IEnumerable ValuesStartingWith( string prefix ) { return values.StartingWith( prefix ); } - /// Finds a subset of keys that start with a given prefix. /// Key prefix. /// Enumeration of keys. - public IEnumerable KeysStartingWith ( string prefix ) { + public IEnumerable KeysStartingWith( string prefix ) { return keys.StartingWith( prefix ); } - /// Finds a subset of key/value pairs that start with a given prefix. /// Key prefix. /// Enumeration of key/value pairs. - public IEnumerable> StartingWith ( string prefix ) { + public IEnumerable> StartingWith( string prefix ) { return new TrieSubset( this, prefix ); } - /// A subset of trie's key/value pairs that start with a certain prefix. public sealed class TrieSubset : IEnumerable> { - readonly Trie trie; - readonly string prefix; + private readonly Trie trie; + private readonly string prefix; - public TrieSubset ( Trie trie, string prefix ) { + public TrieSubset( Trie trie, string prefix ) { this.trie = trie; this.prefix = prefix; } - - public IEnumerator> GetEnumerator () { + public IEnumerator> GetEnumerator() { TrieNode node = trie.GetNode( prefix ); return new TrieEnumerator( node, trie, CanonicizeKey( prefix ) ); } - - IEnumerator IEnumerable.GetEnumerator () { + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } - #endregion - + #endregion Subset Enumerators #region Enumerator Base - class EnumeratorBase { + private class EnumeratorBase { // Starting node ("root" of the trie/subtrie) protected readonly TrieNode StartingNode; @@ -354,16 +343,18 @@ class EnumeratorBase { protected readonly string BasePrefix; - // A couple stacks to keep track of our position in the trie protected readonly Stack Parents = new Stack(); - protected readonly Stack ParentIndices = new Stack(); + protected readonly Stack ParentIndices = new Stack(); - protected EnumeratorBase ( [NotNull] TrieNode node, [NotNull] Trie trie, [NotNull] string prefix ) { - if ( node == null ) throw new ArgumentNullException( "node" ); - if ( trie == null ) throw new ArgumentNullException( "trie" ); - if ( prefix == null ) throw new ArgumentNullException( "prefix" ); + protected EnumeratorBase( [NotNull] TrieNode node, [NotNull] Trie trie, [NotNull] string prefix ) { + if ( node == null ) + throw new ArgumentNullException( "node" ); + if ( trie == null ) + throw new ArgumentNullException( "trie" ); + if ( prefix == null ) + throw new ArgumentNullException( "prefix" ); StartingNode = node; BaseTrie = trie; BasePrefix = prefix; @@ -371,9 +362,9 @@ protected EnumeratorBase ( [NotNull] TrieNode node, [NotNull] Trie trie, [Not StartingVersion = BaseTrie.version; } - - protected bool MoveNextInternal () { - if ( StartingNode == null ) return false; + protected bool MoveNextInternal() { + if ( StartingNode == null ) + return false; if ( BaseTrie.version != StartingVersion ) { ThrowCollectionModifiedException(); } @@ -386,8 +377,7 @@ protected bool MoveNextInternal () { return FindNextPayload(); } - - protected void ResetInternal () { + protected void ResetInternal() { Parents.Clear(); ParentIndices.Clear(); CurrentNode = null; @@ -395,8 +385,7 @@ protected void ResetInternal () { CurrentKeyName = new StringBuilder( BasePrefix ); } - - protected bool FindNextPayload () { + protected bool FindNextPayload() { continueLoop: switch ( CurrentNode.Tag ) { case MultiNode: @@ -412,11 +401,13 @@ protected bool FindNextPayload () { CurrentIndex++; } } - if ( !MoveUp() ) return false; + if ( !MoveUp() ) + return false; goto continueLoop; case LeafNode: - if ( !MoveUp() ) return false; + if ( !MoveUp() ) + return false; goto continueLoop; default: @@ -426,16 +417,15 @@ protected bool FindNextPayload () { return true; } } else { - if ( !MoveUp() ) return false; + if ( !MoveUp() ) + return false; } goto continueLoop; - } } - // Pops the nearest parent from the stack (moving up the trie) - protected bool MoveUp () { + protected bool MoveUp() { if ( Parents.Count == 0 ) { return false; } else { @@ -446,9 +436,8 @@ protected bool MoveUp () { } } - // Pushes current node onto the stack, and makes the given node current. - protected void MoveDown ( TrieNode node, int index ) { + protected void MoveDown( TrieNode node, int index ) { CurrentKeyName.Append( CodeToChar( index ) ); Parents.Push( CurrentNode ); ParentIndices.Push( CurrentIndex + 1 ); @@ -456,45 +445,42 @@ protected void MoveDown ( TrieNode node, int index ) { CurrentIndex = 0; } - - protected static void ThrowCollectionModifiedException () { + protected static void ThrowCollectionModifiedException() { throw new InvalidOperationException( "Trie was modified since enumeration started." ); } } - #endregion - + #endregion Enumerator Base #region IDictionary Members - readonly TrieKeyCollection keys; + private readonly TrieKeyCollection keys; + public ICollection Keys { get { return keys; } } + private readonly TrieValueCollection values; - readonly TrieValueCollection values; public ICollection Values { get { return values; } } - /// Adds a new object by key. If an entry for this key already exists, it is NOT overwritten. /// Full key. /// Object associated with the key. /// True if object was added, false if an entry for this key already exists. - public void Add ( string key, T payload ) { + public void Add( string key, T payload ) { if ( !Add( key, payload, false ) ) { throw new ArgumentException( "Duplicate key.", "key" ); } } - /// Tries to get a value by full key. /// Full key to search for. /// Result. /// True of a value was found for this key. - public bool TryGetValue ( string key, out T result ) { + public bool TryGetValue( string key, out T result ) { TrieNode node = GetNode( key ); if ( node == null ) { result = null; @@ -505,7 +491,6 @@ public bool TryGetValue ( string key, out T result ) { } } - public T this[string key] { get { return Get( key ); @@ -515,23 +500,23 @@ public T this[string key] { } } - /// Checks whether the trie contains a given full key. /// Full key to search for. /// True if the trie contains a given key. - public bool ContainsKey ( string key ) { + public bool ContainsKey( string key ) { TrieNode node = GetNode( key ); return ( node != null && node.Payload != null ); } - /// Removes an entry by key. /// Key for the entry to remove. /// True if the entry was removed, false if no entry was found for this key. - public bool Remove ( string key ) { - if ( key == null ) throw new ArgumentNullException( "key" ); + public bool Remove( string key ) { + if ( key == null ) + throw new ArgumentNullException( "key" ); if ( key.Length == 0 ) { - if ( root.Payload == null ) return false; + if ( root.Payload == null ) + return false; root.Payload = null; Count--; version++; @@ -592,36 +577,31 @@ public bool Remove ( string key ) { return true; } - /// Removes all keys/values from the trie, making it empty. - public void Clear () { + public void Clear() { root = new TrieNode(); Count = 0; version = 0; } - #endregion - + #endregion IDictionary Members #region IDictionary Members public bool IsFixedSize { get { return false; } } - ICollection IDictionary.Values { get { return ( ICollection )Values; } } - ICollection IDictionary.Keys { get { return ( ICollection )Keys; } } - object IDictionary.this[object key] { get { if ( key == null ) { @@ -652,8 +632,7 @@ object IDictionary.this[object key] { } } - - void IDictionary.Remove ( object key ) { + void IDictionary.Remove( object key ) { if ( key == null ) { throw new ArgumentNullException( "key" ); } @@ -664,8 +643,7 @@ void IDictionary.Remove ( object key ) { Remove( castKey ); } - - void IDictionary.Add ( object key, [NotNull] object value ) { + void IDictionary.Add( object key, [NotNull] object value ) { if ( key == null ) { throw new ArgumentNullException( "key" ); } @@ -683,8 +661,7 @@ void IDictionary.Add ( object key, [NotNull] object value ) { Add( castKey, castValue ); } - - bool IDictionary.Contains ( object key ) { + bool IDictionary.Contains( object key ) { if ( key == null ) { throw new ArgumentNullException( "key" ); } @@ -696,19 +673,16 @@ bool IDictionary.Contains ( object key ) { return ContainsKey( castKey ); } - - IDictionaryEnumerator IDictionary.GetEnumerator () { + IDictionaryEnumerator IDictionary.GetEnumerator() { return new TrieDictionaryEnumerator( root, this, "" ); } + private sealed class TrieDictionaryEnumerator : EnumeratorBase, IDictionaryEnumerator { - sealed class TrieDictionaryEnumerator : EnumeratorBase, IDictionaryEnumerator { - - public TrieDictionaryEnumerator ( TrieNode node, Trie trie, string prefix ) + public TrieDictionaryEnumerator( TrieNode node, Trie trie, string prefix ) : base( node, trie, prefix ) { } - public object Key { get { if ( CurrentNode == null || CurrentNode.Payload == null ) { @@ -718,7 +692,6 @@ public object Key { } } - public object Value { get { if ( CurrentNode == null || CurrentNode.Payload == null ) { @@ -728,7 +701,6 @@ public object Value { } } - public DictionaryEntry Entry { get { if ( CurrentNode == null || CurrentNode.Payload == null ) { @@ -738,55 +710,48 @@ public DictionaryEntry Entry { } } - object IEnumerator.Current { get { return Entry; } } - - public bool MoveNext () { + public bool MoveNext() { return MoveNextInternal(); } - - public void Reset () { + public void Reset() { ResetInternal(); } } - #endregion - + #endregion IDictionary Members #region ValueCollection [DebuggerDisplay( "Count = {Count}" )] public sealed class TrieValueCollection : ICollection, ICollection { - readonly Trie trie; - + private readonly Trie trie; - public TrieValueCollection ( [NotNull] Trie trie ) { - if ( trie == null ) throw new ArgumentNullException( "trie" ); + public TrieValueCollection( [NotNull] Trie trie ) { + if ( trie == null ) + throw new ArgumentNullException( "trie" ); this.trie = trie; } - public int Count { get { return trie.Count; } } - public bool IsReadOnly { get { return true; } } - public bool IsSynchronized { get { return false; } } - public object SyncRoot { get { return trie.syncRoot; } } - - public void CopyTo ( Array array, int index ) { - if ( array == null ) throw new ArgumentNullException( "array" ); - if ( index < 0 || index > array.Length ) throw new ArgumentOutOfRangeException( "index" ); + public void CopyTo( Array array, int index ) { + if ( array == null ) + throw new ArgumentNullException( "array" ); + if ( index < 0 || index > array.Length ) + throw new ArgumentOutOfRangeException( "index" ); T[] castArray = array as T[]; if ( castArray == null ) { @@ -800,10 +765,11 @@ public void CopyTo ( Array array, int index ) { } } - - public void CopyTo ( T[] array, int index ) { - if ( array == null ) throw new ArgumentNullException( "array" ); - if ( index < 0 || index > array.Length ) throw new ArgumentOutOfRangeException( "index" ); + public void CopyTo( T[] array, int index ) { + if ( array == null ) + throw new ArgumentNullException( "array" ); + if ( index < 0 || index > array.Length ) + throw new ArgumentOutOfRangeException( "index" ); int i = index; foreach ( T element in this ) { @@ -812,82 +778,71 @@ public void CopyTo ( T[] array, int index ) { } } - - public bool Contains ( T value ) { + public bool Contains( T value ) { return ( this as IEnumerable ).Contains( value ); } - #region Unsupported members (Add/Remove/Clear) - const string ReadOnlyMessage = "Trie value collection is read-only"; - + private const string ReadOnlyMessage = "Trie value collection is read-only"; - public void Add ( T value ) { + public void Add( T value ) { throw new NotSupportedException( ReadOnlyMessage ); } - - public bool Remove ( T value ) { + public bool Remove( T value ) { throw new NotSupportedException( ReadOnlyMessage ); } - - public void Clear () { + public void Clear() { throw new NotSupportedException( ReadOnlyMessage ); } - #endregion - + #endregion Unsupported members (Add/Remove/Clear) - public IEnumerable StartingWith ( string prefix ) { + public IEnumerable StartingWith( string prefix ) { return new TrieValueSubset( trie, prefix ); } - public sealed class TrieValueSubset : IEnumerable { - readonly Trie trie; - readonly string prefix; - - public TrieValueSubset ( [NotNull] Trie trie, [NotNull] string prefix ) { - if ( trie == null ) throw new ArgumentNullException( "trie" ); - if ( prefix == null ) throw new ArgumentNullException( "prefix" ); + private readonly Trie trie; + private readonly string prefix; + + public TrieValueSubset( [NotNull] Trie trie, [NotNull] string prefix ) { + if ( trie == null ) + throw new ArgumentNullException( "trie" ); + if ( prefix == null ) + throw new ArgumentNullException( "prefix" ); this.trie = trie; this.prefix = prefix; } - - public IEnumerator GetEnumerator () { + public IEnumerator GetEnumerator() { TrieNode node = trie.GetNode( prefix ); return new TrieValueEnumerator( node, trie, CanonicizeKey( prefix ) ); } - - IEnumerator IEnumerable.GetEnumerator () { + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } - #region TrieValueEnumerator - public IEnumerator GetEnumerator () { + public IEnumerator GetEnumerator() { return new TrieValueEnumerator( trie.root, trie, "" ); } - - IEnumerator IEnumerable.GetEnumerator () { + IEnumerator IEnumerable.GetEnumerator() { return new TrieValueEnumerator( trie.root, trie, "" ); } + private sealed class TrieValueEnumerator : EnumeratorBase, IEnumerator { - sealed class TrieValueEnumerator : EnumeratorBase, IEnumerator { - - public TrieValueEnumerator ( TrieNode node, Trie trie, string prefix ) + public TrieValueEnumerator( TrieNode node, Trie trie, string prefix ) : base( node, trie, prefix ) { } - public T Current { get { if ( CurrentNode == null || CurrentNode.Payload == null ) { @@ -897,7 +852,6 @@ public T Current { } } - object IEnumerator.Current { get { if ( CurrentNode == null || CurrentNode.Payload == null ) { @@ -907,54 +861,48 @@ object IEnumerator.Current { } } - - public bool MoveNext () { + public bool MoveNext() { return MoveNextInternal(); } - - public void Reset () { + public void Reset() { ResetInternal(); } - - void IDisposable.Dispose () { } + void IDisposable.Dispose() { + } } - #endregion + #endregion TrieValueEnumerator } - #endregion - + #endregion ValueCollection #region KeyCollection [DebuggerDisplay( "Count = {Count}" )] public sealed class TrieKeyCollection : ICollection, ICollection { - readonly Trie trie; - + private readonly Trie trie; - public TrieKeyCollection ( [NotNull] Trie trie ) { - if ( trie == null ) throw new ArgumentNullException( "trie" ); + public TrieKeyCollection( [NotNull] Trie trie ) { + if ( trie == null ) + throw new ArgumentNullException( "trie" ); this.trie = trie; } - public int Count { get { return trie.Count; } } - public bool IsReadOnly { get { return true; } } - public bool IsSynchronized { get { return false; } } - public object SyncRoot { get { return trie.syncRoot; } } - - public void CopyTo ( Array array, int index ) { - if ( array == null ) throw new ArgumentNullException( "array" ); - if ( index < 0 || index > array.Length ) throw new ArgumentOutOfRangeException( "index" ); + public void CopyTo( Array array, int index ) { + if ( array == null ) + throw new ArgumentNullException( "array" ); + if ( index < 0 || index > array.Length ) + throw new ArgumentOutOfRangeException( "index" ); string[] castArray = array as string[]; if ( castArray == null ) { @@ -968,10 +916,11 @@ public void CopyTo ( Array array, int index ) { } } - - public void CopyTo ( string[] array, int index ) { - if ( array == null ) throw new ArgumentNullException( "array" ); - if ( index < 0 || index > array.Length ) throw new ArgumentOutOfRangeException( "index" ); + public void CopyTo( string[] array, int index ) { + if ( array == null ) + throw new ArgumentNullException( "array" ); + if ( index < 0 || index > array.Length ) + throw new ArgumentOutOfRangeException( "index" ); int i = index; foreach ( string element in this ) { @@ -980,82 +929,71 @@ public void CopyTo ( string[] array, int index ) { } } - - public bool Contains ( string value ) { + public bool Contains( string value ) { return trie.ContainsKey( value ); } - #region Unsupported members (Add/Remove/Clear) - const string ReadOnlyMessage = "Trie value collection is read-only"; - + private const string ReadOnlyMessage = "Trie value collection is read-only"; - public void Add ( string value ) { + public void Add( string value ) { throw new NotSupportedException( ReadOnlyMessage ); } - - public bool Remove ( string value ) { + public bool Remove( string value ) { throw new NotSupportedException( ReadOnlyMessage ); } - - public void Clear () { + public void Clear() { throw new NotSupportedException( ReadOnlyMessage ); } - #endregion - + #endregion Unsupported members (Add/Remove/Clear) - public IEnumerable StartingWith ( string prefix ) { + public IEnumerable StartingWith( string prefix ) { return new TrieKeySubset( trie, prefix ); } - public sealed class TrieKeySubset : IEnumerable { - readonly Trie trie; - readonly string prefix; - - public TrieKeySubset ( [NotNull] Trie trie, [NotNull] string prefix ) { - if ( trie == null ) throw new ArgumentNullException( "trie" ); - if ( prefix == null ) throw new ArgumentNullException( "prefix" ); + private readonly Trie trie; + private readonly string prefix; + + public TrieKeySubset( [NotNull] Trie trie, [NotNull] string prefix ) { + if ( trie == null ) + throw new ArgumentNullException( "trie" ); + if ( prefix == null ) + throw new ArgumentNullException( "prefix" ); this.trie = trie; this.prefix = prefix; } - - public IEnumerator GetEnumerator () { + public IEnumerator GetEnumerator() { TrieNode node = trie.GetNode( prefix ); return new TrieKeyEnumerator( node, trie, CanonicizeKey( prefix ) ); } - - IEnumerator IEnumerable.GetEnumerator () { + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } - #region TrieKeyEnumerator - public IEnumerator GetEnumerator () { + public IEnumerator GetEnumerator() { return new TrieKeyEnumerator( trie.root, trie, "" ); } - - IEnumerator IEnumerable.GetEnumerator () { + IEnumerator IEnumerable.GetEnumerator() { return new TrieKeyEnumerator( trie.root, trie, "" ); } + private sealed class TrieKeyEnumerator : EnumeratorBase, IEnumerator { - sealed class TrieKeyEnumerator : EnumeratorBase, IEnumerator { - - public TrieKeyEnumerator ( TrieNode node, Trie trie, string prefix ) + public TrieKeyEnumerator( TrieNode node, Trie trie, string prefix ) : base( node, trie, prefix ) { } - public string Current { get { if ( CurrentNode == null || CurrentNode.Payload == null ) { @@ -1065,52 +1003,45 @@ public string Current { } } - object IEnumerator.Current { get { return Current; } } - - public bool MoveNext () { + public bool MoveNext() { return MoveNextInternal(); } - - public void Reset () { + public void Reset() { ResetInternal(); } - - void IDisposable.Dispose () { } + void IDisposable.Dispose() { + } } - #endregion + #endregion TrieKeyEnumerator } - #endregion - + #endregion KeyCollection #region IEnumerable> Members - public IEnumerator> GetEnumerator () { + public IEnumerator> GetEnumerator() { return new TrieEnumerator( root, this, "" ); } - - IEnumerator IEnumerable.GetEnumerator () { + IEnumerator IEnumerable.GetEnumerator() { return new TrieEnumerator( root, this, "" ); } + private sealed class TrieEnumerator : EnumeratorBase, IEnumerator> { - sealed class TrieEnumerator : EnumeratorBase, IEnumerator> { - - public TrieEnumerator ( TrieNode node, Trie trie, string prefix ) + public TrieEnumerator( TrieNode node, Trie trie, string prefix ) : base( node, trie, prefix ) { } - public KeyValuePair Current { get { if ( CurrentNode == null || CurrentNode.Payload == null ) { @@ -1120,53 +1051,46 @@ public KeyValuePair Current { } } - object IEnumerator.Current { get { return Current; } } - - public bool MoveNext () { + public bool MoveNext() { return MoveNextInternal(); } - - public void Reset () { + public void Reset() { ResetInternal(); } - - void IDisposable.Dispose () { } + void IDisposable.Dispose() { + } } - #endregion - + #endregion IEnumerable> Members #region ICollection> Members - public int Count { get; private set; } - public bool IsReadOnly { get { return false; } } - - public void Add ( KeyValuePair pair ) { + public void Add( KeyValuePair pair ) { Add( pair.Key, pair.Value ); } - - public bool Contains ( KeyValuePair pair ) { + public bool Contains( KeyValuePair pair ) { TrieNode node = GetNode( pair.Key ); - if ( node == null ) return false; - if ( node.Payload == null ) return false; + if ( node == null ) + return false; + if ( node.Payload == null ) + return false; return node.Payload.Equals( pair.Value ); } - - public bool Remove ( KeyValuePair pair ) { + public bool Remove( KeyValuePair pair ) { if ( Contains( pair ) ) { return Remove( pair.Key ); } else { @@ -1174,10 +1098,11 @@ public bool Remove ( KeyValuePair pair ) { } } - - public void CopyTo ( KeyValuePair[] pairArray, int index ) { - if ( pairArray == null ) throw new ArgumentNullException( "pairArray" ); - if ( index < 0 || index > pairArray.Length ) throw new ArgumentOutOfRangeException( "index" ); + public void CopyTo( KeyValuePair[] pairArray, int index ) { + if ( pairArray == null ) + throw new ArgumentNullException( "pairArray" ); + if ( index < 0 || index > pairArray.Length ) + throw new ArgumentOutOfRangeException( "index" ); int i = index; foreach ( var pair in this ) { @@ -1186,21 +1111,21 @@ public void CopyTo ( KeyValuePair[] pairArray, int index ) { } } - #endregion - + #endregion ICollection> Members #region ICollection Members public bool IsSynchronized { get { return false; } } + private readonly object syncRoot = new object(); - readonly object syncRoot = new object(); public object SyncRoot { get { return syncRoot; } } - - public void CopyTo ( Array pairArray, int index ) { - if ( pairArray == null ) throw new ArgumentNullException( "pairArray" ); - if ( index < 0 || index > pairArray.Length ) throw new ArgumentOutOfRangeException( "index" ); + public void CopyTo( Array pairArray, int index ) { + if ( pairArray == null ) + throw new ArgumentNullException( "pairArray" ); + if ( index < 0 || index > pairArray.Length ) + throw new ArgumentOutOfRangeException( "index" ); var castPairArray = pairArray as KeyValuePair[]; if ( castPairArray == null ) { @@ -1214,22 +1139,18 @@ public void CopyTo ( Array pairArray, int index ) { } } - - #endregion - + #endregion ICollection Members #region ICloneable Members - public object Clone () { + public object Clone() { return new Trie( this ); } - #endregion - - - sealed class TrieNode { - const int ChildCount = 37; + #endregion ICloneable Members + private sealed class TrieNode { + private const int ChildCount = 37; // Tag identifies TrieNode as being either a LeafNode, // a MultiNode, or a single-child node. @@ -1244,8 +1165,7 @@ sealed class TrieNode { [CanBeNull] public T Payload; - - public void LeafToSingle ( byte charCode ) { + public void LeafToSingle( byte charCode ) { if ( Children != null || Tag != LeafNode ) { throw new Exception( InconsistentStateMessage ); } @@ -1253,8 +1173,7 @@ public void LeafToSingle ( byte charCode ) { Tag = charCode; } - - public void SingleToLeaf () { + public void SingleToLeaf() { if ( Children == null || Children.Length != 1 || Tag >= ChildCount ) { throw new Exception( InconsistentStateMessage ); } @@ -1264,8 +1183,7 @@ public void SingleToLeaf () { } } - - public void SingleToMulti () { + public void SingleToMulti() { if ( Children == null || Children.Length != 1 || Tag >= ChildCount ) { throw new Exception( InconsistentStateMessage ); } @@ -1275,8 +1193,7 @@ public void SingleToMulti () { Tag = MultiNode; } - - public void MultiToSingle () { + public void MultiToSingle() { if ( Children == null || Children.Length != ChildCount || Tag != MultiNode ) { throw new Exception( InconsistentStateMessage ); } @@ -1287,12 +1204,9 @@ public void MultiToSingle () { if ( Children[i] != null && Children[i].Tag == LeafNode && Children[i].Payload == null ) { - Children[i] = null; - } else if ( index != -1 ) { index = i; - } else { return; } @@ -1307,19 +1221,22 @@ public void MultiToSingle () { } } - - public bool GetAllChildren ( ICollection list, int limit ) { - if ( list.Count >= limit ) return false; + public bool GetAllChildren( ICollection list, int limit ) { + if ( list.Count >= limit ) + return false; if ( Payload != null ) { list.Add( Payload ); } - if ( Children == null ) return true; + if ( Children == null ) + return true; switch ( Tag ) { case MultiNode: for ( int i = 0; i < Children.Length; i++ ) { - if ( Children[i] == null ) continue; - if ( !Children[i].GetAllChildren( list, limit ) ) return false; + if ( Children[i] == null ) + continue; + if ( !Children[i].GetAllChildren( list, limit ) ) + return false; } return true; diff --git a/fCraft/Utils/Updater.cs b/fCraft/Utils/Updater.cs index 37f8f41..6cd18d0 100644 --- a/fCraft/Utils/Updater.cs +++ b/fCraft/Utils/Updater.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Net; using System.Net.Cache; @@ -10,9 +11,9 @@ using System.Xml.Linq; using fCraft.Events; using JetBrains.Annotations; -using System.IO; namespace fCraft { + /// Checks for updates, and keeps track of current version/revision. public static class Updater { @@ -35,17 +36,18 @@ public static string UserAgent { public static string UpdateUrl { get; set; } - static Updater () { + static Updater() { UpdateCheckTimeout = 4000; UpdateUrl = "http://au70.net/UpdateCheck.php?r={0}"; } + public static int WebVersion; public static string WebVersionFullString; public static string DownloadLocation; public static string UpdaterLocation; public static string Changelog; - public static bool UpdateCheck () { + public static bool UpdateCheck() { try { using ( WebClient client = new WebClient() ) { using ( Stream stream = client.OpenRead( "http://forums.au70.net/public/update.txt" ) ) { @@ -78,12 +80,14 @@ public static bool UpdateCheck () { public static int UpdateCheckTimeout { get; set; } - public static UpdaterResult CheckForUpdates () { + public static UpdaterResult CheckForUpdates() { UpdaterMode mode = ConfigKey.UpdaterMode.GetEnum(); - if ( mode == UpdaterMode.Disabled ) return UpdaterResult.NoUpdate; + if ( mode == UpdaterMode.Disabled ) + return UpdaterResult.NoUpdate; string url = String.Format( UpdateUrl, CurrentRelease.Revision ); - if ( RaiseCheckingForUpdatesEvent( ref url ) ) return UpdaterResult.NoUpdate; + if ( RaiseCheckingForUpdatesEvent( ref url ) ) + return UpdaterResult.NoUpdate; Logger.Log( LogType.SystemActivity, "Checking for 800Craft updates..." ); try { @@ -138,61 +142,63 @@ public static UpdaterResult CheckForUpdates () { } } - public static bool RunAtShutdown { get; set; } - #region Events /// Occurs when fCraft is about to check for updates (cancellable). /// The update Url may be overridden. public static event EventHandler CheckingForUpdates; - /// Occurs when fCraft has just checked for updates. public static event EventHandler CheckedForUpdates; - - static bool RaiseCheckingForUpdatesEvent ( ref string updateUrl ) { + private static bool RaiseCheckingForUpdatesEvent( ref string updateUrl ) { var h = CheckingForUpdates; - if ( h == null ) return false; + if ( h == null ) + return false; var e = new CheckingForUpdatesEventArgs( updateUrl ); h( null, e ); updateUrl = e.Url; return e.Cancel; } - - static void RaiseCheckedForUpdatesEvent ( string url, UpdaterResult result ) { + private static void RaiseCheckedForUpdatesEvent( string url, UpdaterResult result ) { var h = CheckedForUpdates; - if ( h != null ) h( null, new CheckedForUpdatesEventArgs( url, result ) ); + if ( h != null ) + h( null, new CheckedForUpdatesEventArgs( url, result ) ); } - #endregion + #endregion Events } - public sealed class UpdaterResult { + public static UpdaterResult NoUpdate { get { return new UpdaterResult( false, null, new ReleaseInfo[0] ); } } - internal UpdaterResult ( bool updateAvailable, Uri downloadUri, IEnumerable releases ) { + + internal UpdaterResult( bool updateAvailable, Uri downloadUri, IEnumerable releases ) { UpdateAvailable = updateAvailable; DownloadUri = downloadUri; History = releases.OrderByDescending( r => r.Revision ).ToArray(); LatestRelease = releases.FirstOrDefault(); } + public bool UpdateAvailable { get; private set; } + public Uri DownloadUri { get; private set; } + public ReleaseInfo[] History { get; private set; } + public ReleaseInfo LatestRelease { get; private set; } } - public sealed class ReleaseInfo { - internal ReleaseInfo ( int version, int revision, DateTime releaseDate, + + internal ReleaseInfo( int version, int revision, DateTime releaseDate, string summary, string changeLog, ReleaseFlags releaseType ) { Version = version; Revision = revision; @@ -239,38 +245,48 @@ public string VersionString { public string[] ChangeLog { get; private set; } - public static ReleaseFlags StringToReleaseFlags ( [NotNull] string str ) { - if ( str == null ) throw new ArgumentNullException( "str" ); + public static ReleaseFlags StringToReleaseFlags( [NotNull] string str ) { + if ( str == null ) + throw new ArgumentNullException( "str" ); ReleaseFlags flags = ReleaseFlags.None; for ( int i = 0; i < str.Length; i++ ) { switch ( Char.ToUpper( str[i] ) ) { case 'A': flags |= ReleaseFlags.APIChange; break; + case 'B': flags |= ReleaseFlags.Bugfix; break; + case 'C': flags |= ReleaseFlags.ConfigFormatChange; break; + case 'D': flags |= ReleaseFlags.Dev; break; + case 'F': flags |= ReleaseFlags.Feature; break; + case 'M': flags |= ReleaseFlags.MapFormatChange; break; + case 'P': flags |= ReleaseFlags.PlayerDBFormatChange; break; + case 'S': flags |= ReleaseFlags.Security; break; + case 'U': flags |= ReleaseFlags.Unstable; break; + case 'O': flags |= ReleaseFlags.Optimized; break; @@ -279,46 +295,66 @@ public static ReleaseFlags StringToReleaseFlags ( [NotNull] string str ) { return flags; } - public static string ReleaseFlagsToString ( ReleaseFlags flags ) { + public static string ReleaseFlagsToString( ReleaseFlags flags ) { StringBuilder sb = new StringBuilder(); - if ( ( flags & ReleaseFlags.APIChange ) == ReleaseFlags.APIChange ) sb.Append( 'A' ); - if ( ( flags & ReleaseFlags.Bugfix ) == ReleaseFlags.Bugfix ) sb.Append( 'B' ); - if ( ( flags & ReleaseFlags.ConfigFormatChange ) == ReleaseFlags.ConfigFormatChange ) sb.Append( 'C' ); - if ( ( flags & ReleaseFlags.Dev ) == ReleaseFlags.Dev ) sb.Append( 'D' ); - if ( ( flags & ReleaseFlags.Feature ) == ReleaseFlags.Feature ) sb.Append( 'F' ); - if ( ( flags & ReleaseFlags.MapFormatChange ) == ReleaseFlags.MapFormatChange ) sb.Append( 'M' ); - if ( ( flags & ReleaseFlags.PlayerDBFormatChange ) == ReleaseFlags.PlayerDBFormatChange ) sb.Append( 'P' ); - if ( ( flags & ReleaseFlags.Security ) == ReleaseFlags.Security ) sb.Append( 'S' ); - if ( ( flags & ReleaseFlags.Unstable ) == ReleaseFlags.Unstable ) sb.Append( 'U' ); - if ( ( flags & ReleaseFlags.Optimized ) == ReleaseFlags.Optimized ) sb.Append( 'O' ); + if ( ( flags & ReleaseFlags.APIChange ) == ReleaseFlags.APIChange ) + sb.Append( 'A' ); + if ( ( flags & ReleaseFlags.Bugfix ) == ReleaseFlags.Bugfix ) + sb.Append( 'B' ); + if ( ( flags & ReleaseFlags.ConfigFormatChange ) == ReleaseFlags.ConfigFormatChange ) + sb.Append( 'C' ); + if ( ( flags & ReleaseFlags.Dev ) == ReleaseFlags.Dev ) + sb.Append( 'D' ); + if ( ( flags & ReleaseFlags.Feature ) == ReleaseFlags.Feature ) + sb.Append( 'F' ); + if ( ( flags & ReleaseFlags.MapFormatChange ) == ReleaseFlags.MapFormatChange ) + sb.Append( 'M' ); + if ( ( flags & ReleaseFlags.PlayerDBFormatChange ) == ReleaseFlags.PlayerDBFormatChange ) + sb.Append( 'P' ); + if ( ( flags & ReleaseFlags.Security ) == ReleaseFlags.Security ) + sb.Append( 'S' ); + if ( ( flags & ReleaseFlags.Unstable ) == ReleaseFlags.Unstable ) + sb.Append( 'U' ); + if ( ( flags & ReleaseFlags.Optimized ) == ReleaseFlags.Optimized ) + sb.Append( 'O' ); return sb.ToString(); } - public static string[] ReleaseFlagsToStringArray ( ReleaseFlags flags ) { + public static string[] ReleaseFlagsToStringArray( ReleaseFlags flags ) { List list = new List(); - if ( ( flags & ReleaseFlags.APIChange ) == ReleaseFlags.APIChange ) list.Add( "API Changes" ); - if ( ( flags & ReleaseFlags.Bugfix ) == ReleaseFlags.Bugfix ) list.Add( "Fixes" ); - if ( ( flags & ReleaseFlags.ConfigFormatChange ) == ReleaseFlags.ConfigFormatChange ) list.Add( "Config Changes" ); - if ( ( flags & ReleaseFlags.Dev ) == ReleaseFlags.Dev ) list.Add( "Developer" ); - if ( ( flags & ReleaseFlags.Feature ) == ReleaseFlags.Feature ) list.Add( "New Features" ); - if ( ( flags & ReleaseFlags.MapFormatChange ) == ReleaseFlags.MapFormatChange ) list.Add( "Map Format Changes" ); - if ( ( flags & ReleaseFlags.PlayerDBFormatChange ) == ReleaseFlags.PlayerDBFormatChange ) list.Add( "PlayerDB Changes" ); - if ( ( flags & ReleaseFlags.Security ) == ReleaseFlags.Security ) list.Add( "Security Patch" ); - if ( ( flags & ReleaseFlags.Unstable ) == ReleaseFlags.Unstable ) list.Add( "Unstable" ); - if ( ( flags & ReleaseFlags.Optimized ) == ReleaseFlags.Optimized ) list.Add( "Optimized" ); + if ( ( flags & ReleaseFlags.APIChange ) == ReleaseFlags.APIChange ) + list.Add( "API Changes" ); + if ( ( flags & ReleaseFlags.Bugfix ) == ReleaseFlags.Bugfix ) + list.Add( "Fixes" ); + if ( ( flags & ReleaseFlags.ConfigFormatChange ) == ReleaseFlags.ConfigFormatChange ) + list.Add( "Config Changes" ); + if ( ( flags & ReleaseFlags.Dev ) == ReleaseFlags.Dev ) + list.Add( "Developer" ); + if ( ( flags & ReleaseFlags.Feature ) == ReleaseFlags.Feature ) + list.Add( "New Features" ); + if ( ( flags & ReleaseFlags.MapFormatChange ) == ReleaseFlags.MapFormatChange ) + list.Add( "Map Format Changes" ); + if ( ( flags & ReleaseFlags.PlayerDBFormatChange ) == ReleaseFlags.PlayerDBFormatChange ) + list.Add( "PlayerDB Changes" ); + if ( ( flags & ReleaseFlags.Security ) == ReleaseFlags.Security ) + list.Add( "Security Patch" ); + if ( ( flags & ReleaseFlags.Unstable ) == ReleaseFlags.Unstable ) + list.Add( "Unstable" ); + if ( ( flags & ReleaseFlags.Optimized ) == ReleaseFlags.Optimized ) + list.Add( "Optimized" ); return list.ToArray(); } - public bool IsFlagged ( ReleaseFlags flag ) { + public bool IsFlagged( ReleaseFlags flag ) { return ( Flags & flag ) == flag; } } - #region Enums /// Updater behavior. public enum UpdaterMode { + /// Does not check for updates. Disabled, @@ -336,7 +372,6 @@ public enum UpdaterMode { Auto, } - /// A list of release flags/attributes. /// Use binary flag logic (value & flag == flag) or Release.IsFlagged() to test for flags. [Flags] @@ -375,28 +410,31 @@ public enum ReleaseFlags { Optimized = 512 } - #endregion + #endregion Enums } - namespace fCraft.Events { + public sealed class CheckingForUpdatesEventArgs : EventArgs, ICancellableEvent { - internal CheckingForUpdatesEventArgs ( string url ) { + + internal CheckingForUpdatesEventArgs( string url ) { Url = url; } public string Url { get; set; } + public bool Cancel { get; set; } } - public sealed class CheckedForUpdatesEventArgs : EventArgs { - internal CheckedForUpdatesEventArgs ( string url, UpdaterResult result ) { + + internal CheckedForUpdatesEventArgs( string url, UpdaterResult result ) { Url = url; Result = result; } public string Url { get; private set; } + public UpdaterResult Result { get; private set; } } } \ No newline at end of file diff --git a/fCraft/Utils/Vector3F.cs b/fCraft/Utils/Vector3F.cs index 089a9b6..93460f8 100644 --- a/fCraft/Utils/Vector3F.cs +++ b/fCraft/Utils/Vector3F.cs @@ -4,6 +4,7 @@ using fCraft.Drawing; namespace fCraft { + /// Floating-point (single precision) 3D vector. public struct Vector3F : IEquatable, IComparable, IComparable { public static readonly Vector3F Zero = new Vector3F( 0, 0, 0 ); @@ -11,10 +12,12 @@ public struct Vector3F : IEquatable, IComparable, IComparabl public static readonly Vector3F Down = new Vector3F( 0, 0, -1 ); public float X, Y, Z; + public float X2 { get { return X * X; } } + public float Y2 { get { return Y * Y; } } - public float Z2 { get { return Z * Z; } } + public float Z2 { get { return Z * Z; } } public Vector3F( float x, float y, float z ) { X = x; @@ -34,10 +37,9 @@ public Vector3F( Vector3I other ) { Z = other.Z; } - public float Length { get { - return (float)Math.Sqrt( X * X + Y * Y + Z * Z ); + return ( float )Math.Sqrt( X * X + Y * Y + Z * Z ); } } @@ -47,43 +49,62 @@ public float LengthSquared { } } - public float this[int i] { get { - switch( i ) { - case 0: return X; - case 1: return Y; - default: return Z; + switch ( i ) { + case 0: + return X; + case 1: + return Y; + default: + return Z; } } set { - switch( i ) { - case 0: X = value; return; - case 1: Y = value; return; - default: Z = value; return; + switch ( i ) { + case 0: + X = value; + return; + + case 1: + Y = value; + return; + + default: + Z = value; + return; } } } - public float this[Axis i] { get { - switch( i ) { - case Axis.X: return X; - case Axis.Y: return Y; - default: return Z; + switch ( i ) { + case Axis.X: + return X; + case Axis.Y: + return Y; + default: + return Z; } } set { - switch( i ) { - case Axis.X: X = value; return; - case Axis.Y: Y = value; return; - default: Z = value; return; + switch ( i ) { + case Axis.X: + X = value; + return; + + case Axis.Y: + Y = value; + return; + + default: + Z = value; + return; } } } - #region Operators public static Vector3F operator +( Vector3F a, Vector3F b ) { @@ -98,7 +119,6 @@ public float this[Axis i] { return new Vector3F( a.X + b.X, a.Y + b.Y, a.Z + b.Z ); } - public static Vector3F operator -( Vector3F a, Vector3F b ) { return new Vector3F( a.X - b.X, a.Y - b.Y, a.Z - b.Z ); } @@ -111,7 +131,6 @@ public float this[Axis i] { return new Vector3F( a.X - b.X, a.Y - b.Y, a.Z - b.Z ); } - public static Vector3F operator *( Vector3F a, float scalar ) { return new Vector3F( a.X * scalar, a.Y * scalar, a.Z * scalar ); } @@ -124,14 +143,13 @@ public float this[Axis i] { return new Vector3F( a.X / scalar, a.Y / scalar, a.Z / scalar ); } - #endregion - + #endregion Operators #region Equality public override bool Equals( object obj ) { - if( obj is Vector3F ) { - return Equals( (Vector3F)obj ); + if ( obj is Vector3F ) { + return Equals( ( Vector3F )obj ); } else { return base.Equals( obj ); } @@ -141,7 +159,6 @@ public bool Equals( Vector3F other ) { return ( X == other.X ) && ( Y == other.Y ) && ( Z == other.Z ); } - public static bool operator ==( Vector3F a, Vector3F b ) { return a.Equals( b ); } @@ -150,13 +167,11 @@ public bool Equals( Vector3F other ) { return !a.Equals( b ); } - public override int GetHashCode() { - return (int)( X + Y * 1625 + Z * 2642245 ); + return ( int )( X + Y * 1625 + Z * 2642245 ); } - #endregion - + #endregion Equality #region Comparison @@ -168,7 +183,6 @@ public int CompareTo( Vector3F other ) { return Math.Sign( LengthSquared - LengthSquared ); } - public static bool operator >( Vector3F a, Vector3F b ) { return a.LengthSquared > b.LengthSquared; } @@ -185,8 +199,7 @@ public int CompareTo( Vector3F other ) { return a.LengthSquared <= b.LengthSquared; } - #endregion - + #endregion Comparison public float Dot( Vector3I b ) { return ( X * b.X ) + ( Y * b.Y ) + ( Z * b.Z ); @@ -208,12 +221,13 @@ public Vector3F Cross( Vector3F b ) { ( X * b.Y ) - ( Y * b.X ) ); } - public Axis LongestComponent { get { float maxVal = Math.Max( Math.Abs( X ), Math.Max( Math.Abs( Y ), Math.Abs( Z ) ) ); - if( maxVal == Math.Abs( X ) ) return Axis.X; - if( maxVal == Math.Abs( Y ) ) return Axis.Y; + if ( maxVal == Math.Abs( X ) ) + return Axis.X; + if ( maxVal == Math.Abs( Y ) ) + return Axis.Y; return Axis.Z; } } @@ -221,8 +235,10 @@ public Axis LongestComponent { public Axis ShortestComponent { get { float minVal = Math.Min( Math.Abs( X ), Math.Min( Math.Abs( Y ), Math.Abs( Z ) ) ); - if( minVal == Math.Abs( X ) ) return Axis.X; - if( minVal == Math.Abs( Y ) ) return Axis.Y; + if ( minVal == Math.Abs( X ) ) + return Axis.X; + if ( minVal == Math.Abs( Y ) ) + return Axis.Y; return Axis.Z; } } @@ -232,38 +248,38 @@ public Vector3F Abs() { } public Vector3F Normalize() { - if( X == 0 && Y == 0 && Z == 0 ) return Zero; - double len = Math.Sqrt( (double)X * X + (double)Y * Y + (double)Z * Z ); - return new Vector3F( (float)(X / len), (float)(Y / len), (float)(Z / len) ); + if ( X == 0 && Y == 0 && Z == 0 ) + return Zero; + double len = Math.Sqrt( ( double )X * X + ( double )Y * Y + ( double )Z * Z ); + return new Vector3F( ( float )( X / len ), ( float )( Y / len ), ( float )( Z / len ) ); } public override string ToString() { return String.Format( "({0},{1},{2})", X, Y, Z ); } - #region Conversion public static explicit operator Vector3I( Vector3F a ) { - return new Vector3I( (int)a.X, (int)a.Y, (int)a.Z ); + return new Vector3I( ( int )a.X, ( int )a.Y, ( int )a.Z ); } public Vector3I Round() { - return new Vector3I( (int)Math.Round( X ), (int)Math.Round( Y ), (int)Math.Round( Z ) ); + return new Vector3I( ( int )Math.Round( X ), ( int )Math.Round( Y ), ( int )Math.Round( Z ) ); } public Vector3I RoundDown() { - return new Vector3I( (int)Math.Floor( X ), (int)Math.Floor( Y ), (int)Math.Floor( Z ) ); + return new Vector3I( ( int )Math.Floor( X ), ( int )Math.Floor( Y ), ( int )Math.Floor( Z ) ); } public Vector3I RoundUp() { - return new Vector3I( (int)Math.Ceiling( X ), (int)Math.Ceiling( Y ), (int)Math.Ceiling( Z ) ); + return new Vector3I( ( int )Math.Ceiling( X ), ( int )Math.Ceiling( Y ), ( int )Math.Ceiling( Z ) ); } public Position ToPlayerCoords() { - return new Position( (int)(X * 32), (int)(Y * 32), (int)(Z * 32) ); + return new Position( ( int )( X * 32 ), ( int )( Y * 32 ), ( int )( Z * 32 ) ); } - #endregion + #endregion Conversion } } \ No newline at end of file diff --git a/fCraft/Utils/Vector3I.cs b/fCraft/Utils/Vector3I.cs index 560f9b9..26dcbd7 100644 --- a/fCraft/Utils/Vector3I.cs +++ b/fCraft/Utils/Vector3I.cs @@ -4,6 +4,7 @@ using fCraft.Drawing; namespace fCraft { + /// Integer 3D vector. public struct Vector3I : IEquatable, IComparable, IComparable { public static readonly Vector3I Zero = new Vector3I( 0, 0, 0 ); @@ -11,8 +12,11 @@ public struct Vector3I : IEquatable, IComparable, IComparabl public static readonly Vector3I Down = new Vector3I( 0, 0, -1 ); public int X, Y, Z; + public int X2 { get { return X * X; } } + public int Y2 { get { return Y * Y; } } + public int Z2 { get { return Z * Z; } } public Vector3I( int x, int y, int z ) { @@ -28,15 +32,14 @@ public Vector3I( Vector3I other ) { } public Vector3I( Vector3F other ) { - X = (int)other.X; - Y = (int)other.Y; - Z = (int)other.Z; + X = ( int )other.X; + Y = ( int )other.Y; + Z = ( int )other.Z; } - public float Length { get { - return (float)Math.Sqrt( (double)X * X + (double)Y * Y + (double)Z * Z ); + return ( float )Math.Sqrt( ( double )X * X + ( double )Y * Y + ( double )Z * Z ); } } @@ -46,54 +49,72 @@ public int LengthSquared { } } - public int this[int i] { get { - switch( i ) { - case 0: return X; - case 1: return Y; - default: return Z; + switch ( i ) { + case 0: + return X; + case 1: + return Y; + default: + return Z; } } set { - switch( i ) { - case 0: X = value; return; - case 1: Y = value; return; - default: Z = value; return; + switch ( i ) { + case 0: + X = value; + return; + + case 1: + Y = value; + return; + + default: + Z = value; + return; } } } public int this[Axis i] { get { - switch( i ) { - case Axis.X: return X; - case Axis.Y: return Y; - default: return Z; + switch ( i ) { + case Axis.X: + return X; + case Axis.Y: + return Y; + default: + return Z; } } set { - switch( i ) { - case Axis.X: X = value; return; - case Axis.Y: Y = value; return; - default: Z = value; return; + switch ( i ) { + case Axis.X: + X = value; + return; + + case Axis.Y: + Y = value; + return; + + default: + Z = value; + return; } } } - #region Operations public static Vector3I operator +( Vector3I a, Vector3I b ) { return new Vector3I( a.X + b.X, a.Y + b.Y, a.Z + b.Z ); } - public static Vector3I operator -( Vector3I a, Vector3I b ) { return new Vector3I( a.X - b.X, a.Y - b.Y, a.Z - b.Z ); } - public static Vector3I operator *( Vector3I a, int scalar ) { return new Vector3I( a.X * scalar, a.Y * scalar, a.Z * scalar ); } @@ -110,7 +131,6 @@ public int this[Axis i] { return new Vector3F( a.X * scalar, a.Y * scalar, a.Z * scalar ); } - /// Integer division! public static Vector3I operator /( Vector3I a, int scalar ) { return new Vector3I( a.X / scalar, a.Y / scalar, a.Z / scalar ); @@ -120,25 +140,22 @@ public int this[Axis i] { return new Vector3F( a.X / scalar, a.Y / scalar, a.Z / scalar ); } - - #endregion - + #endregion Operations #region Equality public override bool Equals( object obj ) { - if( obj is Vector3I ) { - return Equals( (Vector3I)obj ); + if ( obj is Vector3I ) { + return Equals( ( Vector3I )obj ); } else { return base.Equals( obj ); } } public bool Equals( Vector3I other ) { - return (X == other.X) && (Y == other.Y) && (Z == other.Z); + return ( X == other.X ) && ( Y == other.Y ) && ( Z == other.Z ); } - public static bool operator ==( Vector3I a, Vector3I b ) { return a.Equals( b ); } @@ -147,13 +164,11 @@ public bool Equals( Vector3I other ) { return !a.Equals( b ); } - public override int GetHashCode() { return X + Z * 1625 + Y * 2642245; } - #endregion - + #endregion Equality #region Comparison @@ -165,7 +180,6 @@ public int CompareTo( Vector3F other ) { return Math.Sign( LengthSquared - other.LengthSquared ); } - public static bool operator >( Vector3I a, Vector3I b ) { return a.LengthSquared > b.LengthSquared; } @@ -182,35 +196,35 @@ public int CompareTo( Vector3F other ) { return a.LengthSquared <= b.LengthSquared; } - #endregion - + #endregion Comparison public int Dot( Vector3I b ) { - return (X * b.X) + (Y * b.Y) + (Z * b.Z); + return ( X * b.X ) + ( Y * b.Y ) + ( Z * b.Z ); } public float Dot( Vector3F b ) { - return (X * b.X) + (Y * b.Y) + (Z * b.Z); + return ( X * b.X ) + ( Y * b.Y ) + ( Z * b.Z ); } public Vector3I Cross( Vector3I b ) { - return new Vector3I( (Y * b.Z) - (Z * b.Y), - (Z * b.X) - (X * b.Z), - (X * b.Y) - (Y * b.X) ); + return new Vector3I( ( Y * b.Z ) - ( Z * b.Y ), + ( Z * b.X ) - ( X * b.Z ), + ( X * b.Y ) - ( Y * b.X ) ); } public Vector3F Cross( Vector3F b ) { - return new Vector3F( (Y * b.Z) - (Z * b.Y), - (Z * b.X) - (X * b.Z), - (X * b.Y) - (Y * b.X) ); + return new Vector3F( ( Y * b.Z ) - ( Z * b.Y ), + ( Z * b.X ) - ( X * b.Z ), + ( X * b.Y ) - ( Y * b.X ) ); } - public Axis LongestAxis { get { int maxVal = Math.Max( Math.Abs( X ), Math.Max( Math.Abs( Y ), Math.Abs( Z ) ) ); - if( maxVal == Math.Abs( X ) ) return Axis.X; - if( maxVal == Math.Abs( Y ) ) return Axis.Y; + if ( maxVal == Math.Abs( X ) ) + return Axis.X; + if ( maxVal == Math.Abs( Y ) ) + return Axis.Y; return Axis.Z; } } @@ -218,13 +232,14 @@ public Axis LongestAxis { public Axis ShortestAxis { get { int maxVal = Math.Min( Math.Abs( X ), Math.Min( Math.Abs( Y ), Math.Abs( Z ) ) ); - if( maxVal == Math.Abs( X ) ) return Axis.X; - if( maxVal == Math.Abs( Y ) ) return Axis.Y; + if ( maxVal == Math.Abs( X ) ) + return Axis.X; + if ( maxVal == Math.Abs( Y ) ) + return Axis.Y; return Axis.Z; } } - public override string ToString() { return String.Format( "({0},{1},{2})", X, Y, Z ); } @@ -234,12 +249,12 @@ public Vector3I Abs() { } public Vector3F Normalize() { - if( X == 0 && Y == 0 && Z == 0 ) return Vector3F.Zero; + if ( X == 0 && Y == 0 && Z == 0 ) + return Vector3F.Zero; float len = Length; return new Vector3F( X / len, Y / len, Z / len ); } - #region Conversion public static explicit operator Position( Vector3I a ) { @@ -254,6 +269,6 @@ public Position ToPlayerCoords() { return new Position( X * 32 + 16, Y * 32 + 16, Z * 32 + 16 ); } - #endregion + #endregion Conversion } } \ No newline at end of file diff --git a/fCraft/Utils/YesNoAuto.cs b/fCraft/Utils/YesNoAuto.cs index 6bceec6..7347a7a 100644 --- a/fCraft/Utils/YesNoAuto.cs +++ b/fCraft/Utils/YesNoAuto.cs @@ -1,6 +1,7 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft { + public enum YesNoAuto { Auto, Yes, diff --git a/fCraft/Utils/ZipStorer.cs b/fCraft/Utils/ZipStorer.cs index 8db0a51..20f6756 100644 --- a/fCraft/Utils/ZipStorer.cs +++ b/fCraft/Utils/ZipStorer.cs @@ -6,44 +6,58 @@ using JetBrains.Annotations; namespace System.IO.Compression { + /// /// Unique class for compression/decompression file. Represents a Zip file. /// public sealed class ZipStorer : IDisposable { + /// Compression method enumeration. public enum Compression : ushort { - /// Uncompressed storage + + /// Uncompressed storage Store = 0, + /// Deflate compression method Deflate = 8 } /// Represents an entry in Zip file directory. public struct ZipFileEntry { + /// Compression method public Compression Method; + /// Full path and filename as stored in Zip public string FilenameInZip; + /// Original file size public uint FileSize; + /// Compressed file size public uint CompressedSize; + /// Offset of header information inside Zip storage public uint HeaderOffset; + /// Offset of file inside Zip storage public uint FileOffset; // ReSharper disable UnaccessedField.Global /// Size of header information public uint HeaderSize; + // ReSharper restore UnaccessedField.Global /// 32-bit checksum of entire file public uint Crc32; + /// Last modification time of file public DateTime ModifyTime; + /// User comment for file public string Comment; + /// True if UTF8 encoding for filename and comments, false if default (CP 437) public bool EncodeUTF8; @@ -55,43 +69,57 @@ public override string ToString() { } #region Public fields + /// True if UTF8 encoding for filename and comments, false if default (CP 437) public bool EncodeUTF8 { get; set; } + /// Force deflate algotithm even if it inflates the stored file. Off by default. public bool ForceDeflating { get; set; } - #endregion + + #endregion Public fields #region Private fields + // List of files to store private readonly List files = new List(); + // Filename of storage file private string fileName; + // Stream object of storage file private Stream zipFileStream; + // General comment private string comment = ""; + // Central dir image private byte[] centralDirImage; + // Existing files in zip private ushort existingFiles; + // File access for Open method private FileAccess access; + // Static CRC32 Table private readonly static UInt32[] CrcTable; + // Default filename encoder private readonly static Encoding DefaultEncoding = Encoding.GetEncoding( 437 ); - #endregion + + #endregion Private fields #region Public methods + // Static constructor. Just invoked once in order to create the CRC32 lookup table. static ZipStorer() { // Generate CRC32 table CrcTable = new UInt32[256]; - for( int i = 0; i < CrcTable.Length; i++ ) { - UInt32 c = (UInt32)i; - for( int j = 0; j < 8; j++ ) { - if( (c & 1) != 0 ) - c = 3988292384 ^ (c >> 1); + for ( int i = 0; i < CrcTable.Length; i++ ) { + UInt32 c = ( UInt32 )i; + for ( int j = 0; j < 8; j++ ) { + if ( ( c & 1 ) != 0 ) + c = 3988292384 ^ ( c >> 1 ); else c >>= 1; } @@ -104,7 +132,8 @@ static ZipStorer() { /// General comment for Zip file /// A valid ZipStorer object public static ZipStorer Create( [NotNull] string filename, [CanBeNull] string fileComment ) { - if( filename == null ) throw new ArgumentNullException( "filename" ); + if ( filename == null ) + throw new ArgumentNullException( "filename" ); Stream stream = new FileStream( filename, FileMode.Create, FileAccess.ReadWrite ); ZipStorer zip = Create( stream, fileComment ); @@ -121,7 +150,8 @@ public static ZipStorer Create( [NotNull] string filename, [CanBeNull] string fi /// /// A valid ZipStorer object public static ZipStorer Create( [NotNull] Stream stream, [CanBeNull] string fileComment ) { - if( stream == null ) throw new ArgumentNullException( "stream" ); + if ( stream == null ) + throw new ArgumentNullException( "stream" ); return new ZipStorer { comment = fileComment, zipFileStream = stream, @@ -129,7 +159,6 @@ public static ZipStorer Create( [NotNull] Stream stream, [CanBeNull] string file }; } - /// /// Method to open an existing storage file /// @@ -137,7 +166,8 @@ public static ZipStorer Create( [NotNull] Stream stream, [CanBeNull] string file /// File access mode as used in FileStream constructor /// A valid ZipStorer object public static ZipStorer Open( [NotNull] string filename, FileAccess fileAccess ) { - if( filename == null ) throw new ArgumentNullException( "filename" ); + if ( filename == null ) + throw new ArgumentNullException( "filename" ); Stream stream = new FileStream( filename, FileMode.Open, fileAccess == FileAccess.Read ? FileAccess.Read : FileAccess.ReadWrite ); ZipStorer zip = Open( stream, fileAccess ); @@ -153,13 +183,14 @@ public static ZipStorer Open( [NotNull] string filename, FileAccess fileAccess ) /// File access mode for stream operations /// A valid ZipStorer object public static ZipStorer Open( [NotNull] Stream stream, FileAccess fileFileAccess ) { - if( stream == null ) throw new ArgumentNullException( "stream" ); - if( !stream.CanSeek && fileFileAccess != FileAccess.Read ) + if ( stream == null ) + throw new ArgumentNullException( "stream" ); + if ( !stream.CanSeek && fileFileAccess != FileAccess.Read ) throw new InvalidOperationException( "Stream cannot seek" ); ZipStorer zip = new ZipStorer { zipFileStream = stream, access = fileFileAccess }; - if( zip.ReadFileInfo() ) + if ( zip.ReadFileInfo() ) return zip; throw new InvalidDataException(); @@ -171,11 +202,13 @@ public static ZipStorer Open( [NotNull] Stream stream, FileAccess fileFileAccess /// Compression method /// Full path of file to add to Zip storage /// Filename and path as desired in Zip directory - /// Comment for stored file + /// Comment for stored file public void AddFile( Compression method, [NotNull] string pathname, [NotNull] string filenameInZip, [CanBeNull] string fileComment ) { - if( pathname == null ) throw new ArgumentNullException( "pathname" ); - if( filenameInZip == null ) throw new ArgumentNullException( "filenameInZip" ); - if( access == FileAccess.Read ) + if ( pathname == null ) + throw new ArgumentNullException( "pathname" ); + if ( filenameInZip == null ) + throw new ArgumentNullException( "filenameInZip" ); + if ( access == FileAccess.Read ) throw new InvalidOperationException( "Writing is not alowed" ); FileStream stream = new FileStream( pathname, FileMode.Open, FileAccess.Read ); @@ -193,9 +226,11 @@ public void AddFile( Compression method, [NotNull] string pathname, [NotNull] st /// Comment for stored file public void AddStream( Compression method, [NotNull] string filenameInZip, [NotNull] Stream source, DateTime modTime, [CanBeNull] string fileComment ) { - if( filenameInZip == null ) throw new ArgumentNullException( "filenameInZip" ); - if( source == null ) throw new ArgumentNullException( "source" ); - if( access == FileAccess.Read ) + if ( filenameInZip == null ) + throw new ArgumentNullException( "filenameInZip" ); + if ( source == null ) + throw new ArgumentNullException( "source" ); + if ( access == FileAccess.Read ) throw new InvalidOperationException( "Writing is not alowed" ); /*long offset; @@ -211,9 +246,9 @@ public void AddStream( Compression method, [NotNull] string filenameInZip, [NotN Method = method, EncodeUTF8 = EncodeUTF8, FilenameInZip = NormalizedFilename( filenameInZip ), - Comment = (fileComment ?? ""), + Comment = ( fileComment ?? "" ), Crc32 = 0, - HeaderOffset = (uint)zipFileStream.Position, + HeaderOffset = ( uint )zipFileStream.Position, ModifyTime = modTime }; @@ -221,7 +256,7 @@ public void AddStream( Compression method, [NotNull] string filenameInZip, [NotN // Write local header WriteLocalHeader( ref zfe ); - zfe.FileOffset = (uint)zipFileStream.Position; + zfe.FileOffset = ( uint )zipFileStream.Position; // Write file to zip (store) Store( ref zfe, source ); @@ -237,26 +272,27 @@ public void AddStream( Compression method, [NotNull] string filenameInZip, [NotN /// /// This is a required step, unless automatic dispose is used public void Close() { - if( access != FileAccess.Read ) { - uint centralOffset = (uint)zipFileStream.Position; + if ( access != FileAccess.Read ) { + uint centralOffset = ( uint )zipFileStream.Position; uint centralSize = 0; - if( centralDirImage != null ) + if ( centralDirImage != null ) zipFileStream.Write( centralDirImage, 0, centralDirImage.Length ); - for( int i = 0; i < files.Count; i++ ) { + for ( int i = 0; i < files.Count; i++ ) { long pos = zipFileStream.Position; WriteCentralDirRecord( files[i] ); - centralSize += (uint)(zipFileStream.Position - pos); + centralSize += ( uint )( zipFileStream.Position - pos ); } - if( centralDirImage != null ) - WriteEndRecord( centralSize + (uint)centralDirImage.Length, centralOffset ); + if ( centralDirImage != null ) + WriteEndRecord( centralSize + ( uint )centralDirImage.Length, centralOffset ); else WriteEndRecord( centralSize, centralOffset ); } - if( zipFileStream == null ) return; + if ( zipFileStream == null ) + return; zipFileStream.Flush(); zipFileStream.Dispose(); @@ -264,21 +300,21 @@ public void Close() { } /// - /// Read all the file records in the central directory + /// Read all the file records in the central directory /// /// List of all entries in directory public List ReadCentralDir() { - if( centralDirImage == null ) + if ( centralDirImage == null ) throw new InvalidOperationException( "Central directory currently does not exist" ); List result = new List(); - for( int pointer = 0; pointer < centralDirImage.Length; ) { + for ( int pointer = 0; pointer < centralDirImage.Length; ) { uint signature = BitConverter.ToUInt32( centralDirImage, pointer ); - if( signature != 0x02014b50 ) + if ( signature != 0x02014b50 ) break; - bool encodeUTF8 = (BitConverter.ToUInt16( centralDirImage, pointer + 8 ) & 0x0800) != 0; + bool encodeUTF8 = ( BitConverter.ToUInt16( centralDirImage, pointer + 8 ) & 0x0800 ) != 0; ushort method = BitConverter.ToUInt16( centralDirImage, pointer + 10 ); uint modifyTime = BitConverter.ToUInt32( centralDirImage, pointer + 12 ); uint crc32 = BitConverter.ToUInt32( centralDirImage, pointer + 16 ); @@ -288,12 +324,12 @@ public List ReadCentralDir() { ushort extraSize = BitConverter.ToUInt16( centralDirImage, pointer + 30 ); ushort commentSize = BitConverter.ToUInt16( centralDirImage, pointer + 32 ); uint headerOffset = BitConverter.ToUInt32( centralDirImage, pointer + 42 ); - uint headerSize = (uint)(46 + filenameSize + extraSize + commentSize); + uint headerSize = ( uint )( 46 + filenameSize + extraSize + commentSize ); Encoding encoder = encodeUTF8 ? Encoding.UTF8 : DefaultEncoding; ZipFileEntry zfe = new ZipFileEntry { - Method = (Compression)method, + Method = ( Compression )method, FilenameInZip = encoder.GetString( centralDirImage, pointer + 46, filenameSize ), @@ -305,11 +341,11 @@ public List ReadCentralDir() { Crc32 = crc32, ModifyTime = DosTimeToDateTime( modifyTime ) }; - if( commentSize > 0 ) + if ( commentSize > 0 ) zfe.Comment = encoder.GetString( centralDirImage, pointer + 46 + filenameSize + extraSize, commentSize ); result.Add( zfe ); - pointer += (46 + filenameSize + extraSize + commentSize); + pointer += ( 46 + filenameSize + extraSize + commentSize ); } return result; @@ -323,22 +359,24 @@ public List ReadCentralDir() { /// True if success, false if not. /// Unique compression methods are Store and Deflate public bool ExtractFile( ZipFileEntry zfe, [NotNull] string filename ) { - if( filename == null ) throw new ArgumentNullException( "filename" ); + if ( filename == null ) + throw new ArgumentNullException( "filename" ); // Make sure the parent directory exist string path = Path.GetDirectoryName( filename ); - if( path == null ) throw new NotImplementedException(); + if ( path == null ) + throw new NotImplementedException(); - if( !Directory.Exists( path ) ) { + if ( !Directory.Exists( path ) ) { Directory.CreateDirectory( path ); } // Check it is directory. If so, do nothing - if( Directory.Exists( filename ) ) { + if ( Directory.Exists( filename ) ) { return true; } Stream output = new FileStream( filename, FileMode.Create, FileAccess.Write ); bool result = ExtractFile( zfe, output ); - if( result ) + if ( result ) output.Close(); File.SetCreationTime( filename, zfe.ModifyTime ); @@ -347,29 +385,29 @@ public bool ExtractFile( ZipFileEntry zfe, [NotNull] string filename ) { return result; } - /// Copy the contents of a stored file into an opened stream /// Entry information of file to extract /// Stream to store the uncompressed data /// True if success, false if not. /// Unique compression methods are Store and Deflate public bool ExtractFile( ZipFileEntry zfe, [NotNull] Stream stream ) { - if( stream == null ) throw new ArgumentNullException( "stream" ); - if( !stream.CanWrite ) + if ( stream == null ) + throw new ArgumentNullException( "stream" ); + if ( !stream.CanWrite ) throw new InvalidOperationException( "Stream cannot be written" ); // check signature byte[] signature = new byte[4]; zipFileStream.Seek( zfe.HeaderOffset, SeekOrigin.Begin ); zipFileStream.Read( signature, 0, 4 ); - if( BitConverter.ToUInt32( signature, 0 ) != 0x04034b50 ) + if ( BitConverter.ToUInt32( signature, 0 ) != 0x04034b50 ) return false; // Select input stream for inflating or just reading Stream inStream; - if( zfe.Method == Compression.Store ) { + if ( zfe.Method == Compression.Store ) { inStream = zipFileStream; - } else if( zfe.Method == Compression.Deflate ) { + } else if ( zfe.Method == Compression.Deflate ) { inStream = new DeflateStream( zipFileStream, CompressionMode.Decompress, true ); } else { return false; @@ -379,14 +417,14 @@ public bool ExtractFile( ZipFileEntry zfe, [NotNull] Stream stream ) { byte[] buffer = new byte[16384]; zipFileStream.Seek( zfe.FileOffset, SeekOrigin.Begin ); uint bytesPending = zfe.FileSize; - while( bytesPending > 0 ) { - int bytesRead = inStream.Read( buffer, 0, (int)Math.Min( bytesPending, buffer.Length ) ); + while ( bytesPending > 0 ) { + int bytesRead = inStream.Read( buffer, 0, ( int )Math.Min( bytesPending, buffer.Length ) ); stream.Write( buffer, 0, bytesRead ); - bytesPending -= (uint)bytesRead; + bytesPending -= ( uint )bytesRead; } stream.Flush(); - if( zfe.Method == Compression.Deflate ) + if ( zfe.Method == Compression.Deflate ) inStream.Dispose(); return true; } @@ -399,11 +437,11 @@ public bool ExtractFile( ZipFileEntry zfe, [NotNull] Stream stream ) { /// True if success, false if not /// This method only works for storage of type FileStream public static bool RemoveEntries( ref ZipStorer zip, [NotNull] List zfes ) { - if( zfes == null ) throw new ArgumentNullException( "zfes" ); - if( !(zip.zipFileStream is FileStream) ) + if ( zfes == null ) + throw new ArgumentNullException( "zfes" ); + if ( !( zip.zipFileStream is FileStream ) ) throw new InvalidOperationException( "RemoveEntries is allowed just over streams of type FileStream" ); - //Get full list of entries List fullList = zip.ReadCentralDir(); @@ -414,9 +452,9 @@ public static bool RemoveEntries( ref ZipStorer zip, [NotNull] List 0 ) { + totalRead += ( uint )bytesRead; + if ( bytesRead > 0 ) { outStream.Write( buffer, 0, bytesRead ); - for( uint i = 0; i < bytesRead; i++ ) { - zfe.Crc32 = CrcTable[(zfe.Crc32 ^ buffer[i]) & 0xFF] ^ (zfe.Crc32 >> 8); + for ( uint i = 0; i < bytesRead; i++ ) { + zfe.Crc32 = CrcTable[( zfe.Crc32 ^ buffer[i] ) & 0xFF] ^ ( zfe.Crc32 >> 8 ); } } - } while( bytesRead == buffer.Length ); + } while ( bytesRead == buffer.Length ); - if( totalRead > 0 ) + if ( totalRead > 0 ) outStream.Flush(); // fix for "Internal error Flush" under Mono - if( zfe.Method == Compression.Deflate ) + if ( zfe.Method == Compression.Deflate ) outStream.Dispose(); zfe.Crc32 ^= 0xffffffff; zfe.FileSize = totalRead; - zfe.CompressedSize = (uint)(zipFileStream.Position - posStart); + zfe.CompressedSize = ( uint )( zipFileStream.Position - posStart ); // Verify for real compression - if( zfe.Method == Compression.Deflate && !ForceDeflating && source.CanSeek && zfe.CompressedSize > zfe.FileSize ) { + if ( zfe.Method == Compression.Deflate && !ForceDeflating && source.CanSeek && zfe.CompressedSize > zfe.FileSize ) { // Start operation again with Store algorithm zfe.Method = Compression.Store; zipFileStream.Position = posStart; @@ -616,33 +660,36 @@ private void Store( ref ZipFileEntry zfe, Stream source ) { Store( ref zfe, source ); } } + /* DOS Date and time: - MS-DOS date. The date is a packed value with the following format. Bits Description - 0-4 Day of the month (1–31) - 5-8 Month (1 = January, 2 = February, and so on) - 9-15 Year offset from 1980 (add 1980 to get actual year) - MS-DOS time. The time is a packed value with the following format. Bits Description - 0-4 Second divided by 2 - 5-10 Minute (0–59) - 11-15 Hour (0–23 on a 24-hour clock) + MS-DOS date. The date is a packed value with the following format. Bits Description + 0-4 Day of the month (1–31) + 5-8 Month (1 = January, 2 = February, and so on) + 9-15 Year offset from 1980 (add 1980 to get actual year) + MS-DOS time. The time is a packed value with the following format. Bits Description + 0-4 Second divided by 2 + 5-10 Minute (0–59) + 11-15 Hour (0–23 on a 24-hour clock) */ + private static uint DateTimeToDosTime( DateTime dt ) { - return (uint)( - (dt.Second / 2) | (dt.Minute << 5) | (dt.Hour << 11) | - (dt.Day << 16) | (dt.Month << 21) | ((dt.Year - 1980) << 25)); + return ( uint )( + ( dt.Second / 2 ) | ( dt.Minute << 5 ) | ( dt.Hour << 11 ) | + ( dt.Day << 16 ) | ( dt.Month << 21 ) | ( ( dt.Year - 1980 ) << 25 ) ); } + private static DateTime DosTimeToDateTime( uint dt ) { return new DateTime( - (int)(dt >> 25) + 1980, - (int)(dt >> 21) & 15, - (int)(dt >> 16) & 31, - (int)(dt >> 11) & 31, - (int)(dt >> 5) & 63, - (int)(dt & 31) * 2 ); + ( int )( dt >> 25 ) + 1980, + ( int )( dt >> 21 ) & 15, + ( int )( dt >> 16 ) & 31, + ( int )( dt >> 11 ) & 31, + ( int )( dt >> 5 ) & 63, + ( int )( dt & 31 ) * 2 ); } /* CRC32 algorithm - The 'magic number' for the CRC is 0xdebb20e3. + The 'magic number' for the CRC is 0xdebb20e3. The proper CRC pre and post conditioning is used, meaning that the CRC register is pre-conditioned with all ones (a starting value @@ -653,11 +700,12 @@ field is set to zero in the local header and the correct value is put in the data descriptor and in the central directory. */ + private void UpdateCrcAndSizes( ref ZipFileEntry zfe ) { long lastPos = zipFileStream.Position; // remember position zipFileStream.Position = zfe.HeaderOffset + 8; - zipFileStream.Write( BitConverter.GetBytes( (ushort)zfe.Method ), 0, 2 ); // zipping method + zipFileStream.Write( BitConverter.GetBytes( ( ushort )zfe.Method ), 0, 2 ); // zipping method zipFileStream.Position = zfe.HeaderOffset + 14; zipFileStream.Write( BitConverter.GetBytes( zfe.Crc32 ), 0, 4 ); // Update CRC @@ -666,19 +714,21 @@ private void UpdateCrcAndSizes( ref ZipFileEntry zfe ) { zipFileStream.Position = lastPos; // restore position } + // Replaces backslashes with slashes to store in zip header private static string NormalizedFilename( string filename ) { string normalizedFilename = filename.Replace( '\\', '/' ); int pos = normalizedFilename.IndexOf( ':' ); - if( pos >= 0 ) + if ( pos >= 0 ) normalizedFilename = normalizedFilename.Remove( 0, pos + 1 ); return normalizedFilename.Trim( '/' ); } + // Reads the end-of-central-directory record private bool ReadFileInfo() { - if( zipFileStream.Length < 22 ) + if ( zipFileStream.Length < 22 ) return false; try { @@ -687,7 +737,8 @@ private bool ReadFileInfo() { do { zipFileStream.Seek( -5, SeekOrigin.Current ); UInt32 sig = br.ReadUInt32(); - if( sig != 0x06054b50 ) continue; + if ( sig != 0x06054b50 ) + continue; zipFileStream.Seek( 6, SeekOrigin.Current ); @@ -697,7 +748,7 @@ private bool ReadFileInfo() { UInt16 commentSize = br.ReadUInt16(); // check if comment field is the very last data in file - if( zipFileStream.Position + commentSize != zipFileStream.Length ) + if ( zipFileStream.Position + commentSize != zipFileStream.Length ) return false; // Copy entire central directory to a memory buffer @@ -709,22 +760,25 @@ private bool ReadFileInfo() { // Leave the pointer at the begining of central dir, to append new files zipFileStream.Seek( centralDirOffset, SeekOrigin.Begin ); return true; - } while( zipFileStream.Position > 0 ); + } while ( zipFileStream.Position > 0 ); // ReSharper disable EmptyGeneralCatchClause } catch { } // ReSharper restore EmptyGeneralCatchClause return false; } - #endregion + + #endregion Private methods #region IDisposable Members + /// /// Closes the Zip file stream /// public void Dispose() { Close(); } - #endregion + + #endregion IDisposable Members } } \ No newline at end of file diff --git a/fCraft/World/Block.cs b/fCraft/World/Block.cs index 67cff8a..eb239a0 100644 --- a/fCraft/World/Block.cs +++ b/fCraft/World/Block.cs @@ -1,6 +1,7 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft { + /// Enumeration of all standard Minecraft Classic block types. public enum Block : byte { Undefined = 255, // for error checking diff --git a/fCraft/World/BlockChangeContext.cs b/fCraft/World/BlockChangeContext.cs index 753c4c4..1a9fe99 100644 --- a/fCraft/World/BlockChangeContext.cs +++ b/fCraft/World/BlockChangeContext.cs @@ -2,9 +2,11 @@ using System; namespace fCraft { + /// Context of the block change. Multiple flags can be combined. [Flags] public enum BlockChangeContext { // Backed by Int32. + /// Default/unknown context. Unknown = 0, @@ -47,7 +49,6 @@ public enum BlockChangeContext { // Backed by Int32. /// A player-made door Door = 4096, - /// Combination of Manual and Replaced (as used by /Paint). PaintedCombo = Manual | Replaced, diff --git a/fCraft/World/BlockDB.cs b/fCraft/World/BlockDB.cs index 287de45..25b9474 100644 --- a/fCraft/World/BlockDB.cs +++ b/fCraft/World/BlockDB.cs @@ -10,20 +10,21 @@ using JetBrains.Annotations; namespace fCraft { + /// Database of block changes. Each BlockDB object is associated with a world. /// Provides controls for storage/retention, and methods to look up data. public sealed unsafe class BlockDB { - internal BlockDB ( [NotNull] World world ) { - if ( world == null ) throw new ArgumentNullException( "world" ); + + internal BlockDB( [NotNull] World world ) { + if ( world == null ) + throw new ArgumentNullException( "world" ); World = world; } - /// World associated with this BlockDB. [NotNull] public World World { get; internal set; } - /// Sets this BlockDB's enabled state to Yes (always on), No (aways off), /// or Auto (on or off depending on BlockDBAutoEnableRank config key and World's build permissions). public YesNoAuto EnabledState { @@ -47,7 +48,6 @@ public YesNoAuto EnabledState { Flush( true ); CacheClear(); IsEnabled = false; - } else if ( !IsEnabled && ( value == YesNoAuto.Yes || value == YesNoAuto.Auto && ShouldBeAutoEnabled ) ) { // going from disabled to enabled/auto-enabled @@ -60,7 +60,6 @@ public YesNoAuto EnabledState { } } enabledState = value; - } finally { // release write lock, if we were holding it if ( writeLockHandle != null ) { @@ -70,18 +69,16 @@ public YesNoAuto EnabledState { } } - YesNoAuto enabledState; - + private YesNoAuto enabledState; /// Checks whether this BlockDB is enabled (either automatically or manually). /// Set EnabledState to enable/disable. public bool IsEnabled { get; private set; } - // BlockDB files are supposed to be aligned to 20 bytes. // Misalignment might happen if writing didnt finish properly - e.g. power outage, or ungraceful shutdown. // If that's not the case, the last few bytes are trimmed off the BlockDB file. - void CheckAlignment () { + private void CheckAlignment() { FileInfo fi = new FileInfo( FileName ); if ( fi.Exists ) { long length = fi.Length; @@ -97,30 +94,26 @@ void CheckAlignment () { } } - /// If EnabledState is set to Auto, calling this auto-enables / auto-disables /// BlockDB depending on world's BuildSecurity.MinRank and BlockDBAutoEnableRank config key. /// True if call resulted in IsEnabled being changed; otherwise false. - public bool AutoToggleIfNeeded () { + public bool AutoToggleIfNeeded() { bool oldEnabled = IsEnabled; EnabledState = enabledState; return ( oldEnabled != IsEnabled ); } - - bool ShouldBeAutoEnabled { + private bool ShouldBeAutoEnabled { get { return ( World.BuildSecurity.MinRank <= RankManager.BlockDBAutoEnableRank ); } } - /// Full path to the file where BlockDB data is stored. [NotNull] public string FileName { get { return Path.Combine( Paths.BlockDBPath, World.Name + ".fbdb" ); } } - - void AddEntry ( BlockDBEntry item ) { + private void AddEntry( BlockDBEntry item ) { try { locker.EnterUpgradeableReadLock(); if ( CacheSize == cacheStore.Length ) { @@ -141,20 +134,18 @@ void AddEntry ( BlockDBEntry item ) { } } - #region Cache - const int BufferSize = 64 * 1024; // 64 KB (at 16 bytes/entry) - readonly byte[] ioBuffer = new byte[BufferSize]; + private const int BufferSize = 64 * 1024; // 64 KB (at 16 bytes/entry) + private readonly byte[] ioBuffer = new byte[BufferSize]; - BlockDBEntry[] cacheStore = new BlockDBEntry[MinCacheSize]; + private BlockDBEntry[] cacheStore = new BlockDBEntry[MinCacheSize]; internal int CacheSize; - const int MinCacheSize = 2 * 1024, // 32 KB (at 16 bytes/entry) + private const int MinCacheSize = 2 * 1024, // 32 KB (at 16 bytes/entry) CacheLinearResizeThreshold = 64 * 1024; // 1 MB (at 16 bytes/entry) - - void CacheClear () { + private void CacheClear() { CacheSize = 0; if ( IsEnabled ) { cacheStore = new BlockDBEntry[MinCacheSize]; @@ -164,8 +155,7 @@ void CacheClear () { LastFlushedIndex = 0; } - - void EnsureCapacity ( int min ) { + private void EnsureCapacity( int min ) { if ( cacheStore.Length < min ) { int num = cacheStore.Length; while ( num < min ) { @@ -179,18 +169,15 @@ void EnsureCapacity ( int min ) { } } - - void LimitCapacity ( int max ) { + private void LimitCapacity( int max ) { if ( cacheStore.Length > max ) { int newCapacity = max; if ( newCapacity < MinCacheSize ) { // minimum capacity newCapacity = MinCacheSize; - } else if ( newCapacity < CacheLinearResizeThreshold ) { // exponential resizing (x2 each time) newCapacity = 1 << ( int )( 1 + Math.Floor( Math.Log( newCapacity, 2 ) ) ); - } else { // linear resizing (in 1 MB increments) newCapacity = ( newCapacity / CacheLinearResizeThreshold + 1 ) * CacheLinearResizeThreshold; @@ -205,7 +192,6 @@ void LimitCapacity ( int max ) { } } - internal int CacheCapacity { get { return cacheStore.Length; } set { @@ -219,7 +205,6 @@ internal int CacheCapacity { Array.Copy( cacheStore, CacheSize - value, destinationArray, 0, value ); LastFlushedIndex -= ( CacheSize - value ); CacheSize = value; - } else { // upsizing the cache Array.Copy( cacheStore, 0, destinationArray, 0, Math.Min( cacheStore.Length, CacheSize ) ); @@ -232,12 +217,11 @@ internal int CacheCapacity { } } - #endregion - + #endregion Cache #region Preload - bool isPreloaded; + private bool isPreloaded; public bool IsPreloaded { get { return isPreloaded; } @@ -249,7 +233,8 @@ public bool IsPreloaded { } if ( IsEnabledGlobally ) { - if ( value == isPreloaded ) return; + if ( value == isPreloaded ) + return; Flush( true ); if ( value ) { Preload(); @@ -269,9 +254,9 @@ public bool IsPreloaded { } } - - void Preload () { - if ( !File.Exists( FileName ) ) return; + private void Preload() { + if ( !File.Exists( FileName ) ) + return; using ( FileStream fs = OpenRead() ) { CacheSize = ( int )( fs.Length / sizeof( BlockDBEntry ) ); EnsureCapacity( CacheSize ); @@ -297,31 +282,33 @@ void Preload () { } } - #endregion - + #endregion Preload #region Limiting - static readonly TimeSpan MinLimitDelay = TimeSpan.FromMinutes( 5 ), + private static readonly TimeSpan MinLimitDelay = TimeSpan.FromMinutes( 5 ), MinTimeLimitDelay = TimeSpan.FromMinutes( 10 ); - const double LimitEnforcementThreshold = 1.15; // 15% + + private const double LimitEnforcementThreshold = 1.15; // 15% internal int LastFlushedIndex; - int changesSinceLimitEnforcement; - DateTime lastLimit, - lastTimeLimit; + private int changesSinceLimitEnforcement; + private DateTime lastLimit, + lastTimeLimit; - void TrimFile ( int maxCapacity ) { + private void TrimFile( int maxCapacity ) { if ( maxCapacity == 0 ) { using ( File.Create( FileName ) ) { } return; } - if ( !File.Exists( FileName ) ) return; + if ( !File.Exists( FileName ) ) + return; string tempFileName = FileName + ".tmp"; using ( FileStream source = File.OpenRead( FileName ) ) { int entries = ( int )( source.Length / sizeof( BlockDBEntry ) ); - if ( entries <= maxCapacity ) return; + if ( entries <= maxCapacity ) + return; // skip beginning of the file (that's where old entries are) source.Seek( ( entries - maxCapacity ) * sizeof( BlockDBEntry ), SeekOrigin.Begin ); @@ -337,13 +324,12 @@ void TrimFile ( int maxCapacity ) { Paths.MoveOrReplace( tempFileName, FileName ); } - /// Counts entries that are newer than the given age. /// Maximum age of entry /// Number of entries newer than given age. /// 0 if all entries are older than given age. /// -1 if all entries are newer than given age. - int CountNewerEntries ( TimeSpan age ) { + private int CountNewerEntries( TimeSpan age ) { if ( age < TimeSpan.Zero ) { throw new ArgumentOutOfRangeException( "age", "Age must be non-negative." ); } @@ -357,10 +343,10 @@ int CountNewerEntries ( TimeSpan age ) { } } } - } else { Flush( false ); - if ( !File.Exists( FileName ) ) return -1; + if ( !File.Exists( FileName ) ) + return -1; using ( FileStream fs = OpenRead() ) { long length = fs.Length; @@ -377,7 +363,8 @@ int CountNewerEntries ( TimeSpan age ) { int bytesRead = 0; while ( bytesLeft > 0 ) { int readPass = fs.Read( buffer, bytesRead, bytesLeft ); - if ( readPass == 0 ) throw new EndOfStreamException(); + if ( readPass == 0 ) + throw new EndOfStreamException(); bytesRead += readPass; bytesLeft -= readPass; } @@ -386,7 +373,8 @@ int CountNewerEntries ( TimeSpan age ) { fixed ( byte* parr = buffer ) { BlockDBEntry* entries = ( BlockDBEntry* )parr; int entryCount = bytesRead / sizeof( BlockDBEntry ); - if ( bytesRead % sizeof( BlockDBEntry ) != 0 ) throw new DataMisalignedException(); + if ( bytesRead % sizeof( BlockDBEntry ) != 0 ) + throw new DataMisalignedException(); for ( int i = entryCount - 1; i >= 0; i-- ) { if ( entries[i].Timestamp < minTimestamp ) { return entryCount - i; @@ -399,7 +387,6 @@ int CountNewerEntries ( TimeSpan age ) { return -1; } - public int Limit { get { return limit; } set { @@ -422,7 +409,6 @@ public int Limit { #if DEBUG_BLOCKDB Logger.Log( LogType.Debug, "BlockDB({0}): Limit={1}", World.Name, value ); #endif - } finally { if ( writeLockHandle != null ) { writeLockHandle.Dispose(); @@ -431,15 +417,14 @@ public int Limit { } } - int limit; + private int limit; /// Whether this BlockDB instance has a limit on the number of entries. public bool HasLimit { get { return limit > 0; } } - - void EnforceLimit () { + private void EnforceLimit() { if ( IsEnabled && limit > 0 ) { #if DEBUG_BLOCKDB int oldCap = CacheCapacity; @@ -459,7 +444,6 @@ void EnforceLimit () { } } - public TimeSpan TimeLimit { get { return timeLimit; } set { @@ -492,14 +476,13 @@ public TimeSpan TimeLimit { } } - TimeSpan timeLimit; + private TimeSpan timeLimit; public bool HasTimeLimit { get { return timeLimit > TimeSpan.Zero; } } - - void EnforceTimeLimit () { + private void EnforceTimeLimit() { if ( IsEnabled && timeLimit > TimeSpan.Zero ) { #if DEBUG_BLOCKDB int oldCap = CacheCapacity; @@ -522,11 +505,10 @@ void EnforceTimeLimit () { } } - #endregion - + #endregion Limiting /// Clears cache and deletes the .fbdb file. - public void Clear () { + public void Clear() { IDisposable writeLockHandle = null; try { if ( !locker.IsWriteLockHeld ) { @@ -537,7 +519,6 @@ public void Clear () { if ( File.Exists( FileName ) ) { File.Delete( FileName ); } - } finally { if ( writeLockHandle != null ) { writeLockHandle.Dispose(); @@ -545,8 +526,7 @@ public void Clear () { } } - - internal void Flush ( bool enforceLimits ) { + internal void Flush( bool enforceLimits ) { IDisposable writeLockHandle = null; try { if ( !locker.IsWriteLockHeld ) { @@ -567,7 +547,8 @@ internal void Flush ( bool enforceLimits ) { count++; } } - if ( !isPreloaded ) CacheSize = 0; + if ( !isPreloaded ) + CacheSize = 0; LastFlushedIndex = CacheSize; changesSinceLimitEnforcement += count; #if DEBUG_BLOCKDB @@ -577,7 +558,8 @@ internal void Flush ( bool enforceLimits ) { #endif } - if ( !enforceLimits ) return; + if ( !enforceLimits ) + return; // enforce size limit, if needed if ( limit > 0 ) { @@ -604,18 +586,15 @@ internal void Flush ( bool enforceLimits ) { } } - - FileStream OpenRead () { + private FileStream OpenRead() { return new FileStream( FileName, FileMode.Open, FileAccess.Read, FileShare.Read, BufferSize, FileOptions.SequentialScan ); } - - FileStream OpenAppend () { + private FileStream OpenAppend() { return new FileStream( FileName, FileMode.Append, FileAccess.Write, FileShare.Read, BufferSize ); } - #region Lookup /// Searches the database for BlockDBEntries, based on given criteria. @@ -630,13 +609,16 @@ FileStream OpenAppend () { /// FBDB file is not aligned to 20 bytes (likely corrupted). /// An I/O error occurrs while trying to read FBDB file from disk. [NotNull] - public BlockDBEntry[] Lookup ( int max, BlockDBSearchType searchType, [NotNull] Func selector ) { + public BlockDBEntry[] Lookup( int max, BlockDBSearchType searchType, [NotNull] Func selector ) { if ( !IsEnabled || !IsEnabledGlobally ) { throw new InvalidOperationException( "Trying to lookup on disabled BlockDB." ); } - if ( max == 0 ) return new BlockDBEntry[0]; - if ( max < 0 ) throw new ArgumentOutOfRangeException( "max" ); - if ( selector == null ) throw new ArgumentNullException( "selector" ); + if ( max == 0 ) + return new BlockDBEntry[0]; + if ( max < 0 ) + throw new ArgumentOutOfRangeException( "max" ); + if ( selector == null ) + throw new ArgumentNullException( "selector" ); IBlockDBQueryProcessor processor; @@ -644,12 +626,15 @@ public BlockDBEntry[] Lookup ( int max, BlockDBSearchType searchType, [NotNull] case BlockDBSearchType.ReturnAll: processor = new ReturnAllProcessor( max, selector ); break; + case BlockDBSearchType.ReturnNewest: processor = new ReturnNewestProcessor( World.LoadMap(), max, selector ); break; + case BlockDBSearchType.ReturnOldest: processor = new ReturnOldestProcessor( World.LoadMap(), max, selector ); break; + default: throw new ArgumentOutOfRangeException( "searchType" ); } @@ -658,7 +643,6 @@ public BlockDBEntry[] Lookup ( int max, BlockDBSearchType searchType, [NotNull] return processor.GetResults(); } - /// Traverses the database, newest to oldest entries, processing each entry with the given IBlockDBQueryProcessor. /// Processor to use for each BlockDBEntry. /// processor is null. @@ -666,8 +650,9 @@ public BlockDBEntry[] Lookup ( int max, BlockDBSearchType searchType, [NotNull] /// The end of FBDB file is reached prematurely (corrupted file, or outside interference). /// FBDB file is not aligned to 20 bytes (likely corrupted). /// An I/O error occurrs while trying to read FBDB file from disk. - public void Traverse ( [NotNull] IBlockDBQueryProcessor processor ) { - if ( processor == null ) throw new ArgumentNullException( "processor" ); + public void Traverse( [NotNull] IBlockDBQueryProcessor processor ) { + if ( processor == null ) + throw new ArgumentNullException( "processor" ); if ( !IsEnabled || !IsEnabledGlobally ) { throw new InvalidOperationException( "Trying to lookup on disabled BlockDB." ); } @@ -687,7 +672,6 @@ public void Traverse ( [NotNull] IBlockDBQueryProcessor processor ) { } } } - } else { // Search unflushed cache for matches if ( LastFlushedIndex < CacheSize ) { @@ -701,7 +685,8 @@ public void Traverse ( [NotNull] IBlockDBQueryProcessor processor ) { } // If we still have some searching to do, read the file - if ( !File.Exists( FileName ) ) return; + if ( !File.Exists( FileName ) ) + return; using ( FileStream fs = OpenRead() ) { long length = fs.Length; long bytesReadTotal = 0; @@ -719,7 +704,8 @@ public void Traverse ( [NotNull] IBlockDBQueryProcessor processor ) { int bytesRead = 0; while ( bytesLeft > 0 ) { int readPass = fs.Read( buffer, bytesRead, bytesLeft ); - if ( readPass == 0 ) throw new EndOfStreamException(); + if ( readPass == 0 ) + throw new EndOfStreamException(); bytesRead += readPass; bytesLeft -= readPass; } @@ -749,25 +735,22 @@ public void Traverse ( [NotNull] IBlockDBQueryProcessor processor ) { } } - #endregion - + #endregion Lookup #region Lookup processors - sealed class ReturnAllProcessor : IBlockDBQueryProcessor { - int count; - readonly int max; - readonly Func selector; - readonly List result = new List(); + private sealed class ReturnAllProcessor : IBlockDBQueryProcessor { + private int count; + private readonly int max; + private readonly Func selector; + private readonly List result = new List(); - - public ReturnAllProcessor ( int max, Func selector ) { + public ReturnAllProcessor( int max, Func selector ) { this.max = max; this.selector = selector; } - - public bool ProcessEntry ( BlockDBEntry entry ) { + public bool ProcessEntry( BlockDBEntry entry ) { if ( selector( entry ) ) { result.Add( entry ); count++; @@ -778,29 +761,25 @@ public bool ProcessEntry ( BlockDBEntry entry ) { return true; } - - public BlockDBEntry[] GetResults () { + public BlockDBEntry[] GetResults() { return result.ToArray(); } } + private sealed class ReturnOldestProcessor : IBlockDBQueryProcessor { + private readonly Map map; + private int count; + private readonly int max; + private readonly Func selector; + private readonly Dictionary result = new Dictionary(); - sealed class ReturnOldestProcessor : IBlockDBQueryProcessor { - readonly Map map; - int count; - readonly int max; - readonly Func selector; - readonly Dictionary result = new Dictionary(); - - - public ReturnOldestProcessor ( Map map, int max, Func selector ) { + public ReturnOldestProcessor( Map map, int max, Func selector ) { this.max = max; this.selector = selector; this.map = map; } - - public bool ProcessEntry ( BlockDBEntry entry ) { + public bool ProcessEntry( BlockDBEntry entry ) { if ( selector( entry ) ) { int index = map.Index( entry.X, entry.Y, entry.Z ); result[index] = entry; @@ -812,28 +791,25 @@ public bool ProcessEntry ( BlockDBEntry entry ) { return true; } - public BlockDBEntry[] GetResults () { + public BlockDBEntry[] GetResults() { return result.Values.ToArray(); } } + private sealed class ReturnNewestProcessor : IBlockDBQueryProcessor { + private readonly Map map; + private int count; + private readonly int max; + private readonly Func selector; + private readonly Dictionary result = new Dictionary(); - sealed class ReturnNewestProcessor : IBlockDBQueryProcessor { - readonly Map map; - int count; - readonly int max; - readonly Func selector; - readonly Dictionary result = new Dictionary(); - - - public ReturnNewestProcessor ( Map map, int max, Func selector ) { + public ReturnNewestProcessor( Map map, int max, Func selector ) { this.max = max; this.selector = selector; this.map = map; } - - public bool ProcessEntry ( BlockDBEntry entry ) { + public bool ProcessEntry( BlockDBEntry entry ) { if ( selector( entry ) ) { int index = map.Index( entry.X, entry.Y, entry.Z ); if ( !result.ContainsKey( index ) ) { @@ -846,23 +822,22 @@ public bool ProcessEntry ( BlockDBEntry entry ) { } return true; } - public BlockDBEntry[] GetResults () { + + public BlockDBEntry[] GetResults() { return result.Values.ToArray(); } } + private sealed class ExcludingReturnOldestProcessor : IBlockDBQueryProcessor { + private readonly Map map; + private int count; + private readonly int max; + private readonly Func inclusionSelector; + private readonly Func exclusionSelector; + private readonly HashSet excluded = new HashSet(); + private readonly Dictionary result = new Dictionary(); - sealed class ExcludingReturnOldestProcessor : IBlockDBQueryProcessor { - readonly Map map; - int count; - readonly int max; - readonly Func inclusionSelector; - readonly Func exclusionSelector; - readonly HashSet excluded = new HashSet(); - readonly Dictionary result = new Dictionary(); - - - public ExcludingReturnOldestProcessor ( Map map, int max, + public ExcludingReturnOldestProcessor( Map map, int max, Func inclusionSelector, Func exclusionSelector ) { this.max = max; @@ -871,8 +846,7 @@ public ExcludingReturnOldestProcessor ( Map map, int max, this.map = map; } - - public bool ProcessEntry ( BlockDBEntry entry ) { + public bool ProcessEntry( BlockDBEntry entry ) { if ( inclusionSelector( entry ) ) { int index = map.Index( entry.X, entry.Y, entry.Z ); if ( !excluded.Contains( index ) ) { @@ -890,14 +864,12 @@ public bool ProcessEntry ( BlockDBEntry entry ) { return true; } - - public BlockDBEntry[] GetResults () { + public BlockDBEntry[] GetResults() { return result.Values.ToArray(); } } - #endregion - + #endregion Lookup processors #region Lookup shortcuts @@ -905,7 +877,7 @@ public BlockDBEntry[] GetResults () { /// Maximum number of changes to return. /// Coordinate to search at. /// Given coordinates are outside the map. - public BlockDBEntry[] Lookup ( int max, Vector3I coords ) { + public BlockDBEntry[] Lookup( int max, Vector3I coords ) { if ( !World.LoadMap().InBounds( coords ) ) { throw new ArgumentOutOfRangeException( "coords" ); } @@ -913,39 +885,39 @@ public BlockDBEntry[] Lookup ( int max, Vector3I coords ) { entry => ( entry.X == coords.X && entry.Y == coords.Y && entry.Z == coords.Z ) ); } - - public BlockDBEntry[] Lookup ( int max ) { + public BlockDBEntry[] Lookup( int max ) { return Lookup( max, BlockDBSearchType.ReturnOldest, entry => true ); } - - public BlockDBEntry[] Lookup ( int max, TimeSpan span ) { - if ( span < TimeSpan.Zero ) throw new ArgumentOutOfRangeException( "span" ); + public BlockDBEntry[] Lookup( int max, TimeSpan span ) { + if ( span < TimeSpan.Zero ) + throw new ArgumentOutOfRangeException( "span" ); long ticks = DateTime.UtcNow.Subtract( span ).ToUnixTime(); return Lookup( max, BlockDBSearchType.ReturnOldest, entry => entry.Timestamp >= ticks ); } - - public BlockDBEntry[] Lookup ( int max, [NotNull] BoundingBox area ) { - if ( area == null ) throw new ArgumentNullException( "area" ); + public BlockDBEntry[] Lookup( int max, [NotNull] BoundingBox area ) { + if ( area == null ) + throw new ArgumentNullException( "area" ); return Lookup( max, BlockDBSearchType.ReturnOldest, entry => area.Contains( entry.X, entry.Y, entry.Z ) ); } - - public BlockDBEntry[] Lookup ( int max, [NotNull] BoundingBox area, TimeSpan span ) { - if ( area == null ) throw new ArgumentNullException( "area" ); - if ( span < TimeSpan.Zero ) throw new ArgumentOutOfRangeException( "span" ); + public BlockDBEntry[] Lookup( int max, [NotNull] BoundingBox area, TimeSpan span ) { + if ( area == null ) + throw new ArgumentNullException( "area" ); + if ( span < TimeSpan.Zero ) + throw new ArgumentOutOfRangeException( "span" ); long ticks = DateTime.UtcNow.Subtract( span ).ToUnixTime(); return Lookup( max, BlockDBSearchType.ReturnOldest, entry => entry.Timestamp >= ticks && area.Contains( entry.X, entry.Y, entry.Z ) ); } - - public BlockDBEntry[] Lookup ( int max, [NotNull] PlayerInfo info, bool exclude ) { - if ( info == null ) throw new ArgumentNullException( "info" ); + public BlockDBEntry[] Lookup( int max, [NotNull] PlayerInfo info, bool exclude ) { + if ( info == null ) + throw new ArgumentNullException( "info" ); int pid = info.ID; Map map = World.LoadMap(); @@ -962,10 +934,11 @@ public BlockDBEntry[] Lookup ( int max, [NotNull] PlayerInfo info, bool exclude return processor.GetResults(); } - - public BlockDBEntry[] Lookup ( int max, [NotNull] PlayerInfo info, bool exclude, TimeSpan span ) { - if ( info == null ) throw new ArgumentNullException( "info" ); - if ( span < TimeSpan.Zero ) throw new ArgumentOutOfRangeException( "span" ); + public BlockDBEntry[] Lookup( int max, [NotNull] PlayerInfo info, bool exclude, TimeSpan span ) { + if ( info == null ) + throw new ArgumentNullException( "info" ); + if ( span < TimeSpan.Zero ) + throw new ArgumentOutOfRangeException( "span" ); int pid = info.ID; long ticks = DateTime.UtcNow.Subtract( span ).ToUnixTime(); Map map = World.LoadMap(); @@ -983,11 +956,13 @@ public BlockDBEntry[] Lookup ( int max, [NotNull] PlayerInfo info, bool exclude, return processor.GetResults(); } - - public BlockDBEntry[] Lookup ( int max, [NotNull] PlayerInfo[] infos, bool exclude ) { - if ( infos == null ) throw new ArgumentNullException( "infos" ); - if ( infos.Length == 0 ) throw new ArgumentException( "At least one PlayerInfo must be given", "infos" ); - if ( infos.Length == 1 ) return Lookup( max, infos[0], exclude ); + public BlockDBEntry[] Lookup( int max, [NotNull] PlayerInfo[] infos, bool exclude ) { + if ( infos == null ) + throw new ArgumentNullException( "infos" ); + if ( infos.Length == 0 ) + throw new ArgumentException( "At least one PlayerInfo must be given", "infos" ); + if ( infos.Length == 1 ) + return Lookup( max, infos[0], exclude ); Map map = World.LoadMap(); IBlockDBQueryProcessor processor; @@ -1003,12 +978,15 @@ public BlockDBEntry[] Lookup ( int max, [NotNull] PlayerInfo[] infos, bool exclu return processor.GetResults(); } - - public BlockDBEntry[] Lookup ( int max, [NotNull] PlayerInfo[] infos, bool exclude, TimeSpan span ) { - if ( infos == null ) throw new ArgumentNullException( "infos" ); - if ( infos.Length == 0 ) throw new ArgumentException( "At least one PlayerInfo must be given", "infos" ); - if ( span < TimeSpan.Zero ) throw new ArgumentOutOfRangeException( "span" ); - if ( infos.Length == 1 ) return Lookup( max, infos[0], exclude, span ); + public BlockDBEntry[] Lookup( int max, [NotNull] PlayerInfo[] infos, bool exclude, TimeSpan span ) { + if ( infos == null ) + throw new ArgumentNullException( "infos" ); + if ( infos.Length == 0 ) + throw new ArgumentException( "At least one PlayerInfo must be given", "infos" ); + if ( span < TimeSpan.Zero ) + throw new ArgumentOutOfRangeException( "span" ); + if ( infos.Length == 1 ) + return Lookup( max, infos[0], exclude, span ); long ticks = DateTime.UtcNow.Subtract( span ).ToUnixTime(); Map map = World.LoadMap(); @@ -1028,10 +1006,11 @@ public BlockDBEntry[] Lookup ( int max, [NotNull] PlayerInfo[] infos, bool exclu return processor.GetResults(); } - - public BlockDBEntry[] Lookup ( int max, [NotNull] BoundingBox area, [NotNull] PlayerInfo info, bool exclude ) { - if ( area == null ) throw new ArgumentNullException( "area" ); - if ( info == null ) throw new ArgumentNullException( "info" ); + public BlockDBEntry[] Lookup( int max, [NotNull] BoundingBox area, [NotNull] PlayerInfo info, bool exclude ) { + if ( area == null ) + throw new ArgumentNullException( "area" ); + if ( info == null ) + throw new ArgumentNullException( "info" ); int pid = info.ID; Map map = World.LoadMap(); @@ -1051,11 +1030,13 @@ public BlockDBEntry[] Lookup ( int max, [NotNull] BoundingBox area, [NotNull] Pl return processor.GetResults(); } - - public BlockDBEntry[] Lookup ( int max, [NotNull] BoundingBox area, [NotNull] PlayerInfo info, bool exclude, TimeSpan span ) { - if ( area == null ) throw new ArgumentNullException( "area" ); - if ( info == null ) throw new ArgumentNullException( "info" ); - if ( span < TimeSpan.Zero ) throw new ArgumentOutOfRangeException( "span" ); + public BlockDBEntry[] Lookup( int max, [NotNull] BoundingBox area, [NotNull] PlayerInfo info, bool exclude, TimeSpan span ) { + if ( area == null ) + throw new ArgumentNullException( "area" ); + if ( info == null ) + throw new ArgumentNullException( "info" ); + if ( span < TimeSpan.Zero ) + throw new ArgumentOutOfRangeException( "span" ); int pid = info.ID; long ticks = DateTime.UtcNow.Subtract( span ).ToUnixTime(); Map map = World.LoadMap(); @@ -1078,12 +1059,15 @@ public BlockDBEntry[] Lookup ( int max, [NotNull] BoundingBox area, [NotNull] Pl return processor.GetResults(); } - - public BlockDBEntry[] Lookup ( int max, [NotNull] BoundingBox area, [NotNull] PlayerInfo[] infos, bool exclude ) { - if ( area == null ) throw new ArgumentNullException( "area" ); - if ( infos == null ) throw new ArgumentNullException( "infos" ); - if ( infos.Length == 0 ) throw new ArgumentException( "At least one PlayerInfo must be given", "infos" ); - if ( infos.Length == 1 ) return Lookup( max, area, infos[0], exclude ); + public BlockDBEntry[] Lookup( int max, [NotNull] BoundingBox area, [NotNull] PlayerInfo[] infos, bool exclude ) { + if ( area == null ) + throw new ArgumentNullException( "area" ); + if ( infos == null ) + throw new ArgumentNullException( "infos" ); + if ( infos.Length == 0 ) + throw new ArgumentException( "At least one PlayerInfo must be given", "infos" ); + if ( infos.Length == 1 ) + return Lookup( max, area, infos[0], exclude ); Map map = World.LoadMap(); IBlockDBQueryProcessor processor; @@ -1102,13 +1086,17 @@ public BlockDBEntry[] Lookup ( int max, [NotNull] BoundingBox area, [NotNull] Pl return processor.GetResults(); } - - public BlockDBEntry[] Lookup ( int max, [NotNull] BoundingBox area, [NotNull] PlayerInfo[] infos, bool exclude, TimeSpan span ) { - if ( area == null ) throw new ArgumentNullException( "area" ); - if ( infos == null ) throw new ArgumentNullException( "infos" ); - if ( infos.Length == 0 ) throw new ArgumentException( "At least one PlayerInfo must be given", "infos" ); - if ( span < TimeSpan.Zero ) throw new ArgumentOutOfRangeException( "span" ); - if ( infos.Length == 1 ) return Lookup( max, area, infos[0], exclude, span ); + public BlockDBEntry[] Lookup( int max, [NotNull] BoundingBox area, [NotNull] PlayerInfo[] infos, bool exclude, TimeSpan span ) { + if ( area == null ) + throw new ArgumentNullException( "area" ); + if ( infos == null ) + throw new ArgumentNullException( "infos" ); + if ( infos.Length == 0 ) + throw new ArgumentException( "At least one PlayerInfo must be given", "infos" ); + if ( span < TimeSpan.Zero ) + throw new ArgumentOutOfRangeException( "span" ); + if ( infos.Length == 1 ) + return Lookup( max, area, infos[0], exclude, span ); long ticks = DateTime.UtcNow.Subtract( span ).ToUnixTime(); Map map = World.LoadMap(); @@ -1130,38 +1118,32 @@ public BlockDBEntry[] Lookup ( int max, [NotNull] BoundingBox area, [NotNull] Pl return processor.GetResults(); } - #endregion - + #endregion Lookup shortcuts /// Acquires and returns an exclusive (write) lock for this BlockDB. /// Disposing the object returned by this method releases the lock. - public IDisposable GetWriteLock () { + public IDisposable GetWriteLock() { return locker.WriteLock(); } - /// Acquires and returns a shared (read) lock for this BlockDB. /// Disposing the object returned by this method releases the lock. - public IDisposable GetReadLock () { + public IDisposable GetReadLock() { return locker.ReadLock(); } - - readonly ReaderWriterLockSlim locker = new ReaderWriterLockSlim(); - const int SearchBufferSize = 1000000; // in bytes - + private readonly ReaderWriterLockSlim locker = new ReaderWriterLockSlim(); + private const int SearchBufferSize = 1000000; // in bytes #region Serialization public const string XmlRootName = "BlockDB"; - - public XElement SaveSettings () { + public XElement SaveSettings() { return SaveSettings( XmlRootName ); } - - public XElement SaveSettings ( string rootName ) { + public XElement SaveSettings( string rootName ) { XElement root = new XElement( rootName ); root.Add( new XAttribute( "enabled", EnabledState ) ); root.Add( new XAttribute( "preload", IsPreloaded ) ); @@ -1174,8 +1156,7 @@ public XElement SaveSettings ( string rootName ) { return root; } - - public void LoadSettings ( XElement el ) { + public void LoadSettings( XElement el ) { XAttribute temp; if ( ( temp = el.Attribute( "enabled" ) ) != null ) { YesNoAuto enabledStateTemp; @@ -1221,8 +1202,7 @@ public void LoadSettings ( XElement el ) { } } - #endregion - + #endregion Serialization #region Static @@ -1230,16 +1210,15 @@ public void LoadSettings ( XElement el ) { /// Changing this setting currently requires a server restart. public static bool IsEnabledGlobally { get; private set; } - - internal static void Init () { + internal static void Init() { Paths.TestDirectory( "BlockDB", Paths.BlockDBPath, true ); Player.PlacedBlock += OnPlayerPlacedBlock; IsEnabledGlobally = true; } - - static void OnPlayerPlacedBlock ( object sender, [NotNull] PlayerPlacedBlockEventArgs e ) { - if ( e == null ) throw new ArgumentNullException( "e" ); + private static void OnPlayerPlacedBlock( object sender, [NotNull] PlayerPlacedBlockEventArgs e ) { + if ( e == null ) + throw new ArgumentNullException( "e" ); World world = e.Map.World; if ( world != null && world.BlockDB.IsEnabled ) { BlockDBEntry newEntry = new BlockDBEntry( ( int )DateTime.UtcNow.ToUnixTime(), @@ -1252,17 +1231,18 @@ static void OnPlayerPlacedBlock ( object sender, [NotNull] PlayerPlacedBlockEven } } - #endregion + #endregion Static } - /// Class used to process results of traversing the BlockDB. public interface IBlockDBQueryProcessor { + /// Callback for each BlockDBEntry. /// Current entry. /// True if traversal should continue. False if traversal should end. - bool ProcessEntry ( BlockDBEntry entry ); + bool ProcessEntry( BlockDBEntry entry ); + /// Returns the gathered results, as an array of BlockDBEntry structs. - BlockDBEntry[] GetResults (); + BlockDBEntry[] GetResults(); } } \ No newline at end of file diff --git a/fCraft/World/BlockDBEntry.cs b/fCraft/World/BlockDBEntry.cs index 5977add..abc97b5 100644 --- a/fCraft/World/BlockDBEntry.cs +++ b/fCraft/World/BlockDBEntry.cs @@ -3,10 +3,12 @@ using System.Runtime.InteropServices; namespace fCraft { + /// Struct representing a single block change. /// You may safely cast byte* pointers directly to BlockDBEntry* and vice versa. [StructLayout( LayoutKind.Sequential, Pack = 1 )] public struct BlockDBEntry { + /// UTC Unix timestamp of the change. public readonly int Timestamp; @@ -36,8 +38,7 @@ public Vector3I Coord { /// Context for this block change. public readonly BlockChangeContext Context; - - public BlockDBEntry ( int timestamp, int playerID, short x, short y, short z, + public BlockDBEntry( int timestamp, int playerID, short x, short y, short z, Block oldBlock, Block newBlock, BlockChangeContext flags ) { Timestamp = timestamp; PlayerID = playerID; @@ -49,7 +50,7 @@ public BlockDBEntry ( int timestamp, int playerID, short x, short y, short z, Context = flags; } - public BlockDBEntry ( int timestamp, int playerID, Vector3I coords, + public BlockDBEntry( int timestamp, int playerID, Vector3I coords, Block oldBlock, Block newBlock, BlockChangeContext flags ) { Timestamp = timestamp; PlayerID = playerID; @@ -61,7 +62,7 @@ public BlockDBEntry ( int timestamp, int playerID, Vector3I coords, Context = flags; } - public void Serialize ( BinaryWriter writer ) { + public void Serialize( BinaryWriter writer ) { writer.Write( Timestamp ); writer.Write( PlayerID ); writer.Write( X ); diff --git a/fCraft/World/BlockDBSearchType.cs b/fCraft/World/BlockDBSearchType.cs index 0e10efa..c90c780 100644 --- a/fCraft/World/BlockDBSearchType.cs +++ b/fCraft/World/BlockDBSearchType.cs @@ -1,8 +1,10 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft { + /// Describes what kind of results should BlockDB.Lookup return. public enum BlockDBSearchType { + /// All BlockDB Entries (even those that have been overriden) are returned, /// possibly multiple entries per coordinate. ReturnAll, diff --git a/fCraft/World/BlockUpdate.cs b/fCraft/World/BlockUpdate.cs index 3fa87f7..7d0a97f 100644 --- a/fCraft/World/BlockUpdate.cs +++ b/fCraft/World/BlockUpdate.cs @@ -1,6 +1,7 @@ // Copyright 2009-2013 Matvei Stefarov namespace fCraft { + /// Structure representing a pending update to the map's block array. /// Contains information about the block coordinates, type, and change's origin. public struct BlockUpdate { @@ -18,9 +19,9 @@ public BlockUpdate( Player origin, short x, short y, short z, Block blockType ) public BlockUpdate( Player origin, Vector3I coord, Block blockType ) { Origin = origin; - X = (short)coord.X; - Y = (short)coord.Y; - Z = (short)coord.Z; + X = ( short )coord.X; + Y = ( short )coord.Y; + Z = ( short )coord.Z; BlockType = blockType; } } diff --git a/fCraft/World/Forester.cs b/fCraft/World/Forester.cs index 6fc6c70..aa1cd8f 100644 --- a/fCraft/World/Forester.cs +++ b/fCraft/World/Forester.cs @@ -8,64 +8,71 @@ using JetBrains.Annotations; namespace fCraft.Events { + public sealed class ForesterBlockPlacingEventArgs : EventArgs { + internal ForesterBlockPlacingEventArgs( Vector3I coordinate, Block block ) { Coordinate = coordinate; Block = block; } + public Vector3I Coordinate { get; private set; } + public Block Block { get; private set; } } } namespace fCraft { + /// Vegetation generator for MapGenerator. public static class Forester { - const int MaxTries = 1000; + private const int MaxTries = 1000; public static void Generate( [NotNull] ForesterArgs args ) { - if( args == null ) throw new ArgumentNullException( "args" ); + if ( args == null ) + throw new ArgumentNullException( "args" ); args.Validate(); List treeList = new List(); - if( args.Operation == ForesterOperation.Conserve ) { + if ( args.Operation == ForesterOperation.Conserve ) { FindTrees( args, treeList ); } - if( args.TreeCount > 0 && treeList.Count > args.TreeCount ) { + if ( args.TreeCount > 0 && treeList.Count > args.TreeCount ) { treeList = treeList.Take( args.TreeCount ).ToList(); } - if( args.Operation == ForesterOperation.Replant || args.Operation == ForesterOperation.Add ) { - switch( args.Shape ) { + if ( args.Operation == ForesterOperation.Replant || args.Operation == ForesterOperation.Add ) { + switch ( args.Shape ) { case TreeShape.Rainforest: PlantRainForestTrees( args, treeList ); break; + case TreeShape.Mangrove: PlantMangroves( args, treeList ); break; + default: PlantTrees( args, treeList ); break; } } - if( args.Operation != ForesterOperation.ClearCut ) { + if ( args.Operation != ForesterOperation.ClearCut ) { ProcessTrees( args, treeList ); - if( args.Foliage ) { - foreach( Tree tree in treeList ) { + if ( args.Foliage ) { + foreach ( Tree tree in treeList ) { tree.MakeFoliage(); } } - if( args.Wood ) { - foreach( Tree tree in treeList ) { + if ( args.Wood ) { + foreach ( Tree tree in treeList ) { tree.MakeTrunk(); } } } } - public static void Plant( [NotNull] ForesterArgs args, Vector3I treeCoordinate ) { List treeList = new List { new Tree { @@ -74,32 +81,33 @@ public static void Plant( [NotNull] ForesterArgs args, Vector3I treeCoordinate ) Pos = treeCoordinate } }; - switch( args.Shape ) { + switch ( args.Shape ) { case TreeShape.Rainforest: PlantRainForestTrees( args, treeList ); break; + case TreeShape.Mangrove: PlantMangroves( args, treeList ); break; + default: PlantTrees( args, treeList ); break; } ProcessTrees( args, treeList ); - if( args.Foliage ) { - foreach( Tree tree in treeList ) { + if ( args.Foliage ) { + foreach ( Tree tree in treeList ) { tree.MakeFoliage(); } } - if( args.Wood ) { - foreach( Tree tree in treeList ) { + if ( args.Wood ) { + foreach ( Tree tree in treeList ) { tree.MakeTrunk(); } } } - public static void SexyPlant([NotNull] ForesterArgs args, Vector3I treeCoordinate) - { + public static void SexyPlant( [NotNull] ForesterArgs args, Vector3I treeCoordinate ) { List treeList = new List { new Tree { Args = args, @@ -107,54 +115,51 @@ public static void SexyPlant([NotNull] ForesterArgs args, Vector3I treeCoordinat Pos = new Vector3I(treeCoordinate.X, treeCoordinate.Z, treeCoordinate.Y) } }; - switch (args.Shape) - { + switch ( args.Shape ) { case TreeShape.Rainforest: - PlantRainForestTrees(args, treeList); + PlantRainForestTrees( args, treeList ); break; + case TreeShape.Mangrove: - PlantMangroves(args, treeList); + PlantMangroves( args, treeList ); break; + default: - PlantTrees(args, treeList); + PlantTrees( args, treeList ); break; } - ProcessTrees(args, treeList); - if (args.Foliage) - { - foreach (Tree tree in treeList) - { + ProcessTrees( args, treeList ); + if ( args.Foliage ) { + foreach ( Tree tree in treeList ) { tree.MakeFoliage(); } } - if (args.Wood) - { - foreach (Tree tree in treeList) - { + if ( args.Wood ) { + foreach ( Tree tree in treeList ) { tree.MakeTrunk(); } } } - - static void FindTrees( ForesterArgs args, ICollection treelist ) { + private static void FindTrees( ForesterArgs args, ICollection treelist ) { int treeheight = args.Height; - for( int x = 0; x < args.Map.Width; x++ ) { - for( int z = 0; z < args.Map.Length; z++ ) { + for ( int x = 0; x < args.Map.Width; x++ ) { + for ( int z = 0; z < args.Map.Length; z++ ) { int y = args.Map.Height - 1; - while( true ) { + while ( true ) { int foliagetop = args.Map.SearchColumn( x, z, args.FoliageBlock, y ); - if( foliagetop < 0 ) break; + if ( foliagetop < 0 ) + break; y = foliagetop; Vector3I trunktop = new Vector3I( x, y - 1, z ); int height = DistanceToBlock( args.Map, new Vector3F( trunktop ), Vector3F.Down, args.TrunkBlock, true ); - if( height == 0 ) { + if ( height == 0 ) { y--; continue; } y -= height; - if( args.Height > 0 ) { + if ( args.Height > 0 ) { height = args.Rand.Next( treeheight - args.HeightVariation, treeheight + args.HeightVariation + 1 ); } @@ -169,19 +174,20 @@ static void FindTrees( ForesterArgs args, ICollection treelist ) { } } - - static void PlantTrees( ForesterArgs args, ICollection treelist ) { + private static void PlantTrees( ForesterArgs args, ICollection treelist ) { int treeheight = args.Height; int attempts = 0; - while( treelist.Count < args.TreeCount && attempts < MaxTries ) { + while ( treelist.Count < args.TreeCount && attempts < MaxTries ) { attempts++; int height = args.Rand.Next( treeheight - args.HeightVariation, treeheight + args.HeightVariation + 1 ); Vector3I treeLoc = FindRandomTreeLocation( args, height ); - if( treeLoc.Y < 0 ) continue; - else treeLoc.Y++; + if ( treeLoc.Y < 0 ) + continue; + else + treeLoc.Y++; treelist.Add( new Tree { Args = args, Height = height, @@ -190,21 +196,19 @@ static void PlantTrees( ForesterArgs args, ICollection treelist ) { } } - - static Vector3I FindRandomTreeLocation( ForesterArgs args, int height ) { - int padding = (int)(height / 3f + 1); + private static Vector3I FindRandomTreeLocation( ForesterArgs args, int height ) { + int padding = ( int )( height / 3f + 1 ); int mindim = Math.Min( args.Map.Width, args.Map.Length ); - if( padding > mindim / 2.2 ) { - padding = (int)(mindim / 2.2); + if ( padding > mindim / 2.2 ) { + padding = ( int )( mindim / 2.2 ); } int x = args.Rand.Next( padding, args.Map.Width - padding - 1 ); int z = args.Rand.Next( padding, args.Map.Length - padding - 1 ); int y = args.Map.SearchColumn( x, z, args.PlantOn ); - return new Vector3I( x, y, z); + return new Vector3I( x, y, z ); } - - static void PlantRainForestTrees( ForesterArgs args, ICollection treelist ) { + private static void PlantRainForestTrees( ForesterArgs args, ICollection treelist ) { int treeHeight = args.Height; int existingTreeNum = treelist.Count; @@ -212,37 +216,39 @@ static void PlantRainForestTrees( ForesterArgs args, ICollection treelist const int shortTreeFraction = 6; int attempts = 0; - for( int i = 0; i < remainingTrees && attempts < MaxTries; attempts++ ) { + for ( int i = 0; i < remainingTrees && attempts < MaxTries; attempts++ ) { float randomfac = - (float)( ( Math.Sqrt( args.Rand.NextDouble() ) * 1.618 - .618 ) * args.HeightVariation + .5 ); + ( float )( ( Math.Sqrt( args.Rand.NextDouble() ) * 1.618 - .618 ) * args.HeightVariation + .5 ); int height; - if( i % shortTreeFraction == 0 ) { - height = (int)( treeHeight + randomfac ); + if ( i % shortTreeFraction == 0 ) { + height = ( int )( treeHeight + randomfac ); } else { - height = (int)( treeHeight - randomfac ); + height = ( int )( treeHeight - randomfac ); } Vector3I xyz = FindRandomTreeLocation( args, height ); - if( xyz.Y < 0 ) continue; + if ( xyz.Y < 0 ) + continue; xyz.Y++; bool displaced = false; // ReSharper disable LoopCanBeConvertedToQuery - foreach( Tree otherTree in treelist ) { + foreach ( Tree otherTree in treelist ) { Vector3I otherLoc = otherTree.Pos; float otherheight = otherTree.Height; int tallx = otherLoc[0]; int tallz = otherLoc[2]; - float dist = (float)Math.Sqrt( Sqr( tallx - xyz.X + .5 ) + Sqr( tallz - xyz.Z + .5 ) ); + float dist = ( float )Math.Sqrt( Sqr( tallx - xyz.X + .5 ) + Sqr( tallz - xyz.Z + .5 ) ); float threshold = ( otherheight + height ) * .193f; - if( dist < threshold ) { + if ( dist < threshold ) { displaced = true; break; } } // ReSharper restore LoopCanBeConvertedToQuery - if( displaced ) continue; + if ( displaced ) + continue; treelist.Add( new RainforestTree { Args = args, Pos = xyz, @@ -252,19 +258,18 @@ static void PlantRainForestTrees( ForesterArgs args, ICollection treelist } } - - static void PlantMangroves( ForesterArgs args, ICollection treelist ) { + private static void PlantMangroves( ForesterArgs args, ICollection treelist ) { int treeheight = args.Height; int attempts = 0; - while( treelist.Count < args.TreeCount && attempts < MaxTries ) { + while ( treelist.Count < args.TreeCount && attempts < MaxTries ) { attempts++; int height = args.Rand.Next( treeheight - args.HeightVariation, treeheight + args.HeightVariation + 1 ); - int padding = (int)(height / 3f + 1); + int padding = ( int )( height / 3f + 1 ); int mindim = Math.Min( args.Map.Width, args.Map.Length ); - if( padding > mindim / 2.2 ) { - padding = (int)(mindim / 2.2); + if ( padding > mindim / 2.2 ) { + padding = ( int )( mindim / 2.2 ); } int x = args.Rand.Next( padding, args.Map.Width - padding - 1 ); int z = args.Rand.Next( padding, args.Map.Length - padding - 1 ); @@ -273,11 +278,11 @@ static void PlantMangroves( ForesterArgs args, ICollection treelist ) { int y = top - DistanceToBlock( args.Map, new Vector3F( x, z, top ), Vector3F.Down, Block.Air, true ); int dist = DistanceToBlock( args.Map, new Vector3F( x, z, y ), Vector3F.Down, Block.Water, true ); - if( dist > height * .618 || dist == 0 ) { + if ( dist > height * .618 || dist == 0 ) { continue; } - y += (int)Math.Sqrt( height - dist ) + 2; + y += ( int )Math.Sqrt( height - dist ) + 2; treelist.Add( new Tree { Args = args, Height = height, @@ -286,88 +291,99 @@ static void PlantMangroves( ForesterArgs args, ICollection treelist ) { } } - - static void ProcessTrees( ForesterArgs args, IList treelist ) { + private static void ProcessTrees( ForesterArgs args, IList treelist ) { TreeShape[] shapeChoices; - switch( args.Shape ) { + switch ( args.Shape ) { case TreeShape.Stickly: shapeChoices = new[]{ TreeShape.Normal, TreeShape.Bamboo, TreeShape.Palm }; break; + case TreeShape.Procedural: shapeChoices = new[]{ TreeShape.Round, TreeShape.Cone }; break; + default: shapeChoices = new[] { args.Shape }; break; } - for( int i = 0; i < treelist.Count; i++ ) { + for ( int i = 0; i < treelist.Count; i++ ) { TreeShape newshape = shapeChoices[args.Rand.Next( 0, shapeChoices.Length )]; Tree newTree; - switch( newshape ) { + switch ( newshape ) { case TreeShape.Normal: newTree = new NormalTree(); break; + case TreeShape.Bamboo: newTree = new BambooTree(); break; + case TreeShape.Palm: newTree = new PalmTree(); break; + case TreeShape.Round: newTree = new RoundTree(); break; + case TreeShape.Cone: newTree = new ConeTree(); break; + case TreeShape.Rainforest: newTree = new RainforestTree(); break; + case TreeShape.Mangrove: newTree = new MangroveTree(); break; + default: throw new ArgumentException( "Unknown tree shape type" ); } newTree.Copy( treelist[i] ); - if( args.MapHeightLimit ) { + if ( args.MapHeightLimit ) { int height = newTree.Height; int ybase = newTree.Pos[1]; int mapHeight = args.Map.Height; int foliageHeight; - if( args.Shape == TreeShape.Rainforest ) { + if ( args.Shape == TreeShape.Rainforest ) { foliageHeight = 2; } else { foliageHeight = 4; } - if( ybase + height + foliageHeight > mapHeight ) { + if ( ybase + height + foliageHeight > mapHeight ) { newTree.Height = mapHeight - ybase - foliageHeight; } } - if( newTree.Height < 1 ) newTree.Height = 1; + if ( newTree.Height < 1 ) + newTree.Height = 1; newTree.Prepare(); treelist[i] = newTree; } } - #region Trees - class Tree { + private class Tree { public Vector3I Pos; public int Height = 1; public ForesterArgs Args; - public virtual void Prepare() { } + public virtual void Prepare() { + } - public virtual void MakeTrunk() { } + public virtual void MakeTrunk() { + } - public virtual void MakeFoliage() { } + public virtual void MakeFoliage() { + } public void Copy( Tree other ) { Args = other.Args; @@ -376,32 +392,32 @@ public void Copy( Tree other ) { } } + private class StickTree : Tree { - class StickTree : Tree { public override void MakeTrunk() { - for( int i = 0; i < Height; i++ ) { + for ( int i = 0; i < Height; i++ ) { Args.PlaceBlock( Pos.X, Pos.Z, Pos.Y + i, Args.TrunkBlock ); } } } + private sealed class NormalTree : StickTree { - sealed class NormalTree : StickTree { public override void MakeFoliage() { int topy = Pos[1] + Height - 1; int start = topy - 2; int end = topy + 2; - for( int y = start; y < end; y++ ) { + for ( int y = start; y < end; y++ ) { int rad; - if( y > start + 1 ) { + if ( y > start + 1 ) { rad = 1; } else { rad = 2; } - for( int xoff = -rad; xoff < rad + 1; xoff++ ) { - for( int zoff = -rad; zoff < rad + 1; zoff++ ) { - if( Args.Rand.NextDouble() > .618 && + for ( int xoff = -rad; xoff < rad + 1; xoff++ ) { + for ( int zoff = -rad; zoff < rad + 1; zoff++ ) { + if ( Args.Rand.NextDouble() > .618 && Math.Abs( xoff ) == Math.Abs( zoff ) && Math.Abs( xoff ) == rad ) { continue; @@ -413,13 +429,13 @@ public override void MakeFoliage() { } } + private sealed class BambooTree : StickTree { - sealed class BambooTree : StickTree { public override void MakeFoliage() { int start = Pos[1]; int end = start + Height + 1; - for( int y = start; y < end; y++ ) { - for( int i = 0; i < 2; i++ ) { + for ( int y = start; y < end; y++ ) { + for ( int i = 0; i < 2; i++ ) { int xoff = Args.Rand.Next( 0, 2 ) * 2 - 1; int zoff = Args.Rand.Next( 0, 2 ) * 2 - 1; Args.PlaceBlock( Pos[0] + xoff, Pos[2] + zoff, y, Args.FoliageBlock ); @@ -428,13 +444,13 @@ public override void MakeFoliage() { } } + private sealed class PalmTree : StickTree { - sealed class PalmTree : StickTree { public override void MakeFoliage() { int y = Pos[1] + Height; - for( int xoff = -2; xoff < 3; xoff++ ) { - for( int zoff = -2; zoff < 3; zoff++ ) { - if( Math.Abs( xoff ) == Math.Abs( zoff ) ) { + for ( int xoff = -2; xoff < 3; xoff++ ) { + for ( int zoff = -2; zoff < 3; zoff++ ) { + if ( Math.Abs( xoff ) == Math.Abs( zoff ) ) { Args.PlaceBlock( Pos[0] + xoff, Pos[2] + zoff, y, Args.FoliageBlock ); } } @@ -442,33 +458,38 @@ public override void MakeFoliage() { } } - - class ProceduralTree : Tree { + private class ProceduralTree : Tree { // ReSharper disable MemberCanBePrivate.Local // ReSharper disable MemberCanBeProtected.Local public float TrunkRadius { get; set; } + public float BranchSlope { get; set; } + public float TrunkHeight { get; set; } + public float BranchDensity { get; set; } + public float[] FoliageShape { get; set; } + public Vector3I[] FoliageCoords { get; set; } + // ReSharper restore MemberCanBeProtected.Local // ReSharper restore MemberCanBePrivate.Local - - void CrossSection( Vector3I center, float radius, int diraxis, Block matidx ) { - int rad = (int)(radius + .618); - int secidx1 = (diraxis - 1) % 3; - int secidx2 = (diraxis + 1) % 3; + private void CrossSection( Vector3I center, float radius, int diraxis, Block matidx ) { + int rad = ( int )( radius + .618 ); + int secidx1 = ( diraxis - 1 ) % 3; + int secidx2 = ( diraxis + 1 ) % 3; Vector3I coord = new Vector3I(); - for( int off1 = -rad; off1 <= rad; off1++ ) { - for( int off2 = -rad; off2 <= rad; off2++ ) { - float thisdist = (float)Math.Sqrt( Sqr( Math.Abs( off1 ) + .5 ) + + for ( int off1 = -rad; off1 <= rad; off1++ ) { + for ( int off2 = -rad; off2 <= rad; off2++ ) { + float thisdist = ( float )Math.Sqrt( Sqr( Math.Abs( off1 ) + .5 ) + Sqr( Math.Abs( off2 ) + .5 ) ); - if( thisdist > radius ) continue; + if ( thisdist > radius ) + continue; int pri = center[diraxis]; int sec1 = center[secidx1] + off1; int sec2 = center[secidx2] + off2; @@ -480,50 +501,50 @@ void CrossSection( Vector3I center, float radius, int diraxis, Block matidx ) { } } - protected virtual float ShapeFunc( int z ) { - if( Args.Rand.NextDouble() < 100f / Sqr( Height ) && z < TrunkHeight ) { + if ( Args.Rand.NextDouble() < 100f / Sqr( Height ) && z < TrunkHeight ) { return Height * .12f; } else { return -1; } } - void FoliageCluster( Vector3I center ) { + private void FoliageCluster( Vector3I center ) { int z = center[1]; - foreach( float i in FoliageShape ) { + foreach ( float i in FoliageShape ) { CrossSection( new Vector3I( center[0], z, center[2] ), i, 1, Args.FoliageBlock ); z++; } } - void TaperedLimb( Vector3I start, Vector3I end, float startSize, float endSize ) { + private void TaperedLimb( Vector3I start, Vector3I end, float startSize, float endSize ) { Vector3I delta = end - start; - int primidx = (int)delta.LongestAxis; + int primidx = ( int )delta.LongestAxis; int maxdist = delta[primidx]; - if( maxdist == 0 ) return; - int primsign = (maxdist > 0 ? 1 : -1); + if ( maxdist == 0 ) + return; + int primsign = ( maxdist > 0 ? 1 : -1 ); - int secidx1 = (primidx - 1) % 3; - int secidx2 = (primidx + 1) % 3; + int secidx1 = ( primidx - 1 ) % 3; + int secidx2 = ( primidx + 1 ) % 3; int secdelta1 = delta[secidx1]; - float secfac1 = secdelta1 / (float)delta[primidx]; + float secfac1 = secdelta1 / ( float )delta[primidx]; int secdelta2 = delta[secidx2]; - float secfac2 = secdelta2 / (float)delta[primidx]; + float secfac2 = secdelta2 / ( float )delta[primidx]; Vector3I coord = new Vector3I(); int endoffset = delta[primidx] + primsign; - for( int primoffset = 0; primoffset < endoffset; primoffset += primsign ) { + for ( int primoffset = 0; primoffset < endoffset; primoffset += primsign ) { int primloc = start[primidx] + primoffset; - int secloc1 = (int)(start[secidx1] + primoffset * secfac1); - int secloc2 = (int)(start[secidx2] + primoffset * secfac2); + int secloc1 = ( int )( start[secidx1] + primoffset * secfac1 ); + int secloc2 = ( int )( start[secidx2] + primoffset * secfac2 ); coord[primidx] = primloc; coord[secidx1] = secloc1; coord[secidx2] = secloc2; float primdist = Math.Abs( delta[primidx] ); - float radius = endSize + (startSize - endSize) * Math.Abs( delta[primidx] - primoffset ) / primdist; + float radius = endSize + ( startSize - endSize ) * Math.Abs( delta[primidx] - primoffset ) / primdist; CrossSection( coord, radius, primidx, Args.TrunkBlock ); } @@ -531,81 +552,87 @@ void TaperedLimb( Vector3I start, Vector3I end, float startSize, float endSize ) } public override void MakeFoliage() { - foreach( Vector3I coord in FoliageCoords ) { + foreach ( Vector3I coord in FoliageCoords ) { FoliageCluster( coord ); } - foreach( Vector3I coord in FoliageCoords ) { + foreach ( Vector3I coord in FoliageCoords ) { Args.PlaceBlock( coord, Args.FoliageBlock ); } } - void MakeBranches() { - int topy = Pos[1] + (int)(TrunkHeight + .5); - float endrad = TrunkRadius * (1 - TrunkHeight / Height); - if( endrad < 1 ) endrad = 1; + private void MakeBranches() { + int topy = Pos[1] + ( int )( TrunkHeight + .5 ); + float endrad = TrunkRadius * ( 1 - TrunkHeight / Height ); + if ( endrad < 1 ) + endrad = 1; - foreach( Vector3I coord in FoliageCoords ) { - float dist = (float)Math.Sqrt( Sqr( coord.X - Pos.X ) + Sqr( coord.Z - Pos.Z ) ); + foreach ( Vector3I coord in FoliageCoords ) { + float dist = ( float )Math.Sqrt( Sqr( coord.X - Pos.X ) + Sqr( coord.Z - Pos.Z ) ); float ydist = coord[1] - Pos[1]; - float value = (BranchDensity * 220 * Height) / Cub( ydist + dist ); + float value = ( BranchDensity * 220 * Height ) / Cub( ydist + dist ); - if( value < Args.Rand.NextDouble() ) continue; + if ( value < Args.Rand.NextDouble() ) + continue; int posy = coord[1]; - float slope = (float)(BranchSlope + (.5 - Args.Rand.NextDouble()) * .16); + float slope = ( float )( BranchSlope + ( .5 - Args.Rand.NextDouble() ) * .16 ); float branchy, basesize; - if( coord[1] - dist * slope > topy ) { - float threshold = 1 / (float)Height; - if( Args.Rand.NextDouble() < threshold ) continue; + if ( coord[1] - dist * slope > topy ) { + float threshold = 1 / ( float )Height; + if ( Args.Rand.NextDouble() < threshold ) + continue; branchy = topy; basesize = endrad; } else { branchy = posy - dist * slope; - basesize = endrad + (TrunkRadius - endrad) * - (topy - branchy) / TrunkHeight; + basesize = endrad + ( TrunkRadius - endrad ) * + ( topy - branchy ) / TrunkHeight; } - float startsize = (float)(basesize * (1 + Args.Rand.NextDouble()) * - .618 * Math.Pow( dist / Height, .618 )); - float rndr = (float)(Math.Sqrt( Args.Rand.NextDouble() ) * basesize * .618); - float rndang = (float)(Args.Rand.NextDouble() * 2 * Math.PI); - int rndx = (int)(rndr * Math.Sin( rndang ) + .5); - int rndz = (int)(rndr * Math.Cos( rndang ) + .5); + float startsize = ( float )( basesize * ( 1 + Args.Rand.NextDouble() ) * + .618 * Math.Pow( dist / Height, .618 ) ); + float rndr = ( float )( Math.Sqrt( Args.Rand.NextDouble() ) * basesize * .618 ); + float rndang = ( float )( Args.Rand.NextDouble() * 2 * Math.PI ); + int rndx = ( int )( rndr * Math.Sin( rndang ) + .5 ); + int rndz = ( int )( rndr * Math.Cos( rndang ) + .5 ); Vector3I startcoord = new Vector3I { X = Pos[0] + rndx, Z = Pos[2] + rndz, - Y = (int)branchy + Y = ( int )branchy }; - if( startsize < 1 ) startsize = 1; + if ( startsize < 1 ) + startsize = 1; const float endsize = 1; TaperedLimb( startcoord, coord, startsize, endsize ); } } - struct RootBase { + private struct RootBase { public int X, Z; public float Radius; } - void MakeRoots( IList rootbases ) { - if( rootbases.Count == 0 ) return; - foreach( Vector3I coord in FoliageCoords ) { - float dist = (float)Math.Sqrt( Sqr( coord[0] - Pos[0] ) + Sqr( coord[2] - Pos[2] ) ); + private void MakeRoots( IList rootbases ) { + if ( rootbases.Count == 0 ) + return; + foreach ( Vector3I coord in FoliageCoords ) { + float dist = ( float )Math.Sqrt( Sqr( coord[0] - Pos[0] ) + Sqr( coord[2] - Pos[2] ) ); float ydist = coord[1] - Pos[1]; - float value = (BranchDensity * 220 * Height) / Cub( ydist + dist ); - if( value < Args.Rand.NextDouble() ) continue; + float value = ( BranchDensity * 220 * Height ) / Cub( ydist + dist ); + if ( value < Args.Rand.NextDouble() ) + continue; RootBase rootbase = rootbases[Args.Rand.Next( 0, rootbases.Count )]; int rootx = rootbase.X; int rootz = rootbase.Z; float rootbaseradius = rootbase.Radius; - float rndr = (float)(Math.Sqrt( Args.Rand.NextDouble() ) * rootbaseradius * .618); - float rndang = (float)(Args.Rand.NextDouble() * 2 * Math.PI); - int rndx = (int)(rndr * Math.Sin( rndang ) + .5); - int rndz = (int)(rndr * Math.Cos( rndang ) + .5); - int rndy = (int)(Args.Rand.NextDouble() * rootbaseradius * .5); + float rndr = ( float )( Math.Sqrt( Args.Rand.NextDouble() ) * rootbaseradius * .618 ); + float rndang = ( float )( Args.Rand.NextDouble() * 2 * Math.PI ); + int rndx = ( int )( rndr * Math.Sin( rndang ) + .5 ); + int rndz = ( int )( rndr * Math.Cos( rndang ) + .5 ); + int rndy = ( int )( Args.Rand.NextDouble() * rootbaseradius * .5 ); Vector3I startcoord = new Vector3I { X = rootx + rndx, Z = rootz + rndz, @@ -613,43 +640,45 @@ void MakeRoots( IList rootbases ) { }; Vector3F offset = new Vector3F( startcoord - coord ); - if( Args.Shape == TreeShape.Mangrove ) { + if ( Args.Shape == TreeShape.Mangrove ) { // offset = [int(val * 1.618 - 1.5) for val in offset] offset = offset * 1.618f - HalfBlock * 3; } Vector3I endcoord = startcoord + offset.RoundDown(); - float rootstartsize = (float)(rootbaseradius * .618 * Math.Abs( offset[1] ) / (Height * .618)); + float rootstartsize = ( float )( rootbaseradius * .618 * Math.Abs( offset[1] ) / ( Height * .618 ) ); - if( rootstartsize < 1 ) rootstartsize = 1; + if ( rootstartsize < 1 ) + rootstartsize = 1; const float endsize = 1; - if( Args.Roots == RootMode.ToStone || + if ( Args.Roots == RootMode.ToStone || Args.Roots == RootMode.Hanging ) { float offlength = offset.Length; - if( offlength < 1 ) continue; + if ( offlength < 1 ) + continue; float rootmid = endsize; Vector3F vec = offset / offlength; Block searchIndex = Block.Air; - if( Args.Roots == RootMode.ToStone ) { + if ( Args.Roots == RootMode.ToStone ) { searchIndex = Block.Stone; - } else if( Args.Roots == RootMode.Hanging ) { + } else if ( Args.Roots == RootMode.Hanging ) { searchIndex = Block.Air; } - int startdist = (int)(Args.Rand.NextDouble() * 6 * Math.Sqrt( rootstartsize ) + 2.8); + int startdist = ( int )( Args.Rand.NextDouble() * 6 * Math.Sqrt( rootstartsize ) + 2.8 ); Vector3I searchstart = new Vector3I( startcoord + vec * startdist ); dist = startdist + DistanceToBlock( Args.Map, new Vector3F( searchstart ), vec, searchIndex ); - if( dist < offlength ) { - rootmid += (rootstartsize - endsize) * (1 - dist / offlength); + if ( dist < offlength ) { + rootmid += ( rootstartsize - endsize ) * ( 1 - dist / offlength ); endcoord = new Vector3I( startcoord + vec * dist ); - if( Args.Roots == RootMode.Hanging ) { + if ( Args.Roots == RootMode.Hanging ) { float remainingDist = offlength - dist; Vector3I bottomcord = endcoord; - bottomcord[1] -= (int)remainingDist; + bottomcord[1] -= ( int )remainingDist; TaperedLimb( endcoord, bottomcord, rootmid, endsize ); } } @@ -662,20 +691,22 @@ void MakeRoots( IList rootbases ) { public override void MakeTrunk() { int starty = Pos[1]; - int midy = (int)(Pos[1] + TrunkHeight * .382); - int topy = (int)(Pos[1] + TrunkHeight + .5); + int midy = ( int )( Pos[1] + TrunkHeight * .382 ); + int topy = ( int )( Pos[1] + TrunkHeight + .5 ); int x = Pos[0]; int z = Pos[2]; float midrad = TrunkRadius * .8f; - float endrad = TrunkRadius * (1 - TrunkHeight / Height); + float endrad = TrunkRadius * ( 1 - TrunkHeight / Height ); - if( endrad < 1 ) endrad = 1; - if( midrad < endrad ) midrad = endrad; + if ( endrad < 1 ) + endrad = 1; + if ( midrad < endrad ) + midrad = endrad; float startrad; List rootbases = new List(); - if( Args.RootButtresses || Args.Shape == TreeShape.Mangrove ) { + if ( Args.RootButtresses || Args.Shape == TreeShape.Mangrove ) { startrad = TrunkRadius * .8f; rootbases.Add( new RootBase { X = x, @@ -684,18 +715,19 @@ public override void MakeTrunk() { } ); float buttressRadius = TrunkRadius * .382f; float posradius = TrunkRadius; - if( Args.Shape == TreeShape.Mangrove ) { + if ( Args.Shape == TreeShape.Mangrove ) { posradius *= 2.618f; } - int numOfButtresss = (int)(Math.Sqrt( TrunkRadius ) + 3.5); - for( int i = 0; i < numOfButtresss; i++ ) { - float rndang = (float)(Args.Rand.NextDouble() * 2 * Math.PI); - float thisposradius = (float)(posradius * (.9 + Args.Rand.NextDouble() * .2)); - int thisx = x + (int)(thisposradius * Math.Sin( rndang )); - int thisz = z + (int)(thisposradius * Math.Cos( rndang )); + int numOfButtresss = ( int )( Math.Sqrt( TrunkRadius ) + 3.5 ); + for ( int i = 0; i < numOfButtresss; i++ ) { + float rndang = ( float )( Args.Rand.NextDouble() * 2 * Math.PI ); + float thisposradius = ( float )( posradius * ( .9 + Args.Rand.NextDouble() * .2 ) ); + int thisx = x + ( int )( thisposradius * Math.Sin( rndang ) ); + int thisz = z + ( int )( thisposradius * Math.Cos( rndang ) ); - float thisbuttressradius = (float)(buttressRadius * (.618 + Args.Rand.NextDouble())); - if( thisbuttressradius < 1 ) thisbuttressradius = 1; + float thisbuttressradius = ( float )( buttressRadius * ( .618 + Args.Rand.NextDouble() ) ); + if ( thisbuttressradius < 1 ) + thisbuttressradius = 1; TaperedLimb( new Vector3I( thisx, starty, thisz ), new Vector3I( x, midy, z ), thisbuttressradius, thisbuttressradius ); @@ -716,33 +748,36 @@ public override void MakeTrunk() { TaperedLimb( new Vector3I( x, starty, z ), new Vector3I( x, midy, z ), startrad, midrad ); TaperedLimb( new Vector3I( x, midy, z ), new Vector3I( x, topy, z ), midrad, endrad ); MakeBranches(); - if( Args.Roots != RootMode.None ) { + if ( Args.Roots != RootMode.None ) { MakeRoots( rootbases.ToArray() ); } } public override void Prepare() { base.Prepare(); - TrunkRadius = (float)Math.Sqrt( Height * Args.TrunkThickness ); - if( TrunkRadius < 1 ) TrunkRadius = 1; + TrunkRadius = ( float )Math.Sqrt( Height * Args.TrunkThickness ); + if ( TrunkRadius < 1 ) + TrunkRadius = 1; TrunkHeight = Height * .618f; - BranchDensity = (Args.BranchDensity / Args.FoliageDensity); + BranchDensity = ( Args.BranchDensity / Args.FoliageDensity ); int ystart = Pos[1]; - int yend = (Pos[1] + Height); - int numOfClustersPerY = (int)(1.5 + Sqr( Args.FoliageDensity * Height / 19f )); - if( numOfClustersPerY < 1 ) numOfClustersPerY = 1; + int yend = ( Pos[1] + Height ); + int numOfClustersPerY = ( int )( 1.5 + Sqr( Args.FoliageDensity * Height / 19f ) ); + if ( numOfClustersPerY < 1 ) + numOfClustersPerY = 1; List foliageCoords = new List(); - for( int y = yend - 1; y >= ystart; y-- ) { - for( int i = 0; i < numOfClustersPerY; i++ ) { + for ( int y = yend - 1; y >= ystart; y-- ) { + for ( int i = 0; i < numOfClustersPerY; i++ ) { float shapefac = ShapeFunc( y - ystart ); - if( shapefac < 0 ) continue; - float r = (float)((Math.Sqrt( Args.Rand.NextDouble() ) + .328) * shapefac); - float theta = (float)(Args.Rand.NextDouble() * 2 * Math.PI); - int x = (int)(r * Math.Sin( theta )) + Pos[0]; - int z = (int)(r * Math.Cos( theta )) + Pos[2]; + if ( shapefac < 0 ) + continue; + float r = ( float )( ( Math.Sqrt( Args.Rand.NextDouble() ) + .328 ) * shapefac ); + float theta = ( float )( Args.Rand.NextDouble() * 2 * Math.PI ); + int x = ( int )( r * Math.Sin( theta ) ) + Pos[0]; + int z = ( int )( r * Math.Cos( theta ) ) + Pos[2]; foliageCoords.Add( new Vector3I( x, y, z ) ); } } @@ -750,8 +785,8 @@ public override void Prepare() { } } + private class RoundTree : ProceduralTree { - class RoundTree : ProceduralTree { public override void Prepare() { base.Prepare(); BranchSlope = .382f; @@ -760,32 +795,32 @@ public override void Prepare() { TrunkHeight = Args.TrunkHeight * Height; } - protected override float ShapeFunc( int y ) { float twigs = base.ShapeFunc( y ); - if( twigs >= 0 ) return twigs; + if ( twigs >= 0 ) + return twigs; - if( y < Height * (.282 + .1 * Math.Sqrt( Args.Rand.NextDouble() )) ) { + if ( y < Height * ( .282 + .1 * Math.Sqrt( Args.Rand.NextDouble() ) ) ) { return -1; } float radius = Height / 2f; float adj = Height / 2f - y; float dist; - if( adj == 0 ) { + if ( adj == 0 ) { dist = radius; - } else if( Math.Abs( adj ) >= radius ) { + } else if ( Math.Abs( adj ) >= radius ) { dist = 0; } else { - dist = (float)Math.Sqrt( radius * radius - adj * adj ); + dist = ( float )Math.Sqrt( radius * radius - adj * adj ); } dist *= .618f; return dist; } } + private sealed class ConeTree : ProceduralTree { - sealed class ConeTree : ProceduralTree { public override void Prepare() { base.Prepare(); BranchSlope = .15f; @@ -794,21 +829,22 @@ public override void Prepare() { TrunkHeight = Height; } - protected override float ShapeFunc( int y ) { float twigs = base.ShapeFunc( y ); - if( twigs >= 0 ) return twigs; - if( y < Height * (.25 + .05 * Math.Sqrt( Args.Rand.NextDouble() )) ) { + if ( twigs >= 0 ) + return twigs; + if ( y < Height * ( .25 + .05 * Math.Sqrt( Args.Rand.NextDouble() ) ) ) { return -1; } - float radius = (Height - y) * .382f; - if( radius < 0 ) radius = 0; + float radius = ( Height - y ) * .382f; + if ( radius < 0 ) + radius = 0; return radius; } } + private sealed class RainforestTree : ProceduralTree { - sealed class RainforestTree : ProceduralTree { public override void Prepare() { FoliageShape = new[] { 3.4f, 2.6f }; base.Prepare(); @@ -817,59 +853,58 @@ public override void Prepare() { TrunkHeight = Height * .9f; } - protected override float ShapeFunc( int y ) { - if( y < Height * .8 ) { - if( Args.Height < Height ) { + if ( y < Height * .8 ) { + if ( Args.Height < Height ) { float twigs = base.ShapeFunc( y ); - if( twigs >= 0 && Args.Rand.NextDouble() < .05 ) { + if ( twigs >= 0 && Args.Rand.NextDouble() < .05 ) { return twigs; } } return -1; } else { float width = Height * .382f; - float topdist = (Height - y) / (Height * .2f); - float dist = (float)(width * (.618 + topdist) * (.618 + Args.Rand.NextDouble()) * .382); + float topdist = ( Height - y ) / ( Height * .2f ); + float dist = ( float )( width * ( .618 + topdist ) * ( .618 + Args.Rand.NextDouble() ) * .382 ); return dist; } } } + private sealed class MangroveTree : RoundTree { - sealed class MangroveTree : RoundTree { public override void Prepare() { base.Prepare(); BranchSlope = 1; TrunkRadius *= .618f; } - protected override float ShapeFunc( int y ) { float val = base.ShapeFunc( y ); - if( val < 0 ) return -1; + if ( val < 0 ) + return -1; val *= 1.618f; return val; } } - #endregion - + #endregion Trees #region Math Helpers - static int DistanceToBlock( Map map, Vector3F coord, Vector3F vec, Block blockType ) { + private static int DistanceToBlock( Map map, Vector3F coord, Vector3F vec, Block blockType ) { return DistanceToBlock( map, coord, vec, blockType, false ); } - static readonly Vector3F HalfBlock = new Vector3F( .5f, .5f, .5f ); - static int DistanceToBlock( Map map, Vector3F coord, Vector3F vec, Block blockType, bool invert ) { + private static readonly Vector3F HalfBlock = new Vector3F( .5f, .5f, .5f ); + + private static int DistanceToBlock( Map map, Vector3F coord, Vector3F vec, Block blockType, bool invert ) { coord += HalfBlock; int iterations = 0; - while( map.InBounds( new Vector3I( coord ) ) ) { + while ( map.InBounds( new Vector3I( coord ) ) ) { Block blockAtPos = map.GetBlock( new Vector3I( coord ) ); - if( (blockAtPos == blockType && !invert) || - (blockAtPos != blockType && invert) ) { + if ( ( blockAtPos == blockType && !invert ) || + ( blockAtPos != blockType && invert ) ) { break; } else { coord += vec; @@ -879,24 +914,23 @@ static int DistanceToBlock( Map map, Vector3F coord, Vector3F vec, Block blockTy return iterations; } - static float Sqr( float val ) { + private static float Sqr( float val ) { return val * val; } - static float Cub( float val ) { + private static float Cub( float val ) { return val * val * val; } - static int Sqr( int val ) { + private static int Sqr( int val ) { return val * val; } - static double Sqr( double val ) { + private static double Sqr( double val ) { return val * val; } - #endregion - + #endregion Math Helpers #region Enumerations @@ -926,7 +960,7 @@ public enum RootMode { None } - #endregion + #endregion Enumerations } // TODO: Add a UI to ConfigGUI.AddWorldPopup to set these @@ -957,22 +991,31 @@ public sealed class ForesterArgs { internal void PlaceBlock( int x, int y, int z, Block block ) { var h = BlockPlacing; - if( h != null ) h( this, new ForesterBlockPlacingEventArgs( new Vector3I( x, y, z ), block ) ); + if ( h != null ) + h( this, new ForesterBlockPlacingEventArgs( new Vector3I( x, y, z ), block ) ); } internal void PlaceBlock( Vector3I coord, Block block ) { var h = BlockPlacing; - if( h != null ) h( this, new ForesterBlockPlacingEventArgs( new Vector3I(coord.X,coord.Z,coord.Y), block ) ); // todo: rewrite the whole thing to use XYZ coords + if ( h != null ) + h( this, new ForesterBlockPlacingEventArgs( new Vector3I( coord.X, coord.Z, coord.Y ), block ) ); // todo: rewrite the whole thing to use XYZ coords } internal void Validate() { - if( TreeCount < 0 ) TreeCount = 0; - if( Height < 1 ) Height = 1; - if( HeightVariation > Height ) HeightVariation = Height; - if( TrunkThickness < 0 ) TrunkThickness = 0; - if( TrunkHeight < 0 ) TrunkHeight = 0; - if( FoliageDensity < 0 ) FoliageDensity = 0; - if( BranchDensity < 0 ) BranchDensity = 0; + if ( TreeCount < 0 ) + TreeCount = 0; + if ( Height < 1 ) + Height = 1; + if ( HeightVariation > Height ) + HeightVariation = Height; + if ( TrunkThickness < 0 ) + TrunkThickness = 0; + if ( TrunkHeight < 0 ) + TrunkHeight = 0; + if ( FoliageDensity < 0 ) + FoliageDensity = 0; + if ( BranchDensity < 0 ) + BranchDensity = 0; } } } \ No newline at end of file diff --git a/fCraft/World/Map.cs b/fCraft/World/Map.cs index 469c18e..fbf6b7d 100644 --- a/fCraft/World/Map.cs +++ b/fCraft/World/Map.cs @@ -1,5 +1,6 @@ // Copyright 2009-2013 Matvei Stefarov using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.IO.Compression; @@ -8,9 +9,9 @@ using fCraft.Drawing; using fCraft.MapConversion; using JetBrains.Annotations; -using System.Collections.Concurrent; namespace fCraft { + public unsafe sealed class Map { public const MapFormat SaveFormat = MapFormat.FCMv3; @@ -33,9 +34,9 @@ public unsafe sealed class Map { /// Map volume, in terms of blocks. public readonly int Volume; - /// Default spawning point on the map. - Position spawn; + private Position spawn; + public Position Spawn { get { return spawn; @@ -54,7 +55,6 @@ public void ResetSpawn() { Math.Min( short.MaxValue, Height * 32 ) ); } - /// Whether the map was modified since last time it was saved. public bool HasChangedSinceSave { get; internal set; } @@ -66,20 +66,25 @@ public void ResetSpawn() { //doors public System.Collections.ArrayList Doors; + public int DoorID = 1; //Portals public System.Collections.ArrayList Portals; + public int portalID = 1; //MessageBlocks public System.Collections.ArrayList MessageBlocks; - public int MessageBlockID = 1; + public int MessageBlockID = 1; #region FCMv3 additions + public DateTime DateModified { get; set; } + public DateTime DateCreated { get; set; } + public Guid Guid { get; set; } /// Array of map blocks. @@ -93,8 +98,8 @@ public void ResetSpawn() { /// All zones within a map. public ZoneCollection Zones { get; private set; } - internal Dictionary LifeZones { get; private set; } + internal Dictionary LifeZones { get; private set; } /// Creates an empty new map of given dimensions. /// Dimensions cannot be changed after creation. @@ -104,9 +109,12 @@ public void ResetSpawn() { /// Height (vertical, Notch's Y). /// If true, the Blocks array will be created. public Map( World world, int width, int length, int height, bool initBlockArray ) { - if( !IsValidDimension( width ) ) throw new ArgumentException( "Invalid map dimension.", "width" ); - if( !IsValidDimension( length ) ) throw new ArgumentException( "Invalid map dimension.", "length" ); - if( !IsValidDimension( height ) ) throw new ArgumentException( "Invalid map dimension.", "height" ); + if ( !IsValidDimension( width ) ) + throw new ArgumentException( "Invalid map dimension.", "width" ); + if ( !IsValidDimension( length ) ) + throw new ArgumentException( "Invalid map dimension.", "length" ); + if ( !IsValidDimension( height ) ) + throw new ArgumentException( "Invalid map dimension.", "height" ); DateCreated = DateTime.UtcNow; DateModified = DateCreated; Guid = Guid.NewGuid(); @@ -125,41 +133,41 @@ public Map( World world, int width, int length, int height, bool initBlockArray Bounds = new BoundingBox( Vector3I.Zero, Width, Length, Height ); Volume = Bounds.Volume; - if( initBlockArray ) { + if ( initBlockArray ) { Blocks = new byte[Volume]; } - LifeZones = new Dictionary(); + LifeZones = new Dictionary(); ResetSpawn(); } - - void OnMetaOrZoneChange( object sender, EventArgs args ) { + private void OnMetaOrZoneChange( object sender, EventArgs args ) { HasChangedSinceSave = true; } -#endregion + + #endregion FCMv3 additions #region Saving /// Saves this map to a file in the default format (FCMv3). /// Whether the saving succeeded. public bool Save( [NotNull] string fileName ) { - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); string tempFileName = fileName + ".temp"; // save to a temporary file try { HasChangedSinceSave = false; - if( !MapUtility.TrySave( this, tempFileName, SaveFormat ) ) { + if ( !MapUtility.TrySave( this, tempFileName, SaveFormat ) ) { HasChangedSinceSave = true; } - - } catch( IOException ex ) { + } catch ( IOException ex ) { HasChangedSinceSave = true; Logger.Log( LogType.Error, "Map.Save: Unable to open file \"{0}\" for writing: {1}", tempFileName, ex ); - if( File.Exists( tempFileName ) ) + if ( File.Exists( tempFileName ) ) File.Delete( tempFileName ); return false; } @@ -170,13 +178,12 @@ public bool Save( [NotNull] string fileName ) { Logger.Log( LogType.SystemActivity, "Saved map to {0}", fileName ); HasChangedSinceBackup = true; - - } catch( Exception ex ) { + } catch ( Exception ex ) { HasChangedSinceSave = true; Logger.Log( LogType.Error, "Map.Save: Error trying to replace file \"{0}\": {1}", fileName, ex ); - if( File.Exists( tempFileName ) ) + if ( File.Exists( tempFileName ) ) File.Delete( tempFileName ); return false; } @@ -184,8 +191,7 @@ public bool Save( [NotNull] string fileName ) { // ReSharper restore EmptyGeneralCatchClause } - #endregion - + #endregion Saving #region Block Getters / Setters @@ -195,18 +201,16 @@ public bool Save( [NotNull] string fileName ) { /// Z coordinate (height, Notch's Y). /// Index of the block in Map.Blocks array. public int Index( int x, int y, int z ) { - return (z * Length + y) * Width + x; + return ( z * Length + y ) * Width + x; } - /// Converts given coordinates to a block array index. /// Coordinate vector (X,Y,Z). /// Index of the block in Map.Blocks array. public int Index( Vector3I coords ) { - return (coords.Z * Length + coords.Y) * Width + coords.X; + return ( coords.Z * Length + coords.Y ) * Width + coords.X; } - /// Sets a block in a safe way. /// Note that using SetBlock does not relay changes to players. /// Use QueueUpdate() for changing blocks on live maps/worlds. @@ -215,46 +219,42 @@ public int Index( Vector3I coords ) { /// Z coordinate (height, Notch's Y). /// Block type to set. public void SetBlock( int x, int y, int z, Block type ) { - if( x < Width && y < Length && z < Height && x >= 0 && y >= 0 && z >= 0 ) { - Blocks[Index( x, y, z )] = (byte)type; + if ( x < Width && y < Length && z < Height && x >= 0 && y >= 0 && z >= 0 ) { + Blocks[Index( x, y, z )] = ( byte )type; HasChangedSinceSave = true; } } - /// Sets a block at given coordinates. Checks bounds. /// Coordinate vector (X,Y,Z). /// Block type to set. public void SetBlock( Vector3I coords, Block type ) { - if( coords.X < Width && coords.Y < Length && coords.Z < Height && coords.X >= 0 && coords.Y >= 0 && coords.Z >= 0 && (byte)type < 50 ) { - Blocks[Index( coords )] = (byte)type; + if ( coords.X < Width && coords.Y < Length && coords.Z < Height && coords.X >= 0 && coords.Y >= 0 && coords.Z >= 0 && ( byte )type < 50 ) { + Blocks[Index( coords )] = ( byte )type; HasChangedSinceSave = true; } } - /// Gets a block at given coordinates. Checks bounds. /// X coordinate (width). /// Y coordinate (length, Notch's Z). /// Z coordinate (height, Notch's Y). /// Block type, as a Block enumeration. Undefined if coordinates were out of bounds. public Block GetBlock( int x, int y, int z ) { - if( x < Width && y < Length && z < Height && x >= 0 && y >= 0 && z >= 0 ) - return (Block)Blocks[Index( x, y, z )]; + if ( x < Width && y < Length && z < Height && x >= 0 && y >= 0 && z >= 0 ) + return ( Block )Blocks[Index( x, y, z )]; return Block.Undefined; } - /// Gets a block at given coordinates. Checks bounds. /// Coordinate vector (X,Y,Z). /// Block type, as a Block enumeration. Undefined if coordinates were out of bounds. public Block GetBlock( Vector3I coords ) { - if( coords.X < Width && coords.Y < Length && coords.Z < Height && coords.X >= 0 && coords.Y >= 0 && coords.Z >= 0 ) - return (Block)Blocks[Index( coords )]; + if ( coords.X < Width && coords.Y < Length && coords.Z < Height && coords.X >= 0 && coords.Y >= 0 && coords.Z >= 0 ) + return ( Block )Blocks[Index( coords )]; return Block.Undefined; } - /// Checks whether the given coordinate (in block units) is within the bounds of the map. /// X coordinate (width). /// Y coordinate (length, Notch's Z). @@ -263,28 +263,24 @@ public bool InBounds( int x, int y, int z ) { return x < Width && y < Length && z < Height && x >= 0 && y >= 0 && z >= 0; } - /// Checks whether the given coordinate (in block units) is within the bounds of the map. /// Coordinate vector (X,Y,Z). public bool InBounds( Vector3I vec ) { return vec.X < Width && vec.Y < Length && vec.Z < Height && vec.X >= 0 && vec.Y >= 0 && vec.Z >= 0; } - #endregion - + #endregion Block Getters / Setters #region Block Updates & Simulation // Queue of block updates. Updates are applied by ProcessUpdates() - ConcurrentQueue updates = new ConcurrentQueue(); - + private ConcurrentQueue updates = new ConcurrentQueue(); /// Number of blocks that are waiting to be processed. public int UpdateQueueLength { get { return updates.Count; } } - /// Queues a new block update to be processed. /// Due to concurrent nature of the server, there is no guarantee /// that updates will be applied in any specific order. @@ -292,21 +288,19 @@ public void QueueUpdate( BlockUpdate update ) { updates.Enqueue( update ); } - /// Clears all pending updates. public void ClearUpdateQueue() { updates = new ConcurrentQueue(); } - // Applies pending updates and sends them to players (if applicable). internal void ProcessUpdates() { - if( World == null ) { + if ( World == null ) { throw new InvalidOperationException( "Map must be assigned to a world to process updates." ); } - if( World.IsLocked ) { - if( World.IsPendingMapUnload ) { + if ( World.IsLocked ) { + if ( World.IsPendingMapUnload ) { World.UnloadMap( true ); } return; @@ -315,42 +309,42 @@ internal void ProcessUpdates() { int packetsSent = 0; bool canFlush = false; int maxPacketsPerUpdate = Server.CalculateMaxPacketsPerUpdate( World ); - while( packetsSent < maxPacketsPerUpdate ) { + while ( packetsSent < maxPacketsPerUpdate ) { BlockUpdate update; - if( !updates.TryDequeue( out update ) ) { - if( World.IsFlushing ) { + if ( !updates.TryDequeue( out update ) ) { + if ( World.IsFlushing ) { canFlush = true; } break; } - if( !InBounds( update.X, update.Y, update.Z ) ) continue; + if ( !InBounds( update.X, update.Y, update.Z ) ) + continue; int blockIndex = Index( update.X, update.Y, update.Z ); - Blocks[blockIndex] = (byte)update.BlockType; + Blocks[blockIndex] = ( byte )update.BlockType; - if( !World.IsFlushing ) { + if ( !World.IsFlushing ) { Packet packet = PacketWriter.MakeSetBlock( update.X, update.Y, update.Z, update.BlockType ); World.Players.SendLowPriority( update.Origin, packet ); } packetsSent++; } - if( drawOps.Count > 0 ) { - lock( drawOpLock ) { - if( drawOps.Count > 0 ) { + if ( drawOps.Count > 0 ) { + lock ( drawOpLock ) { + if ( drawOps.Count > 0 ) { packetsSent += ProcessDrawOps( maxPacketsPerUpdate - packetsSent ); } } - } else if( canFlush ) { + } else if ( canFlush ) { World.EndFlushMapBuffer(); } - if( packetsSent == 0 && World.IsPendingMapUnload ) { + if ( packetsSent == 0 && World.IsPendingMapUnload ) { World.UnloadMap( true ); } } - #endregion - + #endregion Block Updates & Simulation #region Draw Operations @@ -360,33 +354,33 @@ public int DrawQueueLength { public int DrawQueueBlockCount { get { - lock( drawOpLock ) { + lock ( drawOpLock ) { return drawOps.Sum( op => op.BlocksLeftToProcess ); } } } - readonly List drawOps = new List(); - - readonly object drawOpLock = new object(); + private readonly List drawOps = new List(); + private readonly object drawOpLock = new object(); internal void QueueDrawOp( [NotNull] DrawOperation op ) { - if( op == null ) throw new ArgumentNullException( "op" ); - lock( drawOpLock ) { + if ( op == null ) + throw new ArgumentNullException( "op" ); + lock ( drawOpLock ) { drawOps.Add( op ); } } - - int ProcessDrawOps( int maxTotalUpdates ) { - if( World == null ) throw new InvalidOperationException( "No world assigned" ); + private int ProcessDrawOps( int maxTotalUpdates ) { + if ( World == null ) + throw new InvalidOperationException( "No world assigned" ); int blocksDrawnTotal = 0; - for( int i = 0; i < drawOps.Count; i++ ) { + for ( int i = 0; i < drawOps.Count; i++ ) { DrawOperation op = drawOps[i]; // remove a cancelled drawOp from the list - if( op.IsCancelled ) { + if ( op.IsCancelled ) { op.End(); drawOps.RemoveAt( i ); i--; @@ -394,15 +388,15 @@ int ProcessDrawOps( int maxTotalUpdates ) { } // draw a batch of blocks - int blocksToDraw = maxTotalUpdates / (drawOps.Count - i); + int blocksToDraw = maxTotalUpdates / ( drawOps.Count - i ); op.StartBatch(); #if DEBUG int blocksDrawn = op.DrawBatch( blocksToDraw ); #else int blocksDrawn; - try{ + try { blocksDrawn = op.DrawBatch( blocksToDraw ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.LogAndReportCrash( "DrawOp error", "fCraft", ex, false ); op.Player.Message( "&WError occured in your draw command: {0}: {1}", ex.GetType().Name, ex.Message ); @@ -412,13 +406,13 @@ int ProcessDrawOps( int maxTotalUpdates ) { } #endif blocksDrawnTotal += blocksDrawn; - if( blocksDrawn > 0 ) { + if ( blocksDrawn > 0 ) { HasChangedSinceSave = true; } maxTotalUpdates -= blocksDrawn; // remove a completed drawOp from the list - if( op.IsDone ) { + if ( op.IsDone ) { op.End(); drawOps.RemoveAt( i ); i--; @@ -427,10 +421,9 @@ int ProcessDrawOps( int maxTotalUpdates ) { return blocksDrawnTotal; } - public void StopAllDrawOps() { - lock( drawOpLock ) { - for( int i = 0; i < drawOps.Count; i++ ) { + lock ( drawOpLock ) { + for ( int i = 0; i < drawOps.Count; i++ ) { drawOps[i].Cancel(); drawOps[i].End(); } @@ -438,31 +431,30 @@ public void StopAllDrawOps() { } } - #endregion - + #endregion Draw Operations #region Utilities public bool ValidateHeader() { - if( !IsValidDimension( Width ) ) { + if ( !IsValidDimension( Width ) ) { Logger.Log( LogType.Error, "Map.ValidateHeader: Unsupported map width: {0}.", Width ); return false; } - if( !IsValidDimension( Length ) ) { + if ( !IsValidDimension( Length ) ) { Logger.Log( LogType.Error, "Map.ValidateHeader: Unsupported map length: {0}.", Length ); return false; } - if( !IsValidDimension( Height ) ) { + if ( !IsValidDimension( Height ) ) { Logger.Log( LogType.Error, "Map.ValidateHeader: Unsupported map height: {0}.", Height ); return false; } - if( Spawn.X > Width * 32 || Spawn.Y > Length * 32 || Spawn.Z > Height * 32 || Spawn.X < 0 || Spawn.Y < 0 || Spawn.Z < 0 ) { + if ( Spawn.X > Width * 32 || Spawn.Y > Length * 32 || Spawn.Z > Height * 32 || Spawn.X < 0 || Spawn.Y < 0 || Spawn.Z < 0 ) { Logger.Log( LogType.Warning, "Map.ValidateHeader: Spawn coordinates are outside the valid range! Using center of the map instead." ); ResetSpawn(); @@ -471,42 +463,42 @@ public bool ValidateHeader() { return true; } - /// Checks if a given map dimension (width, height, or length) is acceptible. /// Values between 1 and 2047 are technically allowed. public static bool IsValidDimension( int dimension ) { return dimension >= 16 && dimension <= 2048; } - /// Checks if a given map dimension (width, height, or length) is among the set of recommended values /// Recommended values are: 16, 32, 64, 128, 256, 512, 1024 public static bool IsRecommendedDimension( int dimension ) { - return dimension >= 16 && (dimension & (dimension - 1)) == 0 && dimension <= 1024; + return dimension >= 16 && ( dimension & ( dimension - 1 ) ) == 0 && dimension <= 1024; } - /// Converts nonstandard (50-255) blocks using the given mapping. /// Byte array of length 256. /// True if any blocks needed conversion/mapping. public bool ConvertBlockTypes( [NotNull] byte[] mapping ) { - if( mapping == null ) throw new ArgumentNullException( "mapping" ); - if( mapping.Length != 256 ) throw new ArgumentException( "Mapping must list all 256 blocks", "mapping" ); + if ( mapping == null ) + throw new ArgumentNullException( "mapping" ); + if ( mapping.Length != 256 ) + throw new ArgumentException( "Mapping must list all 256 blocks", "mapping" ); bool mapped = false; - fixed( byte* ptr = Blocks ) { - for( int j = 0; j < Blocks.Length; j++ ) { - if( ptr[j] > 49 ) { + fixed ( byte* ptr = Blocks ) { + for ( int j = 0; j < Blocks.Length; j++ ) { + if ( ptr[j] > 49 ) { ptr[j] = mapping[ptr[j]]; mapped = true; } } } - if( mapped ) HasChangedSinceSave = true; + if ( mapped ) + HasChangedSinceSave = true; return mapped; } - static readonly byte[] ZeroMapping = new byte[256]; + private static readonly byte[] ZeroMapping = new byte[256]; /// Replaces all nonstandard (50-255) blocks with air. /// True if any blocks needed replacement. @@ -514,16 +506,15 @@ public bool RemoveUnknownBlocktypes() { return ConvertBlockTypes( ZeroMapping ); } - - static readonly Dictionary BlockNames = new Dictionary(); - static readonly Dictionary BlockEdgeTextures = new Dictionary(); + private static readonly Dictionary BlockNames = new Dictionary(); + private static readonly Dictionary BlockEdgeTextures = new Dictionary(); static Map() { // add default names for blocks, and their numeric codes - foreach( Block block in Enum.GetValues( typeof( Block ) ) ) { - if( block != Block.Undefined ) { + foreach ( Block block in Enum.GetValues( typeof( Block ) ) ) { + if ( block != Block.Undefined ) { BlockNames.Add( block.ToString().ToLower(), block ); - BlockNames.Add( ((int)block).ToString(), block ); + BlockNames.Add( ( ( int )block ).ToString(), block ); } } @@ -728,15 +719,15 @@ static Map() { BlockEdgeTextures[Block.Yellow] = "eff6823a987deb65ad21020a3151bb809d3d062c"; } - public void CalculateShadows() { - if( Shadows != null ) return; + if ( Shadows != null ) + return; Shadows = new short[Width, Length]; - for( int x = 0; x < Width; x++ ) { - for( int y = 0; y < Length; y++ ) { - for( short z = (short)(Height - 1); z >= 0; z-- ) { - switch( GetBlock( x, y, z ) ) { + for ( int x = 0; x < Width; x++ ) { + for ( int y = 0; y < Length; y++ ) { + for ( short z = ( short )( Height - 1 ); z >= 0; z-- ) { + switch ( GetBlock( x, y, z ) ) { case Block.Air: case Block.BrownMushroom: case Block.Glass: @@ -755,14 +746,14 @@ public void CalculateShadows() { } } - /// Tries to find a blocktype by name. /// Name of the block. /// Described Block, or Block.Undefined if name could not be recognized. public static Block GetBlockByName( [NotNull] string blockName ) { - if( blockName == null ) throw new ArgumentNullException( "blockName" ); + if ( blockName == null ) + throw new ArgumentNullException( "blockName" ); Block result; - if( BlockNames.TryGetValue( blockName.ToLower(), out result ) ) { + if ( BlockNames.TryGetValue( blockName.ToLower(), out result ) ) { return result; } else { return Block.Undefined; @@ -775,21 +766,21 @@ public static Block GetBlockByName( [NotNull] string blockName ) { [CanBeNull] internal static string GetEdgeTexture( Block block ) { string result; - if( BlockEdgeTextures.TryGetValue( block, out result ) ) { + if ( BlockEdgeTextures.TryGetValue( block, out result ) ) { return result; } else { return null; } } - /// Writes a copy of the current map to a given stream, compressed with GZipStream. /// Stream to write the compressed data to. /// If true, prepends block data with signed, 32bit, big-endian block count. public void GetCompressedCopy( [NotNull] Stream stream, bool prependBlockCount ) { - if( stream == null ) throw new ArgumentNullException( "stream" ); - using( GZipStream compressor = new GZipStream( stream, CompressionMode.Compress ) ) { - if( prependBlockCount ) { + if ( stream == null ) + throw new ArgumentNullException( "stream" ); + using ( GZipStream compressor = new GZipStream( stream, CompressionMode.Compress ) ) { + if ( prependBlockCount ) { // convert block count to big-endian int convertedBlockCount = IPAddress.HostToNetworkOrder( Blocks.Length ); // write block count to gzip stream @@ -799,45 +790,42 @@ public void GetCompressedCopy( [NotNull] Stream stream, bool prependBlockCount ) } } - /// Makes an admincrete barrier, 1 block thick, around the lower half of the map. public void MakeFloodBarrier() { - for( int x = 0; x < Width; x++ ) { - for( int y = 0; y < Length; y++ ) { + for ( int x = 0; x < Width; x++ ) { + for ( int y = 0; y < Length; y++ ) { SetBlock( x, y, 0, Block.Admincrete ); } } - for( int x = 0; x < Width; x++ ) { - for( int z = 0; z < Height / 2; z++ ) { + for ( int x = 0; x < Width; x++ ) { + for ( int z = 0; z < Height / 2; z++ ) { SetBlock( x, 0, z, Block.Admincrete ); SetBlock( x, Length - 1, z, Block.Admincrete ); } } - for( int y = 0; y < Length; y++ ) { - for( int z = 0; z < Height / 2; z++ ) { + for ( int y = 0; y < Length; y++ ) { + for ( int z = 0; z < Height / 2; z++ ) { SetBlock( 0, y, z, Block.Admincrete ); SetBlock( Width - 1, y, z, Block.Admincrete ); } } } - public int SearchColumn( int x, int y, Block id ) { return SearchColumn( x, y, id, Height - 1 ); } - public int SearchColumn( int x, int y, Block id, int zStart ) { - for( int z = zStart; z > 0; z-- ) { - if( GetBlock( x, y, z ) == id ) { + for ( int z = zStart; z > 0; z-- ) { + if ( GetBlock( x, y, z ) == id ) { return z; } } return -1; // -1 means 'not found' } - #endregion + #endregion Utilities } } \ No newline at end of file diff --git a/fCraft/World/MapGenerator.cs b/fCraft/World/MapGenerator.cs index 9a4fbe1..300fee3 100644 --- a/fCraft/World/MapGenerator.cs +++ b/fCraft/World/MapGenerator.cs @@ -5,12 +5,10 @@ using System.Xml.Linq; using JetBrains.Annotations; -namespace fCraft -{ +namespace fCraft { /// Map generator themes. A theme defines what type of blocks are used to fill the map. - public enum MapGenTheme - { + public enum MapGenTheme { Arctic, Desert, Forest, @@ -18,10 +16,8 @@ public enum MapGenTheme Swamp } - /// Map generator template. Templates define landscape shapes and features. - public enum MapGenTemplate - { + public enum MapGenTemplate { Archipelago, Atoll, Bay, @@ -38,541 +34,439 @@ public enum MapGenTemplate Streams } + public sealed class MapGenerator { + private readonly MapGeneratorArgs args; + private readonly Random rand; + private readonly Noise noise; + private float[,] heightmap, blendmap, slopemap; - public sealed class MapGenerator - { - readonly MapGeneratorArgs args; - readonly Random rand; - readonly Noise noise; - float[,] heightmap, blendmap, slopemap; - - const float CliffsideBlockThreshold = 0.01f; + private const float CliffsideBlockThreshold = 0.01f; // theme-dependent vars - Block bWaterSurface, bGroundSurface, bWater, bGround, bSeaFloor, bBedrock, bDeepWaterSurface, bCliff; + private Block bWaterSurface, bGroundSurface, bWater, bGround, bSeaFloor, bBedrock, bDeepWaterSurface, bCliff; - int groundThickness = 5; - const int SeaFloorThickness = 3; + private int groundThickness = 5; + private const int SeaFloorThickness = 3; - public MapGenerator([NotNull] MapGeneratorArgs generatorArgs) - { - if (generatorArgs == null) throw new ArgumentNullException("generatorArgs"); + public MapGenerator( [NotNull] MapGeneratorArgs generatorArgs ) { + if ( generatorArgs == null ) + throw new ArgumentNullException( "generatorArgs" ); args = generatorArgs; args.Validate(); - if (!args.CustomWaterLevel) - { - args.WaterLevel = (args.MapHeight - 1) / 2; + if ( !args.CustomWaterLevel ) { + args.WaterLevel = ( args.MapHeight - 1 ) / 2; } - rand = new Random(args.Seed); - noise = new Noise(args.Seed, NoiseInterpolationMode.Bicubic); - ApplyTheme(args.Theme); + rand = new Random( args.Seed ); + noise = new Noise( args.Seed, NoiseInterpolationMode.Bicubic ); + ApplyTheme( args.Theme ); EstimateComplexity(); } - - public Map Generate() - { + public Map Generate() { GenerateHeightmap(); return GenerateMap(); } + private const int FlatgrassDirtLevel = 5; - const int FlatgrassDirtLevel = 5; [NotNull] - public static Map GenerateFlatgrass(int width, int length, int height) - { - Map map = new Map(null, width, length, height, true); - map.Blocks.MemSet((byte)Block.Stone, 0, width * length * (height / 2 - FlatgrassDirtLevel)); - map.Blocks.MemSet((byte)Block.Dirt, width * length * (height / 2 - FlatgrassDirtLevel), width * length * (FlatgrassDirtLevel - 1)); - map.Blocks.MemSet((byte)Block.Grass, width * length * (height / 2 - 1), width * length); + public static Map GenerateFlatgrass( int width, int length, int height ) { + Map map = new Map( null, width, length, height, true ); + map.Blocks.MemSet( ( byte )Block.Stone, 0, width * length * ( height / 2 - FlatgrassDirtLevel ) ); + map.Blocks.MemSet( ( byte )Block.Dirt, width * length * ( height / 2 - FlatgrassDirtLevel ), width * length * ( FlatgrassDirtLevel - 1 ) ); + map.Blocks.MemSet( ( byte )Block.Grass, width * length * ( height / 2 - 1 ), width * length ); return map; } [NotNull] - public static Map GenerateEmpty(int width, int length, int height) - { - return new Map(null, width, length, height, true); + public static Map GenerateEmpty( int width, int length, int height ) { + return new Map( null, width, length, height, true ); } [NotNull] - public static Map GenerateOcean(int width, int length, int height) - { - Map map = new Map(null, width, length, height, true); - map.Blocks.MemSet((byte)Block.Sand, 0, width * length); - map.Blocks.MemSet((byte)Block.Water, width * length, width * length * (height / 2 - 1)); + public static Map GenerateOcean( int width, int length, int height ) { + Map map = new Map( null, width, length, height, true ); + map.Blocks.MemSet( ( byte )Block.Sand, 0, width * length ); + map.Blocks.MemSet( ( byte )Block.Water, width * length, width * length * ( height / 2 - 1 ) ); return map; } - #region Progress Reporting public event ProgressChangedEventHandler ProgressChanged; - int progressTotalEstimate, progressRunningTotal; + private int progressTotalEstimate, progressRunningTotal; - - void EstimateComplexity() - { + private void EstimateComplexity() { // heightmap creation progressTotalEstimate = 10; - if (args.UseBias) progressTotalEstimate += 2; - if (args.LayeredHeightmap) progressTotalEstimate += 10; - if (args.MarbledHeightmap) progressTotalEstimate++; - if (args.InvertHeightmap) progressTotalEstimate++; + if ( args.UseBias ) + progressTotalEstimate += 2; + if ( args.LayeredHeightmap ) + progressTotalEstimate += 10; + if ( args.MarbledHeightmap ) + progressTotalEstimate++; + if ( args.InvertHeightmap ) + progressTotalEstimate++; // heightmap processing - if (args.MatchWaterCoverage) progressTotalEstimate += 2; - if (args.BelowFuncExponent != 1 || args.AboveFuncExponent != 1) progressTotalEstimate += 5; - if (args.CliffSmoothing) progressTotalEstimate += 2; + if ( args.MatchWaterCoverage ) + progressTotalEstimate += 2; + if ( args.BelowFuncExponent != 1 || args.AboveFuncExponent != 1 ) + progressTotalEstimate += 5; + if ( args.CliffSmoothing ) + progressTotalEstimate += 2; progressTotalEstimate += 2; // slope - if (args.MaxHeightVariation > 0 || args.MaxDepthVariation > 0) progressTotalEstimate += 5; + if ( args.MaxHeightVariation > 0 || args.MaxDepthVariation > 0 ) + progressTotalEstimate += 5; // filling progressTotalEstimate += 15; // post processing - if (args.AddCaves) progressTotalEstimate += 5; - if (args.AddOre) progressTotalEstimate += 3; - if (args.AddBeaches) progressTotalEstimate += 5; - if (args.AddTrees) progressTotalEstimate += 5; + if ( args.AddCaves ) + progressTotalEstimate += 5; + if ( args.AddOre ) + progressTotalEstimate += 3; + if ( args.AddBeaches ) + progressTotalEstimate += 5; + if ( args.AddTrees ) + progressTotalEstimate += 5; } - - void ReportProgress(int relativeIncrease, [NotNull] string message) - { - if (message == null) throw new ArgumentNullException("message"); + private void ReportProgress( int relativeIncrease, [NotNull] string message ) { + if ( message == null ) + throw new ArgumentNullException( "message" ); var h = ProgressChanged; - if (h != null) - { - h(this, new ProgressChangedEventArgs((100 * progressRunningTotal / progressTotalEstimate), message)); + if ( h != null ) { + h( this, new ProgressChangedEventArgs( ( 100 * progressRunningTotal / progressTotalEstimate ), message ) ); } progressRunningTotal += relativeIncrease; } - #endregion - + #endregion Progress Reporting #region Heightmap Processing - void GenerateHeightmap() - { - ReportProgress(10, "Heightmap: Priming"); + private void GenerateHeightmap() { + ReportProgress( 10, "Heightmap: Priming" ); heightmap = new float[args.MapWidth, args.MapLength]; - noise.PerlinNoise(heightmap, args.FeatureScale, args.DetailScale, args.Roughness, 0, 0); + noise.PerlinNoise( heightmap, args.FeatureScale, args.DetailScale, args.Roughness, 0, 0 ); - if (args.UseBias && !args.DelayBias) - { - ReportProgress(2, "Heightmap: Biasing"); - Noise.Normalize(heightmap); + if ( args.UseBias && !args.DelayBias ) { + ReportProgress( 2, "Heightmap: Biasing" ); + Noise.Normalize( heightmap ); ApplyBias(); } - Noise.Normalize(heightmap); + Noise.Normalize( heightmap ); - if (args.LayeredHeightmap) - { - ReportProgress(10, "Heightmap: Layering"); + if ( args.LayeredHeightmap ) { + ReportProgress( 10, "Heightmap: Layering" ); // needs a new Noise object to randomize second map float[,] heightmap2 = new float[args.MapWidth, args.MapLength]; - new Noise(rand.Next(), NoiseInterpolationMode.Bicubic).PerlinNoise(heightmap2, 0, args.DetailScale, args.Roughness, 0, 0); - Noise.Normalize(heightmap2); + new Noise( rand.Next(), NoiseInterpolationMode.Bicubic ).PerlinNoise( heightmap2, 0, args.DetailScale, args.Roughness, 0, 0 ); + Noise.Normalize( heightmap2 ); // make a blendmap blendmap = new float[args.MapWidth, args.MapLength]; - int blendmapDetailSize = (int)Math.Log(Math.Max(args.MapWidth, args.MapLength), 2) - 2; - new Noise(rand.Next(), NoiseInterpolationMode.Cosine).PerlinNoise(blendmap, 3, blendmapDetailSize, 0.5f, 0, 0); - Noise.Normalize(blendmap); - float cliffSteepness = Math.Max(args.MapWidth, args.MapLength) / 6f; - Noise.ScaleAndClip(blendmap, cliffSteepness); + int blendmapDetailSize = ( int )Math.Log( Math.Max( args.MapWidth, args.MapLength ), 2 ) - 2; + new Noise( rand.Next(), NoiseInterpolationMode.Cosine ).PerlinNoise( blendmap, 3, blendmapDetailSize, 0.5f, 0, 0 ); + Noise.Normalize( blendmap ); + float cliffSteepness = Math.Max( args.MapWidth, args.MapLength ) / 6f; + Noise.ScaleAndClip( blendmap, cliffSteepness ); - Noise.Blend(heightmap, heightmap2, blendmap); + Noise.Blend( heightmap, heightmap2, blendmap ); } - if (args.MarbledHeightmap) - { - ReportProgress(1, "Heightmap: Marbling"); - Noise.Marble(heightmap); + if ( args.MarbledHeightmap ) { + ReportProgress( 1, "Heightmap: Marbling" ); + Noise.Marble( heightmap ); } - if (args.InvertHeightmap) - { - ReportProgress(1, "Heightmap: Inverting"); - Noise.Invert(heightmap); + if ( args.InvertHeightmap ) { + ReportProgress( 1, "Heightmap: Inverting" ); + Noise.Invert( heightmap ); } - if (args.UseBias && args.DelayBias) - { - ReportProgress(2, "Heightmap: Biasing"); - Noise.Normalize(heightmap); + if ( args.UseBias && args.DelayBias ) { + ReportProgress( 2, "Heightmap: Biasing" ); + Noise.Normalize( heightmap ); ApplyBias(); } - Noise.Normalize(heightmap); + Noise.Normalize( heightmap ); } - - void ApplyBias() - { + private void ApplyBias() { // set corners and midpoint float[] corners = new float[4]; int c = 0; - for (int i = 0; i < args.RaisedCorners; i++) - { + for ( int i = 0; i < args.RaisedCorners; i++ ) { corners[c++] = args.Bias; } - for (int i = 0; i < args.LoweredCorners; i++) - { + for ( int i = 0; i < args.LoweredCorners; i++ ) { corners[c++] = -args.Bias; } - float midpoint = (args.MidPoint * args.Bias); + float midpoint = ( args.MidPoint * args.Bias ); // shuffle corners - corners = corners.OrderBy(r => rand.Next()).ToArray(); + corners = corners.OrderBy( r => rand.Next() ).ToArray(); // overlay the bias - Noise.ApplyBias(heightmap, corners[0], corners[1], corners[2], corners[3], midpoint); + Noise.ApplyBias( heightmap, corners[0], corners[1], corners[2], corners[3], midpoint ); } - #endregion - + #endregion Heightmap Processing #region Map Processing - public Map GenerateMap() - { - Map map = new Map(null, args.MapWidth, args.MapLength, args.MapHeight, true); - + public Map GenerateMap() { + Map map = new Map( null, args.MapWidth, args.MapLength, args.MapHeight, true ); // Match water coverage float desiredWaterLevel = .5f; - if (args.MatchWaterCoverage) - { - ReportProgress(2, "Heightmap Processing: Matching water coverage"); - desiredWaterLevel = Noise.FindThreshold(heightmap, args.WaterCoverage); + if ( args.MatchWaterCoverage ) { + ReportProgress( 2, "Heightmap Processing: Matching water coverage" ); + desiredWaterLevel = Noise.FindThreshold( heightmap, args.WaterCoverage ); } - // Calculate above/below water multipliers float aboveWaterMultiplier = 0; - if (desiredWaterLevel != 1) - { - aboveWaterMultiplier = (args.MaxHeight / (1 - desiredWaterLevel)); + if ( desiredWaterLevel != 1 ) { + aboveWaterMultiplier = ( args.MaxHeight / ( 1 - desiredWaterLevel ) ); } - // Apply power functions to above/below water parts of the heightmap - if (args.BelowFuncExponent != 1 || args.AboveFuncExponent != 1) - { - ReportProgress(5, "Heightmap Processing: Adjusting slope"); - for (int x = heightmap.GetLength(0) - 1; x >= 0; x--) - { - for (int y = heightmap.GetLength(1) - 1; y >= 0; y--) - { - if (heightmap[x, y] < desiredWaterLevel) - { + if ( args.BelowFuncExponent != 1 || args.AboveFuncExponent != 1 ) { + ReportProgress( 5, "Heightmap Processing: Adjusting slope" ); + for ( int x = heightmap.GetLength( 0 ) - 1; x >= 0; x-- ) { + for ( int y = heightmap.GetLength( 1 ) - 1; y >= 0; y-- ) { + if ( heightmap[x, y] < desiredWaterLevel ) { float normalizedDepth = 1 - heightmap[x, y] / desiredWaterLevel; - heightmap[x, y] = desiredWaterLevel - (float)Math.Pow(normalizedDepth, args.BelowFuncExponent) * desiredWaterLevel; - } - else - { - float normalizedHeight = (heightmap[x, y] - desiredWaterLevel) / (1 - desiredWaterLevel); - heightmap[x, y] = desiredWaterLevel + (float)Math.Pow(normalizedHeight, args.AboveFuncExponent) * (1 - desiredWaterLevel); + heightmap[x, y] = desiredWaterLevel - ( float )Math.Pow( normalizedDepth, args.BelowFuncExponent ) * desiredWaterLevel; + } else { + float normalizedHeight = ( heightmap[x, y] - desiredWaterLevel ) / ( 1 - desiredWaterLevel ); + heightmap[x, y] = desiredWaterLevel + ( float )Math.Pow( normalizedHeight, args.AboveFuncExponent ) * ( 1 - desiredWaterLevel ); } } } } // Calculate the slope - if (args.CliffSmoothing) - { - ReportProgress(2, "Heightmap Processing: Smoothing"); - slopemap = Noise.CalculateSlope(Noise.GaussianBlur5X5(heightmap)); - } - else - { - slopemap = Noise.CalculateSlope(heightmap); + if ( args.CliffSmoothing ) { + ReportProgress( 2, "Heightmap Processing: Smoothing" ); + slopemap = Noise.CalculateSlope( Noise.GaussianBlur5X5( heightmap ) ); + } else { + slopemap = Noise.CalculateSlope( heightmap ); } float[,] altmap = null; - if (args.MaxHeightVariation != 0 || args.MaxDepthVariation != 0) - { - ReportProgress(5, "Heightmap Processing: Randomizing"); + if ( args.MaxHeightVariation != 0 || args.MaxDepthVariation != 0 ) { + ReportProgress( 5, "Heightmap Processing: Randomizing" ); altmap = new float[map.Width, map.Length]; - int blendmapDetailSize = (int)Math.Log(Math.Max(args.MapWidth, args.MapLength), 2) - 2; - new Noise(rand.Next(), NoiseInterpolationMode.Cosine).PerlinNoise(altmap, 3, blendmapDetailSize, 0.5f, 0, 0); - Noise.Normalize(altmap, -1, 1); + int blendmapDetailSize = ( int )Math.Log( Math.Max( args.MapWidth, args.MapLength ), 2 ) - 2; + new Noise( rand.Next(), NoiseInterpolationMode.Cosine ).PerlinNoise( altmap, 3, blendmapDetailSize, 0.5f, 0, 0 ); + Noise.Normalize( altmap, -1, 1 ); } int snowStartThreshold = args.SnowAltitude - args.SnowTransition; int snowThreshold = args.SnowAltitude; - ReportProgress(10, "Filling"); - for (int x = heightmap.GetLength(0) - 1; x >= 0; x--) - { - for (int y = heightmap.GetLength(1) - 1; y >= 0; y--) - { + ReportProgress( 10, "Filling" ); + for ( int x = heightmap.GetLength( 0 ) - 1; x >= 0; x-- ) { + for ( int y = heightmap.GetLength( 1 ) - 1; y >= 0; y-- ) { int level; float slope; - if (heightmap[x, y] < desiredWaterLevel) - { + if ( heightmap[x, y] < desiredWaterLevel ) { float depth = args.MaxDepth; - if (altmap != null) - { + if ( altmap != null ) { depth += altmap[x, y] * args.MaxDepthVariation; } slope = slopemap[x, y] * depth; - level = args.WaterLevel - (int)Math.Round(Math.Pow(1 - heightmap[x, y] / desiredWaterLevel, args.BelowFuncExponent) * depth); + level = args.WaterLevel - ( int )Math.Round( Math.Pow( 1 - heightmap[x, y] / desiredWaterLevel, args.BelowFuncExponent ) * depth ); - if (args.AddWater) - { - if (args.WaterLevel - level > 3) - { - map.SetBlock(x, y, args.WaterLevel, bDeepWaterSurface); + if ( args.AddWater ) { + if ( args.WaterLevel - level > 3 ) { + map.SetBlock( x, y, args.WaterLevel, bDeepWaterSurface ); + } else { + map.SetBlock( x, y, args.WaterLevel, bWaterSurface ); } - else - { - map.SetBlock(x, y, args.WaterLevel, bWaterSurface); + for ( int i = args.WaterLevel; i > level; i-- ) { + map.SetBlock( x, y, i, bWater ); } - for (int i = args.WaterLevel; i > level; i--) - { - map.SetBlock(x, y, i, bWater); - } - for (int i = level; i >= 0; i--) - { - if (level - i < SeaFloorThickness) - { - map.SetBlock(x, y, i, bSeaFloor); - } - else - { - map.SetBlock(x, y, i, bBedrock); + for ( int i = level; i >= 0; i-- ) { + if ( level - i < SeaFloorThickness ) { + map.SetBlock( x, y, i, bSeaFloor ); + } else { + map.SetBlock( x, y, i, bBedrock ); } } - } - else - { - if (blendmap != null && blendmap[x, y] > .25 && blendmap[x, y] < .75) - { - map.SetBlock(x, y, level, bCliff); - } - else - { - if (slope < args.CliffThreshold) - { - map.SetBlock(x, y, level, bGroundSurface); - } - else - { - map.SetBlock(x, y, level, bCliff); + } else { + if ( blendmap != null && blendmap[x, y] > .25 && blendmap[x, y] < .75 ) { + map.SetBlock( x, y, level, bCliff ); + } else { + if ( slope < args.CliffThreshold ) { + map.SetBlock( x, y, level, bGroundSurface ); + } else { + map.SetBlock( x, y, level, bCliff ); } } - for (int i = level - 1; i >= 0; i--) - { - if (level - i < groundThickness) - { - if (blendmap != null && blendmap[x, y] > CliffsideBlockThreshold && blendmap[x, y] < (1 - CliffsideBlockThreshold)) - { - map.SetBlock(x, y, i, bCliff); - } - else - { - if (slope < args.CliffThreshold) - { - map.SetBlock(x, y, i, bGround); - } - else - { - map.SetBlock(x, y, i, bCliff); + for ( int i = level - 1; i >= 0; i-- ) { + if ( level - i < groundThickness ) { + if ( blendmap != null && blendmap[x, y] > CliffsideBlockThreshold && blendmap[x, y] < ( 1 - CliffsideBlockThreshold ) ) { + map.SetBlock( x, y, i, bCliff ); + } else { + if ( slope < args.CliffThreshold ) { + map.SetBlock( x, y, i, bGround ); + } else { + map.SetBlock( x, y, i, bCliff ); } } - } - else - { - map.SetBlock(x, y, i, bBedrock); + } else { + map.SetBlock( x, y, i, bBedrock ); } } } - - } - else - { + } else { float height; - if (altmap != null) - { + if ( altmap != null ) { height = args.MaxHeight + altmap[x, y] * args.MaxHeightVariation; - } - else - { + } else { height = args.MaxHeight; } slope = slopemap[x, y] * height; - if (height != 0) - { - level = args.WaterLevel + (int)Math.Round(Math.Pow(heightmap[x, y] - desiredWaterLevel, args.AboveFuncExponent) * aboveWaterMultiplier / args.MaxHeight * height); - } - else - { + if ( height != 0 ) { + level = args.WaterLevel + ( int )Math.Round( Math.Pow( heightmap[x, y] - desiredWaterLevel, args.AboveFuncExponent ) * aboveWaterMultiplier / args.MaxHeight * height ); + } else { level = args.WaterLevel; } bool snow = args.AddSnow && - (level > snowThreshold || - (level > snowStartThreshold && rand.NextDouble() < (level - snowStartThreshold) / (double)(snowThreshold - snowStartThreshold))); - - if (blendmap != null && blendmap[x, y] > .25 && blendmap[x, y] < .75) - { - map.SetBlock(x, y, level, bCliff); - } - else - { - if (slope < args.CliffThreshold) - { - map.SetBlock(x, y, level, (snow ? Block.White : bGroundSurface)); - } - else - { - map.SetBlock(x, y, level, bCliff); + ( level > snowThreshold || + ( level > snowStartThreshold && rand.NextDouble() < ( level - snowStartThreshold ) / ( double )( snowThreshold - snowStartThreshold ) ) ); + + if ( blendmap != null && blendmap[x, y] > .25 && blendmap[x, y] < .75 ) { + map.SetBlock( x, y, level, bCliff ); + } else { + if ( slope < args.CliffThreshold ) { + map.SetBlock( x, y, level, ( snow ? Block.White : bGroundSurface ) ); + } else { + map.SetBlock( x, y, level, bCliff ); } } - for (int i = level - 1; i >= 0; i--) - { - if (level - i < groundThickness) - { - if (blendmap != null && blendmap[x, y] > CliffsideBlockThreshold && blendmap[x, y] < (1 - CliffsideBlockThreshold)) - { - map.SetBlock(x, y, i, bCliff); - } - else - { - if (slope < args.CliffThreshold) - { - if (snow) - { - map.SetBlock(x, y, i, Block.White); - } - else - { - map.SetBlock(x, y, i, bGround); + for ( int i = level - 1; i >= 0; i-- ) { + if ( level - i < groundThickness ) { + if ( blendmap != null && blendmap[x, y] > CliffsideBlockThreshold && blendmap[x, y] < ( 1 - CliffsideBlockThreshold ) ) { + map.SetBlock( x, y, i, bCliff ); + } else { + if ( slope < args.CliffThreshold ) { + if ( snow ) { + map.SetBlock( x, y, i, Block.White ); + } else { + map.SetBlock( x, y, i, bGround ); } - } - else - { - map.SetBlock(x, y, i, bCliff); + } else { + map.SetBlock( x, y, i, bCliff ); } } - } - else - { - map.SetBlock(x, y, i, bBedrock); + } else { + map.SetBlock( x, y, i, bBedrock ); } } } } } - if (args.AddCaves || args.AddOre) - { - AddCaves(map); + if ( args.AddCaves || args.AddOre ) { + AddCaves( map ); } - if (args.AddBeaches) - { - ReportProgress(5, "Processing: Adding beaches"); - AddBeaches(map); + if ( args.AddBeaches ) { + ReportProgress( 5, "Processing: Adding beaches" ); + AddBeaches( map ); } - if (args.AddTrees) - { - ReportProgress(5, "Processing: Planting trees"); - if (args.AddGiantTrees) - { - Map outMap = new Map(null, map.Width, map.Length, map.Height, false) { Blocks = (byte[])map.Blocks.Clone() }; - var foresterArgs = new ForesterArgs - { + if ( args.AddTrees ) { + ReportProgress( 5, "Processing: Planting trees" ); + if ( args.AddGiantTrees ) { + Map outMap = new Map( null, map.Width, map.Length, map.Height, false ) { Blocks = ( byte[] )map.Blocks.Clone() }; + var foresterArgs = new ForesterArgs { Map = map, Rand = rand, - TreeCount = (int)(map.Width * map.Length * 4 / (1024f * (args.TreeSpacingMax + args.TreeSpacingMin) / 2)), + TreeCount = ( int )( map.Width * map.Length * 4 / ( 1024f * ( args.TreeSpacingMax + args.TreeSpacingMin ) / 2 ) ), Operation = Forester.ForesterOperation.Add, PlantOn = bGroundSurface }; - foresterArgs.BlockPlacing += (sender, e) => outMap.SetBlock(e.Coordinate, e.Block); - Forester.Generate(foresterArgs); + foresterArgs.BlockPlacing += ( sender, e ) => outMap.SetBlock( e.Coordinate, e.Block ); + Forester.Generate( foresterArgs ); map = outMap; } - GenerateTrees(map); + GenerateTrees( map ); } - ReportProgress(0, "Generation complete"); + ReportProgress( 0, "Generation complete" ); map.Metadata["_Origin", "GeneratorName"] = "fCraft"; map.Metadata["_Origin", "GeneratorVersion"] = Updater.CurrentRelease.VersionString; - map.Metadata["_Origin", "GeneratorParams"] = args.Serialize().ToString(SaveOptions.DisableFormatting); + map.Metadata["_Origin", "GeneratorParams"] = args.Serialize().ToString( SaveOptions.DisableFormatting ); return map; } - #region Caves // Cave generation method from Omen 0.70, used with osici's permission - static void AddSingleCave(Random rand, Map map, byte bedrockType, byte fillingType, int length, double maxDiameter) - { - - int startX = rand.Next(0, map.Width); - int startY = rand.Next(0, map.Length); - int startZ = rand.Next(0, map.Height); + private static void AddSingleCave( Random rand, Map map, byte bedrockType, byte fillingType, int length, double maxDiameter ) { + int startX = rand.Next( 0, map.Width ); + int startY = rand.Next( 0, map.Length ); + int startZ = rand.Next( 0, map.Height ); int k1; - for (k1 = 0; map.Blocks[startX + map.Width * map.Length * (map.Height - 1 - startZ) + map.Width * startY] != bedrockType && k1 < 10000; k1++) - { - startX = rand.Next(0, map.Width); - startY = rand.Next(0, map.Length); - startZ = rand.Next(0, map.Height); + for ( k1 = 0; map.Blocks[startX + map.Width * map.Length * ( map.Height - 1 - startZ ) + map.Width * startY] != bedrockType && k1 < 10000; k1++ ) { + startX = rand.Next( 0, map.Width ); + startY = rand.Next( 0, map.Length ); + startZ = rand.Next( 0, map.Height ); } - if (k1 >= 10000) + if ( k1 >= 10000 ) return; int x = startX; int y = startY; int z = startZ; - for (int k2 = 0; k2 < length; k2++) - { - int diameter = (int)(maxDiameter * rand.NextDouble() * map.Width); - if (diameter < 1) diameter = 2; + for ( int k2 = 0; k2 < length; k2++ ) { + int diameter = ( int )( maxDiameter * rand.NextDouble() * map.Width ); + if ( diameter < 1 ) + diameter = 2; int radius = diameter / 2; - if (radius == 0) radius = 1; - x += (int)(0.7 * (rand.NextDouble() - 0.5D) * diameter); - y += (int)(0.7 * (rand.NextDouble() - 0.5D) * diameter); - z += (int)(0.7 * (rand.NextDouble() - 0.5D) * diameter); - - for (int j3 = 0; j3 < diameter; j3++) - { - for (int k3 = 0; k3 < diameter; k3++) - { - for (int l3 = 0; l3 < diameter; l3++) - { - if ((j3 - radius) * (j3 - radius) + (k3 - radius) * (k3 - radius) + (l3 - radius) * (l3 - radius) >= radius * radius || + if ( radius == 0 ) + radius = 1; + x += ( int )( 0.7 * ( rand.NextDouble() - 0.5D ) * diameter ); + y += ( int )( 0.7 * ( rand.NextDouble() - 0.5D ) * diameter ); + z += ( int )( 0.7 * ( rand.NextDouble() - 0.5D ) * diameter ); + + for ( int j3 = 0; j3 < diameter; j3++ ) { + for ( int k3 = 0; k3 < diameter; k3++ ) { + for ( int l3 = 0; l3 < diameter; l3++ ) { + if ( ( j3 - radius ) * ( j3 - radius ) + ( k3 - radius ) * ( k3 - radius ) + ( l3 - radius ) * ( l3 - radius ) >= radius * radius || x + j3 >= map.Width || z + k3 >= map.Height || y + l3 >= map.Length || - x + j3 < 0 || z + k3 < 0 || y + l3 < 0) - { + x + j3 < 0 || z + k3 < 0 || y + l3 < 0 ) { continue; } - int index = x + j3 + map.Width * map.Length * (map.Height - 1 - (z + k3)) + map.Width * (y + l3); + int index = x + j3 + map.Width * map.Length * ( map.Height - 1 - ( z + k3 ) ) + map.Width * ( y + l3 ); - if (map.Blocks[index] == bedrockType) - { + if ( map.Blocks[index] == bedrockType ) { map.Blocks[index] = fillingType; } - if ((fillingType == 10 || fillingType == 11 || fillingType == 8 || fillingType == 9) && - z + k3 < startZ) - { + if ( ( fillingType == 10 || fillingType == 11 || fillingType == 8 || fillingType == 9 ) && + z + k3 < startZ ) { map.Blocks[index] = 0; } } @@ -581,49 +475,40 @@ static void AddSingleCave(Random rand, Map map, byte bedrockType, byte fillingTy } } - static void AddSingleVein(Random rand, Map map, byte bedrockType, byte fillingType, int k, double maxDiameter, int l) - { - AddSingleVein(rand, map, bedrockType, fillingType, k, maxDiameter, l, 10); + private static void AddSingleVein( Random rand, Map map, byte bedrockType, byte fillingType, int k, double maxDiameter, int l ) { + AddSingleVein( rand, map, bedrockType, fillingType, k, maxDiameter, l, 10 ); } - static void AddSingleVein(Random rand, Map map, byte bedrockType, byte fillingType, int k, double maxDiameter, int l, int i1) - { - - int j1 = rand.Next(0, map.Width); - int k1 = rand.Next(0, map.Height); - int l1 = rand.Next(0, map.Length); - - double thirteenOverK = 1 / (double)k; - - for (int i2 = 0; i2 < i1; i2++) - { - int j2 = j1 + (int)(.5 * (rand.NextDouble() - .5) * map.Width); - int k2 = k1 + (int)(.5 * (rand.NextDouble() - .5) * map.Height); - int l2 = l1 + (int)(.5 * (rand.NextDouble() - .5) * map.Length); - for (int l3 = 0; l3 < k; l3++) - { - int diameter = (int)(maxDiameter * rand.NextDouble() * map.Width); - if (diameter < 1) diameter = 2; + private static void AddSingleVein( Random rand, Map map, byte bedrockType, byte fillingType, int k, double maxDiameter, int l, int i1 ) { + int j1 = rand.Next( 0, map.Width ); + int k1 = rand.Next( 0, map.Height ); + int l1 = rand.Next( 0, map.Length ); + + double thirteenOverK = 1 / ( double )k; + + for ( int i2 = 0; i2 < i1; i2++ ) { + int j2 = j1 + ( int )( .5 * ( rand.NextDouble() - .5 ) * map.Width ); + int k2 = k1 + ( int )( .5 * ( rand.NextDouble() - .5 ) * map.Height ); + int l2 = l1 + ( int )( .5 * ( rand.NextDouble() - .5 ) * map.Length ); + for ( int l3 = 0; l3 < k; l3++ ) { + int diameter = ( int )( maxDiameter * rand.NextDouble() * map.Width ); + if ( diameter < 1 ) + diameter = 2; int radius = diameter / 2; - if (radius == 0) radius = 1; - int i3 = (int)((1 - thirteenOverK) * j1 + thirteenOverK * j2 + (l * radius) * (rand.NextDouble() - .5)); - int j3 = (int)((1 - thirteenOverK) * k1 + thirteenOverK * k2 + (l * radius) * (rand.NextDouble() - .5)); - int k3 = (int)((1 - thirteenOverK) * l1 + thirteenOverK * l2 + (l * radius) * (rand.NextDouble() - .5)); - for (int k4 = 0; k4 < diameter; k4++) - { - for (int l4 = 0; l4 < diameter; l4++) - { - for (int i5 = 0; i5 < diameter; i5++) - { - if ((k4 - radius) * (k4 - radius) + (l4 - radius) * (l4 - radius) + (i5 - radius) * (i5 - radius) < radius * radius && + if ( radius == 0 ) + radius = 1; + int i3 = ( int )( ( 1 - thirteenOverK ) * j1 + thirteenOverK * j2 + ( l * radius ) * ( rand.NextDouble() - .5 ) ); + int j3 = ( int )( ( 1 - thirteenOverK ) * k1 + thirteenOverK * k2 + ( l * radius ) * ( rand.NextDouble() - .5 ) ); + int k3 = ( int )( ( 1 - thirteenOverK ) * l1 + thirteenOverK * l2 + ( l * radius ) * ( rand.NextDouble() - .5 ) ); + for ( int k4 = 0; k4 < diameter; k4++ ) { + for ( int l4 = 0; l4 < diameter; l4++ ) { + for ( int i5 = 0; i5 < diameter; i5++ ) { + if ( ( k4 - radius ) * ( k4 - radius ) + ( l4 - radius ) * ( l4 - radius ) + ( i5 - radius ) * ( i5 - radius ) < radius * radius && i3 + k4 < map.Width && j3 + l4 < map.Height && k3 + i5 < map.Length && - i3 + k4 >= 0 && j3 + l4 >= 0 && k3 + i5 >= 0) - { - - int index = i3 + k4 + map.Width * map.Length * (map.Height - 1 - (j3 + l4)) + map.Width * (k3 + i5); + i3 + k4 >= 0 && j3 + l4 >= 0 && k3 + i5 >= 0 ) { + int index = i3 + k4 + map.Width * map.Length * ( map.Height - 1 - ( j3 + l4 ) ) + map.Width * ( k3 + i5 ); - if (map.Blocks[index] == bedrockType) - { + if ( map.Blocks[index] == bedrockType ) { map.Blocks[index] = fillingType; } } @@ -637,20 +522,15 @@ static void AddSingleVein(Random rand, Map map, byte bedrockType, byte fillingTy } } - static void SealLiquids(Map map, byte sealantType) - { - for (int x = 1; x < map.Width - 1; x++) - { - for (int z = 1; z < map.Height; z++) - { - for (int y = 1; y < map.Length - 1; y++) - { - int index = map.Index(x, y, z); - if ((map.Blocks[index] == 10 || map.Blocks[index] == 11 || map.Blocks[index] == 8 || map.Blocks[index] == 9) && - (map.GetBlock(x - 1, y, z) == Block.Air || map.GetBlock(x + 1, y, z) == Block.Air || - map.GetBlock(x, y - 1, z) == Block.Air || map.GetBlock(x, y + 1, z) == Block.Air || - map.GetBlock(x, y, z - 1) == Block.Air)) - { + private static void SealLiquids( Map map, byte sealantType ) { + for ( int x = 1; x < map.Width - 1; x++ ) { + for ( int z = 1; z < map.Height; z++ ) { + for ( int y = 1; y < map.Length - 1; y++ ) { + int index = map.Index( x, y, z ); + if ( ( map.Blocks[index] == 10 || map.Blocks[index] == 11 || map.Blocks[index] == 8 || map.Blocks[index] == 9 ) && + ( map.GetBlock( x - 1, y, z ) == Block.Air || map.GetBlock( x + 1, y, z ) == Block.Air || + map.GetBlock( x, y - 1, z ) == Block.Air || map.GetBlock( x, y + 1, z ) == Block.Air || + map.GetBlock( x, y, z - 1 ) == Block.Air ) ) { map.Blocks[index] = sealantType; } } @@ -658,119 +538,96 @@ static void SealLiquids(Map map, byte sealantType) } } - public void AddCaves(Map map) - { - if (args.AddCaves) - { - ReportProgress(5, "Processing: Adding caves"); - for (int i1 = 0; i1 < 36 * args.CaveDensity; i1++) - AddSingleCave(rand, map, (byte)bBedrock, (byte)Block.Air, 30, 0.05 * args.CaveSize); - - for (int j1 = 0; j1 < 9 * args.CaveDensity; j1++) - AddSingleVein(rand, map, (byte)bBedrock, (byte)Block.Air, 500, 0.015 * args.CaveSize, 1); + public void AddCaves( Map map ) { + if ( args.AddCaves ) { + ReportProgress( 5, "Processing: Adding caves" ); + for ( int i1 = 0; i1 < 36 * args.CaveDensity; i1++ ) + AddSingleCave( rand, map, ( byte )bBedrock, ( byte )Block.Air, 30, 0.05 * args.CaveSize ); - for (int k1 = 0; k1 < 30 * args.CaveDensity; k1++) - AddSingleVein(rand, map, (byte)bBedrock, (byte)Block.Air, 300, 0.03 * args.CaveSize, 1, 20); + for ( int j1 = 0; j1 < 9 * args.CaveDensity; j1++ ) + AddSingleVein( rand, map, ( byte )bBedrock, ( byte )Block.Air, 500, 0.015 * args.CaveSize, 1 ); + for ( int k1 = 0; k1 < 30 * args.CaveDensity; k1++ ) + AddSingleVein( rand, map, ( byte )bBedrock, ( byte )Block.Air, 300, 0.03 * args.CaveSize, 1, 20 ); - if (args.AddCaveLava) - { - for (int i = 0; i < 8 * args.CaveDensity; i++) - { - AddSingleCave(rand, map, (byte)bBedrock, (byte)Block.Lava, 30, 0.05 * args.CaveSize); + if ( args.AddCaveLava ) { + for ( int i = 0; i < 8 * args.CaveDensity; i++ ) { + AddSingleCave( rand, map, ( byte )bBedrock, ( byte )Block.Lava, 30, 0.05 * args.CaveSize ); } - for (int j = 0; j < 3 * args.CaveDensity; j++) - { - AddSingleVein(rand, map, (byte)bBedrock, (byte)Block.Lava, 1000, 0.015 * args.CaveSize, 1); + for ( int j = 0; j < 3 * args.CaveDensity; j++ ) { + AddSingleVein( rand, map, ( byte )bBedrock, ( byte )Block.Lava, 1000, 0.015 * args.CaveSize, 1 ); } } - - if (args.AddCaveWater) - { - for (int k = 0; k < 8 * args.CaveDensity; k++) - { - AddSingleCave(rand, map, (byte)bBedrock, (byte)Block.Water, 30, 0.05 * args.CaveSize); + if ( args.AddCaveWater ) { + for ( int k = 0; k < 8 * args.CaveDensity; k++ ) { + AddSingleCave( rand, map, ( byte )bBedrock, ( byte )Block.Water, 30, 0.05 * args.CaveSize ); } - for (int l = 0; l < 3 * args.CaveDensity; l++) - { - AddSingleVein(rand, map, (byte)bBedrock, (byte)Block.Water, 1000, 0.015 * args.CaveSize, 1); + for ( int l = 0; l < 3 * args.CaveDensity; l++ ) { + AddSingleVein( rand, map, ( byte )bBedrock, ( byte )Block.Water, 1000, 0.015 * args.CaveSize, 1 ); } } - SealLiquids(map, (byte)bBedrock); + SealLiquids( map, ( byte )bBedrock ); } - - if (args.AddOre) - { - ReportProgress(3, "Processing: Adding ore"); - for (int l1 = 0; l1 < 12 * args.CaveDensity; l1++) - { - AddSingleCave(rand, map, (byte)bBedrock, (byte)Block.Coal, 500, 0.03); + if ( args.AddOre ) { + ReportProgress( 3, "Processing: Adding ore" ); + for ( int l1 = 0; l1 < 12 * args.CaveDensity; l1++ ) { + AddSingleCave( rand, map, ( byte )bBedrock, ( byte )Block.Coal, 500, 0.03 ); } - for (int i2 = 0; i2 < 32 * args.CaveDensity; i2++) - { - AddSingleVein(rand, map, (byte)bBedrock, (byte)Block.Coal, 200, 0.015, 1); - AddSingleCave(rand, map, (byte)bBedrock, (byte)Block.IronOre, 500, 0.02); + for ( int i2 = 0; i2 < 32 * args.CaveDensity; i2++ ) { + AddSingleVein( rand, map, ( byte )bBedrock, ( byte )Block.Coal, 200, 0.015, 1 ); + AddSingleCave( rand, map, ( byte )bBedrock, ( byte )Block.IronOre, 500, 0.02 ); } - for (int k2 = 0; k2 < 8 * args.CaveDensity; k2++) - { - AddSingleVein(rand, map, (byte)bBedrock, (byte)Block.IronOre, 200, 0.015, 1); - AddSingleVein(rand, map, (byte)bBedrock, (byte)Block.GoldOre, 200, 0.0145, 1); + for ( int k2 = 0; k2 < 8 * args.CaveDensity; k2++ ) { + AddSingleVein( rand, map, ( byte )bBedrock, ( byte )Block.IronOre, 200, 0.015, 1 ); + AddSingleVein( rand, map, ( byte )bBedrock, ( byte )Block.GoldOre, 200, 0.0145, 1 ); } - for (int l2 = 0; l2 < 20 * args.CaveDensity; l2++) - { - AddSingleCave(rand, map, (byte)bBedrock, (byte)Block.GoldOre, 400, 0.0175); + for ( int l2 = 0; l2 < 20 * args.CaveDensity; l2++ ) { + AddSingleCave( rand, map, ( byte )bBedrock, ( byte )Block.GoldOre, 400, 0.0175 ); } } } - #endregion + #endregion Caves - - void AddBeaches([NotNull] Map map) - { - if (map == null) throw new ArgumentNullException("map"); - int beachExtentSqr = (args.BeachExtent + 1) * (args.BeachExtent + 1); - for (int x = 0; x < map.Width; x++) - { - for (int y = 0; y < map.Length; y++) - { - for (int z = args.WaterLevel; z <= args.WaterLevel + args.BeachHeight; z++) - { - if (map.GetBlock(x, y, z) != bGroundSurface) continue; + private void AddBeaches( [NotNull] Map map ) { + if ( map == null ) + throw new ArgumentNullException( "map" ); + int beachExtentSqr = ( args.BeachExtent + 1 ) * ( args.BeachExtent + 1 ); + for ( int x = 0; x < map.Width; x++ ) { + for ( int y = 0; y < map.Length; y++ ) { + for ( int z = args.WaterLevel; z <= args.WaterLevel + args.BeachHeight; z++ ) { + if ( map.GetBlock( x, y, z ) != bGroundSurface ) + continue; bool found = false; - for (int dx = -args.BeachExtent; !found && dx <= args.BeachExtent; dx++) - { - for (int dy = -args.BeachExtent; !found && dy <= args.BeachExtent; dy++) - { - for (int dz = -args.BeachHeight; dz <= 0; dz++) - { - if (dx * dx + dy * dy + dz * dz > beachExtentSqr) continue; + for ( int dx = -args.BeachExtent; !found && dx <= args.BeachExtent; dx++ ) { + for ( int dy = -args.BeachExtent; !found && dy <= args.BeachExtent; dy++ ) { + for ( int dz = -args.BeachHeight; dz <= 0; dz++ ) { + if ( dx * dx + dy * dy + dz * dz > beachExtentSqr ) + continue; int xx = x + dx; int yy = y + dy; int zz = z + dz; - if (xx < 0 || xx >= map.Width || yy < 0 || yy >= map.Length || zz < 0 || - zz >= map.Height) continue; - Block block = map.GetBlock(xx, yy, zz); - if (block == bWater || block == bWaterSurface) - { + if ( xx < 0 || xx >= map.Width || yy < 0 || yy >= map.Length || zz < 0 || + zz >= map.Height ) + continue; + Block block = map.GetBlock( xx, yy, zz ); + if ( block == bWater || block == bWaterSurface ) { found = true; break; } } } } - if (found) - { - map.SetBlock(x, y, z, bSeaFloor); - if (z > 0 && map.GetBlock(x, y, z - 1) == bGround) - { - map.SetBlock(x, y, z - 1, bSeaFloor); + if ( found ) { + map.SetBlock( x, y, z, bSeaFloor ); + if ( z > 0 && map.GetBlock( x, y, z - 1 ) == bGround ) { + map.SetBlock( x, y, z - 1, bSeaFloor ); } } } @@ -778,10 +635,9 @@ void AddBeaches([NotNull] Map map) } } - - void GenerateTrees([NotNull] Map map) - { - if (map == null) throw new ArgumentNullException("map"); + private void GenerateTrees( [NotNull] Map map ) { + if ( map == null ) + throw new ArgumentNullException( "map" ); int minHeight = args.TreeHeightMin; int maxHeight = args.TreeHeightMax; int minTrunkPadding = args.TreeSpacingMin; @@ -793,42 +649,37 @@ void GenerateTrees([NotNull] Map map) map.CalculateShadows(); - for (int x = 0; x < map.Width; x += rn.Next(minTrunkPadding, maxTrunkPadding + 1)) - { - for (int y = 0; y < map.Length; y += rn.Next(minTrunkPadding, maxTrunkPadding + 1)) - { - int nx = x + rn.Next(-(minTrunkPadding / 2), (maxTrunkPadding / 2) + 1); - int ny = y + rn.Next(-(minTrunkPadding / 2), (maxTrunkPadding / 2) + 1); - if (nx < 0 || nx >= map.Width || ny < 0 || ny >= map.Length) continue; + for ( int x = 0; x < map.Width; x += rn.Next( minTrunkPadding, maxTrunkPadding + 1 ) ) { + for ( int y = 0; y < map.Length; y += rn.Next( minTrunkPadding, maxTrunkPadding + 1 ) ) { + int nx = x + rn.Next( -( minTrunkPadding / 2 ), ( maxTrunkPadding / 2 ) + 1 ); + int ny = y + rn.Next( -( minTrunkPadding / 2 ), ( maxTrunkPadding / 2 ) + 1 ); + if ( nx < 0 || nx >= map.Width || ny < 0 || ny >= map.Length ) + continue; int nz = map.Shadows[nx, ny]; - if ((map.GetBlock(nx, ny, nz) == bGroundSurface) && slopemap[nx, ny] < .5) - { + if ( ( map.GetBlock( nx, ny, nz ) == bGroundSurface ) && slopemap[nx, ny] < .5 ) { // Pick a random height for the tree between Min and Max, // discarding this tree if it would breach the top of the map int nh; - if ((nh = rn.Next(minHeight, maxHeight + 1)) + nz + nh / 2 > map.Height) + if ( ( nh = rn.Next( minHeight, maxHeight + 1 ) ) + nz + nh / 2 > map.Height ) continue; // Generate the trunk of the tree - for (int z = 1; z <= nh; z++) - map.SetBlock(nx, ny, nz + z, Block.Log); + for ( int z = 1; z <= nh; z++ ) + map.SetBlock( nx, ny, nz + z, Block.Log ); - for (int i = -1; i < nh / 2; i++) - { + for ( int i = -1; i < nh / 2; i++ ) { // Should we draw thin (2x2) or thicker (4x4) foliage - int radius = (i >= (nh / 2) - topLayers) ? 1 : 2; + int radius = ( i >= ( nh / 2 ) - topLayers ) ? 1 : 2; // Draw the foliage - for (int xoff = -radius; xoff < radius + 1; xoff++) - { - for (int yoff = -radius; yoff < radius + 1; yoff++) - { + for ( int xoff = -radius; xoff < radius + 1; xoff++ ) { + for ( int yoff = -radius; yoff < radius + 1; yoff++ ) { // Drop random leaves from the edges - if (rn.NextDouble() > odds && Math.Abs(xoff) == Math.Abs(yoff) && Math.Abs(xoff) == radius) + if ( rn.NextDouble() > odds && Math.Abs( xoff ) == Math.Abs( yoff ) && Math.Abs( xoff ) == radius ) continue; // By default only replace an existing block if its air - if (map.GetBlock(nx + xoff, ny + yoff, nz + nh + i) == Block.Air) - map.SetBlock(nx + xoff, ny + yoff, nz + nh + i, Block.Leaves); + if ( map.GetBlock( nx + xoff, ny + yoff, nz + nh + i ) == Block.Air ) + map.SetBlock( nx + xoff, ny + yoff, nz + nh + i, Block.Leaves ); } } } @@ -837,16 +688,13 @@ void GenerateTrees([NotNull] Map map) } } - #endregion - + #endregion Map Processing #region Themes / Templates - void ApplyTheme(MapGenTheme theme) - { + private void ApplyTheme( MapGenTheme theme ) { args.Theme = theme; - switch (theme) - { + switch ( theme ) { case MapGenTheme.Arctic: bWaterSurface = Block.Glass; bDeepWaterSurface = Block.Water; @@ -858,6 +706,7 @@ void ApplyTheme(MapGenTheme theme) bCliff = Block.Stone; groundThickness = 1; break; + case MapGenTheme.Desert: bWaterSurface = Block.Water; bDeepWaterSurface = Block.Water; @@ -868,6 +717,7 @@ void ApplyTheme(MapGenTheme theme) bBedrock = Block.Stone; bCliff = Block.Gravel; break; + case MapGenTheme.Hell: bWaterSurface = Block.Lava; bDeepWaterSurface = Block.Lava; @@ -878,6 +728,7 @@ void ApplyTheme(MapGenTheme theme) bBedrock = Block.Stone; bCliff = Block.Stone; break; + case MapGenTheme.Forest: bWaterSurface = Block.Water; bDeepWaterSurface = Block.Water; @@ -888,6 +739,7 @@ void ApplyTheme(MapGenTheme theme) bBedrock = Block.Stone; bCliff = Block.Stone; break; + case MapGenTheme.Swamp: bWaterSurface = Block.Water; bDeepWaterSurface = Block.Water; @@ -901,14 +753,10 @@ void ApplyTheme(MapGenTheme theme) } } - - public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) - { - switch (template) - { + public static MapGeneratorArgs MakeTemplate( MapGenTemplate template ) { + switch ( template ) { case MapGenTemplate.Archipelago: - return new MapGeneratorArgs - { + return new MapGeneratorArgs { MaxHeight = 8, MaxDepth = 20, FeatureScale = 3, @@ -918,8 +766,7 @@ public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) }; case MapGenTemplate.Atoll: - return new MapGeneratorArgs - { + return new MapGeneratorArgs { Theme = MapGenTheme.Desert, MaxHeight = 2, MaxDepth = 39, @@ -936,8 +783,7 @@ public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) }; case MapGenTemplate.Bay: - return new MapGeneratorArgs - { + return new MapGeneratorArgs { MaxHeight = 22, MaxDepth = 12, UseBias = true, @@ -952,8 +798,7 @@ public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) }; case MapGenTemplate.Dunes: - return new MapGeneratorArgs - { + return new MapGeneratorArgs { AddTrees = false, AddWater = false, Theme = MapGenTheme.Desert, @@ -967,8 +812,7 @@ public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) }; case MapGenTemplate.Hills: - return new MapGeneratorArgs - { + return new MapGeneratorArgs { AddWater = false, MaxHeight = 8, MaxDepth = 8, @@ -978,8 +822,7 @@ public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) }; case MapGenTemplate.Ice: - return new MapGeneratorArgs - { + return new MapGeneratorArgs { AddTrees = false, Theme = MapGenTheme.Arctic, MaxHeight = 2, @@ -994,8 +837,7 @@ public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) }; case MapGenTemplate.Island: - return new MapGeneratorArgs - { + return new MapGeneratorArgs { MaxHeight = 16, MaxDepth = 39, UseBias = true, @@ -1011,8 +853,7 @@ public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) }; case MapGenTemplate.Lake: - return new MapGeneratorArgs - { + return new MapGeneratorArgs { MaxHeight = 14, MaxDepth = 20, UseBias = true, @@ -1026,8 +867,7 @@ public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) }; case MapGenTemplate.Mountains: - return new MapGeneratorArgs - { + return new MapGeneratorArgs { AddWater = false, MaxHeight = 40, MaxDepth = 10, @@ -1045,8 +885,7 @@ public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) return new MapGeneratorArgs(); case MapGenTemplate.River: - return new MapGeneratorArgs - { + return new MapGeneratorArgs { MaxHeight = 22, MaxDepth = 8, FeatureScale = 0, @@ -1057,8 +896,7 @@ public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) }; case MapGenTemplate.Streams: - return new MapGeneratorArgs - { + return new MapGeneratorArgs { MaxHeight = 5, MaxDepth = 4, FeatureScale = 2, @@ -1072,8 +910,7 @@ public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) }; case MapGenTemplate.Peninsula: - return new MapGeneratorArgs - { + return new MapGeneratorArgs { MaxHeight = 22, MaxDepth = 12, UseBias = true, @@ -1088,8 +925,7 @@ public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) }; case MapGenTemplate.Flat: - return new MapGeneratorArgs - { + return new MapGeneratorArgs { MaxHeight = 0, MaxDepth = 0, MaxHeightVariation = 0, @@ -1100,10 +936,10 @@ public static MapGeneratorArgs MakeTemplate(MapGenTemplate template) }; default: - throw new ArgumentOutOfRangeException("template"); + throw new ArgumentOutOfRangeException( "template" ); } } - #endregion + #endregion Themes / Templates } } \ No newline at end of file diff --git a/fCraft/World/MapGeneratorArgs.cs b/fCraft/World/MapGeneratorArgs.cs index 0b7b65c..498a11c 100644 --- a/fCraft/World/MapGeneratorArgs.cs +++ b/fCraft/World/MapGeneratorArgs.cs @@ -3,14 +3,13 @@ using System.Xml.Linq; using JetBrains.Annotations; -namespace fCraft -{ +namespace fCraft { - public sealed class MapGeneratorArgs - { - const int FormatVersion = 2; + public sealed class MapGeneratorArgs { + private const int FormatVersion = 2; public MapGenTheme Theme = MapGenTheme.Forest; + public int Seed, // 0 MapWidth = 256, MapLength = 256, @@ -23,27 +22,34 @@ public sealed class MapGeneratorArgs public bool AddWater = true, CustomWaterLevel, // false MatchWaterCoverage; // false + public int WaterLevel = 48; public float WaterCoverage = .5f; public bool UseBias, // false DelayBias; // false + public float Bias; // 0 + public int RaisedCorners, // 0 LoweredCorners, // 0 MidPoint; // 0 public int DetailScale = 7, FeatureScale = 1; + public float Roughness = .5f; + public bool LayeredHeightmap, // false MarbledHeightmap, // false InvertHeightmap; // false + public float AboveFuncExponent = 1, BelowFuncExponent = 1; public bool AddTrees = true, AddGiantTrees; // false + public int TreeSpacingMin = 7, TreeSpacingMax = 11, TreeHeightMin = 5, @@ -53,202 +59,211 @@ public sealed class MapGeneratorArgs AddOre, // false AddCaveWater, // false AddCaveLava; // false + public float CaveDensity = 2, CaveSize = 1; public bool AddSnow; // false + public int SnowAltitude = 70, SnowTransition = 7; public bool AddCliffs = true, CliffSmoothing = true; + public float CliffThreshold = 1; public bool AddBeaches; // false + public int BeachExtent = 6, BeachHeight = 2; - public void Validate() - { - if (RaisedCorners < 0 || RaisedCorners > 4 || LoweredCorners < 0 || RaisedCorners > 4 || RaisedCorners + LoweredCorners > 4) - { - throw new ArgumentException("The sum of raisedCorners and loweredCorners must be between 0 and 4."); + public void Validate() { + if ( RaisedCorners < 0 || RaisedCorners > 4 || LoweredCorners < 0 || RaisedCorners > 4 || RaisedCorners + LoweredCorners > 4 ) { + throw new ArgumentException( "The sum of raisedCorners and loweredCorners must be between 0 and 4." ); } - if (CaveDensity <= 0 || CaveSize <= 0) - { - throw new ArgumentException("caveDensity and caveSize must be > 0"); + if ( CaveDensity <= 0 || CaveSize <= 0 ) { + throw new ArgumentException( "caveDensity and caveSize must be > 0" ); } // TODO: additional validation } - public MapGeneratorArgs() - { - Seed = (new Random()).Next(); + public MapGeneratorArgs() { + Seed = ( new Random() ).Next(); } - public MapGeneratorArgs([NotNull] string fileName) - { + public MapGeneratorArgs( [NotNull] string fileName ) { // ReSharper disable PossibleNullReferenceException - if (fileName == null) throw new ArgumentNullException("fileName"); - XDocument doc = XDocument.Load(fileName); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); + XDocument doc = XDocument.Load( fileName ); XElement root = doc.Root; - XAttribute versionTag = root.Attribute("version"); + XAttribute versionTag = root.Attribute( "version" ); int version = 0; - if (versionTag != null && !String.IsNullOrEmpty(versionTag.Value)) - { - version = Int32.Parse(versionTag.Value); + if ( versionTag != null && !String.IsNullOrEmpty( versionTag.Value ) ) { + version = Int32.Parse( versionTag.Value ); } - Theme = (MapGenTheme)Enum.Parse(typeof(MapGenTheme), root.Element("theme").Value, true); - Seed = Int32.Parse(root.Element("seed").Value); - MapWidth = Int32.Parse(root.Element("dimX").Value); - MapLength = Int32.Parse(root.Element("dimY").Value); - MapHeight = Int32.Parse(root.Element("dimH").Value); - MaxHeight = Int32.Parse(root.Element("maxHeight").Value); - MaxDepth = Int32.Parse(root.Element("maxDepth").Value); - - AddWater = Boolean.Parse(root.Element("addWater").Value); - if (root.Element("customWaterLevel") != null) CustomWaterLevel = Boolean.Parse(root.Element("customWaterLevel").Value); - MatchWaterCoverage = Boolean.Parse(root.Element("matchWaterCoverage").Value); - WaterLevel = Int32.Parse(root.Element("waterLevel").Value); - WaterCoverage = float.Parse(root.Element("waterCoverage").Value); - - UseBias = Boolean.Parse(root.Element("useBias").Value); - if (root.Element("delayBias") != null) DelayBias = Boolean.Parse(root.Element("delayBias").Value); - Bias = float.Parse(root.Element("bias").Value); - RaisedCorners = Int32.Parse(root.Element("raisedCorners").Value); - LoweredCorners = Int32.Parse(root.Element("loweredCorners").Value); - MidPoint = Int32.Parse(root.Element("midPoint").Value); - - if (version == 0) - { - DetailScale = Int32.Parse(root.Element("minDetailSize").Value); - FeatureScale = Int32.Parse(root.Element("maxDetailSize").Value); - } - else - { - DetailScale = Int32.Parse(root.Element("detailScale").Value); - FeatureScale = Int32.Parse(root.Element("featureScale").Value); + Theme = ( MapGenTheme )Enum.Parse( typeof( MapGenTheme ), root.Element( "theme" ).Value, true ); + Seed = Int32.Parse( root.Element( "seed" ).Value ); + MapWidth = Int32.Parse( root.Element( "dimX" ).Value ); + MapLength = Int32.Parse( root.Element( "dimY" ).Value ); + MapHeight = Int32.Parse( root.Element( "dimH" ).Value ); + MaxHeight = Int32.Parse( root.Element( "maxHeight" ).Value ); + MaxDepth = Int32.Parse( root.Element( "maxDepth" ).Value ); + + AddWater = Boolean.Parse( root.Element( "addWater" ).Value ); + if ( root.Element( "customWaterLevel" ) != null ) + CustomWaterLevel = Boolean.Parse( root.Element( "customWaterLevel" ).Value ); + MatchWaterCoverage = Boolean.Parse( root.Element( "matchWaterCoverage" ).Value ); + WaterLevel = Int32.Parse( root.Element( "waterLevel" ).Value ); + WaterCoverage = float.Parse( root.Element( "waterCoverage" ).Value ); + + UseBias = Boolean.Parse( root.Element( "useBias" ).Value ); + if ( root.Element( "delayBias" ) != null ) + DelayBias = Boolean.Parse( root.Element( "delayBias" ).Value ); + Bias = float.Parse( root.Element( "bias" ).Value ); + RaisedCorners = Int32.Parse( root.Element( "raisedCorners" ).Value ); + LoweredCorners = Int32.Parse( root.Element( "loweredCorners" ).Value ); + MidPoint = Int32.Parse( root.Element( "midPoint" ).Value ); + + if ( version == 0 ) { + DetailScale = Int32.Parse( root.Element( "minDetailSize" ).Value ); + FeatureScale = Int32.Parse( root.Element( "maxDetailSize" ).Value ); + } else { + DetailScale = Int32.Parse( root.Element( "detailScale" ).Value ); + FeatureScale = Int32.Parse( root.Element( "featureScale" ).Value ); } - Roughness = float.Parse(root.Element("roughness").Value); - LayeredHeightmap = Boolean.Parse(root.Element("layeredHeightmap").Value); - MarbledHeightmap = Boolean.Parse(root.Element("marbledHeightmap").Value); - InvertHeightmap = Boolean.Parse(root.Element("invertHeightmap").Value); - if (root.Element("aboveFuncExponent") != null) AboveFuncExponent = float.Parse(root.Element("aboveFuncExponent").Value); - if (root.Element("belowFuncExponent") != null) BelowFuncExponent = float.Parse(root.Element("belowFuncExponent").Value); - - AddTrees = Boolean.Parse(root.Element("addTrees").Value); - TreeSpacingMin = Int32.Parse(root.Element("treeSpacingMin").Value); - TreeSpacingMax = Int32.Parse(root.Element("treeSpacingMax").Value); - TreeHeightMin = Int32.Parse(root.Element("treeHeightMin").Value); - TreeHeightMax = Int32.Parse(root.Element("treeHeightMax").Value); - - if (root.Element("addCaves") != null) - { - AddCaves = Boolean.Parse(root.Element("addCaves").Value); - AddCaveLava = Boolean.Parse(root.Element("addCaveLava").Value); - AddCaveWater = Boolean.Parse(root.Element("addCaveWater").Value); - AddOre = Boolean.Parse(root.Element("addOre").Value); - CaveDensity = float.Parse(root.Element("caveDensity").Value); - CaveSize = float.Parse(root.Element("caveSize").Value); + Roughness = float.Parse( root.Element( "roughness" ).Value ); + LayeredHeightmap = Boolean.Parse( root.Element( "layeredHeightmap" ).Value ); + MarbledHeightmap = Boolean.Parse( root.Element( "marbledHeightmap" ).Value ); + InvertHeightmap = Boolean.Parse( root.Element( "invertHeightmap" ).Value ); + if ( root.Element( "aboveFuncExponent" ) != null ) + AboveFuncExponent = float.Parse( root.Element( "aboveFuncExponent" ).Value ); + if ( root.Element( "belowFuncExponent" ) != null ) + BelowFuncExponent = float.Parse( root.Element( "belowFuncExponent" ).Value ); + + AddTrees = Boolean.Parse( root.Element( "addTrees" ).Value ); + TreeSpacingMin = Int32.Parse( root.Element( "treeSpacingMin" ).Value ); + TreeSpacingMax = Int32.Parse( root.Element( "treeSpacingMax" ).Value ); + TreeHeightMin = Int32.Parse( root.Element( "treeHeightMin" ).Value ); + TreeHeightMax = Int32.Parse( root.Element( "treeHeightMax" ).Value ); + + if ( root.Element( "addCaves" ) != null ) { + AddCaves = Boolean.Parse( root.Element( "addCaves" ).Value ); + AddCaveLava = Boolean.Parse( root.Element( "addCaveLava" ).Value ); + AddCaveWater = Boolean.Parse( root.Element( "addCaveWater" ).Value ); + AddOre = Boolean.Parse( root.Element( "addOre" ).Value ); + CaveDensity = float.Parse( root.Element( "caveDensity" ).Value ); + CaveSize = float.Parse( root.Element( "caveSize" ).Value ); } - if (root.Element("addSnow") != null) AddSnow = Boolean.Parse(root.Element("addSnow").Value); - if (root.Element("snowAltitude") != null) SnowAltitude = Int32.Parse(root.Element("snowAltitude").Value); - if (root.Element("snowTransition") != null) SnowTransition = Int32.Parse(root.Element("snowTransition").Value); - - if (root.Element("addCliffs") != null) AddCliffs = Boolean.Parse(root.Element("addCliffs").Value); - if (root.Element("cliffSmoothing") != null) CliffSmoothing = Boolean.Parse(root.Element("cliffSmoothing").Value); - if (root.Element("cliffThreshold") != null) CliffThreshold = float.Parse(root.Element("cliffThreshold").Value); - - if (root.Element("addBeaches") != null) AddBeaches = Boolean.Parse(root.Element("addBeaches").Value); - if (root.Element("beachExtent") != null) BeachExtent = Int32.Parse(root.Element("beachExtent").Value); - if (root.Element("beachHeight") != null) BeachHeight = Int32.Parse(root.Element("beachHeight").Value); - - if (root.Element("maxHeightVariation") != null) MaxHeightVariation = Int32.Parse(root.Element("maxHeightVariation").Value); - if (root.Element("maxDepthVariation") != null) MaxDepthVariation = Int32.Parse(root.Element("maxDepthVariation").Value); - - if (root.Element("addGiantTrees") != null) AddGiantTrees = Boolean.Parse(root.Element("addGiantTrees").Value); + if ( root.Element( "addSnow" ) != null ) + AddSnow = Boolean.Parse( root.Element( "addSnow" ).Value ); + if ( root.Element( "snowAltitude" ) != null ) + SnowAltitude = Int32.Parse( root.Element( "snowAltitude" ).Value ); + if ( root.Element( "snowTransition" ) != null ) + SnowTransition = Int32.Parse( root.Element( "snowTransition" ).Value ); + + if ( root.Element( "addCliffs" ) != null ) + AddCliffs = Boolean.Parse( root.Element( "addCliffs" ).Value ); + if ( root.Element( "cliffSmoothing" ) != null ) + CliffSmoothing = Boolean.Parse( root.Element( "cliffSmoothing" ).Value ); + if ( root.Element( "cliffThreshold" ) != null ) + CliffThreshold = float.Parse( root.Element( "cliffThreshold" ).Value ); + + if ( root.Element( "addBeaches" ) != null ) + AddBeaches = Boolean.Parse( root.Element( "addBeaches" ).Value ); + if ( root.Element( "beachExtent" ) != null ) + BeachExtent = Int32.Parse( root.Element( "beachExtent" ).Value ); + if ( root.Element( "beachHeight" ) != null ) + BeachHeight = Int32.Parse( root.Element( "beachHeight" ).Value ); + + if ( root.Element( "maxHeightVariation" ) != null ) + MaxHeightVariation = Int32.Parse( root.Element( "maxHeightVariation" ).Value ); + if ( root.Element( "maxDepthVariation" ) != null ) + MaxDepthVariation = Int32.Parse( root.Element( "maxDepthVariation" ).Value ); + + if ( root.Element( "addGiantTrees" ) != null ) + AddGiantTrees = Boolean.Parse( root.Element( "addGiantTrees" ).Value ); // ReSharper restore PossibleNullReferenceException Validate(); } + private const string RootTagName = "fCraftMapGeneratorArgs"; - const string RootTagName = "fCraftMapGeneratorArgs"; - public void Save(string fileName) - { + public void Save( string fileName ) { XDocument document = new XDocument(); - document.Add(Serialize()); - document.Save(fileName); + document.Add( Serialize() ); + document.Save( fileName ); } - public XElement Serialize() - { - XElement root = new XElement(RootTagName); - - root.Add(new XAttribute("version", FormatVersion)); - - root.Add(new XElement("theme", Theme)); - root.Add(new XElement("seed", Seed)); - root.Add(new XElement("dimX", MapWidth)); - root.Add(new XElement("dimY", MapLength)); - root.Add(new XElement("dimH", MapHeight)); - root.Add(new XElement("maxHeight", MaxHeight)); - root.Add(new XElement("maxDepth", MaxDepth)); - - root.Add(new XElement("addWater", AddWater)); - root.Add(new XElement("customWaterLevel", CustomWaterLevel)); - root.Add(new XElement("matchWaterCoverage", MatchWaterCoverage)); - root.Add(new XElement("waterLevel", WaterLevel)); - root.Add(new XElement("waterCoverage", WaterCoverage)); - - root.Add(new XElement("useBias", UseBias)); - root.Add(new XElement("delayBias", DelayBias)); - root.Add(new XElement("raisedCorners", RaisedCorners)); - root.Add(new XElement("loweredCorners", LoweredCorners)); - root.Add(new XElement("midPoint", MidPoint)); - root.Add(new XElement("bias", Bias)); - - root.Add(new XElement("detailScale", DetailScale)); - root.Add(new XElement("featureScale", FeatureScale)); - root.Add(new XElement("roughness", Roughness)); - root.Add(new XElement("layeredHeightmap", LayeredHeightmap)); - root.Add(new XElement("marbledHeightmap", MarbledHeightmap)); - root.Add(new XElement("invertHeightmap", InvertHeightmap)); - root.Add(new XElement("aboveFuncExponent", AboveFuncExponent)); - root.Add(new XElement("belowFuncExponent", BelowFuncExponent)); - - root.Add(new XElement("addTrees", AddTrees)); - root.Add(new XElement("addGiantTrees", AddGiantTrees)); - root.Add(new XElement("treeSpacingMin", TreeSpacingMin)); - root.Add(new XElement("treeSpacingMax", TreeSpacingMax)); - root.Add(new XElement("treeHeightMin", TreeHeightMin)); - root.Add(new XElement("treeHeightMax", TreeHeightMax)); - - root.Add(new XElement("addCaves", AddCaves)); - root.Add(new XElement("addCaveLava", AddCaveLava)); - root.Add(new XElement("addCaveWater", AddCaveWater)); - root.Add(new XElement("addOre", AddOre)); - root.Add(new XElement("caveDensity", CaveDensity)); - root.Add(new XElement("caveSize", CaveSize)); - - root.Add(new XElement("addSnow", AddSnow)); - root.Add(new XElement("snowAltitude", SnowAltitude)); - root.Add(new XElement("snowTransition", SnowTransition)); - - root.Add(new XElement("addCliffs", AddCliffs)); - root.Add(new XElement("cliffSmoothing", CliffSmoothing)); - root.Add(new XElement("cliffThreshold", CliffThreshold)); - - root.Add(new XElement("addBeaches", AddBeaches)); - root.Add(new XElement("beachExtent", BeachExtent)); - root.Add(new XElement("beachHeight", BeachHeight)); - - root.Add(new XElement("maxHeightVariation", MaxHeightVariation)); - root.Add(new XElement("maxDepthVariation", MaxDepthVariation)); + public XElement Serialize() { + XElement root = new XElement( RootTagName ); + + root.Add( new XAttribute( "version", FormatVersion ) ); + + root.Add( new XElement( "theme", Theme ) ); + root.Add( new XElement( "seed", Seed ) ); + root.Add( new XElement( "dimX", MapWidth ) ); + root.Add( new XElement( "dimY", MapLength ) ); + root.Add( new XElement( "dimH", MapHeight ) ); + root.Add( new XElement( "maxHeight", MaxHeight ) ); + root.Add( new XElement( "maxDepth", MaxDepth ) ); + + root.Add( new XElement( "addWater", AddWater ) ); + root.Add( new XElement( "customWaterLevel", CustomWaterLevel ) ); + root.Add( new XElement( "matchWaterCoverage", MatchWaterCoverage ) ); + root.Add( new XElement( "waterLevel", WaterLevel ) ); + root.Add( new XElement( "waterCoverage", WaterCoverage ) ); + + root.Add( new XElement( "useBias", UseBias ) ); + root.Add( new XElement( "delayBias", DelayBias ) ); + root.Add( new XElement( "raisedCorners", RaisedCorners ) ); + root.Add( new XElement( "loweredCorners", LoweredCorners ) ); + root.Add( new XElement( "midPoint", MidPoint ) ); + root.Add( new XElement( "bias", Bias ) ); + + root.Add( new XElement( "detailScale", DetailScale ) ); + root.Add( new XElement( "featureScale", FeatureScale ) ); + root.Add( new XElement( "roughness", Roughness ) ); + root.Add( new XElement( "layeredHeightmap", LayeredHeightmap ) ); + root.Add( new XElement( "marbledHeightmap", MarbledHeightmap ) ); + root.Add( new XElement( "invertHeightmap", InvertHeightmap ) ); + root.Add( new XElement( "aboveFuncExponent", AboveFuncExponent ) ); + root.Add( new XElement( "belowFuncExponent", BelowFuncExponent ) ); + + root.Add( new XElement( "addTrees", AddTrees ) ); + root.Add( new XElement( "addGiantTrees", AddGiantTrees ) ); + root.Add( new XElement( "treeSpacingMin", TreeSpacingMin ) ); + root.Add( new XElement( "treeSpacingMax", TreeSpacingMax ) ); + root.Add( new XElement( "treeHeightMin", TreeHeightMin ) ); + root.Add( new XElement( "treeHeightMax", TreeHeightMax ) ); + + root.Add( new XElement( "addCaves", AddCaves ) ); + root.Add( new XElement( "addCaveLava", AddCaveLava ) ); + root.Add( new XElement( "addCaveWater", AddCaveWater ) ); + root.Add( new XElement( "addOre", AddOre ) ); + root.Add( new XElement( "caveDensity", CaveDensity ) ); + root.Add( new XElement( "caveSize", CaveSize ) ); + + root.Add( new XElement( "addSnow", AddSnow ) ); + root.Add( new XElement( "snowAltitude", SnowAltitude ) ); + root.Add( new XElement( "snowTransition", SnowTransition ) ); + + root.Add( new XElement( "addCliffs", AddCliffs ) ); + root.Add( new XElement( "cliffSmoothing", CliffSmoothing ) ); + root.Add( new XElement( "cliffThreshold", CliffThreshold ) ); + + root.Add( new XElement( "addBeaches", AddBeaches ) ); + root.Add( new XElement( "beachExtent", BeachExtent ) ); + root.Add( new XElement( "beachHeight", BeachHeight ) ); + + root.Add( new XElement( "maxHeightVariation", MaxHeightVariation ) ); + root.Add( new XElement( "maxDepthVariation", MaxDepthVariation ) ); return root; } } diff --git a/fCraft/World/World.Events.cs b/fCraft/World/World.Events.cs index 3396544..7ff2180 100644 --- a/fCraft/World/World.Events.cs +++ b/fCraft/World/World.Events.cs @@ -4,14 +4,16 @@ using JetBrains.Annotations; namespace fCraft.Events { + public class MainWorldChangedEventArgs : EventArgs { + internal MainWorldChangedEventArgs( [CanBeNull] World oldWorld, [NotNull] World newWorld ) { - if( newWorld == null ) throw new ArgumentNullException( "newWorld" ); + if ( newWorld == null ) + throw new ArgumentNullException( "newWorld" ); OldMainWorld = oldWorld; NewMainWorld = newWorld; } - [CanBeNull] public World OldMainWorld { get; private set; } @@ -19,19 +21,21 @@ internal MainWorldChangedEventArgs( [CanBeNull] World oldWorld, [NotNull] World public World NewMainWorld { get; private set; } } - public sealed class MainWorldChangingEventArgs : MainWorldChangedEventArgs, ICancellableEvent { + internal MainWorldChangingEventArgs( World oldWorld, [NotNull] World newWorld ) : base( oldWorld, newWorld ) { } public bool Cancel { get; set; } } - public sealed class SearchingForWorldEventArgs : EventArgs, IPlayerEvent { + internal SearchingForWorldEventArgs( [CanBeNull] Player player, [NotNull] string searchTerm, [NotNull] List matches ) { - if( searchTerm == null ) throw new ArgumentNullException( "searchTerm" ); - if( matches == null ) throw new ArgumentNullException( "matches" ); + if ( searchTerm == null ) + throw new ArgumentNullException( "searchTerm" ); + if ( matches == null ) + throw new ArgumentNullException( "matches" ); Player = player; SearchTerm = searchTerm; Matches = matches; @@ -47,10 +51,11 @@ internal SearchingForWorldEventArgs( [CanBeNull] Player player, [NotNull] string public List Matches { get; set; } } - public sealed class WorldCreatingEventArgs : EventArgs, ICancellableEvent { + internal WorldCreatingEventArgs( [CanBeNull] Player player, [NotNull] string worldName, [CanBeNull] Map map ) { - if( worldName == null ) throw new ArgumentNullException( "worldName" ); + if ( worldName == null ) + throw new ArgumentNullException( "worldName" ); Player = player; WorldName = worldName; Map = map; @@ -68,10 +73,11 @@ internal WorldCreatingEventArgs( [CanBeNull] Player player, [NotNull] string wor public bool Cancel { get; set; } } - public sealed class WorldCreatedEventArgs : EventArgs, IPlayerEvent, IWorldEvent { + internal WorldCreatedEventArgs( [CanBeNull] Player player, [NotNull] World world ) { - if( world == null ) throw new ArgumentNullException( "world" ); + if ( world == null ) + throw new ArgumentNullException( "world" ); Player = player; World = world; } diff --git a/fCraft/World/World.cs b/fCraft/World/World.cs index ac814de..e101ccb 100644 --- a/fCraft/World/World.cs +++ b/fCraft/World/World.cs @@ -1,25 +1,25 @@ // Copyright 2009-2013 Matvei Stefarov using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Xml.Linq; using fCraft.MapConversion; using JetBrains.Annotations; -using System.Collections; -using System.Collections.Concurrent; -using System.Threading; -using System.Xml.Linq; namespace fCraft { + public sealed class World : IClassy { + /// World name (no formatting). /// Use WorldManager.RenameWorld() method to change this. [NotNull] public string Name { get; internal set; } private GrassTask _plantTask = null; - private List _physSchedulers=new List(); + private List _physSchedulers = new List(); /// Whether the world shows up on the /Worlds list. /// Can be assigned directly. @@ -38,6 +38,7 @@ public sealed class World : IClassy { //physics public bool tntPhysics = false; + public bool fireworkPhysics = false; public bool waterPhysics = false; public bool plantPhysics = false; @@ -47,6 +48,7 @@ public sealed class World : IClassy { //games //move all these tings public ConcurrentDictionary blockCache = new ConcurrentDictionary(); + public List redTeam = new List(); public List blueTeam = new List(); public int redScore = 0; @@ -62,7 +64,7 @@ public sealed class World : IClassy { public string Greeting = null; - /// Whether this world is currently pending unload + /// Whether this world is currently pending unload /// (waiting for block updates to finish processing before unloading). public bool IsPendingMapUnload { get; private set; } @@ -70,34 +72,29 @@ public sealed class World : IClassy { public string RealmXMLRootName = "RealmState"; - public XElement SaveRealmState() - { - return SaveRealmState(RealmXMLRootName); + public XElement SaveRealmState() { + return SaveRealmState( RealmXMLRootName ); } - public XElement SaveRealmState(string rootName) - { - XElement root = new XElement(rootName); - if (IsRealm) - { - root.Add(new XAttribute("IsRealm", true)); + public XElement SaveRealmState( string rootName ) { + XElement root = new XElement( rootName ); + if ( IsRealm ) { + root.Add( new XAttribute( "IsRealm", true ) ); } return root; } - public void LoadRealmState(XElement el) - { + + public void LoadRealmState( XElement el ) { XAttribute temp; - if ((temp = el.Attribute("IsRealm")) != null) - { + if ( ( temp = el.Attribute( "IsRealm" ) ) != null ) { bool isRealm; - if (bool.TryParse(temp.Value, out isRealm)) - { + if ( bool.TryParse( temp.Value, out isRealm ) ) { IsRealm = true; } } } - #endregion + #endregion Realm State Serialization [NotNull] public SecurityController AccessSecurity { get; internal set; } @@ -129,16 +126,15 @@ public string MapChangedByClassy { } } - // used to synchronize player joining/parting with map loading/saving internal readonly object SyncRoot = new object(); - public BlockDB BlockDB { get; private set; } internal World( [NotNull] string name ) { - if( name == null ) throw new ArgumentNullException( "name" ); - if( !IsValidName( name ) ) { + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( !IsValidName( name ) ) { throw new ArgumentException( "Unacceptable world name." ); } BlockDB = new BlockDB( this ); @@ -147,363 +143,314 @@ internal World( [NotNull] string name ) { Name = name; UpdatePlayerList(); - for (int i = 0; i < Enum.GetValues(typeof(TaskCategory)).Length; ++i) - _physSchedulers.Add(new PhysScheduler(this)); - } - - - public bool TryAddLife(Life2DZone life) - { - if (null==life) - { - Logger.Log(LogType.Error, "trying to add null life instance"); - return false; - } - lock (SyncRoot) - { - if (null==Map) - return false; - if (map.LifeZones.ContainsKey(life.Name.ToLower())) - return false; - map.LifeZones.Add(life.Name.ToLower(), life); - if (!_physSchedulers[(int)TaskCategory.Life].Started) - _physSchedulers[(int)TaskCategory.Life].Start(); - } - return true; - } - public void DeleteLife(string name) - { - if (string.IsNullOrWhiteSpace(name)) - { - Logger.Log(LogType.Error, "null or empty string in deleting life"); - return; - } - lock (SyncRoot) - { - if (null == Map) - return; - map.LifeZones.Remove(name.ToLower()); - if (map.LifeZones.Count<=0) - _physSchedulers[(int)TaskCategory.Life].Stop(); - } - } - public Life2DZone GetLife(string name) - { - if (string.IsNullOrWhiteSpace(name)) - { - Logger.Log(LogType.Error, "null or empty string in GetLife"); - return null; - } - lock (SyncRoot) - { - if (null == Map) - return null; - Life2DZone life=null; - map.LifeZones.TryGetValue(name.ToLower(), out life); - return life; - } - } - public IEnumerable GetLifes() - { - lock (SyncRoot) - { - return null == Map ? null : Map.LifeZones.Values.ToList(); - } - } - - #region Physics - internal void StartScheduler(TaskCategory cat) - { - try - { - if (!_physSchedulers[(int)cat].Started) - _physSchedulers[(int)cat].Start(); - } - catch (Exception e) - { - Logger.Log(LogType.Error, "PhySched: " + e); - } - } - internal void AddTask(TaskCategory cat, PhysicsTask task, int Delay) - { - try - { - _physSchedulers[(int)cat].AddTask(task, Delay); - } - catch (Exception e) - { - Logger.Log(LogType.Error, "PhySchedAddTask: " + e); - } - } - - internal void AddPhysicsTask(PhysicsTask task, int Delay) - { - try - { - _physSchedulers[(int)TaskCategory.Physics].AddTask(task, Delay); - } - catch (Exception e) - { - Logger.Log(LogType.Error, "AddPhySchedTask: " + e); + for ( int i = 0; i < Enum.GetValues( typeof( TaskCategory ) ).Length; ++i ) + _physSchedulers.Add( new PhysScheduler( this ) ); + } + + public bool TryAddLife( Life2DZone life ) { + if ( null == life ) { + Logger.Log( LogType.Error, "trying to add null life instance" ); + return false; + } + lock ( SyncRoot ) { + if ( null == Map ) + return false; + if ( map.LifeZones.ContainsKey( life.Name.ToLower() ) ) + return false; + map.LifeZones.Add( life.Name.ToLower(), life ); + if ( !_physSchedulers[( int )TaskCategory.Life].Started ) + _physSchedulers[( int )TaskCategory.Life].Start(); + } + return true; + } + + public void DeleteLife( string name ) { + if ( string.IsNullOrWhiteSpace( name ) ) { + Logger.Log( LogType.Error, "null or empty string in deleting life" ); + return; + } + lock ( SyncRoot ) { + if ( null == Map ) + return; + map.LifeZones.Remove( name.ToLower() ); + if ( map.LifeZones.Count <= 0 ) + _physSchedulers[( int )TaskCategory.Life].Stop(); + } + } + + public Life2DZone GetLife( string name ) { + if ( string.IsNullOrWhiteSpace( name ) ) { + Logger.Log( LogType.Error, "null or empty string in GetLife" ); + return null; + } + lock ( SyncRoot ) { + if ( null == Map ) + return null; + Life2DZone life = null; + map.LifeZones.TryGetValue( name.ToLower(), out life ); + return life; + } + } + + public IEnumerable GetLifes() { + lock ( SyncRoot ) { + return null == Map ? null : Map.LifeZones.Values.ToList(); + } + } + + #region Physics + + internal void StartScheduler( TaskCategory cat ) { + try { + if ( !_physSchedulers[( int )cat].Started ) + _physSchedulers[( int )cat].Start(); + } catch ( Exception e ) { + Logger.Log( LogType.Error, "PhySched: " + e ); + } + } + + internal void AddTask( TaskCategory cat, PhysicsTask task, int Delay ) { + try { + _physSchedulers[( int )cat].AddTask( task, Delay ); + } catch ( Exception e ) { + Logger.Log( LogType.Error, "PhySchedAddTask: " + e ); + } + } + + internal void AddPhysicsTask( PhysicsTask task, int Delay ) { + try { + _physSchedulers[( int )TaskCategory.Physics].AddTask( task, Delay ); + } catch ( Exception e ) { + Logger.Log( LogType.Error, "AddPhySchedTask: " + e ); } } + #region Plant - internal void AddPlantTask(short x, short y, short z) - { - AddPhysicsTask(new PlantTask(this, x, y, z), PlantTask.GetRandomDelay()); - } - public void EnablePlantPhysics(Player player, bool announce) - { - try - { - if (null != _plantTask) - { - player.Message("&WAlready enabled on this world"); + + internal void AddPlantTask( short x, short y, short z ) { + AddPhysicsTask( new PlantTask( this, x, y, z ), PlantTask.GetRandomDelay() ); + } + + public void EnablePlantPhysics( Player player, bool announce ) { + try { + if ( null != _plantTask ) { + player.Message( "&WAlready enabled on this world" ); return; } plantPhysics = true; CheckIfPhysicsStarted(); bool NotLoaded = false; if ( !this.IsLoaded ) { this.LoadMap(); NotLoaded = true; } - _plantTask = new GrassTask(this); - AddPhysicsTask(_plantTask, 0); - if (announce) - Server.Message("{0}&S enabled Plant Physics on {1}", player.ClassyName, ClassyName); + _plantTask = new GrassTask( this ); + AddPhysicsTask( _plantTask, 0 ); + if ( announce ) + Server.Message( "{0}&S enabled Plant Physics on {1}", player.ClassyName, ClassyName ); if ( NotLoaded ) { this.UnloadMap( true ); } - } - catch (Exception e) - { - Logger.Log(LogType.Error, "PhyStartGrassPhysics: " + e); + } catch ( Exception e ) { + Logger.Log( LogType.Error, "PhyStartGrassPhysics: " + e ); } } - public void DisablePlantPhysics(Player player, bool announce) - { - try - { - if (null == _plantTask) - { - player.Message("&WAlready disabled on this world"); + + public void DisablePlantPhysics( Player player, bool announce ) { + try { + if ( null == _plantTask ) { + player.Message( "&WAlready disabled on this world" ); return; } _plantTask.Deleted = true; _plantTask = null; CheckIfToStopPhysics(); plantPhysics = false; - if (announce) - Server.Message("{0}&S disabled Plant Physics on {1}", player.ClassyName, ClassyName); - } - catch (Exception e) - { - Logger.Log(LogType.Error, "PhyStopGrassPhysics: " + e); + if ( announce ) + Server.Message( "{0}&S disabled Plant Physics on {1}", player.ClassyName, ClassyName ); + } catch ( Exception e ) { + Logger.Log( LogType.Error, "PhyStopGrassPhysics: " + e ); } } - #endregion + + #endregion Plant + #region TNT - public void EnableTNTPhysics(Player player, bool announce) - { - try - { - if (tntPhysics == true) - { - player.Message("&WAlready enabled on this world"); + + public void EnableTNTPhysics( Player player, bool announce ) { + try { + if ( tntPhysics == true ) { + player.Message( "&WAlready enabled on this world" ); return; } CheckIfPhysicsStarted(); tntPhysics = true; - if (announce) - Server.Message("{0}&S enabled TNT Physics on {1}", player.ClassyName, ClassyName); - } - catch (Exception e) - { - Logger.Log(LogType.Error, "PhyStartTNTPhysics: " + e); - } - } - - public void DisableTNTPhysics(Player player, bool announce) - { - try - { - if (tntPhysics == false) - { - player.Message("&WAlready disabled on this world"); + if ( announce ) + Server.Message( "{0}&S enabled TNT Physics on {1}", player.ClassyName, ClassyName ); + } catch ( Exception e ) { + Logger.Log( LogType.Error, "PhyStartTNTPhysics: " + e ); + } + } + + public void DisableTNTPhysics( Player player, bool announce ) { + try { + if ( tntPhysics == false ) { + player.Message( "&WAlready disabled on this world" ); return; } tntPhysics = false; CheckIfToStopPhysics(); - if (announce) - Server.Message("{0}&S disabled TNT Physics on {1}", player.ClassyName, ClassyName); - } - catch (Exception e) - { - Logger.Log(LogType.Error, "PhyStopTNTPhysics: " + e); + if ( announce ) + Server.Message( "{0}&S disabled TNT Physics on {1}", player.ClassyName, ClassyName ); + } catch ( Exception e ) { + Logger.Log( LogType.Error, "PhyStopTNTPhysics: " + e ); } } - #endregion + + #endregion TNT + #region Fireworks - public void EnableFireworkPhysics(Player player, bool announce) - { - try - { - if (fireworkPhysics == true) - { - player.Message("&WAlready enabled on this world"); + + public void EnableFireworkPhysics( Player player, bool announce ) { + try { + if ( fireworkPhysics == true ) { + player.Message( "&WAlready enabled on this world" ); return; } CheckIfPhysicsStarted(); fireworkPhysics = true; - if (announce) - Server.Message("{0}&S enabled Firework Physics on {1}", player.ClassyName, ClassyName); - } - catch (Exception e) - { - Logger.Log(LogType.Error, "PhyStartFireworkPhysics: " + e); + if ( announce ) + Server.Message( "{0}&S enabled Firework Physics on {1}", player.ClassyName, ClassyName ); + } catch ( Exception e ) { + Logger.Log( LogType.Error, "PhyStartFireworkPhysics: " + e ); } } - public void DisableFireworkPhysics(Player player, bool announce) - { - try - { - if (fireworkPhysics == false) - { - player.Message("&WAlready disabled on this world"); + public void DisableFireworkPhysics( Player player, bool announce ) { + try { + if ( fireworkPhysics == false ) { + player.Message( "&WAlready disabled on this world" ); return; } fireworkPhysics = false; CheckIfToStopPhysics(); - if (announce) - Server.Message("{0}&S disabled Firework Physics on {1}", player.ClassyName, ClassyName); - } - catch (Exception e) - { - Logger.Log(LogType.Error, "PhyStopFireworkPhysics: " + e); + if ( announce ) + Server.Message( "{0}&S disabled Firework Physics on {1}", player.ClassyName, ClassyName ); + } catch ( Exception e ) { + Logger.Log( LogType.Error, "PhyStopFireworkPhysics: " + e ); } } - #endregion + + #endregion Fireworks + #region Gun - public void EnableGunPhysics(Player player, bool announce) - { - try - { - if (gunPhysics == true) - { - player.Message("&WAlready enabled on this world"); + + public void EnableGunPhysics( Player player, bool announce ) { + try { + if ( gunPhysics == true ) { + player.Message( "&WAlready enabled on this world" ); return; } CheckIfPhysicsStarted(); gunPhysics = true; - if (announce) - Server.Message("{0}&S enabled Gun Physics on {1}", player.ClassyName, ClassyName); - } - catch (Exception e) - { - Logger.Log(LogType.Error, "PhyStartGunPhysics: " + e); + if ( announce ) + Server.Message( "{0}&S enabled Gun Physics on {1}", player.ClassyName, ClassyName ); + } catch ( Exception e ) { + Logger.Log( LogType.Error, "PhyStartGunPhysics: " + e ); } } - public void DisableGunPhysics(Player player, bool announce) - { - try - { - if (gunPhysics == false) - { - player.Message("&WAlready disabled on this world"); + public void DisableGunPhysics( Player player, bool announce ) { + try { + if ( gunPhysics == false ) { + player.Message( "&WAlready disabled on this world" ); return; } gunPhysics = false; CheckIfToStopPhysics(); - if (announce) - Server.Message("{0}&S disabled Gun Physics on {1}", player.ClassyName, ClassyName); - } - catch (Exception e) - { - Logger.Log(LogType.Error, "PhyStopGunPhysics: " + e); + if ( announce ) + Server.Message( "{0}&S disabled Gun Physics on {1}", player.ClassyName, ClassyName ); + } catch ( Exception e ) { + Logger.Log( LogType.Error, "PhyStopGunPhysics: " + e ); } } - #endregion + + #endregion Gun + #region Water - public void EnableWaterPhysics(Player player, bool announce) - { - if (waterPhysics == true) - { - player.Message("&WAlready enabled on this world"); + + public void EnableWaterPhysics( Player player, bool announce ) { + if ( waterPhysics == true ) { + player.Message( "&WAlready enabled on this world" ); return; } CheckIfPhysicsStarted(); waterPhysics = true; - if (announce) - Server.Message("{0}&S enabled Water Physics on {1}", player.ClassyName, ClassyName); + if ( announce ) + Server.Message( "{0}&S enabled Water Physics on {1}", player.ClassyName, ClassyName ); } - public void DisableWaterPhysics(Player player, bool announce) - { - if (waterPhysics == false) - { - player.Message("&WAlready disabled on this world"); + public void DisableWaterPhysics( Player player, bool announce ) { + if ( waterPhysics == false ) { + player.Message( "&WAlready disabled on this world" ); return; } waterPhysics = false; CheckIfToStopPhysics(); - if (announce) - Server.Message("{0}&S disabled Water Physics on {1}", player.ClassyName, ClassyName); + if ( announce ) + Server.Message( "{0}&S disabled Water Physics on {1}", player.ClassyName, ClassyName ); } - #endregion + + #endregion Water + #region Sand - public void EnableSandPhysics(Player player, bool announce) - { - if (sandPhysics == true) - { - player.Message("&WAlready enabled on this world"); + + public void EnableSandPhysics( Player player, bool announce ) { + if ( sandPhysics == true ) { + player.Message( "&WAlready enabled on this world" ); return; } CheckIfPhysicsStarted(); sandPhysics = true; - if(announce) - Server.Message("{0}&S enabled Sand Physics on {1}", player.ClassyName, ClassyName); + if ( announce ) + Server.Message( "{0}&S enabled Sand Physics on {1}", player.ClassyName, ClassyName ); } - public void DisableSandPhysics(Player player, bool announce) - { - if (sandPhysics == false) - { - player.Message("&WAlready disabled on this world"); + public void DisableSandPhysics( Player player, bool announce ) { + if ( sandPhysics == false ) { + player.Message( "&WAlready disabled on this world" ); return; } sandPhysics = false; CheckIfToStopPhysics(); - if(announce) - Server.Message("{0}&S disabled Sand Physics on {1}", player.ClassyName, ClassyName); - } - #endregion - private void CheckIfPhysicsStarted() - { - if (!_physSchedulers[(int)TaskCategory.Physics].Started) - _physSchedulers[(int)TaskCategory.Physics].Start(); - } - private void CheckIfToStopPhysics() - { - if (null == _plantTask && !tntPhysics - && !gunPhysics && !plantPhysics + if ( announce ) + Server.Message( "{0}&S disabled Sand Physics on {1}", player.ClassyName, ClassyName ); + } + + #endregion Sand + + private void CheckIfPhysicsStarted() { + if ( !_physSchedulers[( int )TaskCategory.Physics].Started ) + _physSchedulers[( int )TaskCategory.Physics].Start(); + } + + private void CheckIfToStopPhysics() { + if ( null == _plantTask && !tntPhysics + && !gunPhysics && !plantPhysics && !sandPhysics && !fireworkPhysics - && !waterPhysics) //must be extended to further phys types - _physSchedulers[(int)TaskCategory.Physics].Stop(); - } - - private void StopSchedulers() - { - foreach (PhysScheduler sch in _physSchedulers) - sch.Stop(); - } - private void AddTasksFromNewMap() - { - //assuming lock(SyncRoot) - foreach (Life2DZone life in map.LifeZones.Values) - life.Resume(); - if (map.LifeZones.Count>0) - _physSchedulers[(int)TaskCategory.Life].Start(); - } - #endregion + && !waterPhysics ) //must be extended to further phys types + _physSchedulers[( int )TaskCategory.Physics].Stop(); + } + private void StopSchedulers() { + foreach ( PhysScheduler sch in _physSchedulers ) + sch.Stop(); + } + + private void AddTasksFromNewMap() { + //assuming lock(SyncRoot) + foreach ( Life2DZone life in map.LifeZones.Values ) + life.Resume(); + if ( map.LifeZones.Count > 0 ) + _physSchedulers[( int )TaskCategory.Life].Start(); + } + + #endregion Physics #region Map @@ -512,21 +459,24 @@ private void AddTasksFromNewMap() public Map Map { get { return map; } set { - bool changed = !ReferenceEquals(map, value); - if( map != null && value == null ) StopTasks(); - if( map == null && value != null ) StartTasks(); - if( value != null ) value.World = this; + bool changed = !ReferenceEquals( map, value ); + if ( map != null && value == null ) + StopTasks(); + if ( map == null && value != null ) + StartTasks(); + if ( value != null ) + value.World = this; map = value; - if (changed) - { - if (null == map) - StopSchedulers(); - else - AddTasksFromNewMap(); - } + if ( changed ) { + if ( null == map ) + StopSchedulers(); + else + AddTasksFromNewMap(); + } } } + public Map map; /// Whether the map is currently loaded. @@ -534,22 +484,23 @@ public bool IsLoaded { get { return Map != null; } } - /// Loads the map file, if needed. /// Generates a default map if mapfile is missing or not loadable. /// Guaranteed to return a Map object. [NotNull] public Map LoadMap() { var tempMap = Map; - if( tempMap != null ) return tempMap; + if ( tempMap != null ) + return tempMap; - lock( SyncRoot ) { - if( Map != null ) return Map; + lock ( SyncRoot ) { + if ( Map != null ) + return Map; - if( File.Exists( MapFileName ) ) { + if ( File.Exists( MapFileName ) ) { try { Map = MapUtility.Load( MapFileName ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.Log( LogType.Error, "World.LoadMap: Failed to load map ({0}): {1}", MapFileName, ex ); @@ -557,7 +508,7 @@ public Map LoadMap() { } // or generate a default one - if( Map == null ) { + if ( Map == null ) { Server.Message( "&WMapfile is missing for world {0}&W. A new map has been created.", ClassyName ); Logger.Log( LogType.Warning, "World.LoadMap: Map file missing for world {0}. Generating default flatgrass map.", @@ -568,10 +519,10 @@ public Map LoadMap() { } } - internal void UnloadMap( bool expectedPendingFlag ) { - lock( SyncRoot ) { - if( expectedPendingFlag != IsPendingMapUnload ) return; + lock ( SyncRoot ) { + if ( expectedPendingFlag != IsPendingMapUnload ) + return; SaveMap(); Map = null; IsPendingMapUnload = false; @@ -579,7 +530,6 @@ internal void UnloadMap( bool expectedPendingFlag ) { Server.RequestGC(); } - /// Returns the map filename, including MapPath. public string MapFileName { get { @@ -587,23 +537,22 @@ public string MapFileName { } } - public void SaveMap() { - lock( SyncRoot ) { - if( Map != null ) { + lock ( SyncRoot ) { + if ( Map != null ) { Map.Save( MapFileName ); } } } - public void ChangeMap( [NotNull] Map newMap ) { - if( newMap == null ) throw new ArgumentNullException( "newMap" ); + if ( newMap == null ) + throw new ArgumentNullException( "newMap" ); MapChangedOn = DateTime.UtcNow; - lock( SyncRoot ) { + lock ( SyncRoot ) { World newWorld = new World( Name ) { - AccessSecurity = (SecurityController)AccessSecurity.Clone(), - BuildSecurity = (SecurityController)BuildSecurity.Clone(), + AccessSecurity = ( SecurityController )AccessSecurity.Clone(), + BuildSecurity = ( SecurityController )BuildSecurity.Clone(), IsHidden = IsHidden, IsRealm = IsRealm, fireworkPhysics = fireworkPhysics, @@ -639,78 +588,79 @@ public void ChangeMap( [NotNull] Map newMap ) { BlockDB.Clear(); BlockDB.World = newWorld; } - foreach( Player player in Players ) { + foreach ( Player player in Players ) { player.JoinWorld( newWorld, WorldChangeReason.Rejoin ); } } } + private bool neverUnload; - bool neverUnload; public bool NeverUnload { get { return neverUnload; } set { - lock( SyncRoot ) { - if( neverUnload == value ) return; + lock ( SyncRoot ) { + if ( neverUnload == value ) + return; neverUnload = value; - if( neverUnload ) { - if( Map == null ) LoadMap(); + if ( neverUnload ) { + if ( Map == null ) + LoadMap(); } else { - if( Map != null && playerIndex.Count == 0 ) UnloadMap( false ); + if ( Map != null && playerIndex.Count == 0 ) + UnloadMap( false ); } } } } - #endregion - - + #endregion Map #region Flush public bool IsFlushing { get; private set; } - public void Flush() { - lock( SyncRoot ) { - if( Map == null ) return; + lock ( SyncRoot ) { + if ( Map == null ) + return; Players.Message( "&WMap is being flushed. Stay put, world will reload shortly." ); IsFlushing = true; } } - internal void EndFlushMapBuffer() { - lock( SyncRoot ) { + lock ( SyncRoot ) { IsFlushing = false; Players.Message( "&WMap flushed. Reloading..." ); - foreach( Player player in Players ) { + foreach ( Player player in Players ) { player.JoinWorld( this, WorldChangeReason.Rejoin, player.Position ); } } } - #endregion - + #endregion Flush #region PlayerList - readonly Dictionary playerIndex = new Dictionary(); + private readonly Dictionary playerIndex = new Dictionary(); + public Player[] Players { get; private set; } [CanBeNull] public Map AcceptPlayer( [NotNull] Player player, bool announce ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); - lock( SyncRoot ) { - if( IsFull ) { - if( player.Info.Rank.ReservedSlot ) { + lock ( SyncRoot ) { + if ( IsFull ) { + if ( player.Info.Rank.ReservedSlot ) { Player idlestPlayer = Players.Where( p => p.Info.Rank.IdleKickTimer != 0 ) .OrderBy( p => p.LastActiveTime ) .FirstOrDefault(); - if( idlestPlayer != null ) { + if ( idlestPlayer != null ) { idlestPlayer.Kick( Player.Console, "Auto-kicked to make room (idle).", LeaveReason.IdleKick, false, false, false ); @@ -730,7 +680,7 @@ public Map AcceptPlayer( [NotNull] Player player, bool announce ) { } } - if( playerIndex.ContainsKey( player.Name.ToLower() ) ) { + if ( playerIndex.ContainsKey( player.Name.ToLower() ) ) { Logger.Log( LogType.Error, "This world already contains the player by name ({0}). " + "Some sort of state corruption must have occured.", @@ -744,49 +694,44 @@ public Map AcceptPlayer( [NotNull] Player player, bool announce ) { IsPendingMapUnload = false; Map = LoadMap(); - if( ConfigKey.BackupOnJoin.Enabled() && (Map.HasChangedSinceBackup || !ConfigKey.BackupOnlyWhenChanged.Enabled()) ) { + if ( ConfigKey.BackupOnJoin.Enabled() && ( Map.HasChangedSinceBackup || !ConfigKey.BackupOnlyWhenChanged.Enabled() ) ) { string backupFileName = String.Format( JoinBackupFormat, Name, DateTime.Now, player.Name ); // localized - SaveBackup( MapFileName); + SaveBackup( MapFileName ); } UpdatePlayerList(); - if (!IsRealm && announce && ConfigKey.ShowJoinedWorldMessages.Enabled()) - { - Server.Players.CanSee(player) - .Message("&SPlayer {0}&S joined world {1}", - player.ClassyName, ClassyName); - + if ( !IsRealm && announce && ConfigKey.ShowJoinedWorldMessages.Enabled() ) { + Server.Players.CanSee( player ) + .Message( "&SPlayer {0}&S joined world {1}", + player.ClassyName, ClassyName ); } //realm joining announcer - if (IsRealm && announce && ConfigKey.ShowJoinedWorldMessages.Enabled()) - { - Server.Players.CanSee(player) - .Message("&SPlayer {0}&S joined realm {1}", - player.ClassyName, ClassyName); + if ( IsRealm && announce && ConfigKey.ShowJoinedWorldMessages.Enabled() ) { + Server.Players.CanSee( player ) + .Message( "&SPlayer {0}&S joined realm {1}", + player.ClassyName, ClassyName ); } - if (IsRealm) - { - Logger.Log(LogType.ChangedWorld, + if ( IsRealm ) { + Logger.Log( LogType.ChangedWorld, "Player {0} joined realm {1}.", - player.Name, Name); + player.Name, Name ); } - if (!IsRealm) - { - Logger.Log(LogType.ChangedWorld, + if ( !IsRealm ) { + Logger.Log( LogType.ChangedWorld, "Player {0} joined world {1}.", - player.Name, Name); + player.Name, Name ); } - if( IsLocked ) { + if ( IsLocked ) { player.Message( "&WThis map is currently locked (read-only)." ); } - if( player.Info.IsHidden ) { + if ( player.Info.IsHidden ) { player.Message( "&8Reminder: You are still hidden." ); } @@ -794,11 +739,11 @@ public Map AcceptPlayer( [NotNull] Player player, bool announce ) { } } - public bool ReleasePlayer( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); - lock( SyncRoot ) { - if( !playerIndex.Remove( player.Name.ToLower() ) ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + lock ( SyncRoot ) { + if ( !playerIndex.Remove( player.Name.ToLower() ) ) { return false; } @@ -813,26 +758,27 @@ public bool ReleasePlayer( [NotNull] Player player ) { UpdatePlayerList(); // unload map (if needed) - if( playerIndex.Count == 0 && !neverUnload ) { + if ( playerIndex.Count == 0 && !neverUnload ) { IsPendingMapUnload = true; } return true; } } - public Player[] FindPlayers( [NotNull] Player player, [NotNull] string playerName ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( playerName == null ) throw new ArgumentNullException( "playerName" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( playerName == null ) + throw new ArgumentNullException( "playerName" ); Player[] tempList = Players; List results = new List(); - for( int i = 0; i < tempList.Length; i++ ) { - if( tempList[i] != null && player.CanSee( tempList[i] ) ) { - if( tempList[i].Name.Equals( playerName, StringComparison.OrdinalIgnoreCase ) ) { + for ( int i = 0; i < tempList.Length; i++ ) { + if ( tempList[i] != null && player.CanSee( tempList[i] ) ) { + if ( tempList[i].Name.Equals( playerName, StringComparison.OrdinalIgnoreCase ) ) { results.Clear(); results.Add( tempList[i] ); break; - } else if( tempList[i].Name.StartsWith( playerName, StringComparison.OrdinalIgnoreCase ) ) { + } else if ( tempList[i].Name.StartsWith( playerName, StringComparison.OrdinalIgnoreCase ) ) { results.Add( tempList[i] ); } } @@ -840,15 +786,15 @@ public Player[] FindPlayers( [NotNull] Player player, [NotNull] string playerNam return results.ToArray(); } - /// Gets player by name (without autocompletion) [CanBeNull] public Player FindPlayerExact( [NotNull] string playerName ) { - if( playerName == null ) throw new ArgumentNullException( "playerName" ); + if ( playerName == null ) + throw new ArgumentNullException( "playerName" ); Player[] tempList = Players; // ReSharper disable LoopCanBeConvertedToQuery - for( int i = 0; i < tempList.Length; i++ ) { - if( tempList[i] != null && tempList[i].Name.Equals( playerName, StringComparison.OrdinalIgnoreCase ) ) { + for ( int i = 0; i < tempList.Length; i++ ) { + if ( tempList[i] != null && tempList[i].Name.Equals( playerName, StringComparison.OrdinalIgnoreCase ) ) { return tempList[i]; } } @@ -856,40 +802,36 @@ public Player FindPlayerExact( [NotNull] string playerName ) { return null; } - /// Caches the player list to an array (Players -> PlayerList) public void UpdatePlayerList() { - lock( SyncRoot ) { + lock ( SyncRoot ) { Players = playerIndex.Values.ToArray(); } } - /// Counts all players (optionally includes all hidden players). public int CountPlayers( bool includeHiddenPlayers ) { - if( includeHiddenPlayers ) { + if ( includeHiddenPlayers ) { return Players.Length; } else { return Players.Count( player => !player.Info.IsHidden ); } } - /// Counts only the players who are not hidden from a given observer. public int CountVisiblePlayers( [NotNull] Player observer ) { - if( observer == null ) throw new ArgumentNullException( "observer" ); + if ( observer == null ) + throw new ArgumentNullException( "observer" ); return Players.Count( observer.CanSee ); } - public bool IsFull { get { - return (Players.Length >= ConfigKey.MaxPlayersPerWorld.GetInt()); + return ( Players.Length >= ConfigKey.MaxPlayersPerWorld.GetInt() ); } } - #endregion - + #endregion PlayerList #region Lock / Unlock @@ -899,20 +841,20 @@ public bool IsFull { public string LockedBy, UnlockedBy; public DateTime LockedDate, UnlockedDate; - readonly object lockLock = new object(); - + private readonly object lockLock = new object(); public bool Lock( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); - lock( lockLock ) { - if( IsLocked ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + lock ( lockLock ) { + if ( IsLocked ) { return false; } else { LockedBy = player.Name; LockedDate = DateTime.UtcNow; IsLocked = true; Map mapCache = Map; - if( mapCache != null ) { + if ( mapCache != null ) { mapCache.ClearUpdateQueue(); mapCache.StopAllDrawOps(); } @@ -925,11 +867,11 @@ public bool Lock( [NotNull] Player player ) { } } - public bool Unlock( [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); - lock( lockLock ) { - if( IsLocked ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + lock ( lockLock ) { + if ( IsLocked ) { UnlockedBy = player.Name; UnlockedDate = DateTime.UtcNow; IsLocked = false; @@ -944,20 +886,17 @@ public bool Unlock( [NotNull] Player player ) { } } - #endregion + #endregion Lock / Unlock #region Backups - DateTime lastBackup = DateTime.UtcNow; - static readonly object BackupLock = new object(); + private DateTime lastBackup = DateTime.UtcNow; + private static readonly object BackupLock = new object(); /// Whether timed backups are enabled (either manually or by default) on this world. - public bool BackupsEnabled - { - get - { - switch (BackupEnabledState) - { + public bool BackupsEnabled { + get { + switch ( BackupEnabledState ) { case YesNoAuto.Yes: return BackupInterval > TimeSpan.Zero; case YesNoAuto.No: @@ -968,41 +907,33 @@ public bool BackupsEnabled } } - /// Whether the map was saved since last time it was backed up. public bool HasChangedSinceBackup { get; set; } - /// Backup state. Use "Yes" to enable, "No" to disable, and "Auto" to use default settings. /// If setting to "Yes", make sure to set BackupInterval property value first. - public YesNoAuto BackupEnabledState - { + public YesNoAuto BackupEnabledState { get { return backupEnabledState; } - set - { - lock (BackupLock) - { - if (value == backupEnabledState) return; - if (value == YesNoAuto.Yes && backupInterval <= TimeSpan.Zero) - { - throw new InvalidOperationException("To set BackupEnabledState to 'Yes,' set BackupInterval to the desired time interval."); + set { + lock ( BackupLock ) { + if ( value == backupEnabledState ) + return; + if ( value == YesNoAuto.Yes && backupInterval <= TimeSpan.Zero ) { + throw new InvalidOperationException( "To set BackupEnabledState to 'Yes,' set BackupInterval to the desired time interval." ); } backupEnabledState = value; } } } - YesNoAuto backupEnabledState = YesNoAuto.Auto; + private YesNoAuto backupEnabledState = YesNoAuto.Auto; /// Timed backup interval. /// If BackupEnabledState is set to "Yes", value must be positive. /// If BackupEnabledState is set to "No" or "Auto", this property has no effect. - public TimeSpan BackupInterval - { - get - { - switch (backupEnabledState) - { + public TimeSpan BackupInterval { + get { + switch ( backupEnabledState ) { case YesNoAuto.Yes: return backupInterval; case YesNoAuto.No: @@ -1011,183 +942,149 @@ public TimeSpan BackupInterval return WorldManager.DefaultBackupInterval; } } - set - { - lock (BackupLock) - { + set { + lock ( BackupLock ) { backupInterval = value; - if (value > TimeSpan.Zero) - { + if ( value > TimeSpan.Zero ) { BackupEnabledState = YesNoAuto.Yes; - } - else - { + } else { BackupEnabledState = YesNoAuto.No; } } } } - TimeSpan backupInterval; + + private TimeSpan backupInterval; /// Whether timed backups are enabled by default for worlds that have BackupEnabledState set to "Auto". - public static bool DefaultBackupsEnabled - { + public static bool DefaultBackupsEnabled { get { return WorldManager.DefaultBackupInterval > TimeSpan.Zero; } } - - internal string BackupSettingDescription - { - get - { - switch (backupEnabledState) - { + internal string BackupSettingDescription { + get { + switch ( backupEnabledState ) { case YesNoAuto.No: return "disabled (manual)"; case YesNoAuto.Yes: - return String.Format("every {0} (manual)", backupInterval.ToMiniString()); + return String.Format( "every {0} (manual)", backupInterval.ToMiniString() ); default: //case YesNoAuto.Auto: - if (DefaultBackupsEnabled) - { - return String.Format("every {0} (default)", WorldManager.DefaultBackupInterval.ToMiniString()); - } - else - { + if ( DefaultBackupsEnabled ) { + return String.Format( "every {0} (default)", WorldManager.DefaultBackupInterval.ToMiniString() ); + } else { return "disabled (default)"; } } } } - /// Makes a copy of the current map file associated with this world. /// This does NOT save map to disk, and does NOT guarantee that the most up-to-date copy of the map was backed up. /// Target file name. /// Whether a backup was created or not. /// targetName is null. - public bool SaveBackup([NotNull] string targetName) - { - if (targetName == null) throw new ArgumentNullException("targetName"); - - if (!File.Exists(MapFileName)) return false; - lock (BackupLock) - { - DirectoryInfo directory = new DirectoryInfo(Paths.BackupPath); - - if (!directory.Exists) - { - try - { + public bool SaveBackup( [NotNull] string targetName ) { + if ( targetName == null ) + throw new ArgumentNullException( "targetName" ); + + if ( !File.Exists( MapFileName ) ) + return false; + lock ( BackupLock ) { + DirectoryInfo directory = new DirectoryInfo( Paths.BackupPath ); + + if ( !directory.Exists ) { + try { directory.Create(); - } - catch (Exception ex) - { - Logger.Log(LogType.Error, - "Map.SaveBackup: Error occurred while trying to create backup directory: {0}", ex); + } catch ( Exception ex ) { + Logger.Log( LogType.Error, + "Map.SaveBackup: Error occurred while trying to create backup directory: {0}", ex ); return false; } } - try - { + try { HasChangedSinceBackup = false; - File.Copy(MapFileName, targetName, true); - } - catch (Exception ex) - { + File.Copy( MapFileName, targetName, true ); + } catch ( Exception ex ) { HasChangedSinceBackup = true; - Logger.Log(LogType.Error, + Logger.Log( LogType.Error, "Map.SaveBackup: Error occurred while trying to save backup to \"{0}\": {1}", - targetName, ex); + targetName, ex ); return false; } - if (ConfigKey.MaxBackups.GetInt() > 0 || ConfigKey.MaxBackupSize.GetInt() > 0) - { - DeleteOldBackups(directory); + if ( ConfigKey.MaxBackups.GetInt() > 0 || ConfigKey.MaxBackupSize.GetInt() > 0 ) { + DeleteOldBackups( directory ); } } - Logger.Log(LogType.SystemActivity, - "Saved a backup of world {0} to \"{1}\"", Name, targetName); + Logger.Log( LogType.SystemActivity, + "Saved a backup of world {0} to \"{1}\"", Name, targetName ); return true; } - - static void DeleteOldBackups([NotNull] DirectoryInfo directory) - { - if (directory == null) throw new ArgumentNullException("directory"); - var backupList = directory.GetFiles("*.fcm").OrderBy(fi => -fi.CreationTimeUtc.Ticks).ToList(); + private static void DeleteOldBackups( [NotNull] DirectoryInfo directory ) { + if ( directory == null ) + throw new ArgumentNullException( "directory" ); + var backupList = directory.GetFiles( "*.fcm" ).OrderBy( fi => -fi.CreationTimeUtc.Ticks ).ToList(); int maxFileCount = ConfigKey.MaxBackups.GetInt(); - if (maxFileCount > 0) - { - while (backupList.Count > maxFileCount) - { + if ( maxFileCount > 0 ) { + while ( backupList.Count > maxFileCount ) { FileInfo info = backupList[backupList.Count - 1]; - backupList.RemoveAt(backupList.Count - 1); - try - { - File.Delete(info.FullName); - } - catch (Exception ex) - { - Logger.Log(LogType.Error, + backupList.RemoveAt( backupList.Count - 1 ); + try { + File.Delete( info.FullName ); + } catch ( Exception ex ) { + Logger.Log( LogType.Error, "Map.SaveBackup: Error occurred while trying delete old backup \"{0}\": {1}", - info.FullName, ex); + info.FullName, ex ); break; } - Logger.Log(LogType.SystemActivity, - "Map.SaveBackup: Deleted old backup \"{0}\"", info.Name); + Logger.Log( LogType.SystemActivity, + "Map.SaveBackup: Deleted old backup \"{0}\"", info.Name ); } } int maxFileSize = ConfigKey.MaxBackupSize.GetInt(); - if (maxFileSize > 0) - { - while (true) - { + if ( maxFileSize > 0 ) { + while ( true ) { FileInfo[] fis = directory.GetFiles(); - long size = fis.Sum(fi => fi.Length); + long size = fis.Sum( fi => fi.Length ); - if (size / 1024 / 1024 > maxFileSize) - { + if ( size / 1024 / 1024 > maxFileSize ) { FileInfo info = backupList[backupList.Count - 1]; - backupList.RemoveAt(backupList.Count - 1); - try - { - File.Delete(info.FullName); - } - catch (Exception ex) - { - Logger.Log(LogType.Error, + backupList.RemoveAt( backupList.Count - 1 ); + try { + File.Delete( info.FullName ); + } catch ( Exception ex ) { + Logger.Log( LogType.Error, "Map.SaveBackup: Error occurred while trying delete old backup \"{0}\": {1}", - info.Name, ex); + info.Name, ex ); break; } - Logger.Log(LogType.SystemActivity, - "Map.SaveBackup: Deleted old backup \"{0}\"", info.Name); - } - else - { + Logger.Log( LogType.SystemActivity, + "Map.SaveBackup: Deleted old backup \"{0}\"", info.Name ); + } else { break; } } } } - #endregion + #endregion Backups #region Patrol - readonly object patrolLock = new object(); - static readonly TimeSpan MinPatrolInterval = TimeSpan.FromSeconds( 20 ); + private readonly object patrolLock = new object(); + private static readonly TimeSpan MinPatrolInterval = TimeSpan.FromSeconds( 20 ); public Player GetNextPatrolTarget( [NotNull] Player observer ) { - if( observer == null ) throw new ArgumentNullException( "observer" ); - lock( patrolLock ) { + if ( observer == null ) + throw new ArgumentNullException( "observer" ); + lock ( patrolLock ) { Player candidate = Players.RankedAtMost( RankManager.PatrolledRank ) .CanBeSeen( observer ) .Where( p => p.LastActiveTime > p.LastPatrolTime && @@ -1195,7 +1092,7 @@ public Player GetNextPatrolTarget( [NotNull] Player observer ) { DateTime.UtcNow.Subtract( p.LastPatrolTime ) > MinPatrolInterval ) .OrderBy( p => p.LastPatrolTime.Ticks ) .FirstOrDefault(); - if( candidate != null ) { + if ( candidate != null ) { candidate.LastPatrolTime = DateTime.UtcNow; } return candidate; @@ -1205,9 +1102,11 @@ public Player GetNextPatrolTarget( [NotNull] Player observer ) { public Player GetNextPatrolTarget( [NotNull] Player observer, [NotNull] Predicate predicate, bool setLastPatrolTime ) { - if( observer == null ) throw new ArgumentNullException( "observer" ); - if( predicate == null ) throw new ArgumentNullException( "predicate" ); - lock( patrolLock ) { + if ( observer == null ) + throw new ArgumentNullException( "observer" ); + if ( predicate == null ) + throw new ArgumentNullException( "predicate" ); + lock ( patrolLock ) { Player candidate = Players.RankedAtMost( RankManager.PatrolledRank ) .CanBeSeen( observer ) .Where( p => p.LastActiveTime > p.LastPatrolTime && @@ -1216,89 +1115,77 @@ public Player GetNextPatrolTarget( [NotNull] Player observer, .Where( p => predicate( p ) ) .OrderBy( p => p.LastPatrolTime.Ticks ) .FirstOrDefault(); - if( setLastPatrolTime && candidate != null ) { + if ( setLastPatrolTime && candidate != null ) { candidate.LastPatrolTime = DateTime.UtcNow; } return candidate; } } - #endregion - + #endregion Patrol #region Scheduled Tasks - SchedulerTask updateTask, saveTask; - readonly object taskLock = new object(); + private SchedulerTask updateTask, saveTask; + private readonly object taskLock = new object(); - - void StopTasks() { - lock( taskLock ) { - if( updateTask != null ) { + private void StopTasks() { + lock ( taskLock ) { + if ( updateTask != null ) { updateTask.Stop(); updateTask = null; } - if( saveTask != null ) { + if ( saveTask != null ) { saveTask.Stop(); saveTask = null; } } } - - void StartTasks() - { - lock (taskLock) - { - updateTask = Scheduler.NewTask(UpdateTask); - updateTask.RunForever(this, - TimeSpan.FromMilliseconds(ConfigKey.TickInterval.GetInt()), - TimeSpan.Zero); - - if (ConfigKey.SaveInterval.GetInt() > 0) - { - saveTask = Scheduler.NewBackgroundTask(SaveTask); - saveTask.RunForever(this, - TimeSpan.FromSeconds(ConfigKey.SaveInterval.GetInt()), - TimeSpan.FromSeconds(ConfigKey.SaveInterval.GetInt())); + private void StartTasks() { + lock ( taskLock ) { + updateTask = Scheduler.NewTask( UpdateTask ); + updateTask.RunForever( this, + TimeSpan.FromMilliseconds( ConfigKey.TickInterval.GetInt() ), + TimeSpan.Zero ); + + if ( ConfigKey.SaveInterval.GetInt() > 0 ) { + saveTask = Scheduler.NewBackgroundTask( SaveTask ); + saveTask.RunForever( this, + TimeSpan.FromSeconds( ConfigKey.SaveInterval.GetInt() ), + TimeSpan.FromSeconds( ConfigKey.SaveInterval.GetInt() ) ); } } } - - void UpdateTask( SchedulerTask task ) { + private void UpdateTask( SchedulerTask task ) { Map tempMap = Map; - if( tempMap != null ) { + if ( tempMap != null ) { tempMap.ProcessUpdates(); } } - - const string TimedBackupFormat = "{0}_{1:yyyy-MM-dd_HH-mm}.fcm", + private const string TimedBackupFormat = "{0}_{1:yyyy-MM-dd_HH-mm}.fcm", JoinBackupFormat = "{0}_{1:yyyy-MM-dd_HH-mm}_{2}.fcm"; + private void SaveTask( SchedulerTask task ) { + if ( !IsLoaded ) + return; + lock ( SyncRoot ) { + if ( Map == null ) + return; - void SaveTask(SchedulerTask task) - { - if (!IsLoaded) return; - lock (SyncRoot) - { - if (Map == null) return; - - lock (BackupLock) - { - if (BackupsEnabled && - DateTime.UtcNow.Subtract(lastBackup) > BackupInterval && - (HasChangedSinceBackup || !ConfigKey.BackupOnlyWhenChanged.Enabled())) - { - string backupFileName = String.Format(TimedBackupFormat, Name, DateTime.Now); // localized - SaveBackup(Path.Combine(Paths.BackupPath, backupFileName)); + lock ( BackupLock ) { + if ( BackupsEnabled && + DateTime.UtcNow.Subtract( lastBackup ) > BackupInterval && + ( HasChangedSinceBackup || !ConfigKey.BackupOnlyWhenChanged.Enabled() ) ) { + string backupFileName = String.Format( TimedBackupFormat, Name, DateTime.Now ); // localized + SaveBackup( Path.Combine( Paths.BackupPath, backupFileName ) ); lastBackup = DateTime.UtcNow; } } - if (Map.HasChangedSinceSave) - { + if ( Map.HasChangedSinceSave ) { SaveMap(); } @@ -1308,8 +1195,7 @@ void SaveTask(SchedulerTask task) } } - #endregion - + #endregion Scheduled Tasks #region WoM Extensions @@ -1317,6 +1203,7 @@ void SaveTask(SchedulerTask task) FogColor = -1, SkyColor = -1, EdgeLevel = -1; + public string Terrain { get; set; } public Block EdgeBlock = Block.Water; @@ -1325,47 +1212,51 @@ void SaveTask(SchedulerTask task) public string GenerateWoMConfig( bool sendMotd ) { StringBuilder sb = new StringBuilder(); sb.AppendLine( "server.name = " + ConfigKey.ServerName.GetString() ); - if( sendMotd ) { + if ( sendMotd ) { sb.AppendLine( "server.detail = " + ConfigKey.MOTD.GetString() ); } else { sb.AppendLine( "server.detail = " + ClassyName ); } sb.AppendLine( "user.detail = World " + ClassyName ); - if( CloudColor > -1 ) sb.AppendLine( "environment.cloud = " + CloudColor ); - if( FogColor > -1 ) sb.AppendLine( "environment.fog = " + FogColor ); - if( SkyColor > -1 ) sb.AppendLine( "environment.sky = " + SkyColor ); - if( EdgeLevel > -1 ) sb.AppendLine( "environment.level = " + EdgeLevel ); - if (Terrain != null) sb.AppendLine("environment.terrain = " + Terrain); - if( EdgeBlock != Block.Water ) { + if ( CloudColor > -1 ) + sb.AppendLine( "environment.cloud = " + CloudColor ); + if ( FogColor > -1 ) + sb.AppendLine( "environment.fog = " + FogColor ); + if ( SkyColor > -1 ) + sb.AppendLine( "environment.sky = " + SkyColor ); + if ( EdgeLevel > -1 ) + sb.AppendLine( "environment.level = " + EdgeLevel ); + if ( Terrain != null ) + sb.AppendLine( "environment.terrain = " + Terrain ); + if ( EdgeBlock != Block.Water ) { string edgeTexture = Map.GetEdgeTexture( EdgeBlock ); - if( edgeTexture != null ) { + if ( edgeTexture != null ) { sb.AppendLine( "environment.edge = " + edgeTexture ); } } - if (SideBlock != Block.Admincrete) - { - string sideTexture = Map.GetEdgeTexture(SideBlock); - if (sideTexture != null) - { - sb.AppendLine("environment.side = "+sideTexture); + if ( SideBlock != Block.Admincrete ) { + string sideTexture = Map.GetEdgeTexture( SideBlock ); + if ( sideTexture != null ) { + sb.AppendLine( "environment.side = " + sideTexture ); } } sb.AppendLine( "server.sendwomid = true" ); return sb.ToString(); } - #endregion - + #endregion WoM Extensions /// Ensures that player name has the correct length (2-16 characters) /// and character set (alphanumeric chars and underscores allowed). public static bool IsValidName( [NotNull] string name ) { - if( name == null ) throw new ArgumentNullException( "name" ); - if( name.Length < 2 || name.Length > 16 ) return false; + if ( name == null ) + throw new ArgumentNullException( "name" ); + if ( name.Length < 2 || name.Length > 16 ) + return false; // ReSharper disable LoopCanBeConvertedToQuery - for( int i = 0; i < name.Length; i++ ) { + for ( int i = 0; i < name.Length; i++ ) { char ch = name[i]; - if ( ch != '-' ){ + if ( ch != '-' ) { if ( ch < '0' || ch > '9' && ch < 'A' || ch > 'Z' && ch < '_' || @@ -1379,18 +1270,17 @@ public static bool IsValidName( [NotNull] string name ) { return true; } - /// Returns a nicely formatted name, with optional color codes. public string ClassyName { get { - if( ConfigKey.RankColorsInWorldNames.Enabled() ) { + if ( ConfigKey.RankColorsInWorldNames.Enabled() ) { Rank maxRank; - if( BuildSecurity.MinRank >= AccessSecurity.MinRank ) { + if ( BuildSecurity.MinRank >= AccessSecurity.MinRank ) { maxRank = BuildSecurity.MinRank; } else { maxRank = AccessSecurity.MinRank; } - if( ConfigKey.RankPrefixesInChat.Enabled() ) { + if ( ConfigKey.RankPrefixesInChat.Enabled() ) { return maxRank.Color + maxRank.Prefix + Name; } else { return maxRank.Color + Name; @@ -1401,11 +1291,8 @@ public string ClassyName { } } - public override string ToString() { return String.Format( "World({0})", Name ); } - } -} - +} \ No newline at end of file diff --git a/fCraft/World/WorldManager.cs b/fCraft/World/WorldManager.cs index 16cd87e..faeea59 100644 --- a/fCraft/World/WorldManager.cs +++ b/fCraft/World/WorldManager.cs @@ -9,21 +9,24 @@ using JetBrains.Annotations; namespace fCraft { + public static class WorldManager { + public const string BuildSecurityXmlTagName = "BuildSecurity", AccessSecurityXmlTagName = "AccessSecurity", EnvironmentXmlTagName = "Environment", RankMainXmlTagName = "RankMainWorld"; public static World[] Worlds { get; private set; } - static readonly SortedDictionary WorldIndex = new SortedDictionary(); + + private static readonly SortedDictionary WorldIndex = new SortedDictionary(); public static TimeSpan DefaultBackupInterval { get; set; } internal static readonly object SyncRoot = new object(); + private static World mainWorld; - static World mainWorld; /// Gets or sets the default main world. /// That's the world that players first join upon connecting. /// The map of the new main world is preloaded, and old one is unloaded, if needed. @@ -33,16 +36,18 @@ public static class WorldManager { public static World MainWorld { get { return mainWorld; } set { - if( value == null ) throw new ArgumentNullException( "value" ); - if( value == mainWorld ) return; - if( RaiseMainWorldChangingEvent( mainWorld, value ) ) { + if ( value == null ) + throw new ArgumentNullException( "value" ); + if ( value == mainWorld ) + return; + if ( RaiseMainWorldChangingEvent( mainWorld, value ) ) { throw new WorldOpException( value.Name, WorldOpExceptionCode.Cancelled ); } World oldWorld; - lock( SyncRoot ) { + lock ( SyncRoot ) { value.NeverUnload = true; oldWorld = mainWorld; - if( oldWorld != null ) { + if ( oldWorld != null ) { oldWorld.NeverUnload = false; } mainWorld = value; @@ -51,25 +56,25 @@ public static World MainWorld { } } - #region World List Saving/Loading - static World firstWorld; + private static World firstWorld; + internal static bool LoadWorldList() { World newMainWorld = null; Worlds = new World[0]; - if( File.Exists( Paths.WorldListFileName ) ) { + if ( File.Exists( Paths.WorldListFileName ) ) { try { XDocument doc = XDocument.Load( Paths.WorldListFileName ); XElement root = doc.Root; - if( root != null ) { - foreach( XElement el in root.Elements( "World" ) ) { + if ( root != null ) { + foreach ( XElement el in root.Elements( "World" ) ) { #if !DEBUG try { #endif LoadWorldListEntry( el ); #if !DEBUG - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.LogAndReportCrash( "An error occured while trying to parse one of the entries on the world list", "800Craft", ex, false ); } @@ -77,13 +82,12 @@ internal static bool LoadWorldList() { } XAttribute temp; - if( (temp = root.Attribute( "main" )) != null ) { + if ( ( temp = root.Attribute( "main" ) ) != null ) { World suggestedMainWorld = FindWorldExact( temp.Value ); - if( suggestedMainWorld != null ) { + if ( suggestedMainWorld != null ) { newMainWorld = suggestedMainWorld; - - } else if( firstWorld != null ) { + } else if ( firstWorld != null ) { // if specified main world does not exist, use first-defined world Logger.Log( LogType.Warning, "The specified main world \"{0}\" does not exist. " + @@ -92,23 +96,21 @@ internal static bool LoadWorldList() { newMainWorld = firstWorld; } // if firstWorld was also null, LoadWorldList() should try creating a new mainWorld - - } else if( firstWorld != null ) { + } else if ( firstWorld != null ) { newMainWorld = firstWorld; } } - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.LogAndReportCrash( "Error occured while trying to load the world list.", "800Craft", ex, true ); return false; } - if( newMainWorld == null ) { + if ( newMainWorld == null ) { Logger.Log( LogType.Error, "Server.Start: Could not load any of the specified worlds, or no worlds were specified. " + "Creating default \"main\" world." ); newMainWorld = AddWorld( null, "main", MapGenerator.GenerateFlatgrass( 128, 128, 64 ), true ); } - } else { Logger.Log( LogType.SystemActivity, "Server.Start: No world list found. Creating default \"main\" world." ); @@ -116,10 +118,9 @@ internal static bool LoadWorldList() { } // if there is no default world still, die. - if( newMainWorld == null ) { + if ( newMainWorld == null ) { throw new Exception( "Could not create any worlds." ); - - } else if( newMainWorld.AccessSecurity.HasRestrictions ) { + } else if ( newMainWorld.AccessSecurity.HasRestrictions ) { Logger.Log( LogType.Warning, "Server.LoadWorldList: Main world cannot have any access restrictions. " + "Access permission for \"{0}\" has been reset.", @@ -132,30 +133,31 @@ internal static bool LoadWorldList() { return true; } - static void LoadWorldListEntry( [NotNull] XElement el ) { - if( el == null ) throw new ArgumentNullException( "el" ); + private static void LoadWorldListEntry( [NotNull] XElement el ) { + if ( el == null ) + throw new ArgumentNullException( "el" ); XAttribute tempAttr; - if( (tempAttr = el.Attribute( "name" )) == null ) { + if ( ( tempAttr = el.Attribute( "name" ) ) == null ) { Logger.Log( LogType.Error, "WorldManager: World tag with no name skipped." ); return; } string worldName = tempAttr.Value; - bool neverUnload = (el.Attribute( "noUnload" ) != null); + bool neverUnload = ( el.Attribute( "noUnload" ) != null ); World world; try { world = AddWorld( null, worldName, null, neverUnload ); - } catch( WorldOpException ex ) { + } catch ( WorldOpException ex ) { Logger.Log( LogType.Error, "WorldManager: Error adding world \"{0}\": {1}", worldName, ex.Message ); return; } - if( (tempAttr = el.Attribute( "hidden" )) != null ) { + if ( ( tempAttr = el.Attribute( "hidden" ) ) != null ) { bool isHidden; - if( Boolean.TryParse( tempAttr.Value, out isHidden ) ) { + if ( Boolean.TryParse( tempAttr.Value, out isHidden ) ) { world.IsHidden = isHidden; } else { Logger.Log( LogType.Warning, @@ -164,41 +166,38 @@ static void LoadWorldListEntry( [NotNull] XElement el ) { } } - if ((tempAttr = el.Attribute("visitCount")) != null) - { + if ( ( tempAttr = el.Attribute( "visitCount" ) ) != null ) { int vCount; - if (Int32.TryParse(tempAttr.Value, out vCount)) - { + if ( Int32.TryParse( tempAttr.Value, out vCount ) ) { world.VisitCount = vCount; - } - else - { - Logger.Log(LogType.Warning, + } else { + Logger.Log( LogType.Warning, "WorldManager: Could not parse \"VisitCount\" attribute of world \"{0}\", assuming NO Visits.", - worldName); + worldName ); } } - if( firstWorld == null ) firstWorld = world; + if ( firstWorld == null ) + firstWorld = world; - XElement tempEl = el.Element("Greeting"); - if (tempEl != null && !String.IsNullOrEmpty(tempEl.Value)){ + XElement tempEl = el.Element( "Greeting" ); + if ( tempEl != null && !String.IsNullOrEmpty( tempEl.Value ) ) { world.Greeting = tempEl.Value; } - if( (tempEl = el.Element( AccessSecurityXmlTagName )) != null ) { + if ( ( tempEl = el.Element( AccessSecurityXmlTagName ) ) != null ) { world.AccessSecurity = new SecurityController( tempEl, true ); - } else if( (tempEl = el.Element( "accessSecurity" )) != null ) { + } else if ( ( tempEl = el.Element( "accessSecurity" ) ) != null ) { world.AccessSecurity = new SecurityController( tempEl, true ); } - if( (tempEl = el.Element( BuildSecurityXmlTagName )) != null ) { + if ( ( tempEl = el.Element( BuildSecurityXmlTagName ) ) != null ) { world.BuildSecurity = new SecurityController( tempEl, true ); - } else if( (tempEl = el.Element( "buildSecurity" )) != null ) { + } else if ( ( tempEl = el.Element( "buildSecurity" ) ) != null ) { world.BuildSecurity = new SecurityController( tempEl, true ); } - if( (tempAttr = el.Attribute( "backup" )) != null ) { + if ( ( tempAttr = el.Attribute( "backup" ) ) != null ) { TimeSpan backupInterval; - if( tempAttr.Value.ToTimeSpan( out backupInterval ) ) { + if ( tempAttr.Value.ToTimeSpan( out backupInterval ) ) { world.BackupInterval = backupInterval; } else { world.BackupInterval = WorldManager.DefaultBackupInterval; @@ -212,61 +211,57 @@ static void LoadWorldListEntry( [NotNull] XElement el ) { } XElement blockEl = el.Element( BlockDB.XmlRootName ); - if( blockEl != null ) { + if ( blockEl != null ) { world.BlockDB.LoadSettings( blockEl ); } - XElement PhyEl = el.Element(Physics.XmlRootName); - if (PhyEl != null) - { - Physics.LoadSettings(PhyEl, world); + XElement PhyEl = el.Element( Physics.XmlRootName ); + if ( PhyEl != null ) { + Physics.LoadSettings( PhyEl, world ); } - XElement PhyEl2 = el.Element(Physics.XmlRootName2); - if (PhyEl2 != null) - { - Physics.LoadOtherSettings(PhyEl2, world); + XElement PhyEl2 = el.Element( Physics.XmlRootName2 ); + if ( PhyEl2 != null ) { + Physics.LoadOtherSettings( PhyEl2, world ); } - XElement RealmEl = el.Element(world.RealmXMLRootName); - if (RealmEl != null) - { - world.LoadRealmState(RealmEl); + XElement RealmEl = el.Element( world.RealmXMLRootName ); + if ( RealmEl != null ) { + world.LoadRealmState( RealmEl ); } XElement envEl = el.Element( EnvironmentXmlTagName ); - if( envEl != null ) { - if( (tempAttr = envEl.Attribute( "cloud" )) != null ) { - if( !Int32.TryParse( tempAttr.Value, out world.CloudColor ) ) { + if ( envEl != null ) { + if ( ( tempAttr = envEl.Attribute( "cloud" ) ) != null ) { + if ( !Int32.TryParse( tempAttr.Value, out world.CloudColor ) ) { world.CloudColor = -1; Logger.Log( LogType.Warning, "WorldManager: Could not parse \"cloud\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName ); } } - if ((tempAttr = envEl.Attribute("terrain")) != null) - { - world.Terrain = envEl.Attribute("terrain").Value; + if ( ( tempAttr = envEl.Attribute( "terrain" ) ) != null ) { + world.Terrain = envEl.Attribute( "terrain" ).Value; } - - if( (tempAttr = envEl.Attribute( "fog" )) != null ) { - if( !Int32.TryParse( tempAttr.Value, out world.FogColor ) ) { + + if ( ( tempAttr = envEl.Attribute( "fog" ) ) != null ) { + if ( !Int32.TryParse( tempAttr.Value, out world.FogColor ) ) { world.FogColor = -1; Logger.Log( LogType.Warning, "WorldManager: Could not parse \"fog\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName ); } } - if( (tempAttr = envEl.Attribute( "sky" )) != null ) { - if( !Int32.TryParse( tempAttr.Value, out world.SkyColor ) ) { + if ( ( tempAttr = envEl.Attribute( "sky" ) ) != null ) { + if ( !Int32.TryParse( tempAttr.Value, out world.SkyColor ) ) { world.SkyColor = -1; Logger.Log( LogType.Warning, "WorldManager: Could not parse \"sky\" attribute of Environment settings for world \"{0}\", assuming default (normal).", worldName ); } } - if( (tempAttr = envEl.Attribute( "level" )) != null ) { - if( !Int32.TryParse( tempAttr.Value, out world.EdgeLevel ) ) { + if ( ( tempAttr = envEl.Attribute( "level" ) ) != null ) { + if ( !Int32.TryParse( tempAttr.Value, out world.EdgeLevel ) ) { world.EdgeLevel = -1; Logger.Log( LogType.Warning, "WorldManager: Could not parse \"level\" attribute of Environment settings for world \"{0}\", assuming default (normal).", @@ -274,15 +269,15 @@ static void LoadWorldListEntry( [NotNull] XElement el ) { } } - if( (tempAttr = envEl.Attribute( "edge" )) != null ) { + if ( ( tempAttr = envEl.Attribute( "edge" ) ) != null ) { Block block = Map.GetBlockByName( tempAttr.Value ); - if( block == Block.Undefined ) { + if ( block == Block.Undefined ) { world.EdgeBlock = Block.Water; Logger.Log( LogType.Warning, "WorldManager: Could not parse \"edge\" attribute of Environment settings for world \"{0}\", assuming default (Water).", worldName ); } else { - if( Map.GetEdgeTexture( block ) == null ) { + if ( Map.GetEdgeTexture( block ) == null ) { world.EdgeBlock = Block.Water; Logger.Log( LogType.Warning, "WorldManager: Unacceptable blocktype given for \"edge\" attribute of Environment settings for world \"{0}\", assuming default (Water).", @@ -294,10 +289,10 @@ static void LoadWorldListEntry( [NotNull] XElement el ) { } } - foreach( XElement mainedRankEl in el.Elements( RankMainXmlTagName ) ) { + foreach ( XElement mainedRankEl in el.Elements( RankMainXmlTagName ) ) { Rank rank = Rank.Parse( mainedRankEl.Value ); - if( rank != null ) { - if( rank < world.AccessSecurity.MinRank ) { + if ( rank != null ) { + if ( rank < world.AccessSecurity.MinRank ) { world.AccessSecurity.MinRank = rank; Logger.Log( LogType.Warning, "WorldManager: Lowered access MinRank of world {0} to allow it to be the main world for that rank.", @@ -310,24 +305,24 @@ static void LoadWorldListEntry( [NotNull] XElement el ) { CheckMapFile( world ); } - // Makes sure that the map file exists, is properly named, and is loadable. - static void CheckMapFile( [NotNull] World world ) { - if( world == null ) throw new ArgumentNullException( "world" ); + private static void CheckMapFile( [NotNull] World world ) { + if ( world == null ) + throw new ArgumentNullException( "world" ); // Check the world's map file string fullMapFileName = world.MapFileName; string fileName = Path.GetFileName( fullMapFileName ); - if( Paths.FileExists( fullMapFileName, false ) ) { - if( !Paths.FileExists( fullMapFileName, true ) ) { + if ( Paths.FileExists( fullMapFileName, false ) ) { + if ( !Paths.FileExists( fullMapFileName, true ) ) { // Map file has wrong capitalization FileInfo[] matches = Paths.FindFiles( fullMapFileName ); - if( matches.Length == 1 ) { + if ( matches.Length == 1 ) { // Try to rename the map file to match world's capitalization // ReSharper disable AssignNullToNotNullAttribute Paths.ForceRename( matches[0].FullName, fileName ); // ReSharper restore AssignNullToNotNullAttribute - if( Paths.FileExists( fullMapFileName, true ) ) { + if ( Paths.FileExists( fullMapFileName, true ) ) { Logger.Log( LogType.Warning, "WorldManager.CheckMapFile: Map file for world \"{0}\" was renamed from \"{1}\" to \"{2}\"", world.Name, matches[0].Name, fileName ); @@ -348,7 +343,7 @@ static void CheckMapFile( [NotNull] World world ) { // Try loading the map header try { MapUtility.LoadHeader( world.MapFileName ); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.Log( LogType.Warning, "WorldManager.CheckMapFile: Could not load map file for world \"{0}\": {1}", world.Name, ex ); @@ -360,75 +355,79 @@ static void CheckMapFile( [NotNull] World world ) { } } - /// Saves the current world list to worlds.xml. Thread-safe. public static void SaveWorldList() { const string worldListTempFileName = Paths.WorldListFileName + ".tmp"; // Save world list - lock( SyncRoot ) { + lock ( SyncRoot ) { XDocument doc = new XDocument(); XElement root = new XElement( "fCraftWorldList" ); - foreach( World world in Worlds ) { + foreach ( World world in Worlds ) { XElement temp = new XElement( "World" ); temp.Add( new XAttribute( "name", world.Name ) ); - if( world.AccessSecurity.HasRestrictions ) { + if ( world.AccessSecurity.HasRestrictions ) { temp.Add( world.AccessSecurity.Serialize( AccessSecurityXmlTagName ) ); } - if( world.BuildSecurity.HasRestrictions ) { + if ( world.BuildSecurity.HasRestrictions ) { temp.Add( world.BuildSecurity.Serialize( BuildSecurityXmlTagName ) ); } - if( world.BackupInterval != WorldManager.DefaultBackupInterval ) { + if ( world.BackupInterval != WorldManager.DefaultBackupInterval ) { temp.Add( new XAttribute( "backup", world.BackupInterval.ToTickString() ) ); } - if( world.NeverUnload ) { + if ( world.NeverUnload ) { temp.Add( new XAttribute( "noUnload", true ) ); } - if (world.VisitCount > 0) - { + if ( world.VisitCount > 0 ) { temp.Add( new XAttribute( "visitCount", world.VisitCount ) ); } - if( world.IsHidden ) { + if ( world.IsHidden ) { temp.Add( new XAttribute( "hidden", true ) ); } temp.Add( world.BlockDB.SaveSettings() ); - temp.Add(Physics.SaveSettings(world)); - temp.Add(Physics.SaveOtherSettings(world)); + temp.Add( Physics.SaveSettings( world ) ); + temp.Add( Physics.SaveOtherSettings( world ) ); - temp.Add(world.SaveRealmState()); - if (world.Greeting != null){ + temp.Add( world.SaveRealmState() ); + if ( world.Greeting != null ) { temp.Add( new XElement( "Greeting", world.Greeting ) ); } World world1 = world; - foreach( Rank mainedRank in RankManager.Ranks.Where( r => r.MainWorld == world1 ) ) { + foreach ( Rank mainedRank in RankManager.Ranks.Where( r => r.MainWorld == world1 ) ) { temp.Add( new XElement( RankMainXmlTagName, mainedRank.FullName ) ); } - if( !String.IsNullOrEmpty( world.LoadedBy ) ) { + if ( !String.IsNullOrEmpty( world.LoadedBy ) ) { temp.Add( new XElement( "LoadedBy", world.LoadedBy ) ); } - if( world.LoadedOn != DateTime.MinValue ) { + if ( world.LoadedOn != DateTime.MinValue ) { temp.Add( new XElement( "LoadedOn", world.LoadedOn.ToUnixTime() ) ); } - if( !String.IsNullOrEmpty( world.MapChangedBy ) ) { + if ( !String.IsNullOrEmpty( world.MapChangedBy ) ) { temp.Add( new XElement( "MapChangedBy", world.MapChangedBy ) ); } - if( world.MapChangedOn != DateTime.MinValue ) { + if ( world.MapChangedOn != DateTime.MinValue ) { temp.Add( new XElement( "MapChangedOn", world.MapChangedOn.ToUnixTime() ) ); } XElement elEnv = new XElement( EnvironmentXmlTagName ); - if( world.CloudColor > -1 ) elEnv.Add( new XAttribute( "cloud", world.CloudColor ) ); - if( world.FogColor > -1 ) elEnv.Add( new XAttribute( "fog", world.FogColor ) ); - if( world.SkyColor > -1 ) elEnv.Add( new XAttribute( "sky", world.SkyColor ) ); - if( world.EdgeLevel > -1 ) elEnv.Add( new XAttribute( "level", world.EdgeLevel ) ); - if (world.Terrain != null) elEnv.Add(new XAttribute("terrain", world.Terrain)); - if( world.EdgeBlock != Block.Water ) elEnv.Add( new XAttribute( "edge", world.EdgeBlock ) ); - if( elEnv.HasAttributes ) { + if ( world.CloudColor > -1 ) + elEnv.Add( new XAttribute( "cloud", world.CloudColor ) ); + if ( world.FogColor > -1 ) + elEnv.Add( new XAttribute( "fog", world.FogColor ) ); + if ( world.SkyColor > -1 ) + elEnv.Add( new XAttribute( "sky", world.SkyColor ) ); + if ( world.EdgeLevel > -1 ) + elEnv.Add( new XAttribute( "level", world.EdgeLevel ) ); + if ( world.Terrain != null ) + elEnv.Add( new XAttribute( "terrain", world.Terrain ) ); + if ( world.EdgeBlock != Block.Water ) + elEnv.Add( new XAttribute( "edge", world.EdgeBlock ) ); + if ( elEnv.HasAttributes ) { temp.Add( elEnv ); } root.Add( temp ); @@ -441,8 +440,7 @@ public static void SaveWorldList() { } } - #endregion - + #endregion World List Saving/Loading #region Finding Worlds @@ -451,26 +449,27 @@ public static void SaveWorldList() { /// World if found, or null if not found. [CanBeNull] public static World FindWorldExact( [NotNull] string name ) { - if( name == null ) throw new ArgumentNullException( "name" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); return Worlds.FirstOrDefault( w => w.Name.Equals( name, StringComparison.OrdinalIgnoreCase ) ); } - /// Finds all worlds that match the given world name. /// Autocompletes. Does not raise SearchingForWorld event. /// Target worlds are not guaranteed to have a loaded map. public static World[] FindWorldsNoEvent( [NotNull] string name ) { - if( name == null ) throw new ArgumentNullException( "name" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); World[] worldListCache = Worlds; List results = new List(); - for( int i = 0; i < worldListCache.Length; i++ ) { - if( worldListCache[i] != null ) { - if( worldListCache[i].Name.Equals( name, StringComparison.OrdinalIgnoreCase ) ) { + for ( int i = 0; i < worldListCache.Length; i++ ) { + if ( worldListCache[i] != null ) { + if ( worldListCache[i].Name.Equals( name, StringComparison.OrdinalIgnoreCase ) ) { results.Clear(); results.Add( worldListCache[i] ); break; - } else if( worldListCache[i].Name.StartsWith( name, StringComparison.OrdinalIgnoreCase ) ) { + } else if ( worldListCache[i].Name.StartsWith( name, StringComparison.OrdinalIgnoreCase ) ) { results.Add( worldListCache[i] ); } } @@ -478,7 +477,6 @@ public static World[] FindWorldsNoEvent( [NotNull] string name ) { return results.ToArray(); } - /// Finds all worlds that match the given name. /// Autocompletes. Raises SearchingForWorld event. /// Target worlds are not guaranteed to have a loaded map. @@ -486,10 +484,11 @@ public static World[] FindWorldsNoEvent( [NotNull] string name ) { /// Full or partial world name. /// An array of 0 or more worlds that matched the name. public static World[] FindWorlds( [CanBeNull] Player player, [NotNull] string name ) { - if( name == null ) throw new ArgumentNullException( "name" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); World[] matches = FindWorldsNoEvent( name ); var h = SearchingForWorld; - if( h != null ) { + if ( h != null ) { SearchingForWorldEventArgs e = new SearchingForWorldEventArgs( player, name, matches.ToList() ); h( null, e ); matches = e.Matches.ToArray(); @@ -497,17 +496,18 @@ public static World[] FindWorlds( [CanBeNull] Player player, [NotNull] string na return matches; } - /// Tries to find a single world by full or partial name. /// Returns null if zero or multiple worlds matched. /// Player who will receive messages regarding zero or multiple matches. /// Full or partial world name. [CanBeNull] public static World FindWorldOrPrintMatches( [NotNull] Player player, [NotNull] string worldName ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( worldName == null ) throw new ArgumentNullException( "worldName" ); - if( worldName == "-" ) { - if( player.LastUsedWorldName != null ) { + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( worldName == null ) + throw new ArgumentNullException( "worldName" ); + if ( worldName == "-" ) { + if ( player.LastUsedWorldName != null ) { worldName = player.LastUsedWorldName; } else { player.Message( "Cannot repeat world name: you haven't used any names yet." ); @@ -518,34 +518,34 @@ public static World FindWorldOrPrintMatches( [NotNull] Player player, [NotNull] World[] matches = FindWorlds( player, worldName ); - if( matches.Length == 0 ) { + if ( matches.Length == 0 ) { player.MessageNoWorld( worldName ); return null; } - if( matches.Length > 1 ) { + if ( matches.Length > 1 ) { player.MessageManyMatches( "world", matches ); return null; } return matches[0]; } - #endregion - + #endregion Finding Worlds public static World AddWorld( [CanBeNull] Player player, [NotNull] string name, [CanBeNull] Map map, bool neverUnload ) { - if( name == null ) throw new ArgumentNullException( "name" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); - if( !World.IsValidName( name ) ) { + if ( !World.IsValidName( name ) ) { throw new WorldOpException( name, WorldOpExceptionCode.InvalidWorldName ); } - lock( SyncRoot ) { - if( WorldIndex.ContainsKey( name.ToLower() ) ) { + lock ( SyncRoot ) { + if ( WorldIndex.ContainsKey( name.ToLower() ) ) { throw new WorldOpException( name, WorldOpExceptionCode.DuplicateWorldName ); } - if( RaiseWorldCreatingEvent( player, name, map ) ) { + if ( RaiseWorldCreatingEvent( player, name, map ) ) { throw new WorldOpException( name, WorldOpExceptionCode.Cancelled ); } @@ -553,11 +553,11 @@ public static World AddWorld( [CanBeNull] Player player, [NotNull] string name, Map = map }; - if( neverUnload ) { + if ( neverUnload ) { newWorld.NeverUnload = true; } - if( map != null ) { + if ( map != null ) { newWorld.SaveMap(); } @@ -570,26 +570,27 @@ public static World AddWorld( [CanBeNull] Player player, [NotNull] string name, } } - /// Changes the name of the given world. public static void RenameWorld( [NotNull] World world, [NotNull] string newName, bool moveMapFile, bool overwrite ) { - if( newName == null ) throw new ArgumentNullException( "newName" ); - if( world == null ) throw new ArgumentNullException( "world" ); + if ( newName == null ) + throw new ArgumentNullException( "newName" ); + if ( world == null ) + throw new ArgumentNullException( "world" ); - if( !World.IsValidName( newName ) ) { + if ( !World.IsValidName( newName ) ) { throw new WorldOpException( newName, WorldOpExceptionCode.InvalidWorldName ); } - lock( world.SyncRoot ) { + lock ( world.SyncRoot ) { string oldName = world.Name; - if( oldName == newName ) { + if ( oldName == newName ) { throw new WorldOpException( world.Name, WorldOpExceptionCode.NoChangeNeeded ); } - lock( SyncRoot ) { + lock ( SyncRoot ) { World newWorld = FindWorldExact( newName ); - if( newWorld != null && newWorld != world ) { - if( overwrite ) { + if ( newWorld != null && newWorld != world ) { + if ( overwrite ) { RemoveWorld( newWorld ); } else { throw new WorldOpException( newName, WorldOpExceptionCode.DuplicateWorldName ); @@ -601,26 +602,26 @@ public static void RenameWorld( [NotNull] World world, [NotNull] string newName, WorldIndex.Add( newName.ToLower(), world ); UpdateWorldList(); - if( moveMapFile ) { + if ( moveMapFile ) { string oldMapFile = Path.Combine( Paths.MapPath, oldName + ".fcm" ); string newMapFile = newName + ".fcm"; - if( File.Exists( oldMapFile ) ) { + if ( File.Exists( oldMapFile ) ) { try { Paths.ForceRename( oldMapFile, newMapFile ); - } catch( Exception ex ) { + } catch ( Exception ex ) { throw new WorldOpException( world.Name, WorldOpExceptionCode.MapMoveError, ex ); } } - using( world.BlockDB.GetWriteLock() ) { + using ( world.BlockDB.GetWriteLock() ) { string oldBlockDBFile = Path.Combine( Paths.BlockDBDirectory, oldName + ".fbdb" ); string newBockDBFile = newName + ".fbdb"; - if( File.Exists( oldBlockDBFile ) ) { + if ( File.Exists( oldBlockDBFile ) ) { try { Paths.ForceRename( oldBlockDBFile, newBockDBFile ); - } catch( Exception ex ) { + } catch ( Exception ex ) { throw new WorldOpException( world.Name, WorldOpExceptionCode.MapMoveError, ex ); @@ -632,27 +633,28 @@ public static void RenameWorld( [NotNull] World world, [NotNull] string newName, } } - internal static void ReplaceWorld( [NotNull] World oldWorld, [NotNull] World newWorld ) { - if( oldWorld == null ) throw new ArgumentNullException( "oldWorld" ); - if( newWorld == null ) throw new ArgumentNullException( "newWorld" ); + if ( oldWorld == null ) + throw new ArgumentNullException( "oldWorld" ); + if ( newWorld == null ) + throw new ArgumentNullException( "newWorld" ); - lock( SyncRoot ) { - if( oldWorld == newWorld ) { + lock ( SyncRoot ) { + if ( oldWorld == newWorld ) { throw new WorldOpException( oldWorld.Name, WorldOpExceptionCode.NoChangeNeeded ); } - if( !WorldIndex.ContainsValue( oldWorld ) ) { + if ( !WorldIndex.ContainsValue( oldWorld ) ) { throw new WorldOpException( oldWorld.Name, WorldOpExceptionCode.WorldNotFound ); } - if( WorldIndex.ContainsValue( newWorld ) ) { + if ( WorldIndex.ContainsValue( newWorld ) ) { throw new InvalidOperationException( "New world already exists on the list." ); } // cycle load/unload on the new world to save it under the new name newWorld.Name = oldWorld.Name; - if( newWorld.NeverUnload ) { + if ( newWorld.NeverUnload ) { newWorld.SaveMap(); } else { newWorld.UnloadMap( false ); @@ -662,7 +664,7 @@ internal static void ReplaceWorld( [NotNull] World oldWorld, [NotNull] World new oldWorld.Map = null; // change the main world, if needed - if( oldWorld == MainWorld ) { + if ( oldWorld == MainWorld ) { MainWorld = newWorld; } @@ -670,24 +672,24 @@ internal static void ReplaceWorld( [NotNull] World oldWorld, [NotNull] World new } } - public static void RemoveWorld( [NotNull] World worldToDelete ) { - if( worldToDelete == null ) throw new ArgumentNullException( "worldToDelete" ); + if ( worldToDelete == null ) + throw new ArgumentNullException( "worldToDelete" ); - lock( SyncRoot ) { - if( worldToDelete == MainWorld ) { + lock ( SyncRoot ) { + if ( worldToDelete == MainWorld ) { throw new WorldOpException( worldToDelete.Name, WorldOpExceptionCode.CannotDoThatToMainWorld ); } Player[] worldPlayerList = worldToDelete.Players; worldToDelete.Players.Message( "&SYou have been moved to the main world." ); - foreach( Player player in worldPlayerList ) { + foreach ( Player player in worldPlayerList ) { player.JoinWorld( MainWorld, WorldChangeReason.WorldRemoved ); } try { worldToDelete.BlockDB.Clear(); - } catch( Exception ex ) { + } catch ( Exception ex ) { Logger.Log( LogType.Error, "WorldManager.RemoveWorld: Could not delete BlockDB file: {0}", ex ); } @@ -697,77 +699,70 @@ public static void RemoveWorld( [NotNull] World worldToDelete ) { } } - public static int CountLoadedWorlds() { return Worlds.Count( world => world.IsLoaded ); } - public static int CountLoadedWorlds( [NotNull] Player observer ) { - if( observer == null ) throw new ArgumentNullException( "observer" ); + if ( observer == null ) + throw new ArgumentNullException( "observer" ); return ListLoadedWorlds( observer ).Count(); } - public static IEnumerable ListLoadedWorlds() { return Worlds.Where( world => world.IsLoaded ); } - public static IEnumerable ListLoadedWorlds( [NotNull] Player observer ) { - if( observer == null ) throw new ArgumentNullException( "observer" ); + if ( observer == null ) + throw new ArgumentNullException( "observer" ); return Worlds.Where( w => w.Players.Any( observer.CanSee ) ); } - public static void UpdateWorldList() { - lock( SyncRoot ) { + lock ( SyncRoot ) { Worlds = WorldIndex.Values.ToArray(); } } - [CanBeNull] public static string FindMapFile( [NotNull] Player player, [NotNull] string fileName ) { - if( player == null ) throw new ArgumentNullException( "player" ); - if( fileName == null ) throw new ArgumentNullException( "fileName" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); + if ( fileName == null ) + throw new ArgumentNullException( "fileName" ); // Check if path contains missing drives or invalid characters - if( !Paths.IsValidPath( fileName ) ) { + if ( !Paths.IsValidPath( fileName ) ) { player.Message( "Invalid filename or path." ); return null; } // Look for the file string sourceFullFileName = Path.Combine( Paths.MapPath, fileName ); - if( !File.Exists( sourceFullFileName ) && !Directory.Exists( sourceFullFileName ) ) { - - if( File.Exists( sourceFullFileName + ".fcm" ) ) { + if ( !File.Exists( sourceFullFileName ) && !Directory.Exists( sourceFullFileName ) ) { + if ( File.Exists( sourceFullFileName + ".fcm" ) ) { // Try with extension added sourceFullFileName += ".fcm"; - - } else if( MonoCompat.IsCaseSensitive ) { + } else if ( MonoCompat.IsCaseSensitive ) { try { // If we're on a case-sensitive OS, try case-insensitive search FileInfo[] candidates = Paths.FindFiles( sourceFullFileName + ".fcm" ); - if( candidates.Length == 0 ) { + if ( candidates.Length == 0 ) { candidates = Paths.FindFiles( sourceFullFileName ); } - if( candidates.Length == 0 ) { + if ( candidates.Length == 0 ) { player.Message( "File/directory not found: {0}", fileName ); - - } else if( candidates.Length == 1 ) { + } else if ( candidates.Length == 1 ) { player.Message( "Filenames are case-sensitive! Did you mean to load \"{0}\"?", candidates[0].Name ); - } else { player.Message( "Filenames are case-sensitive! Did you mean to load one of these: {0}", String.Join( ", ", candidates.Select( c => c.Name ).ToArray() ) ); } - } catch( DirectoryNotFoundException ex ) { + } catch ( DirectoryNotFoundException ex ) { player.Message( ex.Message ); } return null; - } else { // Nothing found! player.Message( "File/directory not found: {0}", fileName ); @@ -776,7 +771,7 @@ public static string FindMapFile( [NotNull] Player player, [NotNull] string file } // Make sure that the given file is within the map directory - if( !Paths.Contains( Paths.MapPath, sourceFullFileName ) ) { + if ( !Paths.Contains( Paths.MapPath, sourceFullFileName ) ) { player.MessageUnsafePath(); return null; } @@ -784,60 +779,62 @@ public static string FindMapFile( [NotNull] Player player, [NotNull] string file return sourceFullFileName; } - #region Events /// Occurs when the main world is being changed (cancellable). public static event EventHandler MainWorldChanging; - /// Occurs after the main world has been changed. public static event EventHandler MainWorldChanged; - /// Occurs when a player is searching for worlds (with autocompletion). /// The list of worlds in the search results may be replaced. public static event EventHandler SearchingForWorld; - /// Occurs before a new world is created/added (cancellable). public static event EventHandler WorldCreating; - /// Occurs after a new world is created/added. public static event EventHandler WorldCreated; - - static bool RaiseMainWorldChangingEvent( World oldWorld, [NotNull] World newWorld ) { - if( newWorld == null ) throw new ArgumentNullException( "newWorld" ); + private static bool RaiseMainWorldChangingEvent( World oldWorld, [NotNull] World newWorld ) { + if ( newWorld == null ) + throw new ArgumentNullException( "newWorld" ); var h = MainWorldChanging; - if( h == null ) return false; + if ( h == null ) + return false; var e = new MainWorldChangingEventArgs( oldWorld, newWorld ); h( null, e ); return e.Cancel; } - static void RaiseMainWorldChangedEvent( [CanBeNull] World oldWorld, [NotNull] World newWorld ) { - if( newWorld == null ) throw new ArgumentNullException( "newWorld" ); + private static void RaiseMainWorldChangedEvent( [CanBeNull] World oldWorld, [NotNull] World newWorld ) { + if ( newWorld == null ) + throw new ArgumentNullException( "newWorld" ); var h = MainWorldChanged; - if( h != null ) h( null, new MainWorldChangedEventArgs( oldWorld, newWorld ) ); + if ( h != null ) + h( null, new MainWorldChangedEventArgs( oldWorld, newWorld ) ); } - static bool RaiseWorldCreatingEvent( [CanBeNull] Player player, [NotNull] string worldName, [CanBeNull] Map map ) { - if( worldName == null ) throw new ArgumentNullException( "worldName" ); + private static bool RaiseWorldCreatingEvent( [CanBeNull] Player player, [NotNull] string worldName, [CanBeNull] Map map ) { + if ( worldName == null ) + throw new ArgumentNullException( "worldName" ); var h = WorldCreating; - if( h == null ) return false; + if ( h == null ) + return false; var e = new WorldCreatingEventArgs( player, worldName, map ); h( null, e ); return e.Cancel; } - static void RaiseWorldCreatedEvent( [CanBeNull] Player player, [NotNull] World world ) { - if( world == null ) throw new ArgumentNullException( "world" ); + private static void RaiseWorldCreatedEvent( [CanBeNull] Player player, [NotNull] World world ) { + if ( world == null ) + throw new ArgumentNullException( "world" ); var h = WorldCreated; - if( h != null ) h( null, new WorldCreatedEventArgs( player, world ) ); + if ( h != null ) + h( null, new WorldCreatedEventArgs( player, world ) ); } - #endregion + #endregion Events } } \ No newline at end of file diff --git a/fCraft/World/WorldOpException.cs b/fCraft/World/WorldOpException.cs index bca53b9..781e24f 100644 --- a/fCraft/World/WorldOpException.cs +++ b/fCraft/World/WorldOpException.cs @@ -2,6 +2,7 @@ using System; namespace fCraft { + public sealed class WorldOpException : Exception { public WorldOpExceptionCode ErrorCode { get; private set; } @@ -27,8 +28,8 @@ public WorldOpException( WorldOpExceptionCode errorCode, string message, Excepti } public static string GetMessage( string worldName, WorldOpExceptionCode code ) { - if( worldName != null ) { - switch( code ) { + if ( worldName != null ) { + switch ( code ) { case WorldOpExceptionCode.CannotDoThatToMainWorld: return "This operation cannot be done on the main world (" + worldName + "). Assign a new main world and try again."; @@ -74,7 +75,7 @@ public static string GetMessage( string worldName, WorldOpExceptionCode code ) { return "Unexpected error occured while working on world \"" + worldName + "\""; } } else { - switch( code ) { + switch ( code ) { case WorldOpExceptionCode.CannotDoThatToMainWorld: return "This operation cannot be done on the main world. " + "Assign a new main world and try again."; @@ -123,7 +124,6 @@ public static string GetMessage( string worldName, WorldOpExceptionCode code ) { } } - /// List of common world operation issues. Used by WorldOpException. public enum WorldOpExceptionCode { Unexpected, diff --git a/fCraft/World/Zone.cs b/fCraft/World/Zone.cs index d6bddc9..748b9e7 100644 --- a/fCraft/World/Zone.cs +++ b/fCraft/World/Zone.cs @@ -57,36 +57,37 @@ public string EditedByClassy { [NotNull] public Map Map { get; set; } - public string Message { get; set; } + public string Message { get; set; } /// Creates the zone boundaries, and sets CreatedDate/CreatedBy. /// New zone boundaries. /// Player who created this zone. May not be null. public void Create( [NotNull] BoundingBox bounds, [NotNull] PlayerInfo createdBy ) { - if( bounds == null ) throw new ArgumentNullException( "bounds" ); - if( createdBy == null ) throw new ArgumentNullException( "createdBy" ); + if ( bounds == null ) + throw new ArgumentNullException( "bounds" ); + if ( createdBy == null ) + throw new ArgumentNullException( "createdBy" ); CreatedDate = DateTime.UtcNow; Bounds = bounds; CreatedBy = createdBy.Name; } - public void Edit( [NotNull] PlayerInfo editedBy ) { - if( editedBy == null ) throw new ArgumentNullException( "editedBy" ); + if ( editedBy == null ) + throw new ArgumentNullException( "editedBy" ); EditedDate = DateTime.UtcNow; EditedBy = editedBy.Name; RaiseChangedEvent(); } - public Zone() { Controller.Changed += ( o, e ) => RaiseChangedEvent(); } - public Zone( [NotNull] string raw, [CanBeNull] World world ) : this() { - if( raw == null ) throw new ArgumentNullException( "raw" ); + if ( raw == null ) + throw new ArgumentNullException( "raw" ); string[] parts = raw.Split( ',' ); string[] header = parts[0].Split( ' ' ); @@ -96,8 +97,8 @@ public Zone( [NotNull] string raw, [CanBeNull] World world ) Rank buildRank = Rank.Parse( header[7] ); // if all else fails, fall back to lowest class - if( buildRank == null ) { - if( world != null ) { + if ( buildRank == null ) { + if ( world != null ) { Controller.MinRank = world.BuildSecurity.MinRank; } else { Controller.ResetMinRank(); @@ -109,17 +110,17 @@ public Zone( [NotNull] string raw, [CanBeNull] World world ) Controller.MinRank = buildRank; } - if( PlayerDB.IsLoaded ) { + if ( PlayerDB.IsLoaded ) { // Part 2: - if( parts[1].Length > 0 ) { - foreach( string playerName in parts[1].Split( ' ' ) ) { - if( !Player.IsValidName( playerName ) ) { + if ( parts[1].Length > 0 ) { + foreach ( string playerName in parts[1].Split( ' ' ) ) { + if ( !Player.IsValidName( playerName ) ) { Logger.Log( LogType.Warning, "Invalid entry in zone \"{0}\" whitelist: {1}", Name, playerName ); continue; } PlayerInfo info = PlayerDB.FindPlayerInfoExact( playerName ); - if( info == null ) { + if ( info == null ) { Logger.Log( LogType.Warning, "Unrecognized player in zone \"{0}\" whitelist: {1}", Name, playerName ); continue; // player name not found in the DB (discarded) @@ -129,15 +130,15 @@ public Zone( [NotNull] string raw, [CanBeNull] World world ) } // Part 3: excluded list - if( parts[2].Length > 0 ) { - foreach( string playerName in parts[2].Split( ' ' ) ) { - if( !Player.IsValidName( playerName ) ) { + if ( parts[2].Length > 0 ) { + foreach ( string playerName in parts[2].Split( ' ' ) ) { + if ( !Player.IsValidName( playerName ) ) { Logger.Log( LogType.Warning, "Invalid entry in zone \"{0}\" blacklist: {1}", Name, playerName ); continue; } PlayerInfo info = PlayerDB.FindPlayerInfoExact( playerName ); - if( info == null ) { + if ( info == null ) { Logger.Log( LogType.Warning, "Unrecognized player in zone \"{0}\" whitelist: {1}", Name, playerName ); continue; // player name not found in the DB (discarded) @@ -151,9 +152,9 @@ public Zone( [NotNull] string raw, [CanBeNull] World world ) } // Part 4: extended header - if( parts.Length > 3 ) { + if ( parts.Length > 3 ) { string[] xheader = parts[3].Split( ' ' ); - if( xheader[0] == "-" ) { + if ( xheader[0] == "-" ) { CreatedBy = null; CreatedDate = DateTime.MinValue; } else { @@ -161,7 +162,7 @@ public Zone( [NotNull] string raw, [CanBeNull] World world ) CreatedDate = DateTime.Parse( xheader[1] ); } - if( xheader[2] == "-" ) { + if ( xheader[2] == "-" ) { EditedBy = null; EditedDate = DateTime.MinValue; } else { @@ -170,67 +171,67 @@ public Zone( [NotNull] string raw, [CanBeNull] World world ) } } - //message - if (parts.Length > 4 && !string.IsNullOrWhiteSpace(parts[4])) - Message = parts[4].Replace('\\',','); - else - Message = null; + //message + if ( parts.Length > 4 && !string.IsNullOrWhiteSpace( parts[4] ) ) + Message = parts[4].Replace( '\\', ',' ); + else + Message = null; } internal string rawWhitelist, rawBlacklist; - public string ClassyName { get { return Controller.MinRank.Color + Name; } } - #region Xml Serialization - const string XmlRootElementName = "Zone"; + private const string XmlRootElementName = "Zone"; public Zone( [NotNull] XContainer root ) { - if( root == null ) throw new ArgumentNullException( "root" ); + if ( root == null ) + throw new ArgumentNullException( "root" ); // ReSharper disable PossibleNullReferenceException Name = root.Element( "name" ).Value; - if( root.Element( "created" ) != null ) { + if ( root.Element( "created" ) != null ) { XElement created = root.Element( "created" ); CreatedBy = created.Attribute( "by" ).Value; CreatedDate = DateTime.Parse( created.Attribute( "on" ).Value ); } - if( root.Element( "edited" ) != null ) { + if ( root.Element( "edited" ) != null ) { XElement edited = root.Element( "edited" ); EditedBy = edited.Attribute( "by" ).Value; EditedDate = DateTime.Parse( edited.Attribute( "on" ).Value ); } XElement temp = root.Element( BoundingBox.XmlRootElementName ); - if( temp == null ) throw new FormatException( "No BoundingBox specified for zone." ); + if ( temp == null ) + throw new FormatException( "No BoundingBox specified for zone." ); Bounds = new BoundingBox( temp ); temp = root.Element( SecurityController.XmlRootElementName ); - if( temp == null ) throw new FormatException( "No SecurityController specified for zone." ); + if ( temp == null ) + throw new FormatException( "No SecurityController specified for zone." ); Controller = new SecurityController( temp, true ); // ReSharper restore PossibleNullReferenceException } - public XElement Serialize() { XElement root = new XElement( XmlRootElementName ); root.Add( new XElement( "name", Name ) ); - if( CreatedBy != null ) { + if ( CreatedBy != null ) { XElement created = new XElement( "created" ); created.Add( new XAttribute( "by", CreatedBy ) ); created.Add( new XAttribute( "on", CreatedDate.ToCompactString() ) ); root.Add( created ); } - if( EditedBy != null ) { + if ( EditedBy != null ) { XElement edited = new XElement( "edited" ); edited.Add( new XAttribute( "by", EditedBy ) ); edited.Add( new XAttribute( "on", EditedDate.ToCompactString() ) ); @@ -242,85 +243,73 @@ public XElement Serialize() { return root; } - #endregion - + #endregion Xml Serialization public event EventHandler Changed; - void RaiseChangedEvent() { + private void RaiseChangedEvent() { var h = Changed; - if( h != null ) h( null, EventArgs.Empty ); + if ( h != null ) + h( null, EventArgs.Empty ); } } - public class ZoneConverterExtension : IConverterExtension - { - private static List _group = new List {"zones"}; - public IEnumerable AcceptedGroups { get { return _group; } } - - public int Serialize(Map map, Stream stream, IMapConverterEx converter) - { - BinaryWriter writer = new BinaryWriter(stream); - int count = 0; - Zone[] zoneList = map.Zones.Cache; - foreach (Zone zone in zoneList) - { - converter.WriteMetadataEntry(_group[0], zone.Name, SerializeZone(zone), writer); - ++count; - } - return count; - } - - static string SerializeZone([NotNull] Zone zone) - { - if (zone == null) throw new ArgumentNullException("zone"); - string xheader; - if (zone.CreatedBy != null) - { - xheader = zone.CreatedBy + " " + zone.CreatedDate.ToCompactString() + " "; - } - else - { - xheader = "- - "; - } - - if (zone.EditedBy != null) - { - xheader += zone.EditedBy + " " + zone.EditedDate.ToCompactString(); - } - else - { - xheader += "- -"; - } - - var zoneExceptions = zone.Controller.ExceptionList; - - string whitelist = zone.rawWhitelist ?? zoneExceptions.Included.JoinToString(" ", p => p.Name); - string blacklist = zone.rawBlacklist ?? zoneExceptions.Excluded.JoinToString(" ", p => p.Name); - - return String.Format("{0},{1},{2},{3},{4}", - String.Format("{0} {1} {2} {3} {4} {5} {6} {7}", - zone.Name, - zone.Bounds.XMin, zone.Bounds.YMin, zone.Bounds.ZMin, - zone.Bounds.XMax, zone.Bounds.YMax, zone.Bounds.ZMax, - zone.Controller.MinRank.FullName), - whitelist, - blacklist, - xheader, - null==zone.Message?"":zone.Message.Replace(',','\\')); - } - - public void Deserialize(string group, string key, string value, Map map) - { - try - { - map.Zones.Add(new Zone(value, map.World)); - } - catch (Exception ex) - { - Logger.Log(LogType.Error, - "ZoneConverterExtension.Deserialize: Error importing zone definition: {0}", ex); - } - } - } + public class ZoneConverterExtension : IConverterExtension { + private static List _group = new List { "zones" }; + + public IEnumerable AcceptedGroups { get { return _group; } } + + public int Serialize( Map map, Stream stream, IMapConverterEx converter ) { + BinaryWriter writer = new BinaryWriter( stream ); + int count = 0; + Zone[] zoneList = map.Zones.Cache; + foreach ( Zone zone in zoneList ) { + converter.WriteMetadataEntry( _group[0], zone.Name, SerializeZone( zone ), writer ); + ++count; + } + return count; + } + + private static string SerializeZone( [NotNull] Zone zone ) { + if ( zone == null ) + throw new ArgumentNullException( "zone" ); + string xheader; + if ( zone.CreatedBy != null ) { + xheader = zone.CreatedBy + " " + zone.CreatedDate.ToCompactString() + " "; + } else { + xheader = "- - "; + } + + if ( zone.EditedBy != null ) { + xheader += zone.EditedBy + " " + zone.EditedDate.ToCompactString(); + } else { + xheader += "- -"; + } + + var zoneExceptions = zone.Controller.ExceptionList; + + string whitelist = zone.rawWhitelist ?? zoneExceptions.Included.JoinToString( " ", p => p.Name ); + string blacklist = zone.rawBlacklist ?? zoneExceptions.Excluded.JoinToString( " ", p => p.Name ); + + return String.Format( "{0},{1},{2},{3},{4}", + String.Format( "{0} {1} {2} {3} {4} {5} {6} {7}", + zone.Name, + zone.Bounds.XMin, zone.Bounds.YMin, zone.Bounds.ZMin, + zone.Bounds.XMax, zone.Bounds.YMax, zone.Bounds.ZMax, + zone.Controller.MinRank.FullName ), + whitelist, + blacklist, + xheader, + null == zone.Message ? "" : zone.Message.Replace( ',', '\\' ) ); + } + + public void Deserialize( string group, string key, string value, Map map ) { + try { + map.Zones.Add( new Zone( value, map.World ) ); + } catch ( Exception ex ) { + Logger.Log( LogType.Error, + "ZoneConverterExtension.Deserialize: Error importing zone definition: {0}", ex ); + } + } + } } \ No newline at end of file diff --git a/fCraft/World/ZoneCollection.cs b/fCraft/World/ZoneCollection.cs index 7236688..995b723 100644 --- a/fCraft/World/ZoneCollection.cs +++ b/fCraft/World/ZoneCollection.cs @@ -7,10 +7,11 @@ using JetBrains.Annotations; namespace fCraft { + /// A collection of zones within a map. [DebuggerDisplay( "Count = {Count}" )] public sealed class ZoneCollection : ICollection, ICollection, ICloneable, INotifiesOnChange { - readonly Dictionary store = new Dictionary(); + private readonly Dictionary store = new Dictionary(); public Zone[] Cache { get; private set; } @@ -19,28 +20,29 @@ public ZoneCollection() { } public ZoneCollection( [NotNull] ZoneCollection other ) { - if( other == null ) throw new ArgumentNullException( "other" ); - lock( other.syncRoot ) { - foreach( Zone zone in other.store.Values ) { + if ( other == null ) + throw new ArgumentNullException( "other" ); + lock ( other.syncRoot ) { + foreach ( Zone zone in other.store.Values ) { Add( zone ); } } } - void UpdateCache() { - lock( syncRoot ) { + private void UpdateCache() { + lock ( syncRoot ) { Cache = store.Values.ToArray(); } } - /// Adds a new zone to the collection. /// The name of the zone cannot match existing names. public void Add( [NotNull] Zone item ) { - if( item == null ) throw new ArgumentNullException( "item" ); - lock( syncRoot ) { + if ( item == null ) + throw new ArgumentNullException( "item" ); + lock ( syncRoot ) { string zoneName = item.Name.ToLower(); - if( store.ContainsValue( item ) ) { + if ( store.ContainsValue( item ) ) { throw new ArgumentException( "Duplicate zone.", "item" ); } store.Add( zoneName, item ); @@ -50,12 +52,12 @@ public void Add( [NotNull] Zone item ) { } } - /// Removes all zones from the collection. public void Clear() { - lock( syncRoot ) { - if( store.Count <= 0 ) return; - foreach( Zone zone in store.Values ) { + lock ( syncRoot ) { + if ( store.Count <= 0 ) + return; + foreach ( Zone zone in store.Values ) { zone.Changed -= OnZoneChanged; } store.Clear(); @@ -64,36 +66,35 @@ public void Clear() { } } - /// Checks whether a given zone is in the collection. public bool Contains( [NotNull] Zone item ) { - if( item == null ) throw new ArgumentNullException( "item" ); + if ( item == null ) + throw new ArgumentNullException( "item" ); Zone[] cache = Cache; return cache.Any( t => t == item ); } - /// Checks whether any zone with a given name is in the collection. public bool Contains( [NotNull] string zoneName ) { - if( zoneName == null ) throw new ArgumentNullException( "zoneName" ); + if ( zoneName == null ) + throw new ArgumentNullException( "zoneName" ); Zone[] cache = Cache; return cache.Any( t => t.Name.Equals( zoneName, StringComparison.OrdinalIgnoreCase ) ); } - /// Returns the total number of zones in this collection. public int Count { get { return store.Count; } } - /// Removes a zone from the collection. /// True if the given zone was found & removed. /// False if this collection did not contain the given zone. public bool Remove( [NotNull] Zone item ) { - if( item == null ) throw new ArgumentNullException( "item" ); - lock( syncRoot ) { - if( store.ContainsValue( item ) ) { + if ( item == null ) + throw new ArgumentNullException( "item" ); + lock ( syncRoot ) { + if ( store.ContainsValue( item ) ) { store.Remove( item.Name.ToLower() ); UpdateCache(); RaiseChangedEvent(); @@ -105,16 +106,16 @@ public bool Remove( [NotNull] Zone item ) { } } - /// Removes a zone from the collection, by name. /// True if the given zone was found & removed. /// False if this collection did not contain the given zone. public bool Remove( [NotNull] string zoneName ) { - if( zoneName == null ) throw new ArgumentNullException( "zoneName" ); - lock( syncRoot ) { + if ( zoneName == null ) + throw new ArgumentNullException( "zoneName" ); + lock ( syncRoot ) { string zoneNameLower = zoneName.ToLower(); Zone item; - if( store.TryGetValue( zoneNameLower, out item ) ) { + if ( store.TryGetValue( zoneNameLower, out item ) ) { item.Changed -= OnZoneChanged; store.Remove( zoneNameLower ); UpdateCache(); @@ -126,7 +127,6 @@ public bool Remove( [NotNull] string zoneName ) { } } - /// Checks how zones affect the given player's ability to affect /// a block at given coordinates. /// Block coordinates. @@ -135,15 +135,17 @@ public bool Remove( [NotNull] string zoneName ) { /// Allow if ALL affecting zones allow the player. /// Deny if ANY affecting zone denies the player. public PermissionOverride Check( Vector3I coords, [NotNull] Player player ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); PermissionOverride result = PermissionOverride.None; - if( Cache.Length == 0 ) return result; + if ( Cache.Length == 0 ) + return result; Zone[] zoneListCache = Cache; - for( int i = 0; i < zoneListCache.Length; i++ ) { - if( zoneListCache[i].Bounds.Contains( coords ) ) { - if( zoneListCache[i].Controller.Check( player.Info ) ) { + for ( int i = 0; i < zoneListCache.Length; i++ ) { + if ( zoneListCache[i].Bounds.Contains( coords ) ) { + if ( zoneListCache[i].Controller.Check( player.Info ) ) { result = PermissionOverride.Allow; } else { return PermissionOverride.Deny; @@ -153,7 +155,6 @@ public PermissionOverride Check( Vector3I coords, [NotNull] Player player ) { return result; } - /// Checks how zones affect the given player's ability to affect /// a block at given coordinates, in detail. /// Block coordinates. @@ -163,16 +164,17 @@ public PermissionOverride Check( Vector3I coords, [NotNull] Player player ) { /// True if any zones were found. False if none affect the given coordinate. public bool CheckDetailed( Vector3I coords, [NotNull] Player player, out Zone[] allowedZones, out Zone[] deniedZones ) { - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); var allowedList = new List(); var deniedList = new List(); bool found = false; Zone[] zoneListCache = Cache; - for( int i = 0; i < zoneListCache.Length; i++ ) { - if( zoneListCache[i].Bounds.Contains( coords ) ) { + for ( int i = 0; i < zoneListCache.Length; i++ ) { + if ( zoneListCache[i].Bounds.Contains( coords ) ) { found = true; - if( zoneListCache[i].Controller.Check( player.Info ) ) { + if ( zoneListCache[i].Controller.Check( player.Info ) ) { allowedList.Add( zoneListCache[i] ); } else { deniedList.Add( zoneListCache[i] ); @@ -184,7 +186,6 @@ public bool CheckDetailed( Vector3I coords, [NotNull] Player player, return found; } - /// Finds which zone denied player's ability to affect /// a block at given coordinates. Used in conjunction with CheckZones(). /// Block coordinates. @@ -194,10 +195,11 @@ public bool CheckDetailed( Vector3I coords, [NotNull] Player player, [CanBeNull] public Zone FindDenied( Vector3I coords, [NotNull] Player player ) { // ReSharper disable LoopCanBeConvertedToQuery - if( player == null ) throw new ArgumentNullException( "player" ); + if ( player == null ) + throw new ArgumentNullException( "player" ); Zone[] zoneListCache = Cache; - for( int i = 0; i < zoneListCache.Length; i++ ) { - if( zoneListCache[i].Bounds.Contains( coords ) && + for ( int i = 0; i < zoneListCache.Length; i++ ) { + if ( zoneListCache[i].Bounds.Contains( coords ) && !zoneListCache[i].Controller.Check( player.Info ) ) { return zoneListCache[i]; } @@ -206,7 +208,6 @@ public Zone FindDenied( Vector3I coords, [NotNull] Player player ) { // ReSharper restore LoopCanBeConvertedToQuery } - /// Finds a zone by name, without using autocompletion. /// Zone names are case-insensitive. /// Full zone name. @@ -214,17 +215,17 @@ public Zone FindDenied( Vector3I coords, [NotNull] Player player ) { /// null if no Zone with the given name could be found. [CanBeNull] public Zone FindExact( [NotNull] string name ) { - if( name == null ) throw new ArgumentNullException( "name" ); - lock( syncRoot ) { + if ( name == null ) + throw new ArgumentNullException( "name" ); + lock ( syncRoot ) { Zone result; - if( store.TryGetValue( name.ToLower(), out result ) ) { + if ( store.TryGetValue( name.ToLower(), out result ) ) { return result; } } return null; } - /// Finds a zone by name, with autocompletion. /// Zone names are case-insensitive. /// Note that this method is a lot slower than FindExact. @@ -233,20 +234,21 @@ public Zone FindExact( [NotNull] string name ) { /// null if no Zone with the given name could be found. [CanBeNull] public Zone Find( [NotNull] string name ) { - if( name == null ) throw new ArgumentNullException( "name" ); + if ( name == null ) + throw new ArgumentNullException( "name" ); // try to find exact match - lock( syncRoot ) { + lock ( syncRoot ) { Zone result; - if( store.TryGetValue( name.ToLower(), out result ) ) { + if ( store.TryGetValue( name.ToLower(), out result ) ) { return result; } } // try to autocomplete Zone match = null; Zone[] cache = Cache; - foreach( Zone zone in cache ) { - if( zone.Name.StartsWith( name, StringComparison.OrdinalIgnoreCase ) ) { - if( match == null ) { + foreach ( Zone zone in cache ) { + if ( zone.Name.StartsWith( name, StringComparison.OrdinalIgnoreCase ) ) { + if ( match == null ) { // first (and hopefully only) match found match = zone; } else { @@ -258,16 +260,17 @@ public Zone Find( [NotNull] string name ) { return match; } - /// Changes the name of a given zone. /// Zone to rename. /// New name to give to the zone. /// Thrown if a zone with a given name already exists. public void Rename( [NotNull] Zone zone, [NotNull] string newName ) { - if( zone == null ) throw new ArgumentNullException( "zone" ); - if( newName == null ) throw new ArgumentNullException( "newName" ); - lock( syncRoot ) { - if( !store.Remove( zone.Name.ToLower() ) ) { + if ( zone == null ) + throw new ArgumentNullException( "zone" ); + if ( newName == null ) + throw new ArgumentNullException( "newName" ); + lock ( syncRoot ) { + if ( !store.Remove( zone.Name.ToLower() ) ) { throw new ArgumentException( "Trying to rename a zone that does not exist.", "zone" ); } zone.Name = newName; @@ -277,69 +280,66 @@ public void Rename( [NotNull] Zone zone, [NotNull] string newName ) { } } - public IEnumerator GetEnumerator() { return store.Values.GetEnumerator(); } - #region ICollection Boilerplate IEnumerator IEnumerable.GetEnumerator() { return store.Values.GetEnumerator(); } - public void CopyTo( [NotNull] Zone[] array, int arrayIndex ) { - if( array == null ) throw new ArgumentNullException( "array" ); - if( arrayIndex < 0 || arrayIndex > array.Length ) throw new ArgumentOutOfRangeException( "arrayIndex" ); + if ( array == null ) + throw new ArgumentNullException( "array" ); + if ( arrayIndex < 0 || arrayIndex > array.Length ) + throw new ArgumentOutOfRangeException( "arrayIndex" ); Zone[] cache = Cache; Array.Copy( cache, 0, array, arrayIndex, cache.Length ); } - void ICollection.CopyTo( [NotNull] Array array, int index ) { - if( array == null ) throw new ArgumentNullException( "array" ); - if( index < 0 || index > array.Length ) throw new ArgumentOutOfRangeException( "index" ); + if ( array == null ) + throw new ArgumentNullException( "array" ); + if ( index < 0 || index > array.Length ) + throw new ArgumentOutOfRangeException( "index" ); Zone[] cache = Cache; Array.Copy( cache, 0, array, index, cache.Length ); } - public bool IsReadOnly { get { return false; } } - public bool IsSynchronized { get { return true; } } + private readonly object syncRoot = new object(); - readonly object syncRoot = new object(); public object SyncRoot { get { return syncRoot; } } - #endregion - + #endregion ICollection Boilerplate public object Clone() { - lock( syncRoot ) { + lock ( syncRoot ) { return new ZoneCollection( this ); } } - public event EventHandler Changed; - void OnZoneChanged( object sender, EventArgs e ) { + private void OnZoneChanged( object sender, EventArgs e ) { RaiseChangedEvent(); } - void RaiseChangedEvent() { + private void RaiseChangedEvent() { var h = Changed; - if( h != null ) h( null, EventArgs.Empty ); + if ( h != null ) + h( null, EventArgs.Empty ); } } -} +} \ No newline at end of file diff --git a/fCraftGUI/AboutWindow.cs b/fCraftGUI/AboutWindow.cs index 4458bd2..9c1429b 100644 --- a/fCraftGUI/AboutWindow.cs +++ b/fCraftGUI/AboutWindow.cs @@ -4,7 +4,9 @@ using System.Windows.Forms; namespace fCraft.GUI { + public sealed partial class AboutWindow : Form { + public AboutWindow() { InitializeComponent(); lSubheader.Text = String.Format( lSubheader.Text, Updater.CurrentRelease.VersionString ); @@ -22,14 +24,10 @@ private void linkLabel2_LinkClicked( object sender, LinkLabelLinkClickedEventArg } catch { } } - private void linkLabel2_LinkClicked_1(object sender, LinkLabelLinkClickedEventArgs e) - { - try - { - Process.Start("http://www.800craft.net"); - } - catch { } + private void linkLabel2_LinkClicked_1( object sender, LinkLabelLinkClickedEventArgs e ) { + try { + Process.Start( "http://www.800craft.net" ); + } catch { } } - } } \ No newline at end of file diff --git a/fCraftGUI/IsoCat.cs b/fCraftGUI/IsoCat.cs index d9c96a8..dded1f1 100644 --- a/fCraftGUI/IsoCat.cs +++ b/fCraftGUI/IsoCat.cs @@ -10,6 +10,7 @@ namespace fCraft.GUI { /// Drawing/clipping mode of IsoCat map renderer. public enum IsoCatMode { + /// Normal isometric view. Normal, @@ -23,16 +24,15 @@ public enum IsoCatMode { Chunk } - /// Isometric map renderer, tightly integrated with BackgroundWorker. /// Creates a bitmap of the map. Every IsoCat instance is single-use. unsafe public sealed class IsoCat { - static readonly byte[] Tiles, ShadowTiles; - static readonly int TileX, TileY; - static readonly int MaxTileDim, TileStride; + private static readonly byte[] Tiles, ShadowTiles; + private static readonly int TileX, TileY; + private static readonly int MaxTileDim, TileStride; static IsoCat() { - using( Bitmap tilesBmp = Resources.Tileset ) { + using ( Bitmap tilesBmp = Resources.Tileset ) { TileX = tilesBmp.Width / 50; TileY = tilesBmp.Height; TileStride = TileX * TileY * 4; @@ -40,10 +40,10 @@ static IsoCat() { MaxTileDim = Math.Max( TileX, TileY ); - for( int i = 0; i < 50; i++ ) { - for( int y = 0; y < TileY; y++ ) { - for( int x = 0; x < TileX; x++ ) { - int p = i * TileStride + (y * TileX + x) * 4; + for ( int i = 0; i < 50; i++ ) { + for ( int y = 0; y < TileY; y++ ) { + for ( int x = 0; x < TileX; x++ ) { + int p = i * TileStride + ( y * TileX + x ) * 4; System.Drawing.Color c = tilesBmp.GetPixel( x + i * TileX, y ); Tiles[p] = c.B; Tiles[p + 1] = c.G; @@ -54,14 +54,13 @@ static IsoCat() { } } - using( Bitmap stilesBmp = Resources.TilesetShadowed ) { - + using ( Bitmap stilesBmp = Resources.TilesetShadowed ) { ShadowTiles = new byte[50 * TileStride]; - for( int i = 0; i < 50; i++ ) { - for( int y = 0; y < TileY; y++ ) { - for( int x = 0; x < TileX; x++ ) { - int p = i * TileStride + (y * TileX + x) * 4; + for ( int i = 0; i < 50; i++ ) { + for ( int y = 0; y < TileY; y++ ) { + for ( int x = 0; x < TileX; x++ ) { + int p = i * TileStride + ( y * TileX + x ) * 4; System.Drawing.Color c = stilesBmp.GetPixel( x + i * TileX, y ); ShadowTiles[p] = c.B; ShadowTiles[p + 1] = c.G; @@ -73,26 +72,24 @@ static IsoCat() { } } - - int x, y, z; - byte block; + private int x, y, z; + private byte block; public readonly int[] ChunkCoords = new int[6]; - readonly byte* image; - readonly Bitmap imageBmp; - readonly BitmapData imageData; - readonly int imageWidth, imageHeight; + private readonly byte* image; + private readonly Bitmap imageBmp; + private readonly BitmapData imageData; + private readonly int imageWidth, imageHeight; - readonly int dimX, dimY, dimX1, dimY1, dimX2, dimY2; - readonly int offsetX, offsetY; - readonly int isoOffset, isoX, isoY, isoH; - readonly int imageStride; + private readonly int dimX, dimY, dimX1, dimY1, dimX2, dimY2; + private readonly int offsetX, offsetY; + private readonly int isoOffset, isoX, isoY, isoH; + private readonly int imageStride; public readonly int Rot; public readonly IsoCatMode Mode; public readonly Map Map; - public IsoCat( Map map, IsoCatMode mode, int rot ) { Rot = rot; Mode = mode; @@ -117,50 +114,67 @@ public IsoCat( Map map, IsoCatMode mode, int rot ) { ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb ); - image = (byte*)imageData.Scan0; + image = ( byte* )imageData.Scan0; imageStride = imageData.Stride; - isoOffset = (Map.Height * TileY / 2 * imageStride + imageStride / 2 + TileX * 2); - isoX = (TileX / 4 * imageStride + TileX * 2); - isoY = (TileY / 4 * imageStride - TileY * 2); - isoH = (-TileY / 2 * imageStride); + isoOffset = ( Map.Height * TileY / 2 * imageStride + imageStride / 2 + TileX * 2 ); + isoX = ( TileX / 4 * imageStride + TileX * 2 ); + isoY = ( TileY / 4 * imageStride - TileY * 2 ); + isoH = ( -TileY / 2 * imageStride ); mh34 = Map.Height * 3 / 4; } - byte* bp, ctp; + private byte* bp, ctp; + [CanBeNull] public Bitmap Draw( out Rectangle cropRectangle, BackgroundWorker worker ) { cropRectangle = Rectangle.Empty; try { - fixed( byte* bpx = Map.Blocks ) { - fixed( byte* tp = Tiles ) { - fixed( byte* stp = ShadowTiles ) { + fixed ( byte* bpx = Map.Blocks ) { + fixed ( byte* tp = Tiles ) { + fixed ( byte* stp = ShadowTiles ) { bp = bpx; - while( z < Map.Height ) { + while ( z < Map.Height ) { block = GetBlock( x, y, z ); - if( block != 0 ) { - - switch( Rot ) { - case 0: ctp = (z >= Map.Shadows[x, y] ? tp : stp); break; - case 1: ctp = (z >= Map.Shadows[dimX1 - y, x] ? tp : stp); break; - case 2: ctp = (z >= Map.Shadows[dimX1 - x, dimY1 - y] ? tp : stp); break; - case 3: ctp = (z >= Map.Shadows[y, dimY1 - x] ? tp : stp); break; + if ( block != 0 ) { + switch ( Rot ) { + case 0: + ctp = ( z >= Map.Shadows[x, y] ? tp : stp ); + break; + + case 1: + ctp = ( z >= Map.Shadows[dimX1 - y, x] ? tp : stp ); + break; + + case 2: + ctp = ( z >= Map.Shadows[dimX1 - x, dimY1 - y] ? tp : stp ); + break; + + case 3: + ctp = ( z >= Map.Shadows[y, dimY1 - x] ? tp : stp ); + break; } int blockRight, blockLeft, blockUp; - if( x != (Rot == 1 || Rot == 3 ? dimY1 : dimX1) ) blockRight = GetBlock( x + 1, y, z ); - else blockRight = 0; - if( y != (Rot == 1 || Rot == 3 ? dimX1 : dimY1) ) blockLeft = GetBlock( x, y + 1, z ); - else blockLeft = 0; - if( z != Map.Height - 1 ) blockUp = GetBlock( x, y, z + 1 ); - else blockUp = 0; - - if( blockUp == 0 || blockLeft == 0 || blockRight == 0 || // air + if ( x != ( Rot == 1 || Rot == 3 ? dimY1 : dimX1 ) ) + blockRight = GetBlock( x + 1, y, z ); + else + blockRight = 0; + if ( y != ( Rot == 1 || Rot == 3 ? dimX1 : dimY1 ) ) + blockLeft = GetBlock( x, y + 1, z ); + else + blockLeft = 0; + if ( z != Map.Height - 1 ) + blockUp = GetBlock( x, y, z + 1 ); + else + blockUp = 0; + + if ( blockUp == 0 || blockLeft == 0 || blockRight == 0 || // air blockUp == 8 || blockLeft == 8 || blockRight == 8 || // water blockUp == 9 || blockLeft == 9 || blockRight == 9 || // water - (block != 20 && (blockUp == 20 || blockLeft == 20 || blockRight == 20)) || // glass + ( block != 20 && ( blockUp == 20 || blockLeft == 20 || blockRight == 20 ) ) || // glass blockUp == 18 || blockLeft == 18 || blockRight == 18 || // foliage blockLeft == 44 || blockRight == 44 || // step @@ -176,16 +190,17 @@ public Bitmap Draw( out Rectangle cropRectangle, BackgroundWorker worker ) { } x++; - if( x == (Rot == 1 || Rot == 3 ? dimY : dimX) ) { + if ( x == ( Rot == 1 || Rot == 3 ? dimY : dimX ) ) { y++; x = 0; } - if( y == (Rot == 1 || Rot == 3 ? dimX : dimY) ) { + if ( y == ( Rot == 1 || Rot == 3 ? dimX : dimY ) ) { z++; y = 0; - if( worker != null && z % 4 == 0 ) { - if( worker.CancellationPending ) return null; - worker.ReportProgress( (z * 100) / Map.Height ); + if ( worker != null && z % 4 == 0 ) { + if ( worker.CancellationPending ) + return null; + worker.ReportProgress( ( z * 100 ) / Map.Height ); } } } @@ -198,10 +213,10 @@ public Bitmap Draw( out Rectangle cropRectangle, BackgroundWorker worker ) { int offset; // find left bound (xMin) - for( x = 0; cont && x < imageWidth; x++ ) { + for ( x = 0; cont && x < imageWidth; x++ ) { offset = x * 4 + 3; - for( y = 0; y < imageHeight; y++ ) { - if( image[offset] > 0 ) { + for ( y = 0; y < imageHeight; y++ ) { + if ( image[offset] > 0 ) { xMin = x; cont = false; break; @@ -210,14 +225,15 @@ public Bitmap Draw( out Rectangle cropRectangle, BackgroundWorker worker ) { } } - if( worker != null && worker.CancellationPending ) return null; + if ( worker != null && worker.CancellationPending ) + return null; // find top bound (yMin) cont = true; - for( y = 0; cont && y < imageHeight; y++ ) { + for ( y = 0; cont && y < imageHeight; y++ ) { offset = imageStride * y + xMin * 4 + 3; - for( x = xMin; x < imageWidth; x++ ) { - if( image[offset] > 0 ) { + for ( x = xMin; x < imageWidth; x++ ) { + if ( image[offset] > 0 ) { yMin = y; cont = false; break; @@ -226,14 +242,15 @@ public Bitmap Draw( out Rectangle cropRectangle, BackgroundWorker worker ) { } } - if( worker != null && worker.CancellationPending ) return null; + if ( worker != null && worker.CancellationPending ) + return null; // find right bound (xMax) cont = true; - for( x = imageWidth - 1; cont && x >= xMin; x-- ) { + for ( x = imageWidth - 1; cont && x >= xMin; x-- ) { offset = x * 4 + 3 + yMin * imageStride; - for( y = yMin; y < imageHeight; y++ ) { - if( image[offset] > 0 ) { + for ( y = yMin; y < imageHeight; y++ ) { + if ( image[offset] > 0 ) { xMax = x + 1; cont = false; break; @@ -242,14 +259,15 @@ public Bitmap Draw( out Rectangle cropRectangle, BackgroundWorker worker ) { } } - if( worker != null && worker.CancellationPending ) return null; + if ( worker != null && worker.CancellationPending ) + return null; // find bottom bound (yMax) cont = true; - for( y = imageHeight - 1; cont && y >= yMin; y-- ) { + for ( y = imageHeight - 1; cont && y >= yMin; y-- ) { offset = imageStride * y + 3 + xMin * 4; - for( x = xMin; x < xMax; x++ ) { - if( image[offset] > 0 ) { + for ( x = xMin; x < xMax; x++ ) { + if ( image[offset] > 0 ) { yMax = y + 1; cont = false; break; @@ -265,18 +283,18 @@ public Bitmap Draw( out Rectangle cropRectangle, BackgroundWorker worker ) { return imageBmp; } finally { imageBmp.UnlockBits( imageData ); - if( worker != null && worker.CancellationPending && imageBmp != null ) { + if ( worker != null && worker.CancellationPending && imageBmp != null ) { try { imageBmp.Dispose(); - } catch( ObjectDisposedException ) { } + } catch ( ObjectDisposedException ) { } } } } - - void BlendTile() { - int pos = (x + (Rot == 1 || Rot == 3 ? offsetY : offsetX)) * isoX + (y + (Rot == 1 || Rot == 3 ? offsetX : offsetY)) * isoY + z * isoH + isoOffset; - if( block > 49 ) return; + private void BlendTile() { + int pos = ( x + ( Rot == 1 || Rot == 3 ? offsetY : offsetX ) ) * isoX + ( y + ( Rot == 1 || Rot == 3 ? offsetX : offsetY ) ) * isoY + z * isoH + isoOffset; + if ( block > 49 ) + return; int tileOffset = block * TileStride; BlendPixel( pos, tileOffset ); BlendPixel( pos + 4, tileOffset + 4 ); @@ -299,22 +317,22 @@ void BlendTile() { //BlendPixel( pos + 12, tileOffset + 60 ); // bottom right block, always blank in current tileset } - - const byte ShadingStrength = 48; - readonly int blendDivisor, mh34; + private const byte ShadingStrength = 48; + private readonly int blendDivisor, mh34; // inspired by http://www.devmaster.net/wiki/Alpha_blending - void BlendPixel( int imageOffset, int tileOffset ) { + private void BlendPixel( int imageOffset, int tileOffset ) { int sourceAlpha; - if( ctp[tileOffset + 3] == 0 ) return; + if ( ctp[tileOffset + 3] == 0 ) + return; byte tA = ctp[tileOffset + 3]; // Get final alpha channel. - int finalAlpha = tA + ((255 - tA) * image[imageOffset + 3]) / 255; + int finalAlpha = tA + ( ( 255 - tA ) * image[imageOffset + 3] ) / 255; // Get percentage (out of 256) of source alpha compared to final alpha - if( finalAlpha == 0 ) { + if ( finalAlpha == 0 ) { sourceAlpha = 0; } else { sourceAlpha = tA * 255 / finalAlpha; @@ -323,51 +341,54 @@ void BlendPixel( int imageOffset, int tileOffset ) { // Destination percentage is just the additive inverse. int destAlpha = 255 - sourceAlpha; - if( z < (Map.Height >> 1) ) { - int shadow = (z >> 1) + mh34; - image[imageOffset] = (byte)((ctp[tileOffset] * sourceAlpha * shadow + image[imageOffset] * destAlpha * Map.Height) / blendDivisor); - image[imageOffset + 1] = (byte)((ctp[tileOffset + 1] * sourceAlpha * shadow + image[imageOffset + 1] * destAlpha * Map.Height) / blendDivisor); - image[imageOffset + 2] = (byte)((ctp[tileOffset + 2] * sourceAlpha * shadow + image[imageOffset + 2] * destAlpha * Map.Height) / blendDivisor); + if ( z < ( Map.Height >> 1 ) ) { + int shadow = ( z >> 1 ) + mh34; + image[imageOffset] = ( byte )( ( ctp[tileOffset] * sourceAlpha * shadow + image[imageOffset] * destAlpha * Map.Height ) / blendDivisor ); + image[imageOffset + 1] = ( byte )( ( ctp[tileOffset + 1] * sourceAlpha * shadow + image[imageOffset + 1] * destAlpha * Map.Height ) / blendDivisor ); + image[imageOffset + 2] = ( byte )( ( ctp[tileOffset + 2] * sourceAlpha * shadow + image[imageOffset + 2] * destAlpha * Map.Height ) / blendDivisor ); } else { - int shadow = (z - (Map.Height >> 1)) * ShadingStrength; - image[imageOffset] = (byte)Math.Min( 255, (ctp[tileOffset] * sourceAlpha + shadow + image[imageOffset] * destAlpha) / 255 ); - image[imageOffset + 1] = (byte)Math.Min( 255, (ctp[tileOffset + 1] * sourceAlpha + shadow + image[imageOffset + 1] * destAlpha) / 255 ); - image[imageOffset + 2] = (byte)Math.Min( 255, (ctp[tileOffset + 2] * sourceAlpha + shadow + image[imageOffset + 2] * destAlpha) / 255 ); + int shadow = ( z - ( Map.Height >> 1 ) ) * ShadingStrength; + image[imageOffset] = ( byte )Math.Min( 255, ( ctp[tileOffset] * sourceAlpha + shadow + image[imageOffset] * destAlpha ) / 255 ); + image[imageOffset + 1] = ( byte )Math.Min( 255, ( ctp[tileOffset + 1] * sourceAlpha + shadow + image[imageOffset + 1] * destAlpha ) / 255 ); + image[imageOffset + 2] = ( byte )Math.Min( 255, ( ctp[tileOffset + 2] * sourceAlpha + shadow + image[imageOffset + 2] * destAlpha ) / 255 ); } - image[imageOffset + 3] = (byte)finalAlpha; + image[imageOffset + 3] = ( byte )finalAlpha; } - byte GetBlock( int xx, int yy, int zz ) { + private byte GetBlock( int xx, int yy, int zz ) { int realx; int realy; - switch( Rot ) { + switch ( Rot ) { case 0: realx = xx; realy = yy; break; + case 1: realx = dimX1 - yy; realy = xx; break; + case 2: realx = dimX1 - xx; realy = dimY1 - yy; break; + default: realx = yy; realy = dimY1 - xx; break; } - int pos = (zz * dimY + realy) * dimX + realx; + int pos = ( zz * dimY + realy ) * dimX + realx; - if( Mode == IsoCatMode.Normal ) { + if ( Mode == IsoCatMode.Normal ) { return bp[pos]; - } else if( Mode == IsoCatMode.Peeled && (xx == (Rot == 1 || Rot == 3 ? dimY1 : dimX1) || yy == (Rot == 1 || Rot == 3 ? dimX1 : dimY1) || zz == Map.Height - 1) ) { + } else if ( Mode == IsoCatMode.Peeled && ( xx == ( Rot == 1 || Rot == 3 ? dimY1 : dimX1 ) || yy == ( Rot == 1 || Rot == 3 ? dimX1 : dimY1 ) || zz == Map.Height - 1 ) ) { return 0; - } else if( Mode == IsoCatMode.Cut && xx > (Rot == 1 || Rot == 3 ? dimY2 : dimX2) && yy > (Rot == 1 || Rot == 3 ? dimX2 : dimY2) ) { + } else if ( Mode == IsoCatMode.Cut && xx > ( Rot == 1 || Rot == 3 ? dimY2 : dimX2 ) && yy > ( Rot == 1 || Rot == 3 ? dimX2 : dimY2 ) ) { return 0; - } else if( Mode == IsoCatMode.Chunk && (realx < ChunkCoords[0] || realy < ChunkCoords[1] || zz < ChunkCoords[2] || realx > ChunkCoords[3] || realy > ChunkCoords[4] || zz > ChunkCoords[5]) ) { + } else if ( Mode == IsoCatMode.Chunk && ( realx < ChunkCoords[0] || realy < ChunkCoords[1] || zz < ChunkCoords[2] || realx > ChunkCoords[3] || realy > ChunkCoords[4] || zz > ChunkCoords[5] ) ) { return 0; } diff --git a/fCraftGUI/Properties/AssemblyInfo.cs b/fCraftGUI/Properties/AssemblyInfo.cs index 48046e5..3b2df46 100644 --- a/fCraftGUI/Properties/AssemblyInfo.cs +++ b/fCraftGUI/Properties/AssemblyInfo.cs @@ -1,20 +1,20 @@ using System.Reflection; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("800CraftGUI")] -[assembly: AssemblyDescription("Shared graphics-related functionality for 800Craft")] +[assembly: AssemblyTitle( "800CraftGUI" )] +[assembly: AssemblyDescription( "Shared graphics-related functionality for 800Craft" )] [assembly: AssemblyConfiguration( "" )] -[assembly: AssemblyCompany("au70.net")] -[assembly: AssemblyProduct("800CraftGUI")] -[assembly: AssemblyCopyright("")] +[assembly: AssemblyCompany( "au70.net" )] +[assembly: AssemblyProduct( "800CraftGUI" )] +[assembly: AssemblyCopyright( "" )] [assembly: AssemblyTrademark( "" )] [assembly: AssemblyCulture( "" )] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible( false )] @@ -24,12 +24,12 @@ // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -// You can specify all the values or you can default the Build and Revision Numbers +// You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion( "0.6.1.7" )] -[assembly: AssemblyFileVersion( "0.6.1.7" )] +[assembly: AssemblyFileVersion( "0.6.1.7" )] \ No newline at end of file