void StdCompilerINIRead::Raw(void *pData, size_t iSize, RawCompileType eType) { // Read data StdBuf Buf = ReadString(iSize, eType, false); // Correct size? if (Buf.getSize() != iSize) Warn("got %u bytes raw data, but %u bytes expected!", Buf.getSize(), iSize); // Copy MemCopy(Buf.getData(), pData, iSize); }
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; }
StdStrBuf GetDbgRecPktData(C4RecordChunkType eType, const StdBuf &RawData) { StdStrBuf r; switch (eType) { case RCT_AulFunc: r.Ref(reinterpret_cast<const char *>(RawData.getData()), RawData.getSize() - 1); break; default: for (int i = 0; i < RawData.getSize(); ++i) r.AppendFormat("%02x ", (uint32_t)((uint8_t *)RawData.getData())[i]); break; } return r; }
size_t C4Network2IRCClient::UnpackPacket(const StdBuf &rInBuf, const C4NetIO::addr_t &addr) { // Find line seperation const char *pSep = reinterpret_cast<const char *>(memchr(rInBuf.getData(), '\n', rInBuf.getSize())); if(!pSep) return 0; // Check if it's actually correct seperation (rarely the case) int iSize = pSep - getBufPtr<char>(rInBuf) + 1, iLength = iSize - 1; if(iLength && *(pSep - 1) == '\r') iLength--; // Copy the line StdStrBuf Buf; Buf.Copy(getBufPtr<char>(rInBuf), iLength); // Ignore prefix const char *pMsg = Buf.getData(); StdStrBuf Prefix; if(*pMsg == ':') { Prefix.CopyUntil(pMsg + 1, ' '); pMsg += Prefix.getLength() + 1; } // Strip whitespace while(*pMsg == ' ') pMsg++; // Ignore empty message if(!*pMsg) return iSize; // Get command StdStrBuf Cmd; Cmd.CopyUntil(pMsg, ' '); // Precess command const char *szParameters = SSearch(pMsg, " "); OnCommand(Prefix.getData(), Cmd.getData(), szParameters ? szParameters : ""); // Consume the line return iSize; }
size_t C4AulDebug::UnpackPacket(const StdBuf &rInBuf, const C4NetIO::addr_t &addr) { // Find line separation const char *pSep = reinterpret_cast<const char *>(memchr(rInBuf.getData(), '\n', rInBuf.getSize())); if (!pSep) return 0; // Check if it's windows-style separation int iSize = pSep - getBufPtr<char>(rInBuf) + 1, iLength = iSize - 1; if (iLength && *(pSep - 1) == '\r') iLength--; // Copy the line StdStrBuf Buf; Buf.Copy(getBufPtr<char>(rInBuf), iLength); // Password line? if (fConnected) { ProcessLineResult result = ProcessLine(Buf); // Send answer SendLine(result.okay ? "OK" : "ERR", result.answer.length() > 0 ? result.answer.c_str() : NULL); } else if (!Password.getSize() || Password == Buf) { fConnected = true; SendLine("HLO", "This is " C4ENGINECAPTION ", " C4VERSION); Log("C4Aul debugger connected successfully!"); } else C4NetIOTCP::Close(PeerAddr); // Consume line return iSize; }
void StdCompilerConfigWrite::WriteString(const char *szString) { // Append or set the value if (LastString.getLength()) LastString.Append(szString); else LastString.Copy(szString); StdBuf v = LastString.GetWideCharBuf(); if (RegSetValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(), 0, REG_SZ, getBufPtr<BYTE>(v), v.getSize()) != ERROR_SUCCESS) excCorrupt("Could not write key %s!", pKey->Name.getData()); }
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'; }
BOOL C4SoundEffect::Load(const char *szFileName, C4Group &hGroup, BOOL fStatic) { // Sound check if (!Config.Sound.RXSound) return FALSE; // Locate sound in file StdBuf WaveBuffer; if (!hGroup.LoadEntry(szFileName, WaveBuffer)) return FALSE; // load it from mem if (!Load((BYTE *)WaveBuffer.getData(), WaveBuffer.getSize(), fStatic)) return FALSE; // Set name SCopy(szFileName, Name, C4MaxSoundName); return TRUE; }
bool C4Record::Rec(int iFrame, const StdBuf &sBuf, C4RecordChunkType eType) { // filler chunks (this should never be necessary, though) while (iFrame > iLastFrame + 0xff) Rec(iLastFrame + 0xff, StdBuf(), RCT_Frame); // get frame difference uint32_t iFrameDiff = Max<uint32_t>(0, iFrame - iLastFrame); iLastFrame += iFrameDiff; // create head C4RecordChunkHead Head = {static_cast<uint8_t>(iFrameDiff), static_cast<uint8_t>(eType)}; // pack CtrlRec.Write(&Head, sizeof(Head)); CtrlRec.Write(sBuf.getData(), sBuf.getSize()); #ifdef IMMEDIATEREC // immediate rec: always flush CtrlRec.Flush(); #endif // Stream if (fStreaming) Stream(Head, sBuf); return true; }
bool SetRegistryString(const char *szSubKey, const char *szValueName, const char *szValue) { long qerr; HKEY ckey; DWORD disposition; // Open the key if ((qerr=RegCreateKeyExW(HKEY_CURRENT_USER, GetWideChar(szSubKey), 0, L"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &ckey, &disposition ))!=ERROR_SUCCESS) return false; // Set the value StdBuf v = GetWideCharBuf(szValue); if ((qerr=RegSetValueExW(ckey, GetWideChar(szValueName), 0, REG_SZ, getBufPtr<BYTE>(v), v.getSize() ))!=ERROR_SUCCESS) { RegCloseKey(ckey); return false; } // Close the key RegCloseKey(ckey); return true; }
void C4Record::Stream(const C4RecordChunkHead &Head, const StdBuf &sBuf) { if (!fStreaming) return; StreamingData.Append(&Head, sizeof(Head)); StreamingData.Append(sBuf.getData(), sBuf.getSize()); }
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; }