本文整理汇总了C#中Chraft.Net.PacketReader.ReadBytes方法的典型用法代码示例。如果您正苦于以下问题:C# PacketReader.ReadBytes方法的具体用法?C# PacketReader.ReadBytes怎么用?C# PacketReader.ReadBytes使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Chraft.Net.PacketReader
的用法示例。
在下文中一共展示了PacketReader.ReadBytes方法的1个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: HandleStep
/// <summary>
/// 有新資料到達時呼叫的程式
/// </summary>
/// <returns>旗標 (0=斷線, 1=不用回覆, 2=有資料等候回覆)</returns>
/// <remarks>詳細運作方法, 請參考 http://wiki.vg/Protocol_Encryption </remarks>
public int HandleStep() {
byte version;
bool isDisconnect = false;
string ServerHost;
int ServerPort;
try {
PacketReader PR = new PacketReader(Buffer, Buffer.Length);
PacketWriter PW = PacketWriter.CreateInstance();
Queue<byte[]> strings = new Queue<byte[]>();
AppSettingsSection config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).AppSettings;
// 分析客戶端指令
switch(Buffer[0]) {
case 0xFE: // 查詢伺服器資料: 0xFE
ConsoleWriteTime();
Console.WriteLine("@{0} 接收伺服器資訊請求. ", UserName);
// 傳回踢走: 0xFF + 0x00 + (通訊協定版本) + 0x00 + (伺服器版本) + 0x00 + (伺服器名稱) + 0x00 + (在線玩家數) + 0x00 + (在線玩家上限)
PW = kick(String.Format("§1\0{0}\0{1}\0{2}\0{3}\0{4}",
51,
config.Settings["serverVersion"].Value,
config.Settings["motd"].Value,
config.Settings["onlinePlayers"].Value,
config.Settings["maxPlayers"].Value));
isDisconnect = true;
break;
case 0x02: // 接收握手: 0x02 + (客戶端版本) + (玩家 ID) + (伺服器 IP / 網址) + (伺服器連接埠)
version = PR.ReadByte();
UserName = PR.ReadString16(64);
ServerHost = PR.ReadString16(64);
ServerPort = PR.ReadInt();
ConsoleWriteTime();
Console.WriteLine("@{1} 接收握手指令.\n 玩家 {1} 使用通訊協定版本 {0} 連接到 {2}:{3}.",
(int)version, UserName, ServerHost, ServerPort);
strings.Enqueue(ASCIIEncoding.BigEndianUnicode.GetBytes(ConnectionId));
// 傳回加密請求: 0xFD + (伺服器 ID) + (密鑰長度) + (密鑰) + (金幣長度) + (金幣)
PW = PacketWriter.CreateInstance(7 + keyLength + tokenLength, strings);
PW.WriteByte(0xFD);
PW.Write(ConnectionId);
PW.Write(keyLength);
PW.Write(publicKey, 0, keyLength);
PW.Write(tokenLength);
PW.Write(token, 0, tokenLength);
ConsoleWriteTime();
Console.WriteLine("@{3} 送出加密請求指令.\n 伺服器 ID: {0}, 密鑰長度: {1}, 金幣長度: {2}.",
ConnectionId, keyLength, tokenLength, UserName);
break;
case 0xFC: // 接受加密: 0xFC + (分享密碼長度) + (分享密碼) + (已加密的金幣長度) + (已加密的金幣)
short sharedSecretLength = PR.ReadShort();
byte[] sharedSecret = PR.ReadBytes(sharedSecretLength);
short variefyTokenLength = PR.ReadShort();
byte[] variefyToken = PacketCryptography.Decrypt(PR.ReadBytes(variefyTokenLength));
ConsoleWriteTime();
Console.WriteLine("@{2} 接收接受加密指令.\n 分享密碼長度: {0}, 已加密的金幣長度: {1}. ",
sharedSecretLength, variefyTokenLength, UserName);
// 檢查解密後的金幣是否跟傳出去的一樣
if(!variefyToken.SequenceEqual(PacketCryptography.VerifyToken)) {
// 不一樣, 密鑰無效
ConsoleWriteTime();
Console.Write("@{0} 金幣不正確.", UserName);
PW = kick(config.Settings["tokenInvalidText"].Value);
} else {
// 是一樣, 密鑰有效
ConsoleWriteTime();
Console.WriteLine("@{0} 金幣吻合.", UserName);
ConsoleWriteTime();
Console.WriteLine("@{0} 檢查玩家是否正版...", UserName);
// 檢查是否正版
// 查詢地址: http://session.minecraft.net/game/checkserver.jsp?user=(玩家ID)&serverId=(伺服器混湊值)
// 伺服器混湊值 = (伺服器 ID 的 ASCII 碼) + (客戶端傳來的分享密碼) + (伺服器密鑰) -> ...
// ... -> 轉換成 SHA -> 除掉前面的 0 再以二進制補碼補上負號
switch(verifyMinecraft(UserName, PacketCryptography.JavaHexDigest(
Encoding.UTF8.GetBytes(ConnectionId)
.Concat(PacketCryptography.Decrypt(sharedSecret))
.Concat(PacketCryptography.PublicKeyToAsn1(ServerKey)).ToArray()))) {
case -1: // 與官方伺服器連接失敗
ConsoleWriteTime();
Console.WriteLine("@{0} 連接失敗.", UserName);
PW = kick(config.Settings["connectionFailText"].Value);
break;
case 0: // 官方伺服器沒有玩家的登入進程記錄 (不是傳回 YES)
ConsoleWriteTime();
Console.WriteLine("@{0} 得出結果不是正版.", UserName);
PW = kick(config.Settings["verifyFailText"].Value);
break;
case 1: // 官方伺服器有玩家的登入進程記錄 (傳回 YES)
ConsoleWriteTime();
Console.WriteLine("@{0} 得出結果是正版.", UserName);
ConsoleWriteTime();
Console.WriteLine("@{0} 傳送驗證碼...", UserName);
// 傳送驗證碼到指定的網頁
string randomcode = getRandomCapcha();
if(sendCode(config.Settings["successWebPage"].Value, UserName, randomcode, remoteIP)) {
// 傳送成功, 把傳送出去的驗證碼也傳給客戶端
ConsoleWriteTime();
Console.WriteLine("@{0} 驗證碼已傳送.", UserName);
PW = kick(String.Format(config.Settings["successText"].Value, randomcode));
//.........这里部分代码省略.........