From 57834374363965198f8870c9f11111d7c8a12d7f Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sat, 24 Mar 2012 13:28:53 +0000 Subject: Added the new 1.2.4's PlayerAbilities packet; restructures packet files for less files, more dense. git-svn-id: http://mc-server.googlecode.com/svn/trunk@431 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/packets/cPacket_Player.cpp | 243 ++++++++++++++++++++++++++++++ source/packets/cPacket_Player.h | 150 ++++++++++++++++++ source/packets/cPacket_PlayerListItem.cpp | 56 ------- source/packets/cPacket_PlayerListItem.h | 30 ---- source/packets/cPacket_PlayerLook.cpp | 46 ------ source/packets/cPacket_PlayerLook.h | 39 ----- source/packets/cPacket_PlayerMoveLook.cpp | 58 ------- source/packets/cPacket_PlayerMoveLook.h | 43 ------ source/packets/cPacket_PlayerPosition.cpp | 53 ------- source/packets/cPacket_PlayerPosition.h | 44 ------ 10 files changed, 393 insertions(+), 369 deletions(-) create mode 100644 source/packets/cPacket_Player.cpp create mode 100644 source/packets/cPacket_Player.h delete mode 100644 source/packets/cPacket_PlayerListItem.cpp delete mode 100644 source/packets/cPacket_PlayerListItem.h delete mode 100644 source/packets/cPacket_PlayerLook.cpp delete mode 100644 source/packets/cPacket_PlayerLook.h delete mode 100644 source/packets/cPacket_PlayerMoveLook.cpp delete mode 100644 source/packets/cPacket_PlayerMoveLook.h delete mode 100644 source/packets/cPacket_PlayerPosition.cpp delete mode 100644 source/packets/cPacket_PlayerPosition.h (limited to 'source/packets') diff --git a/source/packets/cPacket_Player.cpp b/source/packets/cPacket_Player.cpp new file mode 100644 index 000000000..86214d725 --- /dev/null +++ b/source/packets/cPacket_Player.cpp @@ -0,0 +1,243 @@ + +// cPacket_Player.cpp + +/* Implements the player-related packets: + - PlayerAbilities (0xca) + - PlayerListItem (0xc9) + - PlayerLook (0x0c) + - PlayerMoveLook (0x0d) + - PlayerPosition (0x0b) +*/ + +#include "Globals.h" + +#include "cPacket_Player.h" +#include "../cPlayer.h" +#include "../cChatColor.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerAbilities: + +int cPacket_PlayerAbilities::Parse(const char * a_Data, int a_Size) +{ + if (a_Size < 4) + { + return PACKET_INCOMPLETE; + } + m_Invulnerable = (a_Data[0] != 0); + m_IsFlying = (a_Data[1] != 0); + m_CanFly = (a_Data[2] != 0); + m_InstaMine = (a_Data[3] != 0); + return 4; +} + + + + + +void cPacket_PlayerAbilities::Serialize(AString & a_Data) const +{ + char Data[5]; + Data[0] = m_PacketID; + Data[1] = (char)m_Invulnerable; + Data[2] = (char)m_IsFlying; + Data[3] = (char)m_CanFly; + Data[4] = (char)m_InstaMine; + a_Data.append(Data, 5); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerListItem: + +cPacket_PlayerListItem::cPacket_PlayerListItem(const AString & a_PlayerName, bool a_Online, short a_Ping) +{ + m_PacketID = E_PLAYER_LIST_ITEM; + m_PlayerName = a_PlayerName; + m_Online = a_Online; + m_Ping = a_Ping; +} + + + + + +int cPacket_PlayerListItem::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadString16, m_PlayerName, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_Online, TotalBytes); + HANDLE_PACKET_READ(ReadShort, m_Ping, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PlayerListItem::Serialize(AString & a_Data) const +{ + AString PlayerName(m_PlayerName); + if (PlayerName.length() > 16) + { + PlayerName.erase(16); + } + else if (PlayerName.length() <= 14) + { + PlayerName += cChatColor::White; + } + + AppendByte (a_Data, m_PacketID); + AppendString16(a_Data, PlayerName); + AppendBool (a_Data, m_Online); + AppendShort (a_Data, m_Ping); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerLook: + +cPacket_PlayerLook::cPacket_PlayerLook( cPlayer* a_Player ) +{ + m_PacketID = E_PLAYERLOOK; + m_Rotation = a_Player->GetRotation(); + m_Pitch = a_Player->GetPitch(); + m_bFlying = a_Player->GetFlying(); +} + + + + + +int cPacket_PlayerLook::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadFloat, m_Rotation, TotalBytes); + HANDLE_PACKET_READ(ReadFloat, m_Pitch, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PlayerLook::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendFloat (a_Data, m_Rotation); + AppendFloat (a_Data, m_Pitch); + AppendBool (a_Data, m_bFlying); +} + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerMoveLook: + +cPacket_PlayerMoveLook::cPacket_PlayerMoveLook( cPlayer* a_Player ) +{ + m_PacketID = E_PLAYERMOVELOOK; + m_PosX = a_Player->GetPosX(); + m_PosY = a_Player->GetPosY() + 1.65; + m_PosZ = a_Player->GetPosZ(); + m_Stance = a_Player->GetStance(); + m_Rotation = a_Player->GetRotation(); + m_Pitch = a_Player->GetPitch(); + m_bFlying = a_Player->GetFlying(); +} + + + + + +int cPacket_PlayerMoveLook::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadDouble, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_Stance, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadFloat, m_Rotation, TotalBytes); + HANDLE_PACKET_READ(ReadFloat, m_Pitch, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PlayerMoveLook::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendDouble(a_Data, m_PosX); + AppendDouble(a_Data, m_PosY); + AppendDouble(a_Data, m_Stance); + AppendDouble(a_Data, m_PosZ); + AppendFloat (a_Data, m_Rotation); + AppendFloat (a_Data, m_Pitch); + AppendBool (a_Data, m_bFlying); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPacket_PlayerPosition: + +cPacket_PlayerPosition::cPacket_PlayerPosition( cPlayer* a_Player ) +{ + m_PacketID = E_PLAYERPOS; + + m_PosX = a_Player->GetPosX(); + m_PosY = a_Player->GetPosY() + 1.65; + m_PosZ = a_Player->GetPosZ(); + m_Stance = a_Player->GetStance(); + m_bFlying = a_Player->GetFlying(); +} + + + + + +int cPacket_PlayerPosition::Parse(const char * a_Data, int a_Size) +{ + int TotalBytes = 0; + HANDLE_PACKET_READ(ReadDouble, m_PosX, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_PosY, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_Stance, TotalBytes); + HANDLE_PACKET_READ(ReadDouble, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); + return TotalBytes; +} + + + + + +void cPacket_PlayerPosition::Serialize(AString & a_Data) const +{ + AppendByte (a_Data, m_PacketID); + AppendDouble (a_Data, m_PosX); + AppendDouble (a_Data, m_PosY); + AppendDouble (a_Data, m_Stance); + AppendDouble (a_Data, m_PosZ); + AppendBool (a_Data, m_bFlying); +} + + + + diff --git a/source/packets/cPacket_Player.h b/source/packets/cPacket_Player.h new file mode 100644 index 000000000..ce88cc451 --- /dev/null +++ b/source/packets/cPacket_Player.h @@ -0,0 +1,150 @@ + +// cPacket_Player.h + +/* Interfaces to the player-related packets: + - PlayerAbilities (0xca) + - PlayerListItem (0xc9) + - PlayerLook (0x0c) + - PlayerMoveLook (0x0d) + - PlayerPosition (0x0b) +*/ + +#pragma once + + + + + +#include "cPacket.h" + + + + + +// fwd: +class cPlayer; + + + + + +class cPacket_PlayerAbilities : public cPacket +{ +public: + cPacket_PlayerAbilities(void) { m_PacketID = E_PLAYER_LIST_ITEM; } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + virtual cPacket * Clone() const { return new cPacket_PlayerAbilities(*this); } + + bool m_Invulnerable; // Speculation + bool m_IsFlying; + bool m_CanFly; + bool m_InstaMine; // Speculation +} ; + + + + + +class cPacket_PlayerListItem : public cPacket +{ +public: + cPacket_PlayerListItem() { m_PacketID = E_PLAYER_LIST_ITEM; } + cPacket_PlayerListItem(const AString & a_PlayerName, bool a_Online, short a_Ping); + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + virtual cPacket* Clone() const { return new cPacket_PlayerListItem(*this); } + + AString m_PlayerName; // Supports chat coloring, limited to 16 characters. + bool m_Online; + short m_Ping; +} ; + + + + + +class cPacket_PlayerLook : public cPacket +{ +public: + cPacket_PlayerLook() + : m_Rotation( 0 ) + , m_Pitch( 0 ) + , m_bFlying( false ) + { m_PacketID = E_PLAYERLOOK; } + cPacket_PlayerLook( cPlayer* a_Player ); + virtual cPacket* Clone() const { return new cPacket_PlayerLook(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + float m_Rotation; + float m_Pitch; + bool m_bFlying; // Yeah.. wtf +} ; + + + + + +class cPacket_PlayerMoveLook : public cPacket +{ +public: + cPacket_PlayerMoveLook() + : m_PosX( 0.0 ) + , m_PosY( 0.0 ) + , m_Stance( 0.0 ) + , m_PosZ( 0.0 ) + , m_Rotation( 0.f ) + , m_Pitch( 0.f ) + , m_bFlying( false ) + { m_PacketID = E_PLAYERMOVELOOK; } + cPacket_PlayerMoveLook( cPlayer* a_Player ); + virtual cPacket* Clone() const { return new cPacket_PlayerMoveLook(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + double m_PosX; + double m_PosY; + double m_Stance; + double m_PosZ; + float m_Rotation; + float m_Pitch; + bool m_bFlying; // Yeah.. wtf +} ; + + + + + +class cPacket_PlayerPosition : public cPacket +{ +public: + cPacket_PlayerPosition( cPlayer* a_Player ); + cPacket_PlayerPosition() + : m_PosX( 0.0 ) + , m_PosY( 0.0 ) + , m_Stance( 0.0 ) + , m_PosZ( 0.0 ) + , m_bFlying( false ) + { m_PacketID = E_PLAYERPOS; } + virtual cPacket* Clone() const { return new cPacket_PlayerPosition(*this); } + + virtual int Parse(const char * a_Data, int a_Size) override; + virtual void Serialize(AString & a_Data) const override; + + double m_PosX; + double m_PosY; + double m_Stance; + double m_PosZ; + bool m_bFlying; // Yeah.. wtf +} ; + + + + diff --git a/source/packets/cPacket_PlayerListItem.cpp b/source/packets/cPacket_PlayerListItem.cpp deleted file mode 100644 index 3f8be2bde..000000000 --- a/source/packets/cPacket_PlayerListItem.cpp +++ /dev/null @@ -1,56 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_PlayerListItem.h" -#include "../cChatColor.h" - - - - - -cPacket_PlayerListItem::cPacket_PlayerListItem(const AString & a_PlayerName, bool a_Online, short a_Ping) -{ - m_PacketID = E_PLAYER_LIST_ITEM; - m_PlayerName = a_PlayerName; - m_Online = a_Online; - m_Ping = a_Ping; -} - - - - - -int cPacket_PlayerListItem::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadString16, m_PlayerName, TotalBytes); - HANDLE_PACKET_READ(ReadBool, m_Online, TotalBytes); - HANDLE_PACKET_READ(ReadShort, m_Ping, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_PlayerListItem::Serialize(AString & a_Data) const -{ - AString PlayerName(m_PlayerName); - if (PlayerName.length() > 16) - { - PlayerName.erase(16); - } - else if (PlayerName.length() <= 14) - { - PlayerName += cChatColor::White; - } - - AppendByte (a_Data, m_PacketID); - AppendString16(a_Data, PlayerName); - AppendBool (a_Data, m_Online); - AppendShort (a_Data, m_Ping); -} - - - - diff --git a/source/packets/cPacket_PlayerListItem.h b/source/packets/cPacket_PlayerListItem.h deleted file mode 100644 index 45395c556..000000000 --- a/source/packets/cPacket_PlayerListItem.h +++ /dev/null @@ -1,30 +0,0 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPacket_PlayerListItem : public cPacket -{ -public: - cPacket_PlayerListItem() { m_PacketID = E_PLAYER_LIST_ITEM; } - cPacket_PlayerListItem(const AString & a_PlayerName, bool a_Online, short a_Ping); - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - virtual cPacket* Clone() const { return new cPacket_PlayerListItem(*this); } - - AString m_PlayerName; // Supports chat coloring, limited to 16 characters. - bool m_Online; - short m_Ping; - - static const unsigned int c_Size = 6; // Minimal size ( 6 + string ) -}; - - - - diff --git a/source/packets/cPacket_PlayerLook.cpp b/source/packets/cPacket_PlayerLook.cpp deleted file mode 100644 index 75adcf38c..000000000 --- a/source/packets/cPacket_PlayerLook.cpp +++ /dev/null @@ -1,46 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_PlayerLook.h" -#include "../cPlayer.h" - - - - - -cPacket_PlayerLook::cPacket_PlayerLook( cPlayer* a_Player ) -{ - m_PacketID = E_PLAYERLOOK; - m_Rotation = a_Player->GetRotation(); - m_Pitch = a_Player->GetPitch(); - m_bFlying = a_Player->GetFlying(); -} - - - - - -int cPacket_PlayerLook::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadFloat, m_Rotation, TotalBytes); - HANDLE_PACKET_READ(ReadFloat, m_Pitch, TotalBytes); - HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_PlayerLook::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendFloat (a_Data, m_Rotation); - AppendFloat (a_Data, m_Pitch); - AppendBool (a_Data, m_bFlying); -} - - - - diff --git a/source/packets/cPacket_PlayerLook.h b/source/packets/cPacket_PlayerLook.h deleted file mode 100644 index aed8a954d..000000000 --- a/source/packets/cPacket_PlayerLook.h +++ /dev/null @@ -1,39 +0,0 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPlayer; - - - - - -class cPacket_PlayerLook : public cPacket -{ -public: - cPacket_PlayerLook() - : m_Rotation( 0 ) - , m_Pitch( 0 ) - , m_bFlying( false ) - { m_PacketID = E_PLAYERLOOK; } - cPacket_PlayerLook( cPlayer* a_Player ); - virtual cPacket* Clone() const { return new cPacket_PlayerLook(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - float m_Rotation; - float m_Pitch; - bool m_bFlying; // Yeah.. wtf - - static const unsigned int c_Size = 10; -}; - - - - diff --git a/source/packets/cPacket_PlayerMoveLook.cpp b/source/packets/cPacket_PlayerMoveLook.cpp deleted file mode 100644 index 4b0af62e1..000000000 --- a/source/packets/cPacket_PlayerMoveLook.cpp +++ /dev/null @@ -1,58 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_PlayerMoveLook.h" -#include "../cPlayer.h" - - - - - -cPacket_PlayerMoveLook::cPacket_PlayerMoveLook( cPlayer* a_Player ) -{ - m_PacketID = E_PLAYERMOVELOOK; - m_PosX = a_Player->GetPosX(); - m_PosY = a_Player->GetPosY() + 1.65; - m_PosZ = a_Player->GetPosZ(); - m_Stance = a_Player->GetStance(); - m_Rotation = a_Player->GetRotation(); - m_Pitch = a_Player->GetPitch(); - m_bFlying = a_Player->GetFlying(); -} - - - - - -int cPacket_PlayerMoveLook::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadDouble, m_PosX, TotalBytes); - HANDLE_PACKET_READ(ReadDouble, m_PosY, TotalBytes); - HANDLE_PACKET_READ(ReadDouble, m_Stance, TotalBytes); - HANDLE_PACKET_READ(ReadDouble, m_PosZ, TotalBytes); - HANDLE_PACKET_READ(ReadFloat, m_Rotation, TotalBytes); - HANDLE_PACKET_READ(ReadFloat, m_Pitch, TotalBytes); - HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_PlayerMoveLook::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendDouble(a_Data, m_PosX); - AppendDouble(a_Data, m_PosY); - AppendDouble(a_Data, m_Stance); - AppendDouble(a_Data, m_PosZ); - AppendFloat (a_Data, m_Rotation); - AppendFloat (a_Data, m_Pitch); - AppendBool (a_Data, m_bFlying); -} - - - - diff --git a/source/packets/cPacket_PlayerMoveLook.h b/source/packets/cPacket_PlayerMoveLook.h deleted file mode 100644 index c36698839..000000000 --- a/source/packets/cPacket_PlayerMoveLook.h +++ /dev/null @@ -1,43 +0,0 @@ - -#pragma once - -#include "cPacket.h" - - - - - -class cPlayer; - - - - - -class cPacket_PlayerMoveLook : public cPacket -{ -public: - cPacket_PlayerMoveLook() - : m_PosX( 0.0 ) - , m_PosY( 0.0 ) - , m_Stance( 0.0 ) - , m_PosZ( 0.0 ) - , m_Rotation( 0.f ) - , m_Pitch( 0.f ) - , m_bFlying( false ) - { m_PacketID = E_PLAYERMOVELOOK; } - cPacket_PlayerMoveLook( cPlayer* a_Player ); - virtual cPacket* Clone() const { return new cPacket_PlayerMoveLook(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - double m_PosX; - double m_PosY; - double m_Stance; - double m_PosZ; - float m_Rotation; - float m_Pitch; - bool m_bFlying; // Yeah.. wtf - - static const unsigned int c_Size = 42; -}; diff --git a/source/packets/cPacket_PlayerPosition.cpp b/source/packets/cPacket_PlayerPosition.cpp deleted file mode 100644 index 3dae343dd..000000000 --- a/source/packets/cPacket_PlayerPosition.cpp +++ /dev/null @@ -1,53 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPacket_PlayerPosition.h" -#include "../cPlayer.h" - - - - - -cPacket_PlayerPosition::cPacket_PlayerPosition( cPlayer* a_Player ) -{ - m_PacketID = E_PLAYERPOS; - - m_PosX = a_Player->GetPosX(); - m_PosY = a_Player->GetPosY() + 1.65; - m_PosZ = a_Player->GetPosZ(); - m_Stance = a_Player->GetStance(); - m_bFlying = a_Player->GetFlying(); -} - - - - - -int cPacket_PlayerPosition::Parse(const char * a_Data, int a_Size) -{ - int TotalBytes = 0; - HANDLE_PACKET_READ(ReadDouble, m_PosX, TotalBytes); - HANDLE_PACKET_READ(ReadDouble, m_PosY, TotalBytes); - HANDLE_PACKET_READ(ReadDouble, m_Stance, TotalBytes); - HANDLE_PACKET_READ(ReadDouble, m_PosZ, TotalBytes); - HANDLE_PACKET_READ(ReadBool, m_bFlying, TotalBytes); - return TotalBytes; -} - - - - - -void cPacket_PlayerPosition::Serialize(AString & a_Data) const -{ - AppendByte (a_Data, m_PacketID); - AppendDouble (a_Data, m_PosX); - AppendDouble (a_Data, m_PosY); - AppendDouble (a_Data, m_Stance); - AppendDouble (a_Data, m_PosZ); - AppendBool (a_Data, m_bFlying); -} - - - - diff --git a/source/packets/cPacket_PlayerPosition.h b/source/packets/cPacket_PlayerPosition.h deleted file mode 100644 index f883b6a4d..000000000 --- a/source/packets/cPacket_PlayerPosition.h +++ /dev/null @@ -1,44 +0,0 @@ - -#pragma once - -#include "cPacket.h" - - - - - - -class cPlayer; - - - - - -class cPacket_PlayerPosition : public cPacket -{ -public: - cPacket_PlayerPosition( cPlayer* a_Player ); - cPacket_PlayerPosition() - : m_PosX( 0.0 ) - , m_PosY( 0.0 ) - , m_Stance( 0.0 ) - , m_PosZ( 0.0 ) - , m_bFlying( false ) - { m_PacketID = E_PLAYERPOS; } - virtual cPacket* Clone() const { return new cPacket_PlayerPosition(*this); } - - virtual int Parse(const char * a_Data, int a_Size) override; - virtual void Serialize(AString & a_Data) const override; - - double m_PosX; - double m_PosY; - double m_Stance; - double m_PosZ; - bool m_bFlying; // Yeah.. wtf - - static const unsigned int c_Size = 34; -}; - - - - -- cgit v1.2.3