Example #1
0
void C4Network2IRCClient::PackPacket(const C4NetIOPacket &rPacket, StdBuf &rOutBuf)
	{
	// Enlarge buffer
	int iSize = rPacket.getSize(),
			iPos = rOutBuf.getSize();
	rOutBuf.Grow(iSize + 2);
	// Write packet
	rOutBuf.Write(rPacket, iPos);
	// Terminate
	uint8_t *pPos = getMBufPtr<uint8_t>(rOutBuf, iPos + iSize);
	*pPos = '\r'; *(pPos + 1) = '\n';
	}
Example #2
0
StdBuf C4Playback::ReWriteBinary() {
  const int OUTPUT_GROW = 16 * 1024;
  StdBuf Output;
  int iPos = 0;
  bool fFinished = false;
  uint32_t iFrame = 0;
  for (chunks_t::const_iterator i = chunks.begin();
       !fFinished && i != chunks.end(); i++) {
    // Check frame difference
    if (i->Frame - iFrame < 0 || i->Frame - iFrame > 0xff)
      LogF(
          "ERROR: Invalid frame difference between chunks (0-255 allowed)! "
          "Data will be invalid!");
    // Pack data
    StdBuf Chunk;
    try {
      switch (i->Type) {
        case RCT_Ctrl:
          Chunk = DecompileToBuf<StdCompilerBinWrite>(*i->pCtrl);
          break;
        case RCT_CtrlPkt:
          Chunk = DecompileToBuf<StdCompilerBinWrite>(*i->pPkt);
          break;
        case RCT_End:
          fFinished = true;
          break;
        default:  // debugrec
          if (i->pDbg) Chunk = DecompileToBuf<StdCompilerBinWrite>(*i->pDbg);
          break;
      }
    } catch (StdCompiler::Exception *pEx) {
      LogF("Record: Binary unpack error: %s", pEx->Msg.getData());
      delete pEx;
      return StdBuf();
    }
    // Grow output
    while (Output.getSize() - iPos <
           sizeof(C4RecordChunkHead) + Chunk.getSize())
      Output.Grow(OUTPUT_GROW);
    // Write header
    C4RecordChunkHead *pHead = getMBufPtr<C4RecordChunkHead>(Output, iPos);
    pHead->Type = i->Type;
    pHead->iFrm = i->Frame - iFrame;
    iPos += sizeof(C4RecordChunkHead);
    iFrame = i->Frame;
    // Write chunk
    Output.Write(Chunk, iPos);
    iPos += Chunk.getSize();
  }
  Output.SetSize(iPos);
  return Output;
}
Example #3
0
bool C4Playback::StreamToRecord(const char *szStream, StdStrBuf *pRecordFile) {
  // Load data
  StdBuf CompressedData;
  Log("Reading stream...");
  if (!CompressedData.LoadFromFile(szStream)) return false;

  // Decompress
  unsigned long iStreamSize = CompressedData.getSize() * 5;
  StdBuf StreamData;
  StreamData.New(iStreamSize);
  while (true) {
    // Initialize stream
    z_stream strm;
    ZeroMem(&strm, sizeof strm);
    strm.next_in = getMBufPtr<BYTE>(CompressedData);
    strm.avail_in = CompressedData.getSize();
    strm.next_out = getMBufPtr<BYTE>(StreamData);
    strm.avail_out = StreamData.getSize();

    // Decompress
    if (inflateInit(&strm) != Z_OK) return false;
    int ret = inflate(&strm, Z_FINISH);
    if (ret == Z_STREAM_END) {
      inflateEnd(&strm);
      break;
    }
    if (ret != Z_BUF_ERROR) return false;

    // All input consumed?
    iStreamSize = strm.total_out;
    if (strm.avail_in == 0) {
      Log("Stream data incomplete, using as much data as possible");
      break;
    }

    // Larger buffer needed
    StreamData.Grow(CompressedData.getSize());
    iStreamSize = StreamData.getSize();
  }
  StreamData.SetSize(iStreamSize);

  // Parse
  C4Playback Playback;
  Playback.ReadBinary(StreamData);
  LogF("Got %d chunks from stream", Playback.chunks.size());

  // Get first chunk, which must contain the initial
  chunks_t::iterator chunkIter = Playback.chunks.begin();
  if (chunkIter == Playback.chunks.end() || chunkIter->Type != RCT_File)
    return false;

  // Get initial chunk, go over file name
  StdBuf InitialData = *chunkIter->pFileData;
  const char *szInitialFilename = chunkIter->Filename.getData();

  // Put to temporary file and unpack
  char szInitial[_MAX_PATH + 1] = "~initial.tmp";
  MakeTempFilename(szInitial);
  if (!InitialData.SaveToFile(szInitial) || !C4Group_UnpackDirectory(szInitial))
    return false;

  // Load Scenario.txt from Initial
  C4Group Grp;
  C4Scenario Initial;
  if (!Grp.Open(szInitial) || !Initial.Load(Grp) || !Grp.Close()) return false;

  // Copy original scenario
  const char *szOrigin = Initial.Head.Origin.getData();
  char szRecord[_MAX_PATH + 1];
  SCopy(szStream, szRecord, _MAX_PATH);
  if (GetExtension(szRecord)) *(GetExtension(szRecord) - 1) = 0;
  SAppend(".c4s", szRecord, _MAX_PATH);
  LogF("Original scenario is %s, creating %s.", szOrigin, szRecord);
  if (!C4Group_CopyItem(szOrigin, szRecord, false, false)) return false;

  // Merge initial
  if (!Grp.Open(szRecord) || !Grp.Merge(szInitial)) return false;

  // Process other files in stream
  chunkIter->Delete();
  chunkIter = Playback.chunks.erase(chunkIter);
  while (chunkIter != Playback.chunks.end())
    if (chunkIter->Type == RCT_File) {
      LogF("Inserting %s...", chunkIter->Filename.getData());
      StdStrBuf Temp;
      Temp.Copy(chunkIter->Filename);
      MakeTempFilename(&Temp);
      if (!chunkIter->pFileData->SaveToFile(Temp.getData())) return false;
      if (!Grp.Move(Temp.getData(), chunkIter->Filename.getData()))
        return false;
      chunkIter = Playback.chunks.erase(chunkIter);
    } else
      chunkIter++;

  // Write record data
  StdBuf RecordData = Playback.ReWriteBinary();
  if (!Grp.Add(C4CFN_CtrlRec, RecordData, false, true)) return false;

  // Done
  Log("Writing record file...");
  Grp.Close();
  pRecordFile->Copy(szRecord);
  return true;
}