Documentation ¶
Overview ¶
Package hotline provides Hotline client and server implementations.
Index ¶
- Constants
- Variables
- func CalcItemCount(filePath string) ([]byte, error)
- func CalcTotalSize(filePath string) ([]byte, error)
- func DownloadFolderHandler(rwc io.ReadWriter, fullPath string, fileTransfer *FileTransfer, ...) error
- func DownloadHandler(w io.Writer, fullPath string, fileTransfer *FileTransfer, fs FileStore, ...) error
- func EncodeFilePath(filePath string) []byte
- func EncodeString(clearText []byte) []byte
- func FieldScanner(data []byte, _ bool) (advance int, token []byte, err error)
- func HashAndSalt(pwd []byte) string
- func NewFileWrapper(fs FileStore, path string, dataOffset int64) (*fileWrapper, error)
- func ReadPath(fileRoot string, filePath, fileName []byte) (fullPath string, err error)
- func UploadFolderHandler(rwc io.ReadWriter, fullPath string, fileTransfer *FileTransfer, ...) error
- func UploadHandler(rwc io.ReadWriter, fullPath string, fileTransfer *FileTransfer, ...) error
- func WithConfig(config Config) func(s *Server)
- func WithInterface(netInterface string) func(s *Server)
- func WithLogger(logger *slog.Logger) func(s *Server)
- func WithPort(port int) func(s *Server)
- type AccessBitmap
- type Account
- type AccountManager
- type BanMgr
- type ChatID
- type ChatManager
- type Client
- func (c *Client) Connect(address, login, passwd string) (err error)
- func (c *Client) Disconnect() error
- func (c *Client) HandleFunc(tranType [2]byte, handler ClientHandler)
- func (c *Client) HandleTransaction(ctx context.Context, t *Transaction) error
- func (c *Client) HandleTransactions(ctx context.Context) error
- func (c *Client) Handshake() error
- func (c *Client) Send(t Transaction) error
- type ClientConn
- func (cc *ClientConn) Authenticate(login string, password []byte) bool
- func (cc *ClientConn) Authorize(access int) bool
- func (cc *ClientConn) Disconnect()
- func (cc *ClientConn) FileRoot() string
- func (cc *ClientConn) NewErrReply(t *Transaction, errMsg string) []Transaction
- func (cc *ClientConn) NewFileTransfer(transferType FileTransferType, fileroot string, ...) *FileTransfer
- func (cc *ClientConn) NewReply(t *Transaction, fields ...Field) Transaction
- func (cc *ClientConn) NotifyOthers(t Transaction) (trans []Transaction)
- func (cc *ClientConn) SendAll(t [2]byte, fields ...Field)
- func (cc *ClientConn) String() string
- type ClientFileTransferMgr
- type ClientHandler
- type ClientID
- type ClientManager
- type ClientPrefs
- type ClientTHandler
- type ClientTransaction
- type Config
- type Counter
- type Dialer
- type Field
- type FileHeader
- type FileNameWithInfo
- type FileNameWithInfoHeader
- type FilePath
- type FilePathItem
- type FileResumeData
- type FileStore
- type FileTransfer
- type FileTransferID
- type FileTransferMgr
- type FileTransferType
- type FlatFileForkHeader
- type FlatFileHeader
- type FlatFileInformationFork
- func (ffif *FlatFileInformationFork) DataSize() []byte
- func (ffif *FlatFileInformationFork) FriendlyCreator() []byte
- func (ffif *FlatFileInformationFork) FriendlyType() []byte
- func (ffif *FlatFileInformationFork) Read(p []byte) (int, error)
- func (ffif *FlatFileInformationFork) ReadNameSize() []byte
- func (ffif *FlatFileInformationFork) SetComment(comment []byte) error
- func (ffif *FlatFileInformationFork) Size() [4]byte
- func (ffif *FlatFileInformationFork) UnmarshalBinary(b []byte) error
- func (ffif *FlatFileInformationFork) Write(p []byte) (int, error)
- type ForkInfoList
- type HandlerFunc
- type MemChatManager
- func (cm *MemChatManager) GetSubject(id ChatID) string
- func (cm *MemChatManager) Join(id ChatID, cc *ClientConn)
- func (cm *MemChatManager) Leave(id ChatID, clientID [2]byte)
- func (cm *MemChatManager) Members(id ChatID) []*ClientConn
- func (cm *MemChatManager) New(cc *ClientConn) ChatID
- func (cm *MemChatManager) SetSubject(id ChatID, subject string)
- type MemClientMgr
- type MemFileTransferMgr
- type MockChatManager
- func (m *MockChatManager) GetSubject(id ChatID) string
- func (m *MockChatManager) Join(id ChatID, cc *ClientConn)
- func (m *MockChatManager) Leave(id ChatID, clientID [2]byte)
- func (m *MockChatManager) Members(id ChatID) []*ClientConn
- func (m *MockChatManager) New(cc *ClientConn) ChatID
- func (m *MockChatManager) SetSubject(id ChatID, subject string)
- type MockClientMgr
- type MockFileInfo
- type MockFileStore
- func (mfs *MockFileStore) Create(name string) (*os.File, error)
- func (mfs *MockFileStore) Mkdir(name string, perm os.FileMode) error
- func (mfs *MockFileStore) Open(name string) (*os.File, error)
- func (mfs *MockFileStore) OpenFile(name string, flag int, perm fs.FileMode) (*os.File, error)
- func (mfs *MockFileStore) ReadFile(name string) ([]byte, error)
- func (mfs *MockFileStore) Remove(name string) error
- func (mfs *MockFileStore) RemoveAll(name string) error
- func (mfs *MockFileStore) Rename(oldpath, newpath string) error
- func (mfs *MockFileStore) Stat(name string) (os.FileInfo, error)
- func (mfs *MockFileStore) Symlink(oldname, newname string) error
- func (mfs *MockFileStore) WriteFile(name string, data []byte, perm fs.FileMode) error
- type MockThreadNewsMgr
- func (m *MockThreadNewsMgr) CreateGrouping(newsPath []string, name string, itemType [2]byte) error
- func (m *MockThreadNewsMgr) DeleteArticle(newsPath []string, articleID uint32, recursive bool) error
- func (m *MockThreadNewsMgr) DeleteNewsItem(newsPath []string) error
- func (m *MockThreadNewsMgr) GetArticle(newsPath []string, articleID uint32) *NewsArtData
- func (m *MockThreadNewsMgr) GetCategories(paths []string) []NewsCategoryListData15
- func (m *MockThreadNewsMgr) ListArticles(newsPath []string) NewsArtListData
- func (m *MockThreadNewsMgr) NewsItem(newsPath []string) NewsCategoryListData15
- func (m *MockThreadNewsMgr) PostArticle(newsPath []string, parentArticleID uint32, article NewsArtData) error
- type NewsArtData
- type NewsArtList
- type NewsArtListData
- type NewsCategoryListData15
- type NewsFlavorList
- type OSFileStore
- func (fs *OSFileStore) Create(name string) (*os.File, error)
- func (fs *OSFileStore) Mkdir(name string, perm os.FileMode) error
- func (fs *OSFileStore) Open(name string) (*os.File, error)
- func (fs *OSFileStore) OpenFile(name string, flag int, perm fs.FileMode) (*os.File, error)
- func (fs *OSFileStore) ReadFile(name string) ([]byte, error)
- func (fs *OSFileStore) Remove(name string) error
- func (fs *OSFileStore) RemoveAll(name string) error
- func (fs *OSFileStore) Rename(oldpath string, newpath string) error
- func (fs *OSFileStore) Stat(name string) (os.FileInfo, error)
- func (fs *OSFileStore) Symlink(oldname, newname string) error
- func (fs *OSFileStore) WriteFile(name string, data []byte, perm fs.FileMode) error
- type Option
- type PrivateChat
- type RealDialer
- type Server
- func (s *Server) CurrentStats() map[string]interface{}
- func (s *Server) HandleFunc(tranType [2]byte, handler HandlerFunc)
- func (s *Server) ListenAndServe(ctx context.Context) error
- func (s *Server) NewClientConn(conn io.ReadWriteCloser, remoteAddr string) *ClientConn
- func (s *Server) SendAll(t TranType, fields ...Field)
- func (s *Server) Serve(ctx context.Context, ln net.Listener) error
- func (s *Server) ServeFileTransfers(ctx context.Context, ln net.Listener) error
- func (s *Server) Shutdown(msg []byte)
- type ServerConfig
- type ServerInfoHeader
- type ServerRecord
- type Stats
- type ThreadedNews
- type ThreadedNewsMgr
- type Time
- type TrackerHeader
- type TrackerRegistration
- type TranType
- type Transaction
- type User
- type UserFlags
- type WriteCounter
Constants ¶
const ( AccessDeleteFile = 0 // File System Maintenance: Can Delete Files AccessUploadFile = 1 // File System Maintenance: Can Upload Files AccessDownloadFile = 2 // File System Maintenance: Can Download Files AccessRenameFile = 3 // File System Maintenance: Can Rename Files AccessMoveFile = 4 // File System Maintenance: Can Move Files AccessCreateFolder = 5 // File System Maintenance: Can Create Folders AccessDeleteFolder = 6 // File System Maintenance: Can Delete Folders AccessRenameFolder = 7 // File System Maintenance: Can Rename Folders AccessMoveFolder = 8 // File System Maintenance: Can Move Folders AccessReadChat = 9 // Chat: Can Read Chat AccessSendChat = 10 // Chat: Can Send Chat AccessOpenChat = 11 // Chat: Can Initial Private Chat AccessCloseChat = 12 // Present in the Hotline 1.9 protocol documentation, but seemingly unused AccessShowInList = 13 // Present in the Hotline 1.9 protocol documentation, but seemingly unused AccessCreateUser = 14 // User Maintenance: Can Create Accounts AccessDeleteUser = 15 // User Maintenance: Can Delete Accounts AccessOpenUser = 16 // User Maintenance: Can Read Accounts AccessModifyUser = 17 // User Maintenance: Can Modify Accounts AccessChangeOwnPass = 18 // Present in the Hotline 1.9 protocol documentation, but seemingly unused AccessNewsReadArt = 20 // News: Can Read Articles AccessNewsPostArt = 21 // News: Can Post Articles AccessDisconUser = 22 // User Maintenance: Can Disconnect Users (Note: Turns username red in user list) AccessCannotBeDiscon = 23 // User Maintenance: Cannot be Disconnected AccessGetClientInfo = 24 // User Maintenance: Can Get User Info AccessUploadAnywhere = 25 // File System Maintenance: Can Upload Anywhere AccessAnyName = 26 // Miscellaneous: Can User Any Name AccessNoAgreement = 27 // Miscellaneous: Don't Show Agreement AccessSetFileComment = 28 // File System Maintenance: Can Comment Files AccessSetFolderComment = 29 // File System Maintenance: Can Comment Folders AccessViewDropBoxes = 30 // File System Maintenance: Can View Drop Boxes AccessMakeAlias = 31 // File System Maintenance: Can Make Aliases AccessBroadcast = 32 // Messaging: Can Broadcast AccessNewsDeleteArt = 33 // News: Can Delete Articles AccessNewsCreateCat = 34 // News: Can Create Categories AccessNewsDeleteCat = 35 // News: Can Delete Categories AccessNewsCreateFldr = 36 // News: Can Create News Bundles AccessNewsDeleteFldr = 37 // News: Can Delete News Bundles AccessUploadFolder = 38 // File System Maintenance: Can Upload Folders AccessDownloadFolder = 39 // File System Maintenance: Can Download Folders AccessSendPrivMsg = 40 // Messaging: Can Send Messages (Note: 1.9 protocol doc incorrectly says this is bit 19) )
const ( DlFldrActionSendFile = 1 DlFldrActionResumeFile = 2 DlFldrActionNextFile = 3 )
Folder download actions. Send by the client to indicate the next action the server should take for a folder download.
const ( FileDownload = FileTransferType(0) FileUpload = FileTransferType(1) FolderDownload = FileTransferType(2) FolderUpload = FileTransferType(3) BannerDownload = FileTransferType(4) )
const ( IncompleteFileSuffix = ".incomplete" InfoForkNameTemplate = ".info_%s" // template string for info fork filenames RsrcForkNameTemplate = ".rsrc_%s" // template string for resource fork filenames )
const ( StatCurrentlyConnected = iota StatDownloadsInProgress StatUploadsInProgress StatWaitingDownloads StatConnectionPeak StatConnectionCounter StatDownloadCounter StatUploadCounter )
Stat counter keys
const ( UserFlagAway = 0 // User is away UserFlagAdmin = 1 // User is admin UserFlagRefusePM = 2 // User refuses private messages UserFlagRefusePChat = 3 // User refuses private chat )
User flags are stored as a 2 byte bitmap and represent various user states
const ( UserOptRefusePM = 0 // User has "Refuse private messages" pref set UserOptRefuseChat = 1 // User has "Refuse private chat" pref set UserOptAutoResponse = 2 // User has "Automatic response" pref set )
User options are sent from clients and represent options set in the client's preferences.
const BanDuration = 30 * time.Minute
BanDuration is the length of time for temporary bans.
const GuestAccount = "guest" // default account used when no login is provided for a connection
const LimitChatMsg = 8192
The total size of a chat message data field is 8192 bytes.
const NewsDateFormat = "Jan02 15:04" // Jun23 20:49
const NewsTemplate = `From %s (%s):
%s
__________________________________________________________`
Variables ¶
var ( FieldError = [2]byte{0x00, 0x64} // 100 FieldData = [2]byte{0x00, 0x65} // 101 FieldUserName = [2]byte{0x00, 0x66} // 102 FieldUserID = [2]byte{0x00, 0x67} // 103 FieldUserIconID = [2]byte{0x00, 0x68} // 104 FieldUserLogin = [2]byte{0x00, 0x69} // 105 FieldUserPassword = [2]byte{0x00, 0x6A} // 106 FieldRefNum = [2]byte{0x00, 0x6B} // 107 FieldTransferSize = [2]byte{0x00, 0x6C} // 108 FieldChatOptions = [2]byte{0x00, 0x6D} // 109 FieldUserAccess = [2]byte{0x00, 0x6E} // 110 FieldUserFlags = [2]byte{0x00, 0x70} // 112 FieldOptions = [2]byte{0x00, 0x71} // 113 FieldChatID = [2]byte{0x00, 0x72} // 114 FieldChatSubject = [2]byte{0x00, 0x73} // 115 FieldWaitingCount = [2]byte{0x00, 0x74} // 116 FieldBannerType = [2]byte{0x00, 0x98} // 152 FieldNoServerAgreement = [2]byte{0x00, 0x98} // 152 FieldVersion = [2]byte{0x00, 0xA0} // 160 FieldCommunityBannerID = [2]byte{0x00, 0xA1} // 161 FieldServerName = [2]byte{0x00, 0xA2} // 162 FieldFileNameWithInfo = [2]byte{0x00, 0xC8} // 200 FieldFileName = [2]byte{0x00, 0xC9} // 201 FieldFilePath = [2]byte{0x00, 0xCA} // 202 FieldFileResumeData = [2]byte{0x00, 0xCB} // 203 FieldFileTransferOptions = [2]byte{0x00, 0xCC} // 204 FieldFileTypeString = [2]byte{0x00, 0xCD} // 205 FieldFileCreatorString = [2]byte{0x00, 0xCE} // 206 FieldFileSize = [2]byte{0x00, 0xCF} // 207 FieldFileCreateDate = [2]byte{0x00, 0xD0} // 208 FieldFileModifyDate = [2]byte{0x00, 0xD1} // 209 FieldFileComment = [2]byte{0x00, 0xD2} // 210 FieldFileNewName = [2]byte{0x00, 0xD3} // 211 FieldFileNewPath = [2]byte{0x00, 0xD4} // 212 FieldFileType = [2]byte{0x00, 0xD5} // 213 FieldQuotingMsg = [2]byte{0x00, 0xD6} // 214 FieldAutomaticResponse = [2]byte{0x00, 0xD7} // 215 FieldFolderItemCount = [2]byte{0x00, 0xDC} // 220 FieldUsernameWithInfo = [2]byte{0x01, 0x2C} // 300 FieldNewsArtListData = [2]byte{0x01, 0x41} // 321 FieldNewsCatName = [2]byte{0x01, 0x42} // 322 FieldNewsCatListData15 = [2]byte{0x01, 0x43} // 323 FieldNewsPath = [2]byte{0x01, 0x45} // 325 FieldNewsArtID = [2]byte{0x01, 0x46} // 326 FieldNewsArtDataFlav = [2]byte{0x01, 0x47} // 327 FieldNewsArtTitle = [2]byte{0x01, 0x48} // 328 FieldNewsArtPoster = [2]byte{0x01, 0x49} // 329 FieldNewsArtDate = [2]byte{0x01, 0x4A} // 330 FieldNewsArtPrevArt = [2]byte{0x01, 0x4B} // 331 FieldNewsArtNextArt = [2]byte{0x01, 0x4C} // 332 FieldNewsArtData = [2]byte{0x01, 0x4D} // 333 FieldNewsArtParentArt = [2]byte{0x01, 0x4F} // 335 FieldNewsArt1stChildArt = [2]byte{0x01, 0x50} // 336 FieldNewsArtRecurseDel = [2]byte{0x01, 0x51} // 337 )
List of Hotline protocol field types taken from the official 1.9 protocol document
var ( NewsBundle = [2]byte{0, 2} NewsCategory = [2]byte{0, 3} )
var ( NewsFlavorLen = []byte{0x0a} NewsFlavor = []byte("text/plain") )
var ( TranError = TranType{0x00, 0x00} // 0 TranGetMsgs = TranType{0x00, 0x65} // 101 TranNewMsg = TranType{0x00, 0x66} // 102 TranOldPostNews = TranType{0x00, 0x67} // 103 TranServerMsg = TranType{0x00, 0x68} // 104 TranChatSend = TranType{0x00, 0x69} // 105 TranChatMsg = TranType{0x00, 0x6A} // 106 TranLogin = TranType{0x00, 0x6B} // 107 TranSendInstantMsg = TranType{0x00, 0x6C} // 108 TranShowAgreement = TranType{0x00, 0x6D} // 109 TranDisconnectUser = TranType{0x00, 0x6E} // 110 TranDisconnectMsg = TranType{0x00, 0x6F} // 111 TranInviteNewChat = TranType{0x00, 0x70} // 112 TranInviteToChat = TranType{0x00, 0x71} // 113 TranRejectChatInvite = TranType{0x00, 0x72} // 114 TranJoinChat = TranType{0x00, 0x73} // 115 TranLeaveChat = TranType{0x00, 0x74} // 116 TranNotifyChatChangeUser = TranType{0x00, 0x75} // 117 TranNotifyChatDeleteUser = TranType{0x00, 0x76} // 118 TranNotifyChatSubject = TranType{0x00, 0x77} // 119 TranSetChatSubject = TranType{0x00, 0x78} // 120 TranAgreed = TranType{0x00, 0x79} // 121 TranServerBanner = TranType{0x00, 0x7A} // 122 TranGetFileNameList = TranType{0x00, 0xC8} // 200 TranDownloadFile = TranType{0x00, 0xCA} // 202 TranUploadFile = TranType{0x00, 0xCB} // 203 TranNewFolder = TranType{0x00, 0xCD} // 205 TranDeleteFile = TranType{0x00, 0xCC} // 204 TranGetFileInfo = TranType{0x00, 0xCE} // 206 TranSetFileInfo = TranType{0x00, 0xCF} // 207 TranMoveFile = TranType{0x00, 0xD0} // 208 TranMakeFileAlias = TranType{0x00, 0xD1} // 209 TranDownloadFldr = TranType{0x00, 0xD2} // 210 TranDownloadInfo = TranType{0x00, 0xD3} // 211 TranDownloadBanner = TranType{0x00, 0xD4} // 212 TranUploadFldr = TranType{0x00, 0xD5} // 213 TranGetUserNameList = TranType{0x01, 0x2C} // 300 TranNotifyChangeUser = TranType{0x01, 0x2D} // 301 TranNotifyDeleteUser = TranType{0x01, 0x2E} // 302 TranGetClientInfoText = TranType{0x01, 0x2F} // 303 TranSetClientUserInfo = TranType{0x01, 0x30} // 304 TranListUsers = TranType{0x01, 0x5C} // 348 TranUpdateUser = TranType{0x01, 0x5D} // 349 TranNewUser = TranType{0x01, 0x5E} // 350 TranDeleteUser = TranType{0x01, 0x5F} // 351 TranGetUser = TranType{0x01, 0x60} // 352 TranSetUser = TranType{0x01, 0x61} // 353 TranUserAccess = TranType{0x01, 0x62} // 354 TranUserBroadcast = TranType{0x01, 0x63} // 355 TranGetNewsCatNameList = TranType{0x01, 0x72} // 370 TranGetNewsArtNameList = TranType{0x01, 0x73} // 371 TranDelNewsItem = TranType{0x01, 0x7C} // 380 TranNewNewsFldr = TranType{0x01, 0x7D} // 381 TranNewNewsCat = TranType{0x01, 0x7E} // 382 TranGetNewsArtData = TranType{0x01, 0x90} // 400 TranPostNewsArt = TranType{0x01, 0x9A} // 410 TranDelNewsArt = TranType{0x01, 0x9B} // 411 TranKeepAlive = TranType{0x01, 0xF4} // 500 )
var ClientHandshake = []byte{
0x54, 0x52, 0x54, 0x50,
0x48, 0x4f, 0x54, 0x4c,
0x00, 0x01,
0x00, 0x02,
}
var HTXF = [4]byte{0x48, 0x54, 0x58, 0x46} // (HTXF) is the only supported transfer protocol
var ServerHandshake = []byte{
0x54, 0x52, 0x54, 0x50,
0x00, 0x00, 0x00, 0x00,
}
Functions ¶
func CalcItemCount ¶
CalcItemCount recurses through a file path and counts the number of non-hidden files.
func CalcTotalSize ¶
func DownloadFolderHandler ¶ added in v0.13.0
func DownloadFolderHandler(rwc io.ReadWriter, fullPath string, fileTransfer *FileTransfer, fileStore FileStore, rLogger *slog.Logger, preserveForks bool) error
func DownloadHandler ¶ added in v0.13.0
func EncodeFilePath ¶
func EncodeString ¶ added in v0.13.0
EncodeString takes []byte s containing cleartext and rotates by 255 into obfuscated cleartext. The Hotline protocol uses this format for sending passwords over network. Not secure, but hey, it was the 90s!
func FieldScanner ¶ added in v0.13.0
FieldScanner implements bufio.SplitFunc for parsing byte slices into complete tokens
func HashAndSalt ¶ added in v0.13.0
HashAndSalt generates a password hash from a users obfuscated plaintext password
func NewFileWrapper ¶ added in v0.13.0
func UploadFolderHandler ¶ added in v0.13.0
func UploadFolderHandler(rwc io.ReadWriter, fullPath string, fileTransfer *FileTransfer, fileStore FileStore, rLogger *slog.Logger, preserveForks bool) error
func UploadHandler ¶ added in v0.13.0
func UploadHandler(rwc io.ReadWriter, fullPath string, fileTransfer *FileTransfer, fileStore FileStore, rLogger *slog.Logger, preserveForks bool) error
func WithConfig ¶ added in v0.13.0
func WithInterface ¶ added in v0.13.0
WithInterface optionally sets a specific interface to listen on.
func WithLogger ¶ added in v0.13.0
Types ¶
type AccessBitmap ¶ added in v0.13.0
type AccessBitmap [8]byte
func (*AccessBitmap) IsSet ¶ added in v0.13.0
func (bits *AccessBitmap) IsSet(i int) bool
func (AccessBitmap) MarshalYAML ¶ added in v0.17.0
func (bits AccessBitmap) MarshalYAML() (interface{}, error)
func (*AccessBitmap) Set ¶ added in v0.13.0
func (bits *AccessBitmap) Set(i int)
func (*AccessBitmap) UnmarshalYAML ¶ added in v0.17.0
func (bits *AccessBitmap) UnmarshalYAML(unmarshal func(interface{}) error) error
type Account ¶
type Account struct { Login string `yaml:"Login"` Name string `yaml:"Name"` Password string `yaml:"Password"` Access AccessBitmap `yaml:"Access"` FileRoot string `yaml:"FileRoot"` // contains filtered or unexported fields }
func NewAccount ¶ added in v0.13.0
func NewAccount(login, name, password string, access AccessBitmap) *Account
type AccountManager ¶ added in v0.13.0
type ChatManager ¶ added in v0.13.0
type ChatManager interface { New(cc *ClientConn) ChatID GetSubject(id ChatID) string Join(id ChatID, cc *ClientConn) Leave(id ChatID, clientID [2]byte) SetSubject(id ChatID, subject string) Members(id ChatID) []*ClientConn }
type Client ¶
type Client struct { Connection net.Conn Logger *slog.Logger Pref *ClientPrefs Handlers map[[2]byte]ClientHandler UserList []User // contains filtered or unexported fields }
func (*Client) Connect ¶ added in v0.10.19
JoinServer connects to a Hotline server and completes the login flow
func (*Client) Disconnect ¶
func (*Client) HandleFunc ¶ added in v0.10.20
func (c *Client) HandleFunc(tranType [2]byte, handler ClientHandler)
func (*Client) HandleTransaction ¶
func (c *Client) HandleTransaction(ctx context.Context, t *Transaction) error
func (*Client) HandleTransactions ¶ added in v0.10.19
func (*Client) Send ¶
func (c *Client) Send(t Transaction) error
type ClientConn ¶
type ClientConn struct { Connection io.ReadWriteCloser RemoteAddr string ID ClientID Icon []byte // TODO: make fixed size of 2 Version []byte // TODO: make fixed size of 2 FlagsMU sync.Mutex // TODO: move into UserFlags struct Flags UserFlags UserName []byte Account *Account IdleTime int Server *Server // TODO: consider adding methods to interact with server AutoReply []byte ClientFileTransferMgr ClientFileTransferMgr Logger *slog.Logger // contains filtered or unexported fields }
ClientConn represents a client connected to a Server
func (*ClientConn) Authenticate ¶
func (cc *ClientConn) Authenticate(login string, password []byte) bool
func (*ClientConn) Authorize ¶
func (cc *ClientConn) Authorize(access int) bool
Authorize checks if the user account has the specified permission
func (*ClientConn) Disconnect ¶
func (cc *ClientConn) Disconnect()
Disconnect notifies other clients that a client has disconnected and closes the connection.
func (*ClientConn) FileRoot ¶ added in v0.14.0
func (cc *ClientConn) FileRoot() string
func (*ClientConn) NewErrReply ¶
func (cc *ClientConn) NewErrReply(t *Transaction, errMsg string) []Transaction
NewErrReply returns an error reply Transaction with errMsg
func (*ClientConn) NewFileTransfer ¶ added in v0.13.0
func (cc *ClientConn) NewFileTransfer(transferType FileTransferType, fileroot string, fileName, filePath, size []byte) *FileTransfer
func (*ClientConn) NewReply ¶
func (cc *ClientConn) NewReply(t *Transaction, fields ...Field) Transaction
NewReply returns a reply Transaction with fields for the ClientConn
func (*ClientConn) NotifyOthers ¶
func (cc *ClientConn) NotifyOthers(t Transaction) (trans []Transaction)
NotifyOthers sends transaction t to other clients connected to the server
func (*ClientConn) SendAll ¶ added in v0.13.0
func (cc *ClientConn) SendAll(t [2]byte, fields ...Field)
func (*ClientConn) String ¶ added in v0.7.0
func (cc *ClientConn) String() string
type ClientFileTransferMgr ¶ added in v0.13.0
type ClientFileTransferMgr struct {
// contains filtered or unexported fields
}
func NewClientFileTransferMgr ¶ added in v0.13.0
func NewClientFileTransferMgr() ClientFileTransferMgr
func (*ClientFileTransferMgr) Add ¶ added in v0.13.0
func (cftm *ClientFileTransferMgr) Add(ftType FileTransferType, ft *FileTransfer)
func (*ClientFileTransferMgr) Delete ¶ added in v0.13.0
func (cftm *ClientFileTransferMgr) Delete(ftType FileTransferType, id FileTransferID)
func (*ClientFileTransferMgr) Get ¶ added in v0.13.0
func (cftm *ClientFileTransferMgr) Get(ftType FileTransferType) []FileTransfer
type ClientHandler ¶ added in v0.10.20
type ClientHandler func(context.Context, *Client, *Transaction) ([]Transaction, error)
type ClientManager ¶ added in v0.13.0
type ClientManager interface { List() []*ClientConn // Returns list of sorted clients Get(id ClientID) *ClientConn Add(cc *ClientConn) Delete(id ClientID) }
type ClientPrefs ¶
type ClientPrefs struct { Username string `yaml:"Username"` IconID int `yaml:"IconID"` Tracker string `yaml:"Tracker"` EnableBell bool `yaml:"EnableBell"` }
func (*ClientPrefs) IconBytes ¶
func (cp *ClientPrefs) IconBytes() []byte
type ClientTHandler ¶ added in v0.10.19
type ClientTHandler interface {
Handle(*Client, *Transaction) ([]Transaction, error)
}
type ClientTransaction ¶ added in v0.10.19
type ClientTransaction struct { Name string Handler func(*Client, *Transaction) ([]Transaction, error) }
func (ClientTransaction) Handle ¶ added in v0.10.19
func (ch ClientTransaction) Handle(cc *Client, t *Transaction) ([]Transaction, error)
type Config ¶
type Config struct { Name string `yaml:"Name" validate:"required,max=50"` // Name used for Tracker registration Description string `yaml:"Description" validate:"required,max=200"` // Description used for Tracker registration BannerFile string `yaml:"BannerFile"` // Path to Banner jpg FileRoot string `yaml:"FileRoot" validate:"required"` // Path to Files EnableTrackerRegistration bool `yaml:"EnableTrackerRegistration"` // Toggle Tracker Registration Trackers []string `yaml:"Trackers" validate:"dive,hostname_port"` // List of trackers that the server should register with NewsDelimiter string `yaml:"NewsDelimiter"` // String used to separate news posts NewsDateFormat string `yaml:"NewsDateFormat"` // Go template string to customize news date format MaxDownloads int `yaml:"MaxDownloads"` // Global simultaneous download limit MaxDownloadsPerClient int `yaml:"MaxDownloadsPerClient"` // Per client simultaneous download limit MaxConnectionsPerIP int `yaml:"MaxConnectionsPerIP"` // Max connections per IP PreserveResourceForks bool `yaml:"PreserveResourceForks"` // Enable preservation of file info and resource forks in sidecar files IgnoreFiles []string `yaml:"IgnoreFiles"` // List of regular expression for filtering files from the file list EnableBonjour bool `yaml:"EnableBonjour"` // Enable service announcement on local network with Bonjour }
type Field ¶
type Field struct { Type [2]byte // Type of field FieldSize [2]byte // Size of the data field Data []byte // Field data // contains filtered or unexported fields }
func GetFileNameList ¶ added in v0.13.0
func (*Field) DecodeInt ¶ added in v0.13.0
DecodeInt decodes the field bytes to an int. The official Hotline clients will send uint32s as 2 bytes if possible, but some third party clients such as Frogblast and Heildrun will always send 4 bytes
func (*Field) DecodeNewsPath ¶ added in v0.13.0
DecodeNewsPath decodes the field data to a news path. Example News Path data for a Category nested under two Bundles: 00000000 00 03 00 00 10 54 6f 70 20 4c 65 76 65 6c 20 42 |.....Top Level B| 00000010 75 6e 64 6c 65 00 00 13 53 65 63 6f 6e 64 20 4c |undle...Second L| 00000020 65 76 65 6c 20 42 75 6e 64 6c 65 00 00 0f 4e 65 |evel Bundle...Ne| 00000030 73 74 65 64 20 43 61 74 65 67 6f 72 79 |sted Category|
func (*Field) DecodeObfuscatedString ¶ added in v0.13.0
type FileHeader ¶
type FileHeader struct { Size [2]byte // Total size of FileHeader payload Type [2]byte // 0 for file, 1 for dir FilePath []byte // encoded file path // contains filtered or unexported fields }
func NewFileHeader ¶
func NewFileHeader(fileName string, isDir bool) FileHeader
type FileNameWithInfo ¶
type FileNameWithInfo struct { FileNameWithInfoHeader Name []byte // File Name // contains filtered or unexported fields }
type FileNameWithInfoHeader ¶ added in v0.13.0
type FileNameWithInfoHeader struct { Type [4]byte // File type code Creator [4]byte // File creator code FileSize [4]byte // File Size in bytes RSVD [4]byte NameScript [2]byte // ?? NameSize [2]byte // Length of Name field }
FileNameWithInfoHeader contains the fixed length fields of FileNameWithInfo
type FilePath ¶
type FilePath struct { ItemCount [2]byte Items []FilePathItem }
func (*FilePath) IsDropbox ¶ added in v0.2.0
IsDropbox checks if a FilePath matches the special drop box folder type
func (*FilePath) IsUploadDir ¶ added in v0.2.0
type FilePathItem ¶
FilePathItem represents the file or directory portion of a delimited file path (e.g. foo and bar in "/foo/bar") Example bytes: 00 00 09 73 75 62 66 6f 6c 64 65 72 "subfolder"
type FileResumeData ¶ added in v0.3.0
type FileResumeData struct { Format [4]byte // "RFLT" Version [2]byte // Always 1 RSVD [34]byte // Unused ForkCount [2]byte // Length of ForkInfoList. Either 2 or 3 depending on whether file has a resource fork ForkInfoList []ForkInfoList }
FileResumeData is sent when a client or server would like to resume a transfer from an offset
func NewFileResumeData ¶ added in v0.3.0
func NewFileResumeData(list []ForkInfoList) *FileResumeData
func (*FileResumeData) BinaryMarshal ¶ added in v0.3.0
func (frd *FileResumeData) BinaryMarshal() ([]byte, error)
func (*FileResumeData) UnmarshalBinary ¶ added in v0.3.0
func (frd *FileResumeData) UnmarshalBinary(b []byte) error
type FileStore ¶
type FileStore interface { Create(name string) (*os.File, error) Mkdir(name string, perm os.FileMode) error Open(name string) (*os.File, error) OpenFile(name string, flag int, perm fs.FileMode) (*os.File, error) Remove(name string) error RemoveAll(path string) error Rename(oldpath string, newpath string) error Stat(name string) (fs.FileInfo, error) Symlink(oldname, newname string) error WriteFile(name string, data []byte, perm fs.FileMode) error ReadFile(name string) ([]byte, error) }
type FileTransfer ¶
type FileTransfer struct { FileRoot string FileName []byte FilePath []byte RefNum [4]byte Type FileTransferType TransferSize []byte FolderItemCount []byte FileResumeData *FileResumeData Options []byte ClientConn *ClientConn // contains filtered or unexported fields }
func (*FileTransfer) ItemCount ¶ added in v0.3.0
func (ft *FileTransfer) ItemCount() int
func (*FileTransfer) String ¶
func (ft *FileTransfer) String() string
String returns a string representation of a file transfer and its progress for display in the GetInfo window Example: MasterOfOrionII1.4.0. 0% 197.9M
type FileTransferID ¶ added in v0.13.0
type FileTransferID [4]byte
type FileTransferMgr ¶ added in v0.13.0
type FileTransferMgr interface { Add(ft *FileTransfer) Get(id FileTransferID) *FileTransfer Delete(id FileTransferID) }
type FlatFileForkHeader ¶ added in v0.6.0
type FlatFileHeader ¶
type FlatFileHeader struct { Format [4]byte // Always "FILP" Version [2]byte // Always 1 RSVD [16]byte // Always empty zeros ForkCount [2]byte // Number of forks, either 2 or 3 if there is a resource fork }
FlatFileHeader is the first section of a "Flattened File Object". All fields have static values.
type FlatFileInformationFork ¶
type FlatFileInformationFork struct { Platform [4]byte // Operating System used. ("AMAC" or "MWIN") TypeSignature [4]byte // File type signature CreatorSignature [4]byte // File creator signature Flags [4]byte PlatformFlags [4]byte RSVD [32]byte CreateDate [8]byte ModifyDate [8]byte NameScript [2]byte NameSize [2]byte // Length of file name (Maximum 128 characters) Name []byte // File name CommentSize [2]byte // Length of the comment Comment []byte // File comment // contains filtered or unexported fields }
func NewFlatFileInformationFork ¶
func NewFlatFileInformationFork(fileName string, modifyTime [8]byte, typeSignature string, creatorSignature string) FlatFileInformationFork
func (*FlatFileInformationFork) DataSize ¶
func (ffif *FlatFileInformationFork) DataSize() []byte
DataSize calculates the size of the flat file information fork, which is 72 bytes for the fixed length fields plus the length of the Name + Comment
func (*FlatFileInformationFork) FriendlyCreator ¶ added in v0.13.0
func (ffif *FlatFileInformationFork) FriendlyCreator() []byte
func (*FlatFileInformationFork) FriendlyType ¶ added in v0.13.0
func (ffif *FlatFileInformationFork) FriendlyType() []byte
func (*FlatFileInformationFork) Read ¶ added in v0.13.0
func (ffif *FlatFileInformationFork) Read(p []byte) (int, error)
func (*FlatFileInformationFork) ReadNameSize ¶
func (ffif *FlatFileInformationFork) ReadNameSize() []byte
func (*FlatFileInformationFork) SetComment ¶ added in v0.13.0
func (ffif *FlatFileInformationFork) SetComment(comment []byte) error
func (*FlatFileInformationFork) Size ¶ added in v0.6.0
func (ffif *FlatFileInformationFork) Size() [4]byte
func (*FlatFileInformationFork) UnmarshalBinary ¶ added in v0.2.1
func (ffif *FlatFileInformationFork) UnmarshalBinary(b []byte) error
type ForkInfoList ¶ added in v0.3.0
type ForkInfoList struct { Fork [4]byte // "DATA" or "MACR" DataSize [4]byte // offset from which to resume the transfer of data RSVDA [4]byte // Unused RSVDB [4]byte // Unused }
func NewForkInfoList ¶ added in v0.3.0
func NewForkInfoList(b []byte) *ForkInfoList
type HandlerFunc ¶ added in v0.10.19
type HandlerFunc func(*ClientConn, *Transaction) []Transaction
HandlerFunc is the signature of a func to handle a Hotline transaction.
type MemChatManager ¶ added in v0.13.0
type MemChatManager struct {
// contains filtered or unexported fields
}
func NewMemChatManager ¶ added in v0.13.0
func NewMemChatManager() *MemChatManager
func (*MemChatManager) GetSubject ¶ added in v0.13.0
func (cm *MemChatManager) GetSubject(id ChatID) string
func (*MemChatManager) Join ¶ added in v0.13.0
func (cm *MemChatManager) Join(id ChatID, cc *ClientConn)
func (*MemChatManager) Leave ¶ added in v0.13.0
func (cm *MemChatManager) Leave(id ChatID, clientID [2]byte)
func (*MemChatManager) Members ¶ added in v0.13.0
func (cm *MemChatManager) Members(id ChatID) []*ClientConn
func (*MemChatManager) New ¶ added in v0.13.0
func (cm *MemChatManager) New(cc *ClientConn) ChatID
func (*MemChatManager) SetSubject ¶ added in v0.13.0
func (cm *MemChatManager) SetSubject(id ChatID, subject string)
type MemClientMgr ¶ added in v0.13.0
type MemClientMgr struct {
// contains filtered or unexported fields
}
func NewMemClientMgr ¶ added in v0.13.0
func NewMemClientMgr() *MemClientMgr
func (*MemClientMgr) Add ¶ added in v0.13.0
func (cm *MemClientMgr) Add(cc *ClientConn)
func (*MemClientMgr) Delete ¶ added in v0.13.0
func (cm *MemClientMgr) Delete(id ClientID)
func (*MemClientMgr) Get ¶ added in v0.13.0
func (cm *MemClientMgr) Get(id ClientID) *ClientConn
func (*MemClientMgr) List ¶ added in v0.13.0
func (cm *MemClientMgr) List() []*ClientConn
List returns slice of sorted clients.
type MemFileTransferMgr ¶ added in v0.13.0
type MemFileTransferMgr struct {
// contains filtered or unexported fields
}
func NewMemFileTransferMgr ¶ added in v0.13.0
func NewMemFileTransferMgr() *MemFileTransferMgr
func (*MemFileTransferMgr) Add ¶ added in v0.13.0
func (ftm *MemFileTransferMgr) Add(ft *FileTransfer)
func (*MemFileTransferMgr) Delete ¶ added in v0.13.0
func (ftm *MemFileTransferMgr) Delete(id FileTransferID)
func (*MemFileTransferMgr) Get ¶ added in v0.13.0
func (ftm *MemFileTransferMgr) Get(id FileTransferID) *FileTransfer
type MockChatManager ¶ added in v0.13.0
func (*MockChatManager) GetSubject ¶ added in v0.13.0
func (m *MockChatManager) GetSubject(id ChatID) string
func (*MockChatManager) Join ¶ added in v0.13.0
func (m *MockChatManager) Join(id ChatID, cc *ClientConn)
func (*MockChatManager) Leave ¶ added in v0.13.0
func (m *MockChatManager) Leave(id ChatID, clientID [2]byte)
func (*MockChatManager) Members ¶ added in v0.13.0
func (m *MockChatManager) Members(id ChatID) []*ClientConn
func (*MockChatManager) New ¶ added in v0.13.0
func (m *MockChatManager) New(cc *ClientConn) ChatID
func (*MockChatManager) SetSubject ¶ added in v0.13.0
func (m *MockChatManager) SetSubject(id ChatID, subject string)
type MockClientMgr ¶ added in v0.13.0
func (*MockClientMgr) Add ¶ added in v0.13.0
func (m *MockClientMgr) Add(cc *ClientConn)
func (*MockClientMgr) Delete ¶ added in v0.13.0
func (m *MockClientMgr) Delete(id ClientID)
func (*MockClientMgr) Get ¶ added in v0.13.0
func (m *MockClientMgr) Get(id ClientID) *ClientConn
func (*MockClientMgr) List ¶ added in v0.13.0
func (m *MockClientMgr) List() []*ClientConn
type MockFileInfo ¶ added in v0.6.0
func (*MockFileInfo) IsDir ¶ added in v0.6.0
func (mfi *MockFileInfo) IsDir() bool
func (*MockFileInfo) ModTime ¶ added in v0.6.0
func (mfi *MockFileInfo) ModTime() time.Time
func (*MockFileInfo) Mode ¶ added in v0.6.0
func (mfi *MockFileInfo) Mode() fs.FileMode
func (*MockFileInfo) Name ¶ added in v0.6.0
func (mfi *MockFileInfo) Name() string
func (*MockFileInfo) Size ¶ added in v0.6.0
func (mfi *MockFileInfo) Size() int64
func (*MockFileInfo) Sys ¶ added in v0.6.0
func (mfi *MockFileInfo) Sys() interface{}
type MockFileStore ¶
func (*MockFileStore) Create ¶ added in v0.2.1
func (mfs *MockFileStore) Create(name string) (*os.File, error)
func (*MockFileStore) Open ¶ added in v0.0.13
func (mfs *MockFileStore) Open(name string) (*os.File, error)
func (*MockFileStore) ReadFile ¶ added in v0.6.0
func (mfs *MockFileStore) ReadFile(name string) ([]byte, error)
func (*MockFileStore) Remove ¶ added in v0.2.0
func (mfs *MockFileStore) Remove(name string) error
func (*MockFileStore) RemoveAll ¶ added in v0.6.0
func (mfs *MockFileStore) RemoveAll(name string) error
func (*MockFileStore) Rename ¶ added in v0.6.0
func (mfs *MockFileStore) Rename(oldpath, newpath string) error
func (*MockFileStore) Symlink ¶ added in v0.2.0
func (mfs *MockFileStore) Symlink(oldname, newname string) error
type MockThreadNewsMgr ¶ added in v0.13.0
func (*MockThreadNewsMgr) CreateGrouping ¶ added in v0.13.0
func (m *MockThreadNewsMgr) CreateGrouping(newsPath []string, name string, itemType [2]byte) error
func (*MockThreadNewsMgr) DeleteArticle ¶ added in v0.13.0
func (m *MockThreadNewsMgr) DeleteArticle(newsPath []string, articleID uint32, recursive bool) error
func (*MockThreadNewsMgr) DeleteNewsItem ¶ added in v0.13.0
func (m *MockThreadNewsMgr) DeleteNewsItem(newsPath []string) error
func (*MockThreadNewsMgr) GetArticle ¶ added in v0.13.0
func (m *MockThreadNewsMgr) GetArticle(newsPath []string, articleID uint32) *NewsArtData
func (*MockThreadNewsMgr) GetCategories ¶ added in v0.13.0
func (m *MockThreadNewsMgr) GetCategories(paths []string) []NewsCategoryListData15
func (*MockThreadNewsMgr) ListArticles ¶ added in v0.13.0
func (m *MockThreadNewsMgr) ListArticles(newsPath []string) NewsArtListData
func (*MockThreadNewsMgr) NewsItem ¶ added in v0.13.0
func (m *MockThreadNewsMgr) NewsItem(newsPath []string) NewsCategoryListData15
func (*MockThreadNewsMgr) PostArticle ¶ added in v0.13.0
func (m *MockThreadNewsMgr) PostArticle(newsPath []string, parentArticleID uint32, article NewsArtData) error
type NewsArtData ¶
type NewsArtData struct { Title string `yaml:"Title"` Poster string `yaml:"Poster"` Date [8]byte `yaml:"Date,flow"` PrevArt [4]byte `yaml:"PrevArt,flow"` NextArt [4]byte `yaml:"NextArt,flow"` ParentArt [4]byte `yaml:"ParentArt,flow"` FirstChildArt [4]byte `yaml:"FirstChildArtArt,flow"` DataFlav []byte `yaml:"-"` // MIME type string. Always "text/plain". Data string `yaml:"Data"` }
NewsArtData represents an individual news article.
func (*NewsArtData) DataSize ¶
func (art *NewsArtData) DataSize() [2]byte
type NewsArtList ¶
type NewsArtList struct { ID [4]byte TimeStamp [8]byte // Year (2 bytes), milliseconds (2 bytes) and seconds (4 bytes) ParentID [4]byte Flags [4]byte FlavorCount [2]byte // Title size 1 Title []byte // string // Poster size 1 // Poster Poster string Poster []byte FlavorList []NewsFlavorList // Flavor list… Optional (if flavor count > 0) ArticleSize [2]byte // Size 2 // contains filtered or unexported fields }
NewsArtList is a summarized version of a NewArtData record for display in list view
type NewsArtListData ¶
type NewsCategoryListData15 ¶
type NewsCategoryListData15 struct { Type [2]byte `yaml:"Type,flow"` // Bundle (2) or category (3) Name string `yaml:"Name"` Articles map[uint32]*NewsArtData `yaml:"Articles"` // Optional, if Type is Category SubCats map[string]NewsCategoryListData15 `yaml:"SubCats"` GUID [16]byte `yaml:"-"` // What does this do? Undocumented and seeming unused. AddSN [4]byte `yaml:"-"` // What does this do? Undocumented and seeming unused. DeleteSN [4]byte `yaml:"-"` // What does this do? Undocumented and seeming unused. // contains filtered or unexported fields }
func (*NewsCategoryListData15) GetNewsArtListData ¶
func (newscat *NewsCategoryListData15) GetNewsArtListData() NewsArtListData
type NewsFlavorList ¶
type NewsFlavorList struct { }
type OSFileStore ¶
type OSFileStore struct{}
func (*OSFileStore) Create ¶ added in v0.2.1
func (fs *OSFileStore) Create(name string) (*os.File, error)
func (*OSFileStore) Open ¶ added in v0.0.13
func (fs *OSFileStore) Open(name string) (*os.File, error)
func (*OSFileStore) ReadFile ¶ added in v0.6.0
func (fs *OSFileStore) ReadFile(name string) ([]byte, error)
func (*OSFileStore) Remove ¶ added in v0.2.0
func (fs *OSFileStore) Remove(name string) error
func (*OSFileStore) RemoveAll ¶ added in v0.6.0
func (fs *OSFileStore) RemoveAll(name string) error
func (*OSFileStore) Rename ¶ added in v0.6.0
func (fs *OSFileStore) Rename(oldpath string, newpath string) error
func (*OSFileStore) Symlink ¶ added in v0.2.0
func (fs *OSFileStore) Symlink(oldname, newname string) error
type PrivateChat ¶
type PrivateChat struct { Subject string ClientConn map[[2]byte]*ClientConn }
type RealDialer ¶ added in v0.13.0
type RealDialer struct{}
RealDialer is the real implementation of the Dialer interface
type Server ¶
type Server struct { NetInterface string Port int Config Config Logger *slog.Logger TrackerPassID [4]byte Stats Counter FS FileStore // Storage backend to use for File storage Agreement io.ReadSeeker Banner []byte FileTransferMgr FileTransferMgr ChatMgr ChatManager ClientMgr ClientManager AccountManager AccountManager ThreadedNewsMgr ThreadedNewsMgr BanList BanMgr MessageBoard io.ReadWriteSeeker // contains filtered or unexported fields }
func (*Server) CurrentStats ¶ added in v0.9.0
func (*Server) HandleFunc ¶ added in v0.13.0
func (s *Server) HandleFunc(tranType [2]byte, handler HandlerFunc)
func (*Server) NewClientConn ¶
func (s *Server) NewClientConn(conn io.ReadWriteCloser, remoteAddr string) *ClientConn
func (*Server) ServeFileTransfers ¶
type ServerConfig ¶ added in v0.13.0
type ServerConfig struct { }
type ServerInfoHeader ¶
type ServerRecord ¶
type ServerRecord struct { IPAddr [4]byte Port [2]byte NumUsers [2]byte // Number of users connected to this particular server Unused [2]byte NameSize byte // Length of Name string Name []byte // Server Name DescriptionSize byte Description []byte }
ServerRecord is a tracker listing for a single server
func GetListing ¶
func GetListing(conn io.ReadWriteCloser) ([]ServerRecord, error)
func (*ServerRecord) Addr ¶
func (s *ServerRecord) Addr() string
type ThreadedNews ¶
type ThreadedNews struct {
Categories map[string]NewsCategoryListData15 `yaml:"Categories"`
}
ThreadedNews contains the top level of threaded news categories, bundles, and articles.
type ThreadedNewsMgr ¶ added in v0.13.0
type ThreadedNewsMgr interface { ListArticles(newsPath []string) NewsArtListData GetArticle(newsPath []string, articleID uint32) *NewsArtData DeleteArticle(newsPath []string, articleID uint32, recursive bool) error PostArticle(newsPath []string, parentArticleID uint32, article NewsArtData) error CreateGrouping(newsPath []string, name string, t [2]byte) error GetCategories(paths []string) []NewsCategoryListData15 NewsItem(newsPath []string) NewsCategoryListData15 DeleteNewsItem(newsPath []string) error }
type TrackerHeader ¶
type TrackerHeader struct { Protocol [4]byte // "HTRK" 0x4854524B Version [2]byte // Old protocol (1) or new (2) }
TrackerHeader is sent in reply Reply received from the tracker starts with a header:
type TrackerRegistration ¶
type TrackerRegistration struct { Port [2]byte // Server's listening TCP port number UserCount int // Number of users connected to this particular server PassID [4]byte // Random number generated by the server Name string // Server Name Description string // Description of the server Password string // Tracker password, if required by tracker // contains filtered or unexported fields }
TrackerRegistration represents the payload a Hotline server sends to a Tracker to register
type Transaction ¶
type Transaction struct { Flags byte // Reserved (should be 0) IsReply byte // Request (0) or reply (1) Type TranType // Requested operation (user defined) ID [4]byte // Unique transaction ID (must be != 0) ErrorCode [4]byte // Used in the reply (user defined, 0 = no error) TotalSize [4]byte // Total data size for the fields in this transaction. DataSize [4]byte // Size of data in this transaction part. This allows splitting large transactions into smaller parts. ParamCount [2]byte // Number of the parameters for this transaction Fields []Field ClientID ClientID // Internal identifier for target client // contains filtered or unexported fields }
func NewTransaction ¶
func NewTransaction(t TranType, clientID ClientID, fields ...Field) Transaction
NewTransaction creates a new Transaction with the specified type, client, and optional fields.
func (*Transaction) GetField ¶
func (t *Transaction) GetField(id [2]byte) *Field
func (*Transaction) Read ¶ added in v0.13.0
func (t *Transaction) Read(p []byte) (int, error)
Read implements the io.Reader interface for Transaction
func (*Transaction) Size ¶
func (t *Transaction) Size() []byte
Size returns the total size of the transaction payload
func (*Transaction) Write ¶ added in v0.8.3
func (t *Transaction) Write(p []byte) (n int, err error)
Write implements io.Writer interface for Transaction. Transactions read from the network are read as complete tokens with a bufio.Scanner, so the arg p is guaranteed to have the full byte payload of a complete transaction.
type User ¶
type WriteCounter ¶ added in v0.7.0
type WriteCounter struct { Total int64 // Total # of bytes written // contains filtered or unexported fields }
WriteCounter counts the number of bytes written to it.
Source Files ¶
- access.go
- account.go
- account_manager.go
- ban.go
- chat.go
- client.go
- client_conn.go
- client_manager.go
- config.go
- doc.go
- field.go
- file_name_with_info.go
- file_path.go
- file_resume_data.go
- file_store.go
- file_transfer.go
- file_types.go
- file_wrapper.go
- files.go
- flattened_file_object.go
- handshake.go
- message_board.go
- news.go
- panic.go
- server.go
- stats.go
- time.go
- tracker.go
- transaction.go
- transaction_handlers.go
- transfer.go
- user.go