Merge branch 'master' into IgnoreUnwantedPositions

This commit is contained in:
Goodlyay 2024-02-24 16:48:53 -08:00
commit 07fc21ecee
12 changed files with 93 additions and 42 deletions

View File

@ -101,7 +101,7 @@ namespace MCGalaxy.Gui
// .. // ..
// However, some X11 video drivers will cause XQueryBestCursor to return width/height 0, // However, some X11 video drivers will cause XQueryBestCursor to return width/height 0,
// which will then cause the subsequent 'new Bitmap(width, height)' in XplatUIX11.DefineCursor to fail // which will then cause the subsequent 'new Bitmap(width, height)' in XplatUIX11.DefineCursor to fail
// See https://github.com/UnknownShadow200/MCGalaxy/issues/658 for more details // See https://github.com/ClassiCube/MCGalaxy/issues/658 for more details
try { try {
Cursor c = Cursors.SizeNWSE; Cursor c = Cursors.SizeNWSE;
} catch (ArgumentException ex) { } catch (ArgumentException ex) {

View File

@ -18,7 +18,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace MCGalaxy.Commands.Info namespace MCGalaxy.Commands.Info
{ {
public sealed class CmdRankInfo : Command2 public sealed class CmdRankInfo : Command2
{ {

View File

@ -17,6 +17,7 @@
*/ */
using System; using System;
using System.IO; using System.IO;
using MCGalaxy.Events.BlockDBEvents;
using MCGalaxy.Util; using MCGalaxy.Util;
using MCGalaxy.Maths; using MCGalaxy.Maths;
@ -56,8 +57,10 @@ namespace MCGalaxy.DB
} }
void ReadDimensions() { void ReadDimensions() {
if (!File.Exists(FilePath)) return; string path = FilePath;
using (Stream s = OpenRead()) if (!File.Exists(path)) return;
using (Stream s = OpenRead(path))
BlockDBFile.ReadHeader(s, out Dims); BlockDBFile.ReadHeader(s, out Dims);
} }
@ -66,8 +69,13 @@ namespace MCGalaxy.DB
public void FlushCache() { public void FlushCache() {
if (Cache.Head == null) return; if (Cache.Head == null) return;
BlockDBFile format = ValidateBackingFile(); string path = FilePath;
using (Stream s = OpenWrite()) { bool cancel = false;
OnBlockDBSaveEvent.Call(this, ref path, ref cancel);
if (cancel) return;
BlockDBFile format = ValidateBackingFile(path);
using (Stream s = OpenWrite(path)) {
// This truncates the lower 4 bits off - so e.g. if a power off occurred // This truncates the lower 4 bits off - so e.g. if a power off occurred
// and 21 bytes were in the file, this sets the position to byte 16 // and 21 bytes were in the file, this sets the position to byte 16
s.Position = s.Length & ~0x0F; s.Position = s.Length & ~0x0F;
@ -90,10 +98,11 @@ namespace MCGalaxy.DB
/// <summary> Outputs all block changes which affect the given coordinates. </summary> /// <summary> Outputs all block changes which affect the given coordinates. </summary>
/// <remarks> You must lock using Locker.AccquireRead() **before** entering this method. </remarks> /// <remarks> You must lock using Locker.AccquireRead() **before** entering this method. </remarks>
public void FindChangesAt(ushort x, ushort y, ushort z, Action<BlockDBEntry> output) { public void FindChangesAt(ushort x, ushort y, ushort z, Action<BlockDBEntry> output) {
if (!File.Exists(FilePath)) { FindInMemoryAt(x, y, z, output); return; } string path = FilePath;
if (!File.Exists(path)) { FindInMemoryAt(x, y, z, output); return; }
Vec3U16 dims; Vec3U16 dims;
using (Stream s = OpenRead()) { using (Stream s = OpenRead(path)) {
BlockDBFile format = BlockDBFile.ReadHeader(s, out dims); BlockDBFile format = BlockDBFile.ReadHeader(s, out dims);
if (x >= dims.X || y >= dims.Y || z >= dims.Z) return; if (x >= dims.X || y >= dims.Y || z >= dims.Z) return;
@ -110,7 +119,8 @@ namespace MCGalaxy.DB
BlockDBCacheEntry[] entries = node.Entries; BlockDBCacheEntry[] entries = node.Entries;
int count = node.Count; int count = node.Count;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++)
{
if (entries[i].Index != index) continue; if (entries[i].Index != index) continue;
BlockDBEntry entry = node.Unpack(entries[i]); BlockDBEntry entry = node.Unpack(entries[i]);
output(entry); output(entry);
@ -125,13 +135,14 @@ namespace MCGalaxy.DB
public bool FindChangesBy(int[] ids, DateTime start, DateTime end, public bool FindChangesBy(int[] ids, DateTime start, DateTime end,
out Vec3U16 dims, Action<BlockDBEntry> output) { out Vec3U16 dims, Action<BlockDBEntry> output) {
int startDelta = ClampDelta(start.Subtract(Epoch)); int startDelta = ClampDelta(start.Subtract(Epoch));
int endDelta = ClampDelta(end.Subtract(Epoch)); int endDelta = ClampDelta(end.Subtract(Epoch));
dims = Dims; dims = Dims;
if (FindInMemoryBy(ids, startDelta, endDelta, output)) return true; if (FindInMemoryBy(ids, startDelta, endDelta, output)) return true;
string path = FilePath;
if (!File.Exists(FilePath)) return false; if (!File.Exists(path)) return false;
using (Stream s = OpenRead()) { using (Stream s = OpenRead(path)) {
BlockDBFile format = BlockDBFile.ReadHeader(s, out dims); BlockDBFile format = BlockDBFile.ReadHeader(s, out dims);
return format.FindChangesBy(s, ids, startDelta, endDelta, output); return format.FindChangesBy(s, ids, startDelta, endDelta, output);
} }
@ -143,12 +154,14 @@ namespace MCGalaxy.DB
int count = node.Count; int count = node.Count;
BlockDBCacheEntry[] entries = node.Entries; BlockDBCacheEntry[] entries = node.Entries;
for (int i = count - 1; i >= 0; i--) { for (int i = count - 1; i >= 0; i--)
{
BlockDBEntry entry = node.Unpack(entries[i]); BlockDBEntry entry = node.Unpack(entries[i]);
if (entry.TimeDelta < startDelta) return true; if (entry.TimeDelta < startDelta) return true;
if (entry.TimeDelta > endDelta) continue; if (entry.TimeDelta > endDelta) continue;
for (int j = 0; j < ids.Length; j++) { for (int j = 0; j < ids.Length; j++)
{
if (entry.PlayerID != ids[j]) continue; if (entry.PlayerID != ids[j]) continue;
output(entry); break; output(entry); break;
} }
@ -168,41 +181,43 @@ namespace MCGalaxy.DB
/// <summary> Deletes the backing file on disc if it exists. </summary> /// <summary> Deletes the backing file on disc if it exists. </summary>
public void DeleteBackingFile() { public void DeleteBackingFile() {
string path = FilePath;
using (IDisposable writeLock = Locker.AccquireWrite()) { using (IDisposable writeLock = Locker.AccquireWrite()) {
if (!File.Exists(FilePath)) return; if (!File.Exists(path)) return;
File.Delete(FilePath); File.Delete(path);
} }
} }
/// <summary> Checks if the backing file exists on disc, and if not, creates it. /// <summary> Checks if the backing file exists on disc, and if not, creates it.
/// Also recreates the backing file if dimensions on disc are less than those in memory. </summary> /// Also recreates the backing file if dimensions on disc are less than those in memory. </summary>
BlockDBFile ValidateBackingFile() { BlockDBFile ValidateBackingFile(string path) {
BlockDBFile format = BlockDBFile.V1;
Vec3U16 fileDims; Vec3U16 fileDims;
BlockDBFile format = BlockDBFile.V1; if (!File.Exists(path)) {
if (!File.Exists(FilePath)) { using (Stream s = OpenWrite(path)) {
using (Stream s = OpenWrite()) {
fileDims = Dims; fileDims = Dims;
BlockDBFile.WriteHeader(s, fileDims); BlockDBFile.WriteHeader(s, fileDims);
} }
} else { } else {
using (Stream s = OpenRead()) { using (Stream s = OpenRead(path)) {
format = BlockDBFile.ReadHeader(s, out fileDims); format = BlockDBFile.ReadHeader(s, out fileDims);
} }
if (fileDims.X < Dims.X || fileDims.Y < Dims.Y || fileDims.Z < Dims.Z) { if (fileDims.X < Dims.X || fileDims.Y < Dims.Y || fileDims.Z < Dims.Z) {
BlockDBFile.ResizeBackingFile(this); BlockDBFile.ResizeBackingFile(this, path);
} }
} }
return format; return format;
} }
FileStream OpenWrite() { static FileStream OpenWrite(string path) {
return new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite); return new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
} }
FileStream OpenRead() { static FileStream OpenRead(string path) {
return new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite); return new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite);
} }
} }
} }

View File

@ -93,12 +93,11 @@ namespace MCGalaxy.DB
File.Move(srcPath, dstPath); File.Move(srcPath, dstPath);
} }
public static void ResizeBackingFile(BlockDB db) { public static void ResizeBackingFile(BlockDB db, string path) {
Logger.Log(LogType.BackgroundActivity, "Resizing BlockDB for " + db.MapName); Logger.Log(LogType.BackgroundActivity, "Resizing BlockDB for " + db.MapName);
string filePath = FilePath(db.MapName);
string tempPath = TempPath(db.MapName); string tempPath = TempPath(db.MapName);
using (Stream src = File.OpenRead(filePath), dst = File.Create(tempPath)) { using (Stream src = File.OpenRead(path), dst = File.Create(tempPath)) {
Vec3U16 dims; Vec3U16 dims;
ReadHeader(src, out dims); ReadHeader(src, out dims);
WriteHeader(dst, db.Dims); WriteHeader(dst, db.Dims);
@ -123,8 +122,8 @@ namespace MCGalaxy.DB
} }
} }
File.Delete(filePath); File.Delete(path);
File.Move(tempPath, filePath); File.Move(tempPath, path);
} }

View File

@ -0,0 +1,36 @@
/*
Copyright 2011 MCForge
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
https://opensource.org/license/ecl-2-0/
https://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using System;
using MCGalaxy.DB;
namespace MCGalaxy.Events.BlockDBEvents
{
public delegate void OnBlockDBSave(BlockDB db, ref string path, ref bool cancel);
/// <summary> Called whenever a BlockDB is being flushed from memory to disc </summary>
public sealed class OnBlockDBSaveEvent : IEvent<OnBlockDBSave>
{
public static void Call(BlockDB db, ref string path, ref bool cancel) {
IEvent<OnBlockDBSave>[] items = handlers.Items;
for (int i = 0; i < items.Length; i++)
{
try { items[i].method(db, ref path, ref cancel); }
catch (Exception ex) { LogHandlerException(ex, items[i]); }
}
}
}
}

View File

@ -1,5 +1,5 @@
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 // Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
// Based on: https://github.com/UnknownShadow200/ClassiCube/wiki/Minecraft-Classic-map-generation-algorithm // Based on: https://github.com/ClassiCube/ClassiCube/wiki/Minecraft-Classic-map-generation-algorithm
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using MCGalaxy; using MCGalaxy;

View File

@ -1,5 +1,5 @@
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 // Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
// Based on: https://github.com/UnknownShadow200/ClassiCube/wiki/Minecraft-Classic-map-generation-algorithm // Based on: https://github.com/ClassiCube/ClassiCube/wiki/Minecraft-Classic-map-generation-algorithm
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using MCGalaxy; using MCGalaxy;

View File

@ -2,7 +2,7 @@
// Source from http://mrl.nyu.edu/~perlin/noise/ // Source from http://mrl.nyu.edu/~perlin/noise/
// Optimised form as we can always treat Z as being = 0. // Optimised form as we can always treat Z as being = 0.
// Octave and combined noise based on: // Octave and combined noise based on:
// https://github.com/UnknownShadow200/ClassiCube/wiki/Minecraft-Classic-map-generation-algorithm // https://github.com/ClassiCube/ClassiCube/wiki/Minecraft-Classic-map-generation-algorithm
using System; using System;
namespace MCGalaxy.Generator.Classic namespace MCGalaxy.Generator.Classic

View File

@ -1,5 +1,5 @@
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 // Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
// Based on: https://github.com/UnknownShadow200/ClassiCube/wiki/Minecraft-Classic-map-generation-algorithm // Based on: https://github.com/ClassiCube/ClassiCube/wiki/Minecraft-Classic-map-generation-algorithm
using System; using System;
using MCGalaxy.Generator.Classic; using MCGalaxy.Generator.Classic;

View File

@ -432,6 +432,7 @@
<Compile Include="Entity\ModelInfo.cs" /> <Compile Include="Entity\ModelInfo.cs" />
<Compile Include="Entity\Structs.cs" /> <Compile Include="Entity\Structs.cs" />
<Compile Include="Entity\TabList.cs" /> <Compile Include="Entity\TabList.cs" />
<Compile Include="Events\BlockDBEvents.cs" />
<Compile Include="Events\PlayerDBEvents.cs" /> <Compile Include="Events\PlayerDBEvents.cs" />
<Compile Include="Events\EconomyEvents.cs" /> <Compile Include="Events\EconomyEvents.cs" />
<Compile Include="Events\EntityEvents.cs" /> <Compile Include="Events\EntityEvents.cs" />

View File

@ -25,9 +25,9 @@ namespace MCGalaxy
/// <summary> Checks for and applies software updates. </summary> /// <summary> Checks for and applies software updates. </summary>
public static class Updater public static class Updater
{ {
public static string SourceURL = "https://github.com/UnknownShadow200/MCGalaxy"; public static string SourceURL = "https://github.com/ClassiCube/MCGalaxy";
public const string BaseURL = "https://raw.githubusercontent.com/UnknownShadow200/MCGalaxy/master/"; public const string BaseURL = "https://raw.githubusercontent.com/ClassiCube/MCGalaxy/master/";
public const string UploadsURL = "https://github.com/UnknownShadow200/MCGalaxy/tree/master/Uploads"; public const string UploadsURL = "https://github.com/ClassiCube/MCGalaxy/tree/master/Uploads";
const string CurrentVersionURL = BaseURL + "Uploads/current_version.txt"; const string CurrentVersionURL = BaseURL + "Uploads/current_version.txt";
#if MCG_STANDALONE #if MCG_STANDALONE

View File

@ -2,7 +2,7 @@ MCGalaxy is a fully featured and customisable **ClassiCube Server Software** bas
**Setup** **Setup**
----------------- -----------------
Download the latest MCGalaxy release [from here](https://github.com/UnknownShadow200/MCGalaxy/releases) Download the latest MCGalaxy release [from here](https://github.com/ClassiCube/MCGalaxy/releases)
* Windows: You need to install .NET framework 4.0. Windows 8/10/11 already have this included. * Windows: You need to install .NET framework 4.0. Windows 8/10/11 already have this included.
* macOS: You need to install the [Mono framework](https://www.mono-project.com). * macOS: You need to install the [Mono framework](https://www.mono-project.com).
* Linux: You need to install the [Mono framework](https://www.mono-project.com). (or just `apt install mono-complete` if on Ubuntu) * Linux: You need to install the [Mono framework](https://www.mono-project.com). (or just `apt install mono-complete` if on Ubuntu)
@ -95,10 +95,10 @@ See LICENSE for MCGalaxy license, and license.txt for code used from other softw
Docker support Docker support
----------------- -----------------
Some **unofficial** dockerfiles for running MCGalaxy in Docker: Some **unofficial** dockerfiles for running MCGalaxy in Docker:
* [using Mono](https://github.com/UnknownShadow200/MCGalaxy/pull/577/files) * [using Mono](https://github.com/ClassiCube/MCGalaxy/pull/577/files)
* [using .NET core](https://github.com/UnknownShadow200/MCGalaxy/pull/629/files) * [using .NET core](https://github.com/ClassiCube/MCGalaxy/pull/629/files)
Documentation Documentation
----------------- -----------------
* [General documentation](https://github.com/UnknownShadow200/MCGalaxy/wiki) * [General documentation](https://github.com/ClassiCube/MCGalaxy/wiki)
* [API documentation](https://github.com/ClassiCube/MCGalaxy-API-Documentation) * [API documentation](https://github.com/ClassiCube/MCGalaxy-API-Documentation)