-
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
649 additions
and
2 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
.../kotlin/net/rsprot/protocol/game/outgoing/codec/friendchat/MessageFriendChannelEncoder.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package net.rsprot.protocol.game.outgoing.codec.friendchat | ||
|
||
import io.netty.channel.ChannelHandlerContext | ||
import net.rsprot.buffer.JagByteBuf | ||
import net.rsprot.protocol.ServerProt | ||
import net.rsprot.protocol.channel.ChannelAttributes | ||
import net.rsprot.protocol.game.outgoing.friendchat.MessageFriendChannel | ||
import net.rsprot.protocol.game.outgoing.prot.GameServerProt | ||
import net.rsprot.protocol.message.codec.MessageEncoder | ||
import net.rsprot.protocol.metadata.Consistent | ||
|
||
@Consistent | ||
public class MessageFriendChannelEncoder : MessageEncoder<MessageFriendChannel> { | ||
override val prot: ServerProt = GameServerProt.MESSAGE_FRIENDCHANNEL | ||
|
||
override fun encode( | ||
ctx: ChannelHandlerContext, | ||
buffer: JagByteBuf, | ||
message: MessageFriendChannel, | ||
) { | ||
val huffmanCodec = | ||
ctx.channel().attr(ChannelAttributes.HUFFMAN_CODEC).get() | ||
?: throw IllegalStateException("Huffman codec not initialized.") | ||
buffer.pjstr(message.sender) | ||
buffer.p8(message.channelNameBase37) | ||
buffer.p2(message.worldId) | ||
buffer.p3(message.worldMessageCounter) | ||
buffer.p1(message.chatCrownType) | ||
huffmanCodec.encode(buffer, message.message) | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
...et/rsprot/protocol/game/outgoing/codec/friendchat/UpdateFriendChatChannelFullV1Encoder.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package net.rsprot.protocol.game.outgoing.codec.friendchat | ||
|
||
import io.netty.channel.ChannelHandlerContext | ||
import net.rsprot.buffer.JagByteBuf | ||
import net.rsprot.protocol.ServerProt | ||
import net.rsprot.protocol.game.outgoing.friendchat.UpdateFriendChatChannelFullV1 | ||
import net.rsprot.protocol.game.outgoing.prot.GameServerProt | ||
import net.rsprot.protocol.message.codec.MessageEncoder | ||
import net.rsprot.protocol.metadata.Consistent | ||
|
||
@Consistent | ||
public class UpdateFriendChatChannelFullV1Encoder : MessageEncoder<UpdateFriendChatChannelFullV1> { | ||
override val prot: ServerProt = GameServerProt.UPDATE_FRIENDCHAT_CHANNEL_FULL_V1 | ||
|
||
override fun encode( | ||
ctx: ChannelHandlerContext, | ||
buffer: JagByteBuf, | ||
message: UpdateFriendChatChannelFullV1, | ||
) { | ||
buffer.pjstr(message.channelOwner) | ||
buffer.p8(message.channelNameBase37) | ||
buffer.p1(message.kickRank) | ||
buffer.p1(message.entries.size) | ||
for (entry in message.entries) { | ||
buffer.pjstr(entry.name) | ||
buffer.p2(entry.worldId) | ||
buffer.p1(entry.rank) | ||
buffer.pjstr(entry.worldName) | ||
} | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
...et/rsprot/protocol/game/outgoing/codec/friendchat/UpdateFriendChatChannelFullV2Encoder.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package net.rsprot.protocol.game.outgoing.codec.friendchat | ||
|
||
import io.netty.channel.ChannelHandlerContext | ||
import net.rsprot.buffer.JagByteBuf | ||
import net.rsprot.protocol.ServerProt | ||
import net.rsprot.protocol.game.outgoing.friendchat.UpdateFriendChatChannelFullV2 | ||
import net.rsprot.protocol.game.outgoing.prot.GameServerProt | ||
import net.rsprot.protocol.message.codec.MessageEncoder | ||
import net.rsprot.protocol.metadata.Consistent | ||
|
||
@Consistent | ||
public class UpdateFriendChatChannelFullV2Encoder : MessageEncoder<UpdateFriendChatChannelFullV2> { | ||
override val prot: ServerProt = GameServerProt.UPDATE_FRIENDCHAT_CHANNEL_FULL_V2 | ||
|
||
override fun encode( | ||
ctx: ChannelHandlerContext, | ||
buffer: JagByteBuf, | ||
message: UpdateFriendChatChannelFullV2, | ||
) { | ||
buffer.pjstr(message.channelOwner) | ||
buffer.p8(message.channelNameBase37) | ||
buffer.p1(message.kickRank) | ||
buffer.pSmart1or2(message.entries.size) | ||
for (entry in message.entries) { | ||
buffer.pjstr(entry.name) | ||
buffer.p2(entry.worldId) | ||
buffer.p1(entry.rank) | ||
buffer.pjstr(entry.worldName) | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
...sprot/protocol/game/outgoing/codec/friendchat/UpdateFriendChatChannelSingleUserEncoder.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package net.rsprot.protocol.game.outgoing.codec.friendchat | ||
|
||
import io.netty.channel.ChannelHandlerContext | ||
import net.rsprot.buffer.JagByteBuf | ||
import net.rsprot.protocol.ServerProt | ||
import net.rsprot.protocol.game.outgoing.friendchat.UpdateFriendChatChannelSingleUser | ||
import net.rsprot.protocol.game.outgoing.prot.GameServerProt | ||
import net.rsprot.protocol.message.codec.MessageEncoder | ||
import net.rsprot.protocol.metadata.Consistent | ||
|
||
@Consistent | ||
public class UpdateFriendChatChannelSingleUserEncoder : MessageEncoder<UpdateFriendChatChannelSingleUser> { | ||
override val prot: ServerProt = GameServerProt.UPDATE_FRIENDCHAT_CHANNEL_SINGLEUSER | ||
|
||
override fun encode( | ||
ctx: ChannelHandlerContext, | ||
buffer: JagByteBuf, | ||
message: UpdateFriendChatChannelSingleUser, | ||
) { | ||
val user = message.user | ||
buffer.pjstr(user.name) | ||
buffer.p2(user.worldId) | ||
buffer.p1(user.rank) | ||
if (user is UpdateFriendChatChannelSingleUser.AddedFriendChatUser) { | ||
buffer.pjstr(user.worldName) | ||
} | ||
} | ||
} |
103 changes: 103 additions & 0 deletions
103
...odel/src/main/kotlin/net/rsprot/protocol/game/outgoing/friendchat/MessageFriendChannel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package net.rsprot.protocol.game.outgoing.friendchat | ||
|
||
import net.rsprot.compression.Base37 | ||
import net.rsprot.protocol.message.OutgoingMessage | ||
|
||
/** | ||
* Message friendchannel is used to transmit messages within a friend | ||
* chat channel. | ||
* @property sender the name of the player who is sending the message | ||
* @property channelName the name of the friend chat channel | ||
* @property worldMessageCounter the world-local message counter. | ||
* Each world must have its own message counter which is used to create | ||
* a unique id for each message. This message counter must be | ||
* incrementing with each message that is sent out. | ||
* If two messages share the same unique id (which is a combination of | ||
* the [worldId] and the [worldMessageCounter] properties), | ||
* the client will not render the second message if it already has one | ||
* received in the last 100 messages. | ||
* It is additionally worth noting that servers with low population | ||
* should probably not start the counter at the same value with each | ||
* game boot, as the probability of multiple messages coinciding | ||
* is relatively high in that scenario, given the low quantity of | ||
* messages sent out to begin with. | ||
* Additionally, only the first 24 bits of the counter are utilized, | ||
* meaning a value from 0 to 16,777,215 (inclusive). | ||
* A good starting point for message counting would be to take the | ||
* hour of the year and multiply it by 50,000 when the server boots | ||
* up. This means the roll-over happens roughly after every two weeks. | ||
* Fine-tuning may be used to make it more granular, but the overall | ||
* idea remains the same. | ||
* @property chatCrownType the id of the crown to render next to the | ||
* name of the sender. | ||
* @property message the message to be sent in the friend chat | ||
* channel. | ||
*/ | ||
public class MessageFriendChannel private constructor( | ||
public val sender: String, | ||
public val channelNameBase37: Long, | ||
private val _worldId: UShort, | ||
public val worldMessageCounter: Int, | ||
private val _chatCrownType: UByte, | ||
public val message: String, | ||
) : OutgoingMessage { | ||
public constructor( | ||
sender: String, | ||
channelName: String, | ||
worldId: Int, | ||
worldMessageCounter: Int, | ||
chatCrownType: Int, | ||
message: String, | ||
) : this( | ||
sender, | ||
Base37.encode(channelName), | ||
worldId.toUShort(), | ||
worldMessageCounter, | ||
chatCrownType.toUByte(), | ||
message, | ||
) | ||
|
||
public val channelName: String | ||
get() = Base37.decodeWithCase(channelNameBase37) | ||
public val worldId: Int | ||
get() = _worldId.toInt() | ||
public val chatCrownType: Int | ||
get() = _chatCrownType.toInt() | ||
|
||
override fun equals(other: Any?): Boolean { | ||
if (this === other) return true | ||
if (javaClass != other?.javaClass) return false | ||
|
||
other as MessageFriendChannel | ||
|
||
if (sender != other.sender) return false | ||
if (channelNameBase37 != other.channelNameBase37) return false | ||
if (_worldId != other._worldId) return false | ||
if (worldMessageCounter != other.worldMessageCounter) return false | ||
if (_chatCrownType != other._chatCrownType) return false | ||
if (message != other.message) return false | ||
|
||
return true | ||
} | ||
|
||
override fun hashCode(): Int { | ||
var result = sender.hashCode() | ||
result = 31 * result + channelNameBase37.hashCode() | ||
result = 31 * result + _worldId.hashCode() | ||
result = 31 * result + worldMessageCounter | ||
result = 31 * result + _chatCrownType.hashCode() | ||
result = 31 * result + message.hashCode() | ||
return result | ||
} | ||
|
||
override fun toString(): String { | ||
return "MessageFriendChannel(" + | ||
"sender='$sender', " + | ||
"channelName='$channelName', " + | ||
"worldId=$worldId, " + | ||
"worldMessageCounter=$worldMessageCounter, " + | ||
"chatCrownType=$chatCrownType, " + | ||
"message='$message'" + | ||
")" | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
...c/main/kotlin/net/rsprot/protocol/game/outgoing/friendchat/UpdateFriendChatChannelFull.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package net.rsprot.protocol.game.outgoing.friendchat | ||
|
||
public sealed class UpdateFriendChatChannelFull { | ||
public abstract val channelOwner: String | ||
public abstract val channelName: String | ||
public abstract val kickRank: Int | ||
public abstract val entries: List<FriendChatEntry> | ||
|
||
/** | ||
* A class to contain all the properties of a player in a friend chat. | ||
* @property name the name of the player that is in the friend chat | ||
* @property worldId the id of the world in which the given user is | ||
* @property rank the rank of the given used in this friend chat | ||
* @property worldName world name, unused in OldSchool RuneScape. | ||
*/ | ||
public class FriendChatEntry private constructor( | ||
public val name: String, | ||
private val _worldId: UShort, | ||
private val _rank: Byte, | ||
public val worldName: String, | ||
) { | ||
public constructor( | ||
name: String, | ||
worldId: Int, | ||
rank: Int, | ||
string: String, | ||
) : this( | ||
name, | ||
worldId.toUShort(), | ||
rank.toByte(), | ||
string, | ||
) | ||
|
||
public val worldId: Int | ||
get() = _worldId.toInt() | ||
public val rank: Int | ||
get() = _rank.toInt() | ||
|
||
override fun equals(other: Any?): Boolean { | ||
if (this === other) return true | ||
if (javaClass != other?.javaClass) return false | ||
|
||
other as FriendChatEntry | ||
|
||
if (name != other.name) return false | ||
if (_worldId != other._worldId) return false | ||
if (_rank != other._rank) return false | ||
if (worldName != other.worldName) return false | ||
|
||
return true | ||
} | ||
|
||
override fun hashCode(): Int { | ||
var result = name.hashCode() | ||
result = 31 * result + _worldId.hashCode() | ||
result = 31 * result + _rank.hashCode() | ||
result = 31 * result + worldName.hashCode() | ||
return result | ||
} | ||
|
||
override fun toString(): String { | ||
return "FriendChatEntry(" + | ||
"name='$name', " + | ||
"worldId=$worldId, " + | ||
"rank=$rank, " + | ||
"worldName='$worldName'" + | ||
")" | ||
} | ||
} | ||
} |
Oops, something went wrong.