Skip to content

Commit ecd6f2b

Browse files
committed
make servers independent. Fix crash. bm: hyper bomber eog detection
Split servers into 4 services (bootstrap, outtrigger, propeller arena, bomberman) running the same binary with different roles. Fix crash when joining a room that has been deleted. bm: Fix end of game detection in hyper bomber mode. bm: better map info parsing and checking
1 parent bc6f744 commit ecd6f2b

8 files changed

Lines changed: 189 additions & 70 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ ot_dissect
1010
/.project
1111
/propellerarena.db
1212
/pa_dissect
13+
/kage@.service
14+
/bm_dissect

Makefile

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,26 @@ bm_dissect: bm_dissect.o
3232
$(CXX) $(CXXFLAGS) -o $@ bm_dissect.o
3333

3434
clean:
35-
rm -f *.o kageserver ot_dissect pa_dissect bm_dissect kage.service
35+
rm -f *.o kageserver ot_dissect pa_dissect bm_dissect kage@.service
3636

3737
install: all
3838
mkdir -p $(DESTDIR)$(sbindir)
3939
install kageserver $(DESTDIR)$(sbindir)
4040
mkdir -p $(DESTDIR)$(sysconfdir)
4141
cp -n kage.cfg $(DESTDIR)$(sysconfdir)
4242

43-
kage.service: kage.service.in Makefile
44-
cp kage.service.in kage.service
43+
kage@.service: kage@.service.in Makefile
44+
cp kage@.service.in kage@.service
4545
sed -e "s/INSTALL_USER/$(USER)/g" -e "s:SBINDIR:$(sbindir):g" -e "s:SYSCONFDIR:$(sysconfdir):g" -e "s:LOCALSTATEDIR:$(localstatedir):g" < $< > $@
4646

47-
installservice: kage.service
47+
installservice: kage@.service
4848
mkdir -p /usr/lib/systemd/system/
4949
cp $< /usr/lib/systemd/system/
50-
mkdir -p $(localstatedir)/log/
50+
mkdir -p $(localstatedir)/log/kage
5151
mkdir -p $(localstatedir)/lib/kage
5252
chown $(USER):$(USER) $(localstatedir)/lib/kage
53-
systemctl enable kage.service
53+
systemctl daemon-reload
54+
systemctl enable kage@bs.service
55+
systemctl enable kage@ot.service
56+
systemctl enable kage@pa.service
57+
systemctl enable kage@bm.service

bomberman.cpp

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,6 @@ void BMRoom::savePowerUps(Player *player, const uint8_t *data)
377377
// hidden -> appearing -> visible
378378
// Successful pick up
379379
// claimed -> (granted) -> owned
380-
// TODO: Denied pick up
381380
// Hyper bomber death sequence:
382381
// owned -> released (with coords, unk1=1) -> (lost) -> appearing -> visible
383382
for (unsigned i = 0; i < powerUps.size(); i++)
@@ -431,8 +430,10 @@ void BMRoom::savePowerUps(Player *player, const uint8_t *data)
431430
releaseBombSlot(pup.slot, i);
432431
}
433432
else if (pup.state != PowerUp::Owned) {
434-
WARN_LOG(game, "PowerUp transitioning from owned to %x? slot %d",
433+
DEBUG_LOG(game, "PowerUp transitioning from owned to %x? slot %d",
435434
pup.state, pup.slot);
435+
// end of game?
436+
powerUps[i] = pup;
436437
}
437438
}
438439
break;
@@ -480,10 +481,8 @@ void BMRoom::savePowerUps(Player *player, const uint8_t *data)
480481
break;
481482

482483
default:
483-
if (powerUps[i].param == 0)
484+
if (powerUps[i].param == 0 || pup.slot == powerUps[i].slot)
484485
powerUps[i] = pup;
485-
else
486-
WARN_LOG(game, "PowerUp current state not handled: %x -> %x", curState, pup.state);
487486
break;
488487
}
489488
}
@@ -718,13 +717,13 @@ void BMRoom::releaseBombSlot(int slot, int powerUpIdx)
718717

719718
bool BMRoom::checkEndOfGame(Player *player, uint8_t command, uint8_t mark)
720719
{
721-
if (mark == 0)
722-
return false;
723720
State& playerState = states[getPlayerIndex(player)];
724721
if (playerState.status != State::InGame)
725722
return false;
726-
DEBUG_LOG(game, "[%s] Game end", player->getName().c_str());
727-
playerState.endOfGameMask |= 1 << (command - 1);
723+
if (mark != 0)
724+
playerState.endOfGameMask |= 1 << (command - 1);
725+
if (playerState.endOfGameMask == 7)
726+
DEBUG_LOG(game, "[%s] Game end", player->getName().c_str());
728727
return playerState.endOfGameMask == 7;
729728
}
730729

@@ -737,9 +736,27 @@ void BMRoom::sendEndOfGame(Player *player, Packet& reply, Packet& relay)
737736
return;
738737
state.status = State::GameEnding;
739738
inGame = false;
740-
for (unsigned i = 0; i < players.size(); i++)
741-
if (states[i].endOfGameMask != 7)
739+
if (rules[0] == 0)
740+
{
741+
// survival mode: wait until all players have agreed on the end of game
742+
for (unsigned i = 0; i < players.size(); i++)
743+
if (states[i].endOfGameMask != 7)
744+
return;
745+
}
746+
else
747+
{
748+
// hyper bomber mode: one player is enough
749+
bool allPlayersDone = true;
750+
for (unsigned i = 0; i < players.size(); i++)
751+
{
752+
if (states[i].endOfGameMask != 7) {
753+
states[i].endOfGameMask = 7;
754+
allPlayersDone = false;
755+
}
756+
}
757+
if (!allPlayersDone)
742758
return;
759+
}
743760
if (!reply.empty()) {
744761
player->send(reply);
745762
reply.reset();
@@ -1174,10 +1191,20 @@ bool Map::append(const uint8_t *data, unsigned size)
11741191
if (this->data.size() < blockCount * sizeof(Block))
11751192
return false;
11761193

1177-
this->data.reserve(blockCount);
1194+
blocks.clear();
1195+
blocks.reserve(blockCount);
11781196
for (unsigned i = 0; i < blockCount; i++)
11791197
blocks.emplace_back(&this->data[i * sizeof(Block)]);
11801198

1199+
for (unsigned i = 0; i < blockCount; i++)
1200+
{
1201+
if (blocks[i].type != Wall && blocks[i].type != Brick
1202+
&& blocks[i].type != PowerUp && blocks[i].type != Gate
1203+
&& blocks[i].type != TargetPanel)
1204+
WARN_LOG(Game::Bomberman, "Unknown map block type %d at index %d pos %d,%d",
1205+
blocks[i].type, i, blocks[i].col, blocks[i].row);
1206+
}
1207+
11811208
return true;
11821209
}
11831210

@@ -1187,6 +1214,26 @@ std::array<uint8_t, 16> Map::getBrickMap() const
11871214
for (const Block& block : blocks)
11881215
if (block.type == Brick)
11891216
map[block.order / 8] |= 1 << (block.order % 8);
1217+
bool ones = true;
1218+
for (uint8_t v : map)
1219+
if (v == 0) {
1220+
ones = false;
1221+
}
1222+
else
1223+
{
1224+
if (!ones) {
1225+
WARN_LOG(Game::Bomberman, "Brick map has holes");
1226+
break;
1227+
}
1228+
if (v != 0xff)
1229+
{
1230+
if (((v + 1) & v) != 0) {
1231+
WARN_LOG(Game::Bomberman, "Brick map ones don't end properly: %02x", v);
1232+
break;
1233+
}
1234+
ones = false;
1235+
}
1236+
}
11901237
return map;
11911238
}
11921239

@@ -1196,15 +1243,23 @@ std::array<PowerUp, 28> Map::getPowerUps() const
11961243
indexes.fill(-1);
11971244
for (unsigned i = 0; i < blocks.size(); i++)
11981245
if (blocks[i].type == PowerUp)
1246+
{
1247+
if (indexes[blocks[i].order] != -1)
1248+
WARN_LOG(Game::Bomberman, "PowerUp[%d] already used by block %d", indexes[blocks[i].order]);
11991249
indexes[blocks[i].order] = i;
1250+
}
12001251
std::array<::PowerUp, 28> pups {};
1252+
unsigned pupMap = 0;
12011253
for (unsigned i = 0; i < pups.size(); i++)
12021254
if (indexes[i] != -1)
12031255
{
12041256
const Block& block = blocks[indexes[i]];
12051257
pups[i].pos.x = block.col;
12061258
pups[i].pos.y = block.row;
12071259
pups[i].state = PowerUp::Hidden;
1260+
pupMap |= 1 << i;
12081261
}
1262+
if (((pupMap + 1) & pupMap) != 0)
1263+
WARN_LOG(Game::Bomberman, "PowerUp list has holes: %07x", pupMap);
12091264
return pups;
12101265
}

bomberman.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ class Map
269269
Wall = 2,
270270
Brick = 3,
271271
PowerUp = 4,
272+
Gate = 8,
273+
TargetPanel = 102,
272274
};
273275

274276
struct Block
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[Unit]
2-
Description=Kage Server
2+
Description=Kage Server role %i
33
After=network.target
44
StartLimitIntervalSec=0
55

@@ -8,8 +8,8 @@ Type=simple
88
Restart=always
99
RestartSec=1
1010
User=INSTALL_USER
11-
ExecStart=SBINDIR/kageserver SYSCONFDIR/kage.cfg
12-
StandardOutput=append:LOCALSTATEDIR/log/kage.log
11+
ExecStart=SBINDIR/kageserver -c SYSCONFDIR/kage.cfg -r %i
12+
StandardOutput=append:LOCALSTATEDIR/log/kage/%i.log
1313

1414
[Install]
1515
WantedBy=multi-user.target

0 commit comments

Comments
 (0)