Beispiel #1
0
        /// <summary>
        /// Loads a plane from a given nplane file.
        /// </summary>
        /// <param name="planeDirectory">The directory from which the plane should be loaded.</param>
        /// <returns>The loaded plane.</returns>
        public static async Task <Plane> FromDirectory(string planeDirectory)
        {
            PlaneInfo planeInfo = JsonConvert.DeserializeObject <PlaneInfo>(
                File.ReadAllText(CalcPaths.PlaneIndex(planeDirectory))
                );

            Plane loadedPlane = new Plane(planeInfo, planeDirectory);

            // Load the primary chunks into the plane
            await loadedPlane.LoadPrimaryChunks();

            return(loadedPlane);
        }
        public static async Task <RippleSpaceManager> FromDirectory(string sourceDirectory)
        {
            RippleSpaceManager rippleSpace = new RippleSpaceManager(sourceDirectory);

            if (!Directory.Exists(sourceDirectory))
            {
                Log.WriteLine($"[Core] Creating new ripplespace in {sourceDirectory}.");
                return(rippleSpace);
            }

            Log.WriteLine($"[Core] Loading ripplespace from {sourceDirectory}.");

            // Load the planes in
            if (!File.Exists(Path.Combine(rippleSpace.SourceDirectory, "index.list")))
            {
                Log.WriteLine($"[Core] Warning: The ripplespace at {sourceDirectory} doesn't appear to contain an index file.");
                return(rippleSpace);
            }

            Log.WriteLine("[Core] Importing planes");
            Stopwatch timer = Stopwatch.StartNew();

            StreamReader planeList = new StreamReader(Path.Combine(sourceDirectory, "index.list"));

            List <Task <Plane> > planeLoaders = new List <Task <Plane> >();
            string nextPlaneName = string.Empty;

            while ((nextPlaneName = await planeList.ReadLineAsync()) != null)
            {
                string nextPlaneDirectory = CalcPaths.PlaneDirectory(sourceDirectory, nextPlaneName);
                if (!Directory.Exists(nextPlaneDirectory))
                {
                    Log.WriteLine($"[Core] Warning: Couldn't find listed plane {nextPlaneName} when loading ripplespace.");
                    continue;
                }
                planeLoaders.Add(Plane.FromDirectory(nextPlaneDirectory));
            }
            await Task.WhenAll(planeLoaders);


            rippleSpace.Planes.AddRange(
                planeLoaders.Select((Task <Plane> planeLoader) => planeLoader.Result)
                );

            long msTaken = timer.ElapsedMilliseconds;

            Log.WriteLine($"[Core] done! {rippleSpace.Planes.Count} plane{(rippleSpace.Planes.Count != 1?"s":"")} loaded in {msTaken}ms.");

            return(rippleSpace);
        }
        /// <summary>
        /// Creates a new plane, adds it to this RippleSpaceManager, and then returns it.
        /// </summary>
        /// <param name="newPlaneInfo">The settings for the new plane to create.</param>
        /// <returns>The newly created plane.</returns>
        public Plane CreatePlane(PlaneInfo newPlaneInfo)
        {
            if (this[newPlaneInfo.Name] != null)
            {
                throw new InvalidOperationException($"Error: A plane with the name '{newPlaneInfo.Name}' already exists in this RippleSpaceManager.");
            }

            Log.WriteLine("[RippleSpace] Creating plane {0}", newPlaneInfo.Name);

            Plane newPlane = new Plane(
                newPlaneInfo,
                CalcPaths.PlaneDirectory(SourceDirectory, newPlaneInfo.Name)
                );

            Planes.Add(newPlane);
            return(newPlane);
        }
Beispiel #4
0
        public NibriboardServer(string pathToRippleSpace, int inPort = 31586)
        {
            Port = inPort;

            // Load the specified ripple space if it exists - otherwise save it to disk
            if (Directory.Exists(pathToRippleSpace))
            {
                PlaneManager = RippleSpaceManager.FromDirectory(pathToRippleSpace).Result;
            }
            else
            {
                Log.WriteLine("[NibriboardServer] Couldn't find packed ripple space at {0} - creating new ripple space instead.", pathToRippleSpace);
                PlaneManager = new RippleSpace.RippleSpaceManager(pathToRippleSpace);
            }

            // Next, load the user account data
            string accountDataPath = CalcPaths.RippleSpaceAccountData(pathToRippleSpace);

            AccountManager = new UserManager();
            if (File.Exists(accountDataPath))
            {
                AccountManager.LoadUserDataFile(CalcPaths.RippleSpaceAccountData(pathToRippleSpace)).Wait();
            }


            clientSettings = new ClientSettings()
            {
                SecureWebSocket = false,
                WebSocketHost   = "192.168.0.56",
                WebSocketPort   = Port,
                WebSocketPath   = "/RipplespaceLink"
            };

            // HTTP / Websockets Server setup
            SBRL.GlidingSquirrel.Log.LoggingLevel = SBRL.GlidingSquirrel.LogLevel.Info;
            AppServer = new NibriboardApp(new NibriboardAppStartInfo()
            {
                FilePrefix     = "Nibriboard.obj.client_dist",
                ClientSettings = clientSettings,
                NibriServer    = this
            }, IPAddress.IPv6Any, Port);

            // Command Console Server setup
            CommandServer = new CommandConsoleServer(this, CommandPort);
        }
Beispiel #5
0
        /// <summary>
        /// Saves this plane to disk.
        /// Note that this only affects currently loaded chunks and the plane's metadata.
        /// Unloaded chunks are already persisted on disk, so they don't need saving.
        /// </summary>
        /// <param name="savingMode">
        /// What to save to disk. By default both the metatdata and the loaded chunks are
        /// saved, but this behaviour can be controlled via this argument.
        /// </param>
        /// <returns>The total number of bytes written to disk.</returns>
        public async Task <long> Save(PlaneSavingMode savingMode = PlaneSavingMode.All)
        {
            // Create the storage directory on disk if required
            Directory.CreateDirectory(StorageDirectory);

            // For calculating the total number of bytes written
            long totalSize = 0;

            if (savingMode == PlaneSavingMode.All || savingMode == PlaneSavingMode.ChunkDataOnly)
            {
                // Save all the chunks to disk
                List <Task> chunkSavers = new List <Task>();
                foreach (KeyValuePair <ChunkReference, Chunk> loadedChunkItem in loadedChunkspace)
                {
                    // Figure out where to put the chunk and create the relevant directories
                    string chunkDestinationFilename = CalcPaths.ChunkFilePath(StorageDirectory, loadedChunkItem.Key);
                    Directory.CreateDirectory(Path.GetDirectoryName(chunkDestinationFilename));

                    // Ask the chunk to save itself, but only if it isn't empty
                    if (loadedChunkItem.Value.IsEmpty)
                    {
                        // Delete the existing chunk file, if it exists
                        if (File.Exists(chunkDestinationFilename))
                        {
                            File.Delete(chunkDestinationFilename);
                        }

                        continue;
                    }

                    Stream chunkDestination = File.Open(chunkDestinationFilename, FileMode.OpenOrCreate);
                    chunkSavers.Add(loadedChunkItem.Value.SaveTo(chunkDestination));
                }
                await Task.WhenAll(chunkSavers);

                // Calculate the number of bytes written
                foreach (KeyValuePair <ChunkReference, Chunk> loadedChunkItem in loadedChunkspace)
                {
                    string destFilename = CalcPaths.ChunkFilePath(StorageDirectory, loadedChunkItem.Key);
                    if (!File.Exists(destFilename))                     // Don't assume that the file exists - it might be an empty chunk
                    {
                        continue;
                    }
                    totalSize += (new FileInfo(destFilename)).Length;
                }
            }

            if (savingMode == PlaneSavingMode.All || savingMode == PlaneSavingMode.MetadataOnly)
            {
                // Save the plane information
                string       planeIndexPath  = CalcPaths.PlaneIndex(StorageDirectory);
                StreamWriter planeInfoWriter = new StreamWriter(planeIndexPath);
                await planeInfoWriter.WriteLineAsync(JsonConvert.SerializeObject(Info));

                planeInfoWriter.Close();

                totalSize += (new FileInfo(planeIndexPath)).Length;
            }


            return(totalSize);
        }
Beispiel #6
0
 public async Task SaveUserData()
 {
     await AccountManager.SaveUserDataFile(
         CalcPaths.RippleSpaceAccountData(PlaneManager.SourceDirectory)
         );
 }