Skip to content

Commit

Permalink
Util: Use secure random number generation
Browse files Browse the repository at this point in the history
  • Loading branch information
RyanGrieb committed Nov 27, 2023
1 parent 3fc140c commit 1897f0a
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 11 deletions.
2 changes: 1 addition & 1 deletion client/index.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!DOCTYPE html>

<html>
<html lang="en" xml:lang="en">

<head>
<!-- Prevents our "Start" button from flickering when loading the image.
Expand Down
9 changes: 5 additions & 4 deletions client/src/scene/SceneBackground.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Actor } from "./Actor";
import { Game } from "../Game";
import { GameImage } from "../Assets";
import { SpriteRegion } from "../Assets";
import { Numbers } from "../util/Numbers";

export class SceneBackground {
public static generateOcean() {
Expand Down Expand Up @@ -44,7 +45,7 @@ export class SceneBackground {
tileActors.push(
new Actor({
image: Game.getInstance().getImage(GameImage.SPRITESHEET),
spriteRegion: Math.random() < 0.1 ? SpriteRegion.GRASS_HILL : SpriteRegion.GRASS,
spriteRegion: Numbers.safeRandom() < 0.1 ? SpriteRegion.GRASS_HILL : SpriteRegion.GRASS,
x: xPos,
y: yPos,
width: 32,
Expand All @@ -55,20 +56,20 @@ export class SceneBackground {
}

// Sparse background with a random unit
//const spriteRegionNum = Math.floor(Math.random() * 9); // Random sprite region b/w 0-2
//const spriteRegionNum = Math.floor(Numbers.safeRandom() * 9); // Random sprite region b/w 0-2
for (let y = -1; y < (Game.getInstance().getHeight() + 24) / 24; y++) {
for (let x = -1; x < (Game.getInstance().getWidth() + 32) / 32; x++) {
let yPos = y * 24;
let xPos = x * 32;
if (y % 2 != 0) {
xPos += 16;
}
if (Math.random() > 0.02) continue;
if (Numbers.safeRandom() > 0.02) continue;

tileActors.push(
new Actor({
image: Game.getInstance().getImage(GameImage.SPRITESHEET),
spriteRegion: Object.values(SpriteRegion)[Math.floor(Math.random() * 9)],
spriteRegion: Object.values(SpriteRegion)[Math.floor(Numbers.safeRandom() * 9)],
x: xPos,
y: yPos,
width: 32,
Expand Down
7 changes: 7 additions & 0 deletions client/src/util/Numbers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,11 @@ export class Numbers {

return sum;
}

public static safeRandom() {
const crypto = window.crypto;
const array = new Uint32Array(1);
crypto.getRandomValues(array);
return array[0] / (0xffffffff + 1);
}
}
13 changes: 7 additions & 6 deletions server/src/map/GameMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { MapResources } from "./MapResources";
import { TileIndexer } from "./TileIndexer";
import { Unit } from "../unit/Unit";
import PriorityQueue from "ts-priority-queue";
import { Numbers } from "../util/Numbers";

enum MapSize {
DUEL = "48x32",
Expand Down Expand Up @@ -182,13 +183,13 @@ export class GameMap {
//Assign top 10% of tiles to have a 50% of becoming a hill tile
const totalHills = tallestTiles.length * 0.1;
for (let i = 0; i < totalHills; i++) {
if (Math.random() < 0.5) tallestTiles[i].replaceTileType("grass", "grass_hill");
if (Numbers.safeRandom() < 0.5) tallestTiles[i].replaceTileType("grass", "grass_hill");
}

// TODO: Spawn hills in patches?
// For all other grass tiles, make it a 13% of becoming a hill tile.
for (let i = 0; i < tallestTiles.length; i++) {
if (Math.random() < 0.13) tallestTiles[i].replaceTileType("grass", "grass_hill");
if (Numbers.safeRandom() < 0.13) tallestTiles[i].replaceTileType("grass", "grass_hill");
}

//Assign the top 5% of tiles to be mountains
Expand Down Expand Up @@ -230,7 +231,7 @@ export class GameMap {
if (yPercent <= 0.1 || yPercent >= 0.9) {
this.setTileBiome({ tile: currentTile, tileType: "snow" });
} else if ((yPercent > 0.1 && yPercent < 0.15) || (yPercent > 0.85 && yPercent < 0.9)) {
if (Math.random() > 0.25) {
if (Numbers.safeRandom() > 0.25) {
for (const adjTile of currentTile.getAdjacentTiles()) {
if (!adjTile) continue;
//FIXME: This can create single ocean/freshwater tiles.
Expand Down Expand Up @@ -382,7 +383,7 @@ export class GameMap {
for (const tile of [...TileIndexer.getTilesByTileType("ocean")]) {
for (const adjTile of tile.getAdjacentTiles()) {
if (!adjTile) continue;
if (adjTile.containsTileType("shallow_ocean") && Math.random() > 0.75) {
if (adjTile.containsTileType("shallow_ocean") && Numbers.safeRandom() > 0.75) {
tile.replaceTileType("ocean", "shallow_ocean");
}
}
Expand Down Expand Up @@ -749,7 +750,7 @@ export class GameMap {

private setTilesBiome(tiles: Tile[], tileType: string, setChance: number) {
for (const tile of tiles) {
if (!tile || Math.random() > setChance) continue;
if (!tile || Numbers.safeRandom() > setChance) continue;
this.setTileBiome({ tile: tile, tileType: tileType });
}
}
Expand Down Expand Up @@ -846,7 +847,7 @@ export class GameMap {
// Skip if we want to avoid resource tiles
if (avoidResourceTiles && MapResources.isResourceTile(tile)) continue;

if (Math.random() <= options.setTileChance) {
if (Numbers.safeRandom() <= options.setTileChance) {
this.setTileBiome({
tile: tile,
tileType: options.setTileType,
Expand Down
9 changes: 9 additions & 0 deletions server/src/util/Numbers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import crypto from "crypto";

export class Numbers {
public static safeRandom() {
const buffer = crypto.randomBytes(4); // 4 bytes for a 32-bit number
const randomNum = buffer.readUInt32BE(0) / (0xffffffff + 1);
return randomNum;
}
}

0 comments on commit 1897f0a

Please sign in to comment.