mirror of
https://github.com/renorris/openfsd
synced 2026-05-05 08:15:45 +08:00
v0.1.0-alpha
Changes:
- Implement bootstrapping library for managing several concurrent internal services
- Refactor concurrency model for connections/logical clients and their associated I/O
- Refactor server context singleton
- Refactor error handling
- Most errors are now gracefully sent to the FSD client directly encoded as an $ER packet,
enhancing visibility and debugging
- Most errors are now rightfully treated as non-fatal
- Refactor package/dependency graph
- Refactor calling conventions/interfaces for many packages
- Refactor database package
- Refactor post office
Features:
- Add VATSIM-esque HTTP/JSON "data feed"
- Add ephemeral in-memory database option
- Add user management REST API
- Add improved web interface
- Add MySQL support (drop SQLite support)
This commit is contained in:
178
client/fsd_client.go
Normal file
178
client/fsd_client.go
Normal file
@@ -0,0 +1,178 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/renorris/openfsd/postoffice"
|
||||
"github.com/renorris/openfsd/protocol"
|
||||
"github.com/renorris/openfsd/protocol/vatsimauth"
|
||||
)
|
||||
|
||||
type FSDClient struct {
|
||||
connection *Connection
|
||||
|
||||
authVerify *vatsimauth.VatsimAuth // Auth state to verify browser's auth responses
|
||||
pendingChallenge string // store the pending challenge sent to the browser
|
||||
authSelf *vatsimauth.VatsimAuth // Auth state for interrogating browser
|
||||
|
||||
// General information
|
||||
callsign string
|
||||
cid int
|
||||
networkRating protocol.NetworkRating
|
||||
pilotRating protocol.PilotRating
|
||||
realName string
|
||||
simulatorType int
|
||||
|
||||
spatialState *spatialState
|
||||
|
||||
currentGeohash postoffice.Geohash
|
||||
sendFastEnabled bool
|
||||
|
||||
kill chan string // Signal to disconnect this client
|
||||
mailbox chan string // Incoming messages
|
||||
}
|
||||
|
||||
func NewFSDClient(connection *Connection, clientIdentPDU *protocol.ClientIdentificationPDU,
|
||||
addPilotPDU *protocol.AddPilotPDU, initialServerChallenge string, pilotRating protocol.PilotRating) *FSDClient {
|
||||
|
||||
client := FSDClient{
|
||||
connection: connection,
|
||||
|
||||
authVerify: vatsimauth.NewVatsimAuth(
|
||||
clientIdentPDU.ClientID,
|
||||
vatsimauth.Keys[clientIdentPDU.ClientID]),
|
||||
authSelf: vatsimauth.NewVatsimAuth(
|
||||
clientIdentPDU.ClientID,
|
||||
vatsimauth.Keys[clientIdentPDU.ClientID]),
|
||||
|
||||
callsign: clientIdentPDU.From,
|
||||
cid: clientIdentPDU.CID,
|
||||
networkRating: addPilotPDU.NetworkRating,
|
||||
pilotRating: pilotRating,
|
||||
simulatorType: addPilotPDU.SimulatorType,
|
||||
realName: addPilotPDU.RealName,
|
||||
|
||||
spatialState: &spatialState{},
|
||||
|
||||
kill: make(chan string, 1),
|
||||
mailbox: make(chan string, 32),
|
||||
}
|
||||
|
||||
client.authSelf.SetInitialChallenge(clientIdentPDU.InitialChallenge)
|
||||
client.authVerify.SetInitialChallenge(initialServerChallenge)
|
||||
|
||||
return &client
|
||||
}
|
||||
|
||||
// postoffice.Address implementations:
|
||||
|
||||
func (c *FSDClient) Name() string {
|
||||
return c.callsign
|
||||
}
|
||||
|
||||
func (c *FSDClient) SendMail(packet string) {
|
||||
// Non-blocking send
|
||||
select {
|
||||
case c.mailbox <- packet:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FSDClient) SendKill(packet string) error {
|
||||
// Non-blocking send
|
||||
select {
|
||||
case c.kill <- packet:
|
||||
return nil
|
||||
default:
|
||||
return errors.New("client unavailable")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FSDClient) NetworkRating() protocol.NetworkRating {
|
||||
return c.networkRating
|
||||
}
|
||||
|
||||
func (c *FSDClient) Geohash() postoffice.Geohash {
|
||||
return c.currentGeohash
|
||||
}
|
||||
|
||||
func (c *FSDClient) State() postoffice.AddressState {
|
||||
state := postoffice.AddressState{
|
||||
CID: c.cid,
|
||||
RealName: c.realName,
|
||||
PilotRating: c.pilotRating,
|
||||
}
|
||||
|
||||
c.spatialState.lock.RLock()
|
||||
|
||||
state.Latitude = c.spatialState.latitude
|
||||
state.Longitude = c.spatialState.longitude
|
||||
state.Altitude = c.spatialState.altitude
|
||||
state.Groundspeed = c.spatialState.groundspeed
|
||||
state.Transponder = c.spatialState.transponder
|
||||
state.Heading = c.spatialState.heading
|
||||
state.LastUpdated = c.spatialState.lastUpdated
|
||||
|
||||
c.spatialState.lock.RUnlock()
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
func (c *FSDClient) SetAddressState(state *postoffice.AddressState) {
|
||||
c.spatialState.lock.Lock()
|
||||
|
||||
c.spatialState.latitude = state.Latitude
|
||||
c.spatialState.longitude = state.Longitude
|
||||
c.spatialState.groundspeed = state.Groundspeed
|
||||
c.spatialState.altitude = state.Altitude
|
||||
c.spatialState.heading = state.Heading
|
||||
c.spatialState.transponder = state.Transponder
|
||||
c.spatialState.lastUpdated = state.LastUpdated
|
||||
|
||||
c.spatialState.lock.Unlock()
|
||||
}
|
||||
|
||||
// handler.Invoker implementations:
|
||||
|
||||
func (c *FSDClient) Callsign() string {
|
||||
return c.callsign
|
||||
}
|
||||
|
||||
func (c *FSDClient) AuthSelf() *vatsimauth.VatsimAuth {
|
||||
return c.authSelf
|
||||
}
|
||||
|
||||
func (c *FSDClient) AuthVerify() *vatsimauth.VatsimAuth {
|
||||
return c.authVerify
|
||||
}
|
||||
|
||||
func (c *FSDClient) PendingChallenge() string {
|
||||
return c.pendingChallenge
|
||||
}
|
||||
|
||||
func (c *FSDClient) SetPendingChallenge(s string) {
|
||||
c.pendingChallenge = s
|
||||
}
|
||||
|
||||
func (c *FSDClient) CID() int {
|
||||
return c.cid
|
||||
}
|
||||
|
||||
func (c *FSDClient) SetGeohash(h postoffice.Geohash) {
|
||||
c.currentGeohash = h
|
||||
}
|
||||
|
||||
func (c *FSDClient) SendFastEnabled() bool {
|
||||
return c.sendFastEnabled
|
||||
}
|
||||
|
||||
func (c *FSDClient) SetSendFastEnabled(b bool) {
|
||||
c.sendFastEnabled = b
|
||||
}
|
||||
|
||||
func (c *FSDClient) Address() postoffice.Address {
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *FSDClient) RemoteNetworkAddrString() string {
|
||||
return c.connection.conn.RemoteAddr().String()
|
||||
}
|
||||
Reference in New Issue
Block a user