Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Assets/Facepunch/RustWorldSDK/TerrainBiome.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,31 @@ public enum Enum
Temperate = 1 << TEMPERATE_IDX,
Tundra = 1 << TUNDRA_IDX,
Arctic = 1 << ARCTIC_IDX,
Jungle = 1 << JUNGLE_IDX,
}

public const int COUNT = 4;
public const int COUNT = 5;
public const int EVERYTHING = ~0;
public const int NOTHING = 0;

public const int ARID = (int)Enum.Arid;
public const int TEMPERATE = (int)Enum.Temperate;
public const int TUNDRA = (int)Enum.Tundra;
public const int ARCTIC = (int)Enum.Arctic;
public const int JUNGLE = (int)Enum.Jungle;

public const int ARID_IDX = 0;
public const int TEMPERATE_IDX = 1;
public const int TUNDRA_IDX = 2;
public const int ARCTIC_IDX = 3;
public const int JUNGLE_IDX = 4;

private static Dictionary<int, int> type2index = new Dictionary<int, int>() {
{ ARID, ARID_IDX },
{ TEMPERATE, TEMPERATE_IDX },
{ TUNDRA, TUNDRA_IDX },
{ ARCTIC, ARCTIC_IDX },
{ JUNGLE, JUNGLE_IDX },
};

public static int TypeToIndex(int id)
Expand Down
17 changes: 15 additions & 2 deletions Assets/Facepunch/RustWorldSDK/WorldSerialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

public class WorldSerialization
{
public const uint CurrentVersion = 9;
public const uint CurrentVersion = 10;

public static uint Version
{
Expand Down Expand Up @@ -78,6 +78,7 @@ public class PathData
[ProtoMember(13)] public int splat;
[ProtoMember(14)] public int topology;
[ProtoMember(15)] public VectorData[] nodes;
[ProtoMember(16)] public int toplogy;
}

[Serializable]
Expand Down Expand Up @@ -146,6 +147,7 @@ public void Save(string fileName)
using (var binaryWriter = new BinaryWriter(fileStream))
{
binaryWriter.Write(Version);
binaryWriter.Write((long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds);

using (var compressionStream = new LZ4Stream(fileStream, LZ4StreamMode.Compress))
Serializer.Serialize(compressionStream, world);
Expand All @@ -167,12 +169,23 @@ public void Load(string fileName)
using (var binaryReader = new BinaryReader(fileStream))
{
Version = binaryReader.ReadUInt32();

long Timestamp = binaryReader.ReadInt64();
if (Version != CurrentVersion)
Debug.LogWarning("Map Version is: " + Version + " whilst Rust is on: " + CurrentVersion);

using (var compressionStream = new LZ4Stream(fileStream, LZ4StreamMode.Decompress))
world = Serializer.Deserialize<WorldData>(compressionStream);

// Fix null VectorData fields in PrefabData (game uses struct, we use class)
foreach (var prefab in world.prefabs)
{
if (prefab.position == null)
prefab.position = new VectorData(0, 0, 0);
if (prefab.rotation == null)
prefab.rotation = new VectorData(0, 0, 0);
if (prefab.scale == null)
prefab.scale = new VectorData(1, 1, 1);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,18 @@ public static List<PrefabsListElement> GetPrefabsListElements(bool showAll = fal
List<PrefabsListElement> prefabsListElements = new List<PrefabsListElement>();
prefabsListElements.Add(new PrefabsListElement("Root", -1, 0));

var prefabStrings = showAll ? AssetManager.AssetPaths.Where(x => x.Contains(".prefab")) : AssetManager.AssetPaths.Where(x => SettingsManager.PrefabPaths.Any(y => x.Contains(y) && x.Contains(".prefab")));
// Use scene manifest prefab paths if available, otherwise fall back to legacy AssetPaths
IEnumerable<string> sourcePaths;
if (SceneAssetManager.IsManifestLoaded && SceneAssetManager.ManifestPrefabPaths.Count > 0)
{
sourcePaths = SceneAssetManager.ManifestPrefabPaths;
}
else
{
sourcePaths = AssetManager.AssetPaths;
}

var prefabStrings = showAll ? sourcePaths.Where(x => x.Contains(".prefab")) : sourcePaths.Where(x => SettingsManager.PrefabPaths.Any(y => x.Contains(y) && x.Contains(".prefab")));
int prefabID = 1, parentID = -1;
foreach (var manifestString in prefabStrings)
{
Expand Down
65 changes: 57 additions & 8 deletions Assets/MapEditor/Managers/AssetManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public static class Callbacks
public const string AssetDumpPath = "AssetDump.txt";
public const string MaterialsListPath = "MaterialsList.txt";
public const string VolumesListPath = "VolumesList.txt";
public const string SceneManifestFileName = "AssetSceneManifest.json";

public static Dictionary<uint, string> IDLookup { get; private set; } = new Dictionary<uint, string>();
public static Dictionary<string, uint> PathLookup { get; private set; } = new Dictionary<string, uint>();
Expand Down Expand Up @@ -104,19 +105,39 @@ public static GameObject LoadPrefab(string filePath)
if (AssetCache.ContainsKey(filePath))
return AssetCache[filePath] as GameObject;

else
// Play mode: use scene-based loading
if (Application.isPlaying && SceneAssetManager.IsManifestLoaded)
{
GameObject val = GetAsset<GameObject>(filePath);
GameObject val = SceneAssetManager.GetPrefabFromScene(filePath);
if (val != null)
{
PrefabManager.Setup(val, filePath);
AssetCache.Add(filePath, val);
PrefabManager.Callbacks.OnPrefabLoaded(val);
return val;
PrefabManager.Setup(val, filePath);
AssetCache.Add(filePath, val);
PrefabManager.Callbacks.OnPrefabLoaded(val);
return val;
}
Debug.LogWarning("Prefab not loaded from bundle: " + filePath);
Debug.LogWarning("Prefab not loaded from scene: " + filePath);
return PrefabManager.DefaultPrefab;
}

// Edit mode: try legacy bundle loading (fallback)
GameObject legacyVal = GetAsset<GameObject>(filePath);
if (legacyVal != null)
{
PrefabManager.Setup(legacyVal, filePath);
AssetCache.Add(filePath, legacyVal);
PrefabManager.Callbacks.OnPrefabLoaded(legacyVal);
return legacyVal;
}

// Edit mode with manifest loaded: return default prefab
if (SceneAssetManager.IsManifestLoaded)
{
return PrefabManager.DefaultPrefab;
}

Debug.LogWarning("Prefab not loaded from bundle: " + filePath);
return PrefabManager.DefaultPrefab;
}

/// <summary>Returns a preview image of the asset located at the filepath. Caches the results.</summary>
Expand Down Expand Up @@ -184,6 +205,28 @@ public static void AssetDump()
streamWriter.WriteLine(item + " : " + ToID(item));
}

/// <summary>Loads the AssetSceneManifest.json from the Rust directory.</summary>
public static void LoadSceneManifest()
{
string manifestPath = Path.Combine(SettingsManager.RustDirectory, "Bundles", SceneManifestFileName);
if (File.Exists(manifestPath))
{
try
{
string json = File.ReadAllText(manifestPath);
SceneAssetManager.ParseManifest(json);
}
catch (System.Exception e)
{
Debug.LogError($"Failed to load AssetSceneManifest: {e.Message}");
}
}
else
{
Debug.LogWarning($"AssetSceneManifest not found at: {manifestPath}");
}
}

public static string ToPath(uint i)
{
if ((int)i == 0)
Expand Down Expand Up @@ -230,17 +273,23 @@ public static IEnumerator Initialise(string bundlesRoot)
yield return EditorCoroutineUtility.StartCoroutineOwnerless(SetBundleReferences((progressID, bundleID)));
yield return EditorCoroutineUtility.StartCoroutineOwnerless(SetMaterials(materialID));

// Load scene manifest for scene-based prefab loading
LoadSceneManifest();

IsInitialised = true; IsInitialising = false;
SetVolumeGizmos();
Callbacks.OnBundlesLoaded();
PrefabManager.ReplaceWithLoaded(PrefabManager.CurrentMapPrefabs, prefabID);
}

public static IEnumerator Dispose()
public static IEnumerator Dispose()
{
IsInitialising = true;
ProgressManager.RemoveProgressBars("Unload Asset Bundles");

// Dispose scene asset manager first
SceneAssetManager.Dispose();

int progressID = Progress.Start("Unload Asset Bundles", null, Progress.Options.Sticky);
int bundleID = Progress.Start("Bundles", null, Progress.Options.Sticky, progressID);
int prefabID = Progress.Start("Prefabs", null, Progress.Options.Sticky, progressID);
Expand Down
18 changes: 16 additions & 2 deletions Assets/MapEditor/Managers/PrefabManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,27 @@ public static IEnumerator SpawnPrefabs(PrefabData[] prefabs, int progressID)

for (int i = 0; i < prefabs.Length; i++)
{
if (sw.Elapsed.TotalSeconds > 4f)
string prefabPath = AssetManager.ToPath(prefabs[i].id);

// Play mode: ensure scene is loaded before accessing prefab
// Only yield if prefab is not already cached (scene needs loading)
if (UnityEngine.Application.isPlaying && SceneAssetManager.IsManifestLoaded)
{
if (!SceneAssetManager.IsPrefabCached(prefabPath))
{
yield return SceneAssetManager.EnsurePrefabAvailable(prefabPath);
}
}

Spawn(Load(prefabs[i].id), prefabs[i], GetParent(prefabs[i].category));

// Yield periodically for progress reporting (every 8 seconds)
if (sw.Elapsed.TotalSeconds > 8f)
{
yield return null;
Progress.Report(progressID, (float)i / prefabs.Length, "Spawning Prefabs: " + i + " / " + prefabs.Length);
sw.Restart();
}
Spawn(Load(prefabs[i].id), prefabs[i], GetParent(prefabs[i].category));
}

Progress.Report(progressID, 0.99f, "Spawned " + prefabs.Length + " prefabs.");
Expand Down
Loading