Ejemplo n.º 1
0
// Only use is internal, but let those parameters be available
Action* Replay::GetAction()
{
  ASSERT(!is_recorder && replay_state == PLAYING);

  // Does it contain the 2 elements needed to decode at least
  // action header?
  if (MemUsed() > bufsize-sizeof(Action::Header)) {
    return NULL;
  }

  // Read action
  Action *a = new Action((char*)ptr, NULL);
  Action::Action_t type = a->GetType();
  if (type > Action::ACTION_TIME_VERIFY_SYNC) {
    Error(Format(_("Malformed replay: action with unknow type %08X"), type));
    StopPlaying();
    return NULL;
  }

  // Move pointer
  uint size = a->GetSize();
  if (MemUsed() > bufsize-size) {
    Error(Format(_("Malformed replay: action with datasize=%u"), size));
    StopPlaying();
    return NULL;
  }
  ptr += size;

  MSG_DEBUG("replay", "Read action %s: type=%u length=%i frameless=%i\n",
            ActionHandler::GetActionName(type).c_str(), type, size, a->IsFrameLess());

  return a;
}
Ejemplo n.º 2
0
void LuaInterface::GC()
{
    unsigned int before = MemUsed();
    lua_gc(_lua, LUA_GCCOLLECT, 0);
    unsigned int after = MemUsed();
    logdebug("GC: before: %u KB, after: %u KB", before, after);
}
Ejemplo n.º 3
0
bool Replay::SaveReplay(const std::string& name, const char *comment)
{
  ASSERT(is_recorder);

  FILE *out;
#ifdef _WIN32 // Only case where is_wide is true
  out = _wfopen((wchar_t*)name.c_str(), L"wb");
#else
  out = fopen(name.c_str(), "wb");
#endif
  if (!out)
    return false;

  // Generate replay info and dump it to file
  uint32_t total_time = old_time - start_time;
  ReplayInfo *info = ReplayInfo::ReplayInfoFromCurrent(total_time, comment);
  if (!info->DumpToFile(out)) {
    delete info;
    return false;
  }
  delete info;

  // Save seed
  Write32(out, seed);

  // Flush actions recorded
#ifdef WMX_LOG
  uint32_t pos = ftell(out);
  MSG_DEBUG("replay", "Actions stored at %u on %u bytes in %s, seed %08X\n",
            pos, MemUsed(), name.c_str(), seed);
#endif

  fwrite(buf, 1, MemUsed(), out);
  if (count) {
    count--;
    MSG_DEBUG("replay", "Storing final calculate frames: %u\n", count);
    Write32(out, count);
  }

  bool good = !ferror(out);
  fclose(out);

  // should maybe return length actually written
  return good;
}
Ejemplo n.º 4
0
void Replay::ChangeBufsize(uint32_t n)
{
  if (n <= bufsize)
    return;

  // All data is supposed to be consumed
  uint32_t offset = (bufsize) ? MemUsed() : 0;
  buf = (uint8_t*)realloc(buf, n);
  bufsize = n;
  ptr = buf + offset;
}
Ejemplo n.º 5
0
// The Replay packet header:
// u32: time (ms => 2^16=65s => u16 sufficient)
// Packet is directly an action:
//   . u32 => type
//   . u32 => length
//   . data
void Replay::StoreAction(const Action* a)
{
  uint          size;

  ASSERT(is_recorder && replay_state==RECORDING);

  Action::Action_t type = a->GetType();
  if ((type!=Action::ACTION_CHAT_INGAME_MESSAGE && a->IsFrameLess()) ||
      type == Action::ACTION_NETWORK_PING ||
      type == Action::ACTION_NETWORK_VERIFY_RANDOM_SYNC ||
      type == Action::ACTION_TIME_VERIFY_SYNC ||
      type == Action::ACTION_RULES_SET_GAME_MODE)
    return;

  // Special case to convert into local packet
  if (type == Action::ACTION_REQUEST_BONUS_BOX_DROP) {
    // The timestamp shouldn't have moved
    Action a(Action::ACTION_DROP_BONUS_BOX);
    StoreAction(&a);
    return;
  }

  size = a->GetSize();
  // Enlarge buffer if it can't contain max packet size
  if (MemUsed() > bufsize - size + 2)
    ChangeBufsize(bufsize+30000);

  if (type != Action::ACTION_GAME_CALCULATE_FRAME) {
    if (count) {
      count--;
      MSG_DEBUG("replay", "Calculate frame repeated %u\n", count);
      // 16 bits is sufficient, around 22 minutes without other actions
      SDLNet_Write16(count, ptr); ptr += 2;
    }
    MSG_DEBUG("replay", "Storing action %s: type=%i length=%i\n",
              ActionHandler::GetActionName(type).c_str(), type, size);
    a->Write((char*)ptr);
    ptr += size;
    count = 0;
  } else {
    if (!count) {
      // Packet body
      a->Write((char*)ptr);
      ptr += size;
    }
    count++;
  }

  // Check time
  if (start_time == 0)
    start_time = GameTime::GetInstance()->Read();
  else
    old_time = GameTime::GetInstance()->Read();
}