static bool CreateDemoFileSplit(udtVMLinearAllocator& tempAllocator, udtContext& context, udtStream& file, const char* filePath, const char* outputFolderPath, u32 index, u32 startOffset, u32 endOffset) { if(endOffset <= startOffset) { return false; } if(file.Seek((s32)startOffset, udtSeekOrigin::Start) != 0) { return false; } const udtProtocol::Id protocol = udtGetProtocolByFilePath(filePath); if(protocol == udtProtocol::Invalid) { return false; } udtVMScopedStackAllocator scopedTempAllocator(tempAllocator); const udtString filePathString = udtString::NewConstRef(filePath); udtString fileName; if(!udtPath::GetFileNameWithoutExtension(fileName, tempAllocator, filePathString)) { fileName = udtString::NewConstRef("NEW_UDT_SPLIT_DEMO"); } udtString outputFilePathStart; if(outputFolderPath == NULL) { udtString inputFolderPath; udtPath::GetFolderPath(inputFolderPath, tempAllocator, filePathString); udtPath::Combine(outputFilePathStart, tempAllocator, inputFolderPath, fileName); } else { udtPath::Combine(outputFilePathStart, tempAllocator, udtString::NewConstRef(outputFolderPath), fileName); } char* newFilePath = AllocateSpaceForString(tempAllocator, UDT_MAX_PATH_LENGTH); sprintf(newFilePath, "%s_SPLIT_%u%s", outputFilePathStart.String, index + 1, udtGetFileExtensionByProtocol(protocol)); context.LogInfo("Writing demo %s...", newFilePath); udtFileStream outputFile; if(!outputFile.Open(newFilePath, udtFileOpenMode::Write)) { context.LogError("Could not open file"); return false; } const bool success = CopyFileRange(file, outputFile, tempAllocator, startOffset, endOffset); if(!success) { context.LogError("File copy failed"); } return success; }
bool udtBaseParser::ParseCommandString() { s32 commandStringLength = 0; const s32 commandSequence = _inMsg.ReadLong(); const char* const commandStringTemp = _inMsg.ReadString(commandStringLength); // Do we have it already? if(_inServerCommandSequence >= commandSequence) { // Yes, don't bother processing it. return true; } // Copy the string to some temporary location. udtVMScopedStackAllocator scopedTempAllocator(_tempAllocator); udtString commandString = udtString::NewClone(_tempAllocator, commandStringTemp, (u32)commandStringLength); // We haven't, so let's store the last sequence number received. _inServerCommandSequence = commandSequence; bool plugInSkipsThisCommand = false; tokenize: idTokenizer& tokenizer = _tokenizer; tokenizer.Tokenize(commandString.GetPtr()); const int tokenCount = tokenizer.GetArgCount(); const udtString commandName = (tokenCount > 0) ? tokenizer.GetArg(0) : udtString::NewEmptyConstant(); s32 csIndex = -1; bool isConfigString = false; if(tokenCount == 3 && udtString::Equals(commandName, "cs")) { if(StringParseInt(csIndex, tokenizer.GetArgString(1)) && csIndex >= 0 && csIndex < (s32)UDT_COUNT_OF(_inConfigStrings)) { isConfigString = true; const char* const csStringTemp = tokenizer.GetArgString(2); u32 csStringLength = (u32)strlen(csStringTemp); udtConfigStringConversion outCs; _protocolConverter->ConvertConfigString(outCs, _tempAllocator, csIndex, csStringTemp, csStringLength); if(outCs.NewString || outCs.Index != csIndex) { commandString = udtString::NewEmpty(_privateTempAllocator, 2 * BIG_INFO_STRING); sprintf(commandString.GetWritePtr(), "cs %d \"%s\"", outCs.Index, outCs.String.GetPtr()); commandStringLength = (s32)strlen(commandString.GetPtr()); csStringLength = outCs.String.GetLength(); } // Copy the config string to some safe location. _inConfigStrings[csIndex] = udtString::NewClone(_configStringAllocator, csStringTemp, csStringLength); } } else if(tokenCount == 3 && udtString::Equals(commandName, "bcs0")) { // Start a new big config string. sprintf(_inBigConfigString, "cs %s \"%s", tokenizer.GetArgString(1), tokenizer.GetArgString(2)); plugInSkipsThisCommand = true; } else if(tokenCount == 3 && udtString::Equals(commandName, "bcs1")) { // Append to current big config string. strcat(_inBigConfigString, tokenizer.GetArgString(2)); plugInSkipsThisCommand = true; } else if(tokenCount == 3 && udtString::Equals(commandName, "bcs2")) { // Append to current big config string and finalize it. strcat(_inBigConfigString, tokenizer.GetArgString(2)); strcat(_inBigConfigString, "\""); commandString = udtString::NewConstRef(_inBigConfigString); commandStringLength = (s32)strlen(_inBigConfigString); goto tokenize; } if(EnablePlugIns && !PlugIns.IsEmpty() && !plugInSkipsThisCommand) { udtCommandCallbackArg info; info.CommandSequence = commandSequence; info.String = commandString.GetPtr(); info.StringLength = commandStringLength; info.ConfigStringIndex = csIndex; info.IsConfigString = isConfigString; info.IsEmptyConfigString = isConfigString ? udtString::IsNullOrEmpty(tokenizer.GetArg(2)) : false; for(u32 i = 0, count = PlugIns.GetSize(); i < count; ++i) { PlugIns[i]->ProcessCommandMessage(info, *this); } } if(ShouldWriteMessage()) { if(csIndex >= 0 && commandStringLength >= MAX_STRING_CHARS) { WriteBigConfigStringCommand(tokenizer.GetArg(1), tokenizer.GetArg(2)); } else if(commandStringLength < MAX_STRING_CHARS) { _outMsg.WriteByte(svc_serverCommand); _outMsg.WriteLong(_outServerCommandSequence); _outMsg.WriteString(commandString.GetPtr(), commandStringLength); ++_outServerCommandSequence; } else { _outMsg.WriteByte(svc_nop); } } _privateTempAllocator.Clear(); return true; }