Add calculation of close-tangibles
This commit is contained in:
@@ -298,6 +298,11 @@ void SpookyHash::Hash128(
|
|||||||
uint64_t *hash1,
|
uint64_t *hash1,
|
||||||
uint64_t *hash2)
|
uint64_t *hash2)
|
||||||
{
|
{
|
||||||
|
if ((*hash1 == 0) && (*hash2 == 0)) {
|
||||||
|
*hash1 = 0x9438478934792837;
|
||||||
|
*hash2 = 0x8347848738748378;
|
||||||
|
}
|
||||||
|
|
||||||
if (length < sc_bufSize)
|
if (length < sc_bufSize)
|
||||||
{
|
{
|
||||||
Short(message, length, hash1, hash2);
|
Short(message, length, hash1, hash2);
|
||||||
|
|||||||
@@ -26,6 +26,9 @@
|
|||||||
// slower than MD5.
|
// slower than MD5.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef SPOOKYV2_HPP
|
||||||
|
#define SPOOKYV2_HPP
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -43,5 +46,4 @@ public:
|
|||||||
uint64_t *hash2); // input seed1, output hash1
|
uint64_t *hash2); // input seed1, output hash1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // SPOOKYV2_HPP
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ std::string id_vector_debug_string(const IdVector &idv) {
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IdVector sort_union_id_vectors(const IdVector &v1, const IdVector &v2) {
|
IdVector sort_union_id_vectors(const IdVector &v1, const IdVector &v2) {
|
||||||
IdVector result(v1.size() + v2.size());
|
IdVector result(v1.size() + v2.size());
|
||||||
int next = 0;
|
int next = 0;
|
||||||
@@ -47,6 +46,13 @@ IdVector sort_union_id_vectors(const IdVector &v1, const IdVector &v2) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HashValue hash_id_vector(const IdVector &idv) {
|
||||||
|
uint64_t hash1 = 0;
|
||||||
|
uint64_t hash2 = 0;
|
||||||
|
SpookyHash::Hash128(&idv[0], idv.size() * sizeof(int64_t), &hash1, &hash2);
|
||||||
|
return std::make_pair(hash1, hash2);
|
||||||
|
}
|
||||||
|
|
||||||
StringVec split(const std::string &s, char sep) {
|
StringVec split(const std::string &s, char sep) {
|
||||||
StringVec result;
|
StringVec result;
|
||||||
int start = 0;
|
int start = 0;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "luastack.hpp"
|
#include "luastack.hpp"
|
||||||
|
#include "spookyv2.hpp"
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
@@ -29,6 +30,9 @@ std::string id_vector_debug_string(const IdVector &idv);
|
|||||||
// Unions and sorts two ID vectors.
|
// Unions and sorts two ID vectors.
|
||||||
IdVector sort_union_id_vectors(const IdVector &v1, const IdVector &v2);
|
IdVector sort_union_id_vectors(const IdVector &v1, const IdVector &v2);
|
||||||
|
|
||||||
|
// Get a 64-bit hashvalue for an ID vector.
|
||||||
|
HashValue hash_id_vector(const IdVector &idv);
|
||||||
|
|
||||||
// Split a string into multiple strings
|
// Split a string into multiple strings
|
||||||
StringVec split(const std::string &s, char sep);
|
StringVec split(const std::string &s, char sep);
|
||||||
|
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ std::string World::tangible_ids_debug_string() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
util::IdVector World::get_near(int64_t player_id, float radius, bool exclude_nowhere) const {
|
util::IdVector World::get_near_unsorted(int64_t player_id, float radius, bool exclude_nowhere) const {
|
||||||
const Tangible *player = tangible_get(player_id);
|
const Tangible *player = tangible_get(player_id);
|
||||||
if (player == nullptr) {
|
if (player == nullptr) {
|
||||||
return IdVector();
|
return IdVector();
|
||||||
@@ -200,6 +200,12 @@ util::IdVector World::get_near(int64_t player_id, float radius, bool exclude_now
|
|||||||
return plane_map_.scan_radius(aqback.plane(), aqback.xyz().x, aqback.xyz().y, radius, player_id);
|
return plane_map_.scan_radius(aqback.plane(), aqback.xyz().x, aqback.xyz().y, radius, player_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
util::IdVector World::get_near(int64_t player_id, float radius, bool exclude_nowhere) const {
|
||||||
|
util::IdVector v = get_near_unsorted(player_id, radius, exclude_nowhere);
|
||||||
|
std::sort(v.begin(), v.end());
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
Tangible *World::tangible_make(lua_State *L, int64_t id, bool pushdb) {
|
Tangible *World::tangible_make(lua_State *L, int64_t id, bool pushdb) {
|
||||||
// Get a state if we don't already have one.
|
// Get a state if we don't already have one.
|
||||||
if (L == nullptr) {
|
if (L == nullptr) {
|
||||||
@@ -550,8 +556,8 @@ void World::difference_transmit(int64_t actor_id, const World *master, StreamBuf
|
|||||||
// Get the list of tangibles visible in either model.
|
// Get the list of tangibles visible in either model.
|
||||||
// Some tangibles may be missing in the master, some may be missing in the sync.
|
// Some tangibles may be missing in the master, some may be missing in the sync.
|
||||||
util::IdVector visible = util::sort_union_id_vectors(
|
util::IdVector visible = util::sort_union_id_vectors(
|
||||||
master->get_near(actor_id, 100.0, true),
|
master->get_near_unsorted(actor_id, RadiusVisibility, true),
|
||||||
this->get_near(actor_id, 100.0, true));
|
get_near_unsorted(actor_id, RadiusVisibility, true));
|
||||||
TanVector m_visible = master->tangible_get_all(visible);
|
TanVector m_visible = master->tangible_get_all(visible);
|
||||||
TanVector s_visible = tangible_get_all(visible);
|
TanVector s_visible = tangible_get_all(visible);
|
||||||
assert(m_visible.size() == s_visible.size());
|
assert(m_visible.size() == s_visible.size());
|
||||||
@@ -575,12 +581,24 @@ void World::difference_transmit(int64_t actor_id, const World *master, StreamBuf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Obtain the list of tangibles whose tables we're going to transmit.
|
||||||
|
util::IdVector closetans = get_near(actor_id, RadiusClose, true);
|
||||||
|
assert(closetans == master->get_near(actor_id, RadiusClose, true));
|
||||||
|
util::HashValue closehash = util::hash_id_vector(closetans);
|
||||||
|
|
||||||
|
// Confirm the close tangibles with the client.
|
||||||
|
sb->write_hashvalue(closehash);
|
||||||
|
|
||||||
assert(tsb.at_eof());
|
assert(tsb.at_eof());
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::apply_differences(StreamBuffer *sb) {
|
void World::apply_differences(StreamBuffer *sb) {
|
||||||
patch_actor_essentials(sb);
|
int64_t actor_id = patch_actor_essentials(sb);
|
||||||
patch_visible_animations(sb);
|
patch_visible_animations(sb);
|
||||||
|
util::IdVector closetans = get_near(actor_id, RadiusClose, true);
|
||||||
|
util::HashValue closehash = util::hash_id_vector(closetans);
|
||||||
|
util::HashValue m_closehash = sb->read_hashvalue();
|
||||||
|
assert(closehash == m_closehash);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::diff_actor_essentials(const Tangible *m_actor, const Tangible *s_actor, StreamBuffer *sb) {
|
void World::diff_actor_essentials(const Tangible *m_actor, const Tangible *s_actor, StreamBuffer *sb) {
|
||||||
@@ -594,7 +612,7 @@ void World::diff_actor_essentials(const Tangible *m_actor, const Tangible *s_act
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::patch_actor_essentials(StreamBuffer *sb) {
|
int64_t World::patch_actor_essentials(StreamBuffer *sb) {
|
||||||
int64_t actor_id = sb->read_int64();
|
int64_t actor_id = sb->read_int64();
|
||||||
Tangible *s_actor = tangible_get(actor_id);
|
Tangible *s_actor = tangible_get(actor_id);
|
||||||
if (s_actor == nullptr) {
|
if (s_actor == nullptr) {
|
||||||
@@ -606,6 +624,7 @@ void World::patch_actor_essentials(StreamBuffer *sb) {
|
|||||||
s_actor->anim_queue_.patch(sb);
|
s_actor->anim_queue_.patch(sb);
|
||||||
}
|
}
|
||||||
s_actor->update_plane_item();
|
s_actor->update_plane_item();
|
||||||
|
return actor_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::diff_visible_animations(const TanVector &mvis, const TanVector &svis, StreamBuffer *sb) {
|
void World::diff_visible_animations(const TanVector &mvis, const TanVector &svis, StreamBuffer *sb) {
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ public:
|
|||||||
using IdVector = util::IdVector;
|
using IdVector = util::IdVector;
|
||||||
using TanVector = std::vector<const Tangible*>;
|
using TanVector = std::vector<const Tangible*>;
|
||||||
using Redirects = std::map<int64_t, int64_t>;
|
using Redirects = std::map<int64_t, int64_t>;
|
||||||
|
const float RadiusVisibility = 100.0;
|
||||||
|
const float RadiusClose = 10.0;
|
||||||
|
|
||||||
// Constructor.
|
// Constructor.
|
||||||
//
|
//
|
||||||
@@ -103,9 +105,11 @@ public:
|
|||||||
// get_near
|
// get_near
|
||||||
//
|
//
|
||||||
// Get a list of the tangibles that are near the player. If 'exclude_nowhere' is
|
// Get a list of the tangibles that are near the player. If 'exclude_nowhere' is
|
||||||
// true, exclude any tangibles on the nowhere plane.
|
// true, exclude any tangibles on the nowhere plane. The unsorted version returns
|
||||||
|
// the tangibles in an unpredictable order.
|
||||||
//
|
//
|
||||||
IdVector get_near(int64_t player_id, float radius, bool exclude_nowhere) const;
|
IdVector get_near(int64_t player_id, float radius, bool exclude_nowhere) const;
|
||||||
|
IdVector get_near_unsorted(int64_t player_id, float radius, bool exclude_nowhere) const;
|
||||||
|
|
||||||
// Make a tangible.
|
// Make a tangible.
|
||||||
//
|
//
|
||||||
@@ -247,7 +251,7 @@ private:
|
|||||||
// We also update the actor's ID allocation pipeline.
|
// We also update the actor's ID allocation pipeline.
|
||||||
//
|
//
|
||||||
static void diff_actor_essentials(const Tangible *mactor, const Tangible *sactor, StreamBuffer *sb);
|
static void diff_actor_essentials(const Tangible *mactor, const Tangible *sactor, StreamBuffer *sb);
|
||||||
void patch_actor_essentials(StreamBuffer *sb);
|
int64_t patch_actor_essentials(StreamBuffer *sb);
|
||||||
|
|
||||||
// Pass 2 of difference transmission: visible animations.
|
// Pass 2 of difference transmission: visible animations.
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user