Merge pull request #139 from DrPerkyLegit/fix/s2c-particles
Some checks are pending
Nightly Release / Build Client (push) Waiting to run
Nightly Release / Build Server (push) Waiting to run
Nightly Release / Release Client (push) Blocked by required conditions
Nightly Release / Release Server (push) Blocked by required conditions
Nightly Release / cleanup (push) Blocked by required conditions
Sync branches with main / sync (push) Waiting to run

This commit is contained in:
Fireblade 2026-05-31 20:51:49 -04:00 committed by GitHub
commit 7f967ed66f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 131 additions and 165 deletions

View file

@ -4323,22 +4323,19 @@ void ClientConnection::handleSetPlayerTeamPacket(shared_ptr<SetPlayerTeamPacket>
void ClientConnection::handleParticleEvent(shared_ptr<LevelParticlesPacket> packet) void ClientConnection::handleParticleEvent(shared_ptr<LevelParticlesPacket> packet)
{ {
const ParticleType* type = packet->getType(); ePARTICLE_TYPE particleId = (ePARTICLE_TYPE)Integer::parseInt(packet->getName());
if (type == nullptr) return;
ePARTICLE_TYPE particleId = (ePARTICLE_TYPE)type->getId(); for (int i = 0; i < packet->getCount(); i++)
{
double xVarience = random->nextGaussian() * packet->getXDist();
double yVarience = random->nextGaussian() * packet->getYDist();
double zVarience = random->nextGaussian() * packet->getZDist();
double xa = random->nextGaussian() * packet->getMaxSpeed();
double ya = random->nextGaussian() * packet->getMaxSpeed();
double za = random->nextGaussian() * packet->getMaxSpeed();
for (int i = 0; i < packet->getCount(); i++) level->addParticle(particleId, packet->getX() + xVarience, packet->getY() + yVarience, packet->getZ() + zVarience, xa, ya, za);
{ }
double xVarience = random->nextGaussian() * packet->getXDist();
double yVarience = random->nextGaussian() * packet->getYDist();
double zVarience = random->nextGaussian() * packet->getZDist();
double xa = random->nextGaussian() * packet->getMaxSpeed();
double ya = random->nextGaussian() * packet->getMaxSpeed();
double za = random->nextGaussian() * packet->getMaxSpeed();
level->addParticle(particleId, packet->getX() + xVarience, packet->getY() + yVarience, packet->getZ() + zVarience, xa, ya, za);
}
} }
void ClientConnection::handleUpdateAttributes(shared_ptr<UpdateAttributesPacket> packet) void ClientConnection::handleUpdateAttributes(shared_ptr<UpdateAttributesPacket> packet)

View file

@ -1683,14 +1683,15 @@ void ServerLevel::flagEntitiesToBeRemoved(unsigned int *flags, bool *removedFoun
} }
void ServerLevel::sendParticles(const ParticleType* type, bool longDistance, double x, double y, double z, int count, double dx, double dy, double dz, double speed, arrayWithLength<int> data) void ServerLevel::sendParticles(const ParticleType* type, bool longDistance, double x, double y, double z, int count, double dx, double dy, double dz, double speed, arrayWithLength<int> data)
{ {
wchar_t buf[32];
swprintf_s(buf, L"%d", type->getId());
auto packet = make_shared<LevelParticlesPacket>( auto packet = make_shared<LevelParticlesPacket>(
type, buf,
longDistance,
(float)x, (float)y, (float)z, (float)x, (float)y, (float)z,
(float)dx, (float)dy, (float)dz, (float)dx, (float)dy, (float)dz,
(float)speed, (float)speed,
count, count
data
); );
for (auto const& p : players) for (auto const& p : players)

View file

@ -1281,10 +1281,9 @@ void __cdecl NativeSpawnParticle(int entityId, int particleId, float x, float y,
{ {
auto player = FindPlayer(entityId); auto player = FindPlayer(entityId);
if (!player || !player->connection) return; if (!player || !player->connection) return;
const ParticleType* type = ParticleType::byId(particleId); wchar_t buf[32];
if (!type) type = ParticleType::getDefault(); swprintf_s(buf, L"%d", particleId);
arrayWithLength<int> noParams = { nullptr, 0 }; player->connection->send(std::make_shared<LevelParticlesPacket>(std::wstring(buf), x, y, z, offsetX, offsetY, offsetZ, speed, count));
player->connection->send(std::make_shared<LevelParticlesPacket>(type, false, x, y, z, offsetX, offsetY, offsetZ, speed, count, noParams));
} }
int __cdecl NativeSetPassenger(int entityId, int passengerEntityId) int __cdecl NativeSetPassenger(int entityId, int passengerEntityId)

View file

@ -1,127 +1,110 @@
 #include "stdafx.h"
#include "stdafx.h"
#include "PacketListener.h" #include "PacketListener.h"
#include "LevelParticlesPacket.h" #include "LevelParticlesPacket.h"
#include "../Minecraft.Client/ParticleType.h"
LevelParticlesPacket::LevelParticlesPacket() LevelParticlesPacket::LevelParticlesPacket()
{ {
this->name = L"";
this->overrideLimiter = false; this->x = 0.0f;
this->type = nullptr; this->y = 0.0f;
this->count = 0; this->z = 0.0f;
this->y = 0.0f; this->xDist = 0.0f;
this->paramCount = 0; this->yDist = 0.0f;
this->x = 0.0f; this->zDist = 0.0f;
this->yDist = 0.0f; this->maxSpeed = 0.0f;
this->zDist = 0.0f; this->count = 0;
this->z = 0.0f;
this->maxSpeed = 0.0f;
this->xDist = 0.0f;
this->params = nullptr;
} }
LevelParticlesPacket::LevelParticlesPacket(const ParticleType* type, bool overrideLimiter, LevelParticlesPacket::LevelParticlesPacket(const wstring& name, float x, float y, float z, float xDist, float yDist, float zDist, float maxSpeed, int count)
float x, float y, float z,
float xDist, float yDist, float zDist,
float maxSpeed, int count,
arrayWithLength<int> data)
{ {
this->type = type; this->name = name;
this->overrideLimiter = overrideLimiter; this->x = x;
this->x = x; this->y = y;
this->y = y; this->z = z;
this->z = z; this->xDist = xDist;
this->xDist = xDist; this->yDist = yDist;
this->yDist = yDist; this->zDist = zDist;
this->zDist = zDist; this->maxSpeed = maxSpeed;
this->maxSpeed = maxSpeed; this->count = count;
this->count = count;
this->paramCount = data.length;
if (data.data && data.length > 0)
{
this->params = new int[data.length];
memcpy(this->params, data.data, data.length * sizeof(int));
}
else
{
this->params = nullptr;
}
}
LevelParticlesPacket::~LevelParticlesPacket()
{
if (params)
{
delete[] params;
params = nullptr;
}
} }
void LevelParticlesPacket::read(DataInputStream* dis) void LevelParticlesPacket::read(DataInputStream* dis)
{ {
int particleId = dis->readInt(); name = readUtf(dis, 64);
const ParticleType* resolved = ParticleType::byId(particleId); x = dis->readFloat();
if (!resolved) y = dis->readFloat();
resolved = ParticleType::getDefault(); z = dis->readFloat();
this->type = resolved; xDist = dis->readFloat();
yDist = dis->readFloat();
this->overrideLimiter = dis->readBoolean(); zDist = dis->readFloat();
maxSpeed = dis->readFloat();
this->x = dis->readFloat(); count = dis->readInt();
this->y = dis->readFloat();
this->z = dis->readFloat();
this->xDist = dis->readFloat();
this->yDist = dis->readFloat();
this->zDist = dis->readFloat();
this->maxSpeed = dis->readFloat();
this->count = dis->readInt();
int paramCount = this->type ? this->type->getParamCount() : 0;
this->paramCount = paramCount;
if (paramCount > 0)
{
this->params = new int[paramCount]();
for (int i = 0; i < paramCount; i++)
{
this->params[i] = dis->readInt();
}
}
else
{
this->params = nullptr;
}
} }
void LevelParticlesPacket::write(DataOutputStream* dos) void LevelParticlesPacket::write(DataOutputStream* dos)
{ {
dos->writeInt(this->type ? this->type->getId() : 0); writeUtf(name, dos);
dos->writeBoolean(this->overrideLimiter); dos->writeFloat(x);
dos->writeFloat(this->x); dos->writeFloat(y);
dos->writeFloat(this->y); dos->writeFloat(z);
dos->writeFloat(this->z); dos->writeFloat(xDist);
dos->writeFloat(this->xDist); dos->writeFloat(yDist);
dos->writeFloat(this->yDist); dos->writeFloat(zDist);
dos->writeFloat(this->zDist); dos->writeFloat(maxSpeed);
dos->writeFloat(this->maxSpeed); dos->writeInt(count);
dos->writeInt(this->count); }
int toWrite = this->type ? this->type->getParamCount() : 0; wstring LevelParticlesPacket::getName()
for (int i = 0; i < toWrite; i++) {
{ return name;
dos->writeInt(this->params[i]); }
}
double LevelParticlesPacket::getX()
{
return x;
}
double LevelParticlesPacket::getY()
{
return y;
}
double LevelParticlesPacket::getZ()
{
return z;
}
float LevelParticlesPacket::getXDist()
{
return xDist;
}
float LevelParticlesPacket::getYDist()
{
return yDist;
}
float LevelParticlesPacket::getZDist()
{
return zDist;
}
float LevelParticlesPacket::getMaxSpeed()
{
return maxSpeed;
}
int LevelParticlesPacket::getCount()
{
return count;
} }
void LevelParticlesPacket::handle(PacketListener* listener) void LevelParticlesPacket::handle(PacketListener* listener)
{ {
listener->handleParticleEvent(shared_from_this()); listener->handleParticleEvent(shared_from_this());
} }
int LevelParticlesPacket::getEstimatedSize() int LevelParticlesPacket::getEstimatedSize()
{ {
return 0x40; return 4 * 2 + 7 * 8;
} }

View file

@ -1,53 +1,39 @@
#pragma once #pragma once
#include "Packet.h" #include "Packet.h"
#include "../Minecraft.Client/ParticleType.h"
class LevelParticlesPacket : public Packet, public enable_shared_from_this<LevelParticlesPacket> class LevelParticlesPacket : public Packet, public enable_shared_from_this<LevelParticlesPacket>
{ {
private: private:
wstring name;
const ParticleType* type; float x;
float x; float y;
float y; float z;
float z; float xDist;
float xDist; float yDist;
float yDist; float zDist;
float zDist; float maxSpeed;
float maxSpeed; int count;
int count;
bool overrideLimiter;
int* params;
int paramCount;
public: public:
LevelParticlesPacket(); LevelParticlesPacket();
LevelParticlesPacket(const ParticleType* type, bool overrideLimiter, LevelParticlesPacket(const wstring& name, float x, float y, float z, float xDist, float yDist, float zDist, float maxSpeed, int count);
float x, float y, float z,
float xDist, float yDist, float zDist,
float maxSpeed, int count,
arrayWithLength<int> data);
~LevelParticlesPacket();
void read(DataInputStream* dis) override; void read(DataInputStream* dis);
void write(DataOutputStream* dos) override; void write(DataOutputStream* dos);
wstring getName();
double getX();
double getY();
double getZ();
float getXDist();
float getYDist();
float getZDist();
float getMaxSpeed();
int getCount();
void handle(PacketListener* listener);
int getEstimatedSize();
const ParticleType* getType() { return type; } public:
double getX() { return x; } static shared_ptr<Packet> create() { return std::make_shared<LevelParticlesPacket>(); }
double getY() { return y; } virtual int getId() { return 63; }
double getZ() { return z; }
double getXDist() { return xDist; }
double getYDist() { return yDist; }
double getZDist() { return zDist; }
double getMaxSpeed() { return maxSpeed; }
int getCount() { return count; }
bool isOverrideLimiter() { return overrideLimiter; }
int* getParams() { return params; }
int getParamCount() { return paramCount; }
void handle(PacketListener* listener) override;
int getEstimatedSize() override;
static shared_ptr<Packet> create() { return std::make_shared<LevelParticlesPacket>(); }
virtual int getId() override { return 63; }
}; };