token ring stuff and renaming things to avoid confusion

This commit is contained in:
minjaesong
2025-03-02 15:04:53 +09:00
parent f74b7218b0
commit ef4a5d6eb9
3 changed files with 151 additions and 63 deletions

View File

@@ -4,18 +4,20 @@ import net.torvald.terrarum.serialise.*
import java.util.zip.CRC32
/**
* # Packet data structure
* This class manages Layer 2 of the OSI Model, the Frame.
*
* # Frame data structure
*
* Endianness: big
*
* ## The Header
*
* - (Byte1) Frame Type
* - 00 : invalid (mark the packet as "to be destroyed" by game)
* - FF : token (an "empty" packet for a Token Ring)
* - 00 : invalid (mark the frame as "to be destroyed" by game)
* - FF : token (an "empty" frame for a Token Ring)
* - AA : data
* - EE : abort
* - 99 : ballot (an initialiser packet for electing the Active Monitor for a Token Ring)
* - 99 : ballot (an initialiser frame for electing the Active Monitor for a Token Ring)
* - (Byte1) Frame number. Always 0 for a Token Ring
* - (Byte4) Sender MAC address
*
@@ -30,8 +32,8 @@ import java.util.zip.CRC32
* ### Ballot
*
* - (Byte4) Currently elected Monitor candidate. A NIC examines this number, and if its MAC is larger than
* this value, the NIC writes its own MAC to this area and passes the packet to the next NIC; otherwise it
* just passes the packet as-is
* this value, the NIC writes its own MAC to this area and passes the frame to the next NIC; otherwise it
* just passes the frame as-is
*
* ### Data
*
@@ -47,7 +49,7 @@ import java.util.zip.CRC32
*
* Created by minjaesong on 2025-02-27.
*/
data class IngameNetPacket(val byteArray: ByteArray) {
data class NetFrame(val byteArray: ByteArray) {
fun getFrameType(): String {
return when (byteArray.first().toUint()) {
@@ -68,6 +70,10 @@ data class IngameNetPacket(val byteArray: ByteArray) {
private fun checkIsAbort() { if (getFrameType() != "abort") throw Error() }
private fun checkIsBallot() { if (getFrameType() != "ballot") throw Error() }
fun getSender(): Int = byteArray.toBigInt32(2)
fun getFrameNumber(): Int = byteArray[1].toUint()
fun getBallot(): Int {
checkIsBallot()
return byteArray.toBigInt32(6)
@@ -79,7 +85,7 @@ data class IngameNetPacket(val byteArray: ByteArray) {
}
fun shouldIintercept(mac: Int) = when (getFrameType()) {
"ballot" -> (getBallot() < mac)
"ballot" -> true//(getBallot() < mac)
"data", "ack" -> (getDataRecipient() == mac)
else -> false
}
@@ -107,7 +113,7 @@ data class IngameNetPacket(val byteArray: ByteArray) {
return byteArray.toBigInt32(6)
}
fun discardPacket() {
fun discardFrame() {
byteArray[0] = 0
}
@@ -118,13 +124,18 @@ data class IngameNetPacket(val byteArray: ByteArray) {
return this
}
fun makeToken(mac: Int) = IngameNetPacket(ByteArray(5).makeHeader(0xff, mac))
fun makeToken(mac: Int) = NetFrame(ByteArray(5).makeHeader(0xff, mac))
fun makeAbort(mac: Int) = IngameNetPacket(ByteArray(5).makeHeader(0xee, mac))
fun makeAbort(mac: Int) = NetFrame(ByteArray(5).makeHeader(0xee, mac))
fun makeBallot(mac: Int) = IngameNetPacket(ByteArray(9).makeHeader(0x99, mac))
fun makeBallot(mac: Int) = NetFrame(ByteArray(9).makeHeader(0x99, mac))
fun makeData(sender: Int, recipient: Int, data: ByteArray) = IngameNetPacket(ByteArray(18 + data.size).also {
fun makeWinnerAnnouncement(mac: Int) = NetFrame(ByteArray(9).makeHeader(0x99, mac).also {
it[1] = 1
it.writeBigInt32(mac, 6)
})
fun makeData(sender: Int, recipient: Int, data: ByteArray) = NetFrame(ByteArray(18 + data.size).also {
it.makeHeader(0xaa, sender)
it.writeBigInt32(recipient, 6)
it.writeBigInt32(data.size, 10)
@@ -133,7 +144,7 @@ data class IngameNetPacket(val byteArray: ByteArray) {
it.writeBigInt32(crc, 14 + data.size)
})
fun makeAck(sender: Int, recipient: Int, status: Int = 0) = IngameNetPacket(ByteArray(12).also {
fun makeAck(sender: Int, recipient: Int, status: Int = 0) = NetFrame(ByteArray(12).also {
it.makeHeader(0x55, sender)
it.writeBigInt32(recipient, 6)
it.writeBigInt16(status, 10)

View File

@@ -9,25 +9,25 @@ import java.util.TreeMap
*
* Created by minjaesong on 2025-02-27.
*/
class PacketRunner : TerrarumSavegameExtrafieldSerialisable {
class NetRunner : TerrarumSavegameExtrafieldSerialisable {
@Transient private val rng = HQRNG()
private val ledger = TreeMap<Int, IngameNetPacket>()
private val ledger = TreeMap<Int, NetFrame>()
operator fun set(id: Int, packet: IngameNetPacket) {
operator fun set(id: Int, packet: NetFrame) {
ledger[id] = packet
}
operator fun get(id: Int) = ledger[id]!!
fun addPacket(packet: IngameNetPacket): Int {
fun addFrame(frame: NetFrame): Int {
var i = rng.nextInt()
while (ledger.containsKey(i)) {
i = rng.nextInt()
}
ledger[i] = packet
ledger[i] = frame
return i
}