Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tell the client the LevelChainId before it uses it to read a variable bit length message #75

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions scripts/client/nodes/PlanetNode.as
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,19 @@ class DynTex {
return;
}

// Try to fail more gracefully than causing a CTD if the
// grid size is wrong
// If the netcode messes up this can sometimes be way larger than any
// actual grid size. In that scenario, trying to create the Image
// can easily cause a Crash To Desktop and completely stop the game.
if (size.x > 3000 || size.y > 3000) {
print("Read grid size that is way too high, aborting texture cache to avoid CTD");
print(string(size.x)+"x"+string(size.y));
print("Has the netcode or PlanetSurface gone haywire?");
@this.obj = null;
return;
}

Image img(size, 4);

uint shown = obj.getSurfaceData(img);
Expand Down
11 changes: 11 additions & 0 deletions scripts/server/planets/SurfaceComponent.as
Original file line number Diff line number Diff line change
Expand Up @@ -2591,6 +2591,17 @@ tidy class SurfaceComponent : Component_SurfaceComponent, Savable {
msg.write0();
}
msg.writeBit(needsPopulationForLevel);
// Tell the client the LevelChainId before it tries to use it, fixes
// bug where the client was reading the max level of a planet before
// it found out the level chain of that planet. This meant that any
// planet with a level chain that had a different max level to the
// level chain with an id of 0 would be decoded incorrectly, and offset
// the rest of the message by some number of bits, completely breaking
// all decoding that followed. In the worst case, the broken decoding
// would cause a Crash To Desktop as the PlanetNode tried to create
// an Image with a ludicrous size, or the PlanetSurface tried to
// create an array for a ludicrous grid size that ran out of memory.
msg.writeLimited(LevelChainId,getLevelChainCount());
msg.writeLimited(ResourceLevel,maxLevel);
msg.writeBit(isSendingColonizers);
}
Expand Down
11 changes: 11 additions & 0 deletions scripts/shadow/planets/SurfaceComponent.as
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,17 @@ tidy class SurfaceComponent : Component_SurfaceComponent {
growthRate = 1.0;
needsPopulationForLevel = msg.readBit();

// Tell the client the LevelChainId before it tries to use it, fixes
// bug where the client was reading the max level of a planet before
// it found out the level chain of that planet. This meant that any
// planet with a level chain that had a different max level to the
// level chain with an id of 0 would be decoded incorrectly, and offset
// the rest of the message by some number of bits, completely breaking
// all decoding that followed. In the worst case, the broken decoding
// would cause a Crash To Desktop as the PlanetNode tried to create
// an Image with a ludicrous size, or the PlanetSurface tried to
// create an array for a ludicrous grid size that ran out of memory.
LevelChainId = msg.readLimited(getLevelChainCount());
int maxLevel = getLevelChain(LevelChainId).levels.length-1;
ResourceLevel = msg.readLimited(maxLevel);

Expand Down