private void RestoreFile()
        {
            var  fileName = Path.Combine(Core.Instance.Config.RestoreDirectory, _fileEntry.FileName);
            bool success;

            using (var file = File.OpenWrite(fileName))
            {
                var          chunkNo = 0;
                ChunkMessage chunk   = null;

                do
                {
                    success = true;
                    for (int retryCount = 0; retryCount < MaxEntries; retryCount++)
                    {
                        var restoreChunkProtocol =
                            new EnhancedRestoreChunkProtocol(new FileChunk(_fileEntry.GetFileId(), chunkNo));
                        restoreChunkProtocol.Run().Wait();
                        chunk = restoreChunkProtocol.Message;
                        if (chunk != null && chunk.Body != null && chunk.Body.Length > 0)
                        {
                            file.Write(chunk.Body, 0, chunk.Body.Length);
                            break;
                        }

                        if (retryCount == MaxEntries - 1)
                        {
                            success = false;
                        }
                    }

                    if (!success)
                    {
                        break;
                    }

                    ++chunkNo;
                } while (chunk != null && chunk.Body != null && chunk.Body.Length == Core.Instance.Config.ChunkSize);
            }

            if (success)
            {
                Core.Instance.Log.InfoFormat("EnhancedRestoreFileProtocol: file '{0}' was sucessfuly restored",
                                             _fileEntry.FileName);
            }
            else
            {
                Core.Instance.Log.ErrorFormat("EnhancedRestoreFileProtocol: file '{0}' restore failed",
                                              _fileEntry.FileName);
                try
                {
                    File.Delete(fileName);
                }
                // ReSharper disable once EmptyGeneralCatchClause
                catch (Exception ex)
                {
                    Core.Instance.Log.ErrorFormat("EnhancedRestoreFileProtocol: delete ex", ex);
                }
            }
        }
예제 #2
0
        public List <ChunkMessage> GetConversationMessagesPerChunk(List <ConversationMessageDocument> messages)
        {
            // siempre debe de traer al menos el chunck del dia actual
            List <ChunkMessage> chunks = new List <ChunkMessage>();

            try
            {
                List <List <ConversationMessageDocument> > messagesOrderByDate = GetMessagesOrdeByDistinctDay(messages);
                foreach (var messageByDate in messagesOrderByDate)
                {
                    if (messageByDate.Count > 0)
                    {
                        ChunkMessage chunk = new ChunkMessage
                        {
                            Messages         = messageByDate,
                            DateConversation = DateTime.Parse(messageByDate[0].MessageTime),
                            HeadingDate      = CalculateHeadingDate(DateTime.Parse(messageByDate[0].MessageTime)),
                            ElementToAttach  = CalculateElementToAttach(DateTime.Parse(messageByDate[0].MessageTime))
                        };

                        chunks.Add(chunk);
                    }
                }
                ValidateCurrentChunk(ref chunks);
                chunks.OrderByDescending(x => x.DateConversation);
            }
            catch (Exception e)
            {
                var messageException = telemetria.MakeMessageException(e, System.Reflection.MethodBase.GetCurrentMethod().Name);
                telemetria.Critical(messageException);
            }
            return(chunks);
        }
예제 #3
0
 //called on the client when a chunk is recieved from the server
 public Chunk recieveChunk(ChunkMessage message)
 {
     message.chunk.valid = true;
     if (NetworkServer.active)
     {
         //host mode, don't overrwrite the gameobjects if they already exist.
         return(loadedChunks.AddOrUpdate(message.chunk.chunkCoords, message.chunk, (key, old) =>
         {
             if (message.chunk.solidObject == null)
             {
                 message.chunk.solidObject = old.solidObject;
             }
             if (message.chunk.transparentObject == null)
             {
                 message.chunk.transparentObject = old.transparentObject;
             }
             return message.chunk;
         }));
     }
     else
     {
         //this conserves the chunk object if it's already loaded. The animation won't play and you won't get a new object from the pool.
         return(loadedChunks.AddOrUpdate(message.chunk.chunkCoords, message.chunk, (key, old) =>
         {
             message.chunk.solidObject = old.solidObject;
             message.chunk.transparentObject = old.transparentObject;
             return message.chunk;
         }));
     }
 }
 static bool Prefix(CombatHUDRetreatEscMenu __instance) {
   if (MissionControl.Instance.AllowMissionControl() && MissionControl.Instance.IsDynamicWithdrawAllowed()) {
     Main.LogDebug("[CombatHUDRetreatEscMenuOnRetreatConfirmedPatch] Sending Dynamic Withdraw Trigger Message");
     ChunkMessage triggerDynamicWithdrawMessage = new ChunkMessage(ChunkLogic.DYNAMIC_WITHDRAW_CHUNK_GUID);
     UnityGameInstance.Instance.Game.Combat.MessageCenter.PublishMessage(triggerDynamicWithdrawMessage);
     AccessTools.Method(typeof(CombatHUDRetreatEscMenu), "OnRetreatCancelled").Invoke(__instance, null);
     if (!Main.Settings.DynamicWithdraw.DisorderlyWithdrawalCompatibility) return false;
   }
   return true;
 }
예제 #5
0
        public override bool Evaluate(MessageCenterMessage message, string responseName)
        {
            base.Evaluate(message, responseName);
            ChunkMessage chunkMessage = message as ChunkMessage;

            Main.LogDebug("[ChunkMatchesChunkGuidConditional] Evaluating...");

            if (chunkMessage != null && chunkMessage.ChunkGuid == this.ChunkGuid)
            {
                base.LogEvaluationPassed("Chunk matches guid of message.", responseName);
                return(true);
            }
            base.LogEvaluationFailed("Chunk did NOT match guid of message.", responseName);
            return(false);
        }
예제 #6
0
        public void ValidateCurrentChunk(ref List <ChunkMessage> chunks)
        {
            DateTime time = DateTime.UtcNow;

            if (chunks.Count() == 0)
            {
                ChunkMessage chunk = new ChunkMessage
                {
                    Messages         = new List <ConversationMessageDocument>(),
                    DateConversation = time,
                    HeadingDate      = CalculateHeadingDate(time),
                    ElementToAttach  = CalculateElementToAttach(time)
                };
                chunks.Add(chunk);
            }
        }
        private void SendGetChunk()
        {
            int  timeout = 1000;
            bool timedOut;
            int  retry = 0;

            do
            {
                timedOut = false;
                Core.Instance.MCChannel.Send(new GetChunkMessage(_fileChunk));

                try
                {
                    // wait for response
                    Message = Core.Instance.MDRChannel.Received
                              .Where(message => message.MessageType == MessageType.Chunk)
                              .Cast <ChunkMessage>()
                              .Where(message => message.ChunkNo == _fileChunk.ChunkNo &&
                                     message.FileId == _fileChunk.FileId)
                              .Timeout(TimeSpan.FromMilliseconds(timeout))
                              .Next().First();
                }
                catch (TimeoutException)
                {
                    timedOut = true;
                    ++retry;
                    timeout *= 2;
                    Core.Instance.Log.ErrorFormat(
                        "RestoreChunkSubprotocol: Could not fetch {0} from the network. Retrying.",
                        _fileChunk);
                }
            } while (timedOut && retry < MaxRetries);

            if (timedOut)
            {
                Core.Instance.Log.ErrorFormat(
                    "RestoreChunkSubprotocol: Could not fetch {0} from the network. Giving up.",
                    _fileChunk);
            }
        }
예제 #8
0
        public void OnNext(GetChunkMessage msg)
        {
            var fileChunk = new FileChunk(msg.FileId, msg.ChunkNo);

            if (!fileChunk.Exists())
            {
                // we were supposed to have this chunk: send removed message and remove the entry in the local count
                if (Core.Instance.ChunkPeers.HasChunkPeer(fileChunk, false))
                {
                    Core.Instance.MCChannel.Send(new RemovedMessage(fileChunk));
                }
                return;
            }

            try
            {
                var chunkReceived = false;
                var disposable    = Core.Instance.MDRChannel.Received
                                    .Where(message => message.MessageType == MessageType.Chunk)
                                    .Cast <ChunkMessage>()
                                    .Where(message => message.ChunkNo == msg.ChunkNo &&
                                           message.FileId == msg.FileId)
                                    .Subscribe(_ => chunkReceived = true);

                Task.Delay(Core.Instance.RandomDelay).Wait();
                disposable.Dispose();

                if (!chunkReceived)
                {
                    var data     = fileChunk.GetData();
                    var chunkMsg = new ChunkMessage(fileChunk, data);
                    Core.Instance.MDRChannel.Send(chunkMsg);
                }
            }
            catch (Exception ex)
            {
                Core.Instance.Log.Error("RestoreChunkService", ex);
            }
        }
예제 #9
0
 public void OnChunkRecieved(ChunkMessage message)
 {
     if (message.chunk != null)
     {
         MeshGenerator.queueChunk(world.recieveChunk(message), world);
         //we have to remesh the neighbors as well. all chunks on client are valid, but we check since we could be in host mode.
         if (world.loadedChunks.TryGetValue(message.chunkPos + new Vector3Int(1, 0, 0), out Chunk chunk))
         {
             MeshGenerator.queueChunk(chunk, world);
         }
         if (world.loadedChunks.TryGetValue(message.chunkPos + new Vector3Int(-1, 0, 0), out chunk))
         {
             MeshGenerator.queueChunk(chunk, world);
         }
         if (world.loadedChunks.TryGetValue(message.chunkPos + new Vector3Int(0, 1, 0), out chunk))
         {
             MeshGenerator.queueChunk(chunk, world);
         }
         if (world.loadedChunks.TryGetValue(message.chunkPos + new Vector3Int(0, -1, 0), out chunk))
         {
             MeshGenerator.queueChunk(chunk, world);
         }
         if (world.loadedChunks.TryGetValue(message.chunkPos + new Vector3Int(0, 0, 1), out chunk))
         {
             MeshGenerator.queueChunk(chunk, world);
         }
         if (world.loadedChunks.TryGetValue(message.chunkPos + new Vector3Int(0, 0, -1), out chunk))
         {
             MeshGenerator.queueChunk(chunk, world);
         }
     }
     else if (message.willFulfill && !requestedChunks.Contains(message.chunkPos))
     {
         //re-request the chunk. means that the server is generating it or something
         requestedChunks.Add(message.chunkPos);
     }
 }
예제 #10
0
        public void TestMessageFieldUpperBounds()
        {
            var body = new byte[255];

            for (var i = 0; i < body.Length; ++i)
            {
                body[i] = (byte)i;
            }

            var getChunkMsg  = new GetChunkMessage(9, 9, FileId1, 999999);
            var bytes        = getChunkMsg.Serialize();
            var getChunkMsg2 = Message.Deserialize(bytes) as GetChunkMessage;

            Assert.IsNotNull(getChunkMsg2);
            Assert.AreEqual(getChunkMsg.MessageType, getChunkMsg2.MessageType);
            Assert.AreEqual(getChunkMsg.VersionM, getChunkMsg2.VersionM);
            Assert.AreEqual(getChunkMsg.VersionN, getChunkMsg2.VersionN);
            Assert.AreEqual(getChunkMsg.FileId, getChunkMsg2.FileId);
            Assert.AreEqual(getChunkMsg.ChunkNo, getChunkMsg2.ChunkNo);

            var chunkMsg = new ChunkMessage(9, 9, FileId1, 999999, body);

            bytes = chunkMsg.Serialize();
            var chunkMsg2 = Message.Deserialize(bytes) as ChunkMessage;

            Assert.IsNotNull(chunkMsg2);
            Assert.AreEqual(chunkMsg.MessageType, chunkMsg2.MessageType);
            Assert.AreEqual(chunkMsg.VersionM, chunkMsg2.VersionM);
            Assert.AreEqual(chunkMsg.VersionN, chunkMsg2.VersionN);
            Assert.AreEqual(chunkMsg.FileId, chunkMsg2.FileId);
            Assert.AreEqual(chunkMsg.ChunkNo, chunkMsg2.ChunkNo);
            CollectionAssert.AreEqual(chunkMsg.Body, chunkMsg2.Body);

            var putChunkMsg = new PutChunkMessage(9, 9, FileId1, 999999, 9, body);

            bytes = putChunkMsg.Serialize();
            var putChunkMsg2 = Message.Deserialize(bytes) as PutChunkMessage;

            Assert.IsNotNull(putChunkMsg2);
            Assert.AreEqual(putChunkMsg.MessageType, putChunkMsg2.MessageType);
            Assert.AreEqual(putChunkMsg.VersionM, putChunkMsg2.VersionM);
            Assert.AreEqual(putChunkMsg.VersionN, putChunkMsg2.VersionN);
            Assert.AreEqual(putChunkMsg.FileId, putChunkMsg2.FileId);
            Assert.AreEqual(putChunkMsg.ChunkNo, putChunkMsg2.ChunkNo);
            Assert.AreEqual(putChunkMsg.ReplicationDeg, putChunkMsg2.ReplicationDeg);
            CollectionAssert.AreEqual(putChunkMsg.Body, putChunkMsg2.Body);

            var storedMsg = new StoredMessage(9, 9, FileId1, 999999);

            bytes = storedMsg.Serialize();
            var storedMsg2 = Message.Deserialize(bytes) as StoredMessage;

            Assert.IsNotNull(storedMsg2);
            Assert.AreEqual(storedMsg.MessageType, storedMsg2.MessageType);
            Assert.AreEqual(storedMsg.VersionM, storedMsg2.VersionM);
            Assert.AreEqual(storedMsg.VersionN, storedMsg2.VersionN);
            Assert.AreEqual(storedMsg.FileId, storedMsg2.FileId);
            Assert.AreEqual(storedMsg.ChunkNo, storedMsg2.ChunkNo);

            var deleteMsg = new DeleteMessage(FileId1);

            bytes = deleteMsg.Serialize();
            var deleteMsg2 = Message.Deserialize(bytes) as DeleteMessage;

            Assert.IsNotNull(deleteMsg2);
            Assert.AreEqual(deleteMsg.MessageType, deleteMsg2.MessageType);

            var removedMsg = new RemovedMessage(9, 9, FileId1, 999999);

            bytes = removedMsg.Serialize();
            var removedMsg2 = Message.Deserialize(bytes) as RemovedMessage;

            Assert.IsNotNull(removedMsg2);
            Assert.AreEqual(removedMsg.MessageType, removedMsg2.MessageType);
            Assert.AreEqual(removedMsg.VersionM, removedMsg2.VersionM);
            Assert.AreEqual(removedMsg.VersionN, removedMsg2.VersionN);
            Assert.AreEqual(removedMsg.FileId, removedMsg2.FileId);
            Assert.AreEqual(removedMsg.ChunkNo, removedMsg2.ChunkNo);

            var lookupMsg = new LookupMessage(9, 9, FileId1);

            bytes = lookupMsg.Serialize();
            var lookupMsg2 = Message.Deserialize(bytes) as LookupMessage;

            Assert.IsNotNull(lookupMsg2);
            Assert.AreEqual(lookupMsg.MessageType, lookupMsg2.MessageType);
            Assert.AreEqual(lookupMsg.VersionM, lookupMsg2.VersionM);
            Assert.AreEqual(lookupMsg.VersionN, lookupMsg2.VersionN);
            Assert.AreEqual(lookupMsg.FileId, lookupMsg2.FileId);

            var gotMsg = new GotMessage(9, 9, FileId1);

            bytes = gotMsg.Serialize();
            var gotMsg2 = Message.Deserialize(bytes) as GotMessage;

            Assert.IsNotNull(gotMsg2);
            Assert.AreEqual(gotMsg.MessageType, gotMsg2.MessageType);
            Assert.AreEqual(gotMsg.VersionM, gotMsg2.VersionM);
            Assert.AreEqual(gotMsg.VersionN, gotMsg2.VersionN);
            Assert.AreEqual(gotMsg.FileId, gotMsg2.FileId);

            var ackMsg = new ACKMessage(9, 9, FileId1, 999999);

            bytes = ackMsg.Serialize();
            var ackMsg2 = Message.Deserialize(bytes) as ACKMessage;

            Assert.IsNotNull(ackMsg2);
            Assert.AreEqual(ackMsg.MessageType, ackMsg2.MessageType);
            Assert.AreEqual(ackMsg.VersionM, ackMsg2.VersionM);
            Assert.AreEqual(ackMsg.VersionN, ackMsg2.VersionN);
            Assert.AreEqual(ackMsg.FileId, ackMsg2.FileId);
            Assert.AreEqual(ackMsg.ChunkNo, ackMsg2.ChunkNo);
        }
예제 #11
0
 public void AddWarning(long X, long Y, string msg, FixChunkDelegate FixMethod)
 {
     ChunkMessage cm = new ChunkMessage(ChunkMessageType.WARNING, X, Y, msg, FixMethod);
     Messages.Add(cm);
 }
예제 #12
0
 public void AddInfo(long X, long Y, string msg, FixChunkDelegate FixMethod)
 {
     ChunkMessage cm = new ChunkMessage(ChunkMessageType.INFO, X, Y, msg, FixMethod);
     Messages.Add(cm);
 }
예제 #13
0
 public void AddError(long X, long Y, string msg, FixChunkDelegate FixMethod)
 {
     ChunkMessage cm = new ChunkMessage(ChunkMessageType.ERROR, X, Y, msg, FixMethod);
     Messages.Add(cm);
 }
        public Task Run()
        {
            Core.Instance.Log.InfoFormat("Starting EnhancedRestoreChunkProtocol: {0}", _fileChunk);
            return(Task.Factory.StartNew(() =>
            {
                Core.Instance.MCChannel.Send(new GetChunkMessage(_fileChunk));

                var src1 = Core.Instance.MDRChannel.Received
                           .Where(message => message.MessageType == MessageType.Chunk)
                           .Cast <ChunkMessage>()
                           .Where(message => message.ChunkNo == _fileChunk.ChunkNo &&
                                  message.FileId == _fileChunk.FileId)
                           .Cast <Message>();

                var src2 = Core.Instance.MDRChannel.Received
                           .Where(message => message.MessageType == MessageType.ACK)
                           .Cast <ACKMessage>()
                           .Where(message => message.ChunkNo == _fileChunk.ChunkNo &&
                                  message.FileId == _fileChunk.FileId)
                           .Cast <Message>();

                Message msg;
                try
                {
                    // wait for response
                    msg = src1.Merge(src2).Timeout(TimeSpan.FromMilliseconds(Timeout))
                          .Next().First();
                }
                catch (TimeoutException)
                {
                    Core.Instance.Log.ErrorFormat("EnhancedRestoreChunkProtocol: Could not fetch {0} from the network (timeout).", _fileChunk);
                    return;
                }

                if (msg.MessageType == MessageType.Chunk) // same behaviour as the regular protocol
                {
                    Message = msg as ChunkMessage;
                    return;
                }

                var ackMessage = msg as ACKMessage;
                if (ackMessage == null)
                {
                    Core.Instance.Log.ErrorFormat("EnhancedRestoreChunkProtocol: could not cast message {0} to ACK", msg);
                    return;
                }

                var listener = new TcpListener(IPAddress.Any, 0);
                listener.Start();

                Core.Instance.MCChannel.Send(new ConnInfoMessage(_fileChunk, ((IPEndPoint)listener.LocalEndpoint).Port,
                                                                 ackMessage.RemoteEndPoint.Address));

                var clientTask = listener.AcceptTcpClientAsync();
                if (!clientTask.Wait(Timeout))
                {
                    Core.Instance.Log.Error("EnhancedRestoreChunkProtocol: listener.AcceptTcpClientAsync timed out");
                    return;
                }

                Core.Instance.Log.Info("EnhancedRestoreChunkProtocol: TcpClient accepted");
                try
                {
                    var stream = clientTask.Result.GetStream();
                    var bytes = new byte[Core.Instance.Config.ChunkSize];
                    var bytesRead = stream.Read(bytes, 0, bytes.Length);
                    Message = new ChunkMessage(_fileChunk, bytes.Take(bytesRead).ToArray());
                    clientTask.Result.Close();
                }
                catch (Exception)
                {
                    Core.Instance.Log.Error("EnhancedRestoreChunkProtocol: error receiving chunk");
                }

                Core.Instance.Log.Info("EnhancedRestoreChunkProtocol: chunk was received with success");
            }));
        }