Implement DCC streaming
This commit is contained in:
parent
973578bb49
commit
e33b9f05e4
File diff suppressed because one or more lines are too long
@ -134,6 +134,22 @@ export default function handleSocket({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
dcc_send({ server, from, filename, url }) {
|
||||||
|
const serverName = getState().servers[server]?.name || server;
|
||||||
|
|
||||||
|
dispatch(
|
||||||
|
openModal('confirm', {
|
||||||
|
question: `${from} on ${serverName} is sending you: ${filename}`,
|
||||||
|
confirmation: 'Download',
|
||||||
|
onConfirm: () => {
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.click();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
_connected(connected) {
|
_connected(connected) {
|
||||||
dispatch(setConnected(connected));
|
dispatch(setConnected(connected));
|
||||||
}
|
}
|
||||||
|
@ -109,8 +109,14 @@ func init() {
|
|||||||
viper.BindPFlags(rootCmd.PersistentFlags())
|
viper.BindPFlags(rootCmd.PersistentFlags())
|
||||||
viper.BindPFlags(rootCmd.Flags())
|
viper.BindPFlags(rootCmd.Flags())
|
||||||
|
|
||||||
viper.SetDefault("hexIP", false)
|
|
||||||
viper.SetDefault("verify_certificates", true)
|
viper.SetDefault("verify_certificates", true)
|
||||||
|
viper.SetDefault("https.enabled", true)
|
||||||
|
viper.SetDefault("https.port", 443)
|
||||||
|
viper.SetDefault("auth.anonymous", true)
|
||||||
|
viper.SetDefault("auth.login", true)
|
||||||
|
viper.SetDefault("auth.registration", true)
|
||||||
|
viper.SetDefault("dcc.enabled", true)
|
||||||
|
viper.SetDefault("dcc.autoget.delete", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig(configPath string, overwrite bool) {
|
func initConfig(configPath string, overwrite bool) {
|
||||||
|
@ -4,8 +4,6 @@ port = 80
|
|||||||
# Hex encode the users IP and use it as the ident
|
# Hex encode the users IP and use it as the ident
|
||||||
hexIP = false
|
hexIP = false
|
||||||
verify_certificates = true
|
verify_certificates = true
|
||||||
# Automatically download files from DCC SENDs
|
|
||||||
autoget = false
|
|
||||||
|
|
||||||
# Defaults for the client connect form
|
# Defaults for the client connect form
|
||||||
[defaults]
|
[defaults]
|
||||||
@ -63,6 +61,20 @@ secret = ""
|
|||||||
key = ""
|
key = ""
|
||||||
secret = ""
|
secret = ""
|
||||||
|
|
||||||
|
[dcc]
|
||||||
|
# Receive files through DCC, the user gets to choose if they want to accept the file,
|
||||||
|
# the file then gets streamed to the user
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[dcc.autoget]
|
||||||
|
# Instead of streaming the file to the user, dispatch automatically downloads
|
||||||
|
# DCC files and sends a download link to the user once its done
|
||||||
|
enabled = false
|
||||||
|
# Delete the file after the user has downloaded it once
|
||||||
|
delete = true
|
||||||
|
# Delete the file after a certain time period of inactivity, not implemented yet
|
||||||
|
delete_after = "30m"
|
||||||
|
|
||||||
# Strict-Transport-Security
|
# Strict-Transport-Security
|
||||||
[https.hsts]
|
[https.hsts]
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -14,12 +14,12 @@ type Config struct {
|
|||||||
Dev bool
|
Dev bool
|
||||||
HexIP bool
|
HexIP bool
|
||||||
VerifyCertificates bool `mapstructure:"verify_certificates"`
|
VerifyCertificates bool `mapstructure:"verify_certificates"`
|
||||||
Autoget bool
|
|
||||||
Headers map[string]string
|
Headers map[string]string
|
||||||
Defaults Defaults
|
Defaults Defaults
|
||||||
HTTPS HTTPS
|
HTTPS HTTPS
|
||||||
LetsEncrypt LetsEncrypt
|
LetsEncrypt LetsEncrypt
|
||||||
Auth Auth
|
Auth Auth
|
||||||
|
DCC DCC
|
||||||
}
|
}
|
||||||
|
|
||||||
type Defaults struct {
|
type Defaults struct {
|
||||||
@ -65,6 +65,17 @@ type Provider struct {
|
|||||||
Secret string
|
Secret string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DCC struct {
|
||||||
|
Enabled bool
|
||||||
|
Autoget Autoget
|
||||||
|
}
|
||||||
|
|
||||||
|
type Autoget struct {
|
||||||
|
Enabled bool
|
||||||
|
Delete bool
|
||||||
|
DeleteAfter time.Duration `mapstructure:"delete_after"`
|
||||||
|
}
|
||||||
|
|
||||||
func LoadConfig() (*Config, chan *Config) {
|
func LoadConfig() (*Config, chan *Config) {
|
||||||
viper.SetConfigName("config")
|
viper.SetConfigName("config")
|
||||||
viper.AddConfigPath(storage.Path.ConfigRoot())
|
viper.AddConfigPath(storage.Path.ConfigRoot())
|
||||||
|
@ -41,7 +41,6 @@ func Serve(handler http.Handler, cfg Config) error {
|
|||||||
httpsSrv := &http.Server{
|
httpsSrv := &http.Server{
|
||||||
Addr: net.JoinHostPort(cfg.Addr, cfg.PortHTTPS),
|
Addr: net.JoinHostPort(cfg.Addr, cfg.PortHTTPS),
|
||||||
ReadTimeout: 5 * time.Second,
|
ReadTimeout: 5 * time.Second,
|
||||||
WriteTimeout: 10 * time.Second,
|
|
||||||
IdleTimeout: 120 * time.Second,
|
IdleTimeout: 120 * time.Second,
|
||||||
Handler: handler,
|
Handler: handler,
|
||||||
}
|
}
|
||||||
@ -101,7 +100,6 @@ func Serve(handler http.Handler, cfg Config) error {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
httpSrv.ReadTimeout = 5 * time.Second
|
httpSrv.ReadTimeout = 5 * time.Second
|
||||||
httpSrv.WriteTimeout = 10 * time.Second
|
|
||||||
httpSrv.IdleTimeout = 120 * time.Second
|
httpSrv.IdleTimeout = 120 * time.Second
|
||||||
httpSrv.Handler = handler
|
httpSrv.Handler = handler
|
||||||
|
|
||||||
|
@ -26,12 +26,8 @@ type Client struct {
|
|||||||
// Source is the reply to SOURCE CTCP messages
|
// Source is the reply to SOURCE CTCP messages
|
||||||
Source string
|
Source string
|
||||||
|
|
||||||
DownloadFolder string
|
|
||||||
Autoget bool
|
|
||||||
|
|
||||||
Messages chan *Message
|
Messages chan *Message
|
||||||
ConnectionChanged chan ConnectionState
|
ConnectionChanged chan ConnectionState
|
||||||
Progress chan DownloadProgress
|
|
||||||
Features *Features
|
Features *Features
|
||||||
nick string
|
nick string
|
||||||
channels []string
|
channels []string
|
||||||
@ -59,7 +55,6 @@ func NewClient(nick, username string) *Client {
|
|||||||
Realname: nick,
|
Realname: nick,
|
||||||
Messages: make(chan *Message, 32),
|
Messages: make(chan *Message, 32),
|
||||||
ConnectionChanged: make(chan ConnectionState, 4),
|
ConnectionChanged: make(chan ConnectionState, 4),
|
||||||
Progress: make(chan DownloadProgress, 4),
|
|
||||||
out: make(chan string, 32),
|
out: make(chan string, 32),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
reconnect: make(chan struct{}),
|
reconnect: make(chan struct{}),
|
||||||
|
@ -47,13 +47,6 @@ func (c *Client) handleCTCP(ctcp *CTCP, msg *Message) {
|
|||||||
case "CLIENTINFO":
|
case "CLIENTINFO":
|
||||||
c.ReplyCTCP(msg.Nick, ctcp.Command, ClientInfo)
|
c.ReplyCTCP(msg.Nick, ctcp.Command, ClientInfo)
|
||||||
|
|
||||||
case "DCC":
|
|
||||||
if strings.HasPrefix(ctcp.Params, "SEND") {
|
|
||||||
if dccSend := ParseDCCSend(ctcp); dccSend != nil {
|
|
||||||
go c.Download(dccSend)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case "FINGER", "VERSION":
|
case "FINGER", "VERSION":
|
||||||
if c.Version != "" {
|
if c.Version != "" {
|
||||||
c.ReplyCTCP(msg.Nick, ctcp.Command, c.Version)
|
c.ReplyCTCP(msg.Nick, ctcp.Command, c.Version)
|
||||||
|
@ -2,14 +2,11 @@ package irc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -52,27 +49,16 @@ func ParseDCCSend(ctcp *CTCP) *DCCSend {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Download(pack *DCCSend) {
|
func DownloadDCC(w io.Writer, pack *DCCSend, progress chan DownloadProgress) error {
|
||||||
if !c.Autoget {
|
if progress != nil {
|
||||||
// TODO: ask user if he/she wants to download the file
|
progress <- DownloadProgress{
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Progress <- DownloadProgress{
|
|
||||||
File: pack.File,
|
File: pack.File,
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.OpenFile(filepath.Join(c.DownloadFolder, pack.File), os.O_CREATE|os.O_WRONLY, 0644)
|
|
||||||
if err != nil {
|
|
||||||
c.downloadFailed(pack, err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
conn, err := net.Dial("tcp", net.JoinHostPort(pack.IP, pack.Port))
|
conn, err := net.Dial("tcp", net.JoinHostPort(pack.IP, pack.Port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.downloadFailed(pack, err)
|
return err
|
||||||
return
|
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
@ -87,24 +73,26 @@ func (c *Client) Download(pack *DCCSend) {
|
|||||||
n, err := conn.Read(buf)
|
n, err := conn.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
c.downloadFailed(pack, err)
|
return err
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := file.Write(buf[:n]); err != nil {
|
if _, err := w.Write(buf[:n]); err != nil {
|
||||||
c.downloadFailed(pack, err)
|
return err
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
accBytes += uint64(n)
|
accBytes += uint64(n)
|
||||||
totalBytes += uint64(n)
|
totalBytes += uint64(n)
|
||||||
|
|
||||||
conn.Write(uint64Bytes(totalBytes))
|
_, err = conn.Write(uint64Bytes(totalBytes))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if progress != nil {
|
||||||
if dt := time.Since(prevUpdate); dt >= time.Second {
|
if dt := time.Since(prevUpdate); dt >= time.Second {
|
||||||
prevUpdate = time.Now()
|
prevUpdate = time.Now()
|
||||||
|
|
||||||
@ -119,7 +107,7 @@ func (c *Client) Download(pack *DCCSend) {
|
|||||||
bytesRemaining := float64(pack.Length - totalBytes)
|
bytesRemaining := float64(pack.Length - totalBytes)
|
||||||
percentage := 100 * (float64(totalBytes) / float64(pack.Length))
|
percentage := 100 * (float64(totalBytes) / float64(pack.Length))
|
||||||
|
|
||||||
c.Progress <- DownloadProgress{
|
progress <- DownloadProgress{
|
||||||
Speed: humanReadableByteCount(averageSpeed, true),
|
Speed: humanReadableByteCount(averageSpeed, true),
|
||||||
PercCompletion: percentage,
|
PercCompletion: percentage,
|
||||||
BytesRemaining: humanReadableByteCount(bytesRemaining, false),
|
BytesRemaining: humanReadableByteCount(bytesRemaining, false),
|
||||||
@ -130,8 +118,10 @@ func (c *Client) Download(pack *DCCSend) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.Progress <- DownloadProgress{
|
if progress != nil {
|
||||||
|
progress <- DownloadProgress{
|
||||||
PercCompletion: 100,
|
PercCompletion: 100,
|
||||||
BytesCompleted: humanReadableByteCount(float64(totalBytes), false),
|
BytesCompleted: humanReadableByteCount(float64(totalBytes), false),
|
||||||
SecondsElapsed: secondsSince(start),
|
SecondsElapsed: secondsSince(start),
|
||||||
@ -139,12 +129,7 @@ func (c *Client) Download(pack *DCCSend) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) downloadFailed(pack *DCCSend, err error) {
|
return nil
|
||||||
c.Progress <- DownloadProgress{
|
|
||||||
PercCompletion: -1,
|
|
||||||
File: pack.File,
|
|
||||||
Error: err,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type DownloadProgress struct {
|
type DownloadProgress struct {
|
||||||
@ -158,14 +143,6 @@ type DownloadProgress struct {
|
|||||||
SecondsToGo float64 `json:"eta"`
|
SecondsToGo float64 `json:"eta"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p DownloadProgress) ToJSON() string {
|
|
||||||
progress, err := json.Marshal(p)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return string(progress)
|
|
||||||
}
|
|
||||||
|
|
||||||
func intToIP(n int) string {
|
func intToIP(n int) string {
|
||||||
var byte1 = n & 255
|
var byte1 = n & 255
|
||||||
var byte2 = ((n >> 8) & 255)
|
var byte2 = ((n >> 8) & 255)
|
||||||
|
@ -73,9 +73,6 @@ func connectIRC(server *storage.Server, state *State, srcIP []byte) *irc.Client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i.DownloadFolder = storage.Path.Downloads(state.user.Username)
|
|
||||||
i.Autoget = cfg.Autoget
|
|
||||||
|
|
||||||
state.setIRC(server.Host, i)
|
state.setIRC(server.Host, i)
|
||||||
i.Connect(address)
|
i.Connect(address)
|
||||||
go newIRCHandler(i, state).run()
|
go newIRCHandler(i, state).run()
|
||||||
|
@ -3,8 +3,10 @@ package server
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/kjk/betterguid"
|
"github.com/kjk/betterguid"
|
||||||
@ -26,6 +28,7 @@ type ircHandler struct {
|
|||||||
userBuffers map[string][]string
|
userBuffers map[string][]string
|
||||||
motdBuffer MOTD
|
motdBuffer MOTD
|
||||||
listBuffer storage.ChannelListIndex
|
listBuffer storage.ChannelListIndex
|
||||||
|
dccProgress chan irc.DownloadProgress
|
||||||
|
|
||||||
handlers map[string]func(*irc.Message)
|
handlers map[string]func(*irc.Message)
|
||||||
}
|
}
|
||||||
@ -35,6 +38,7 @@ func newIRCHandler(client *irc.Client, state *State) *ircHandler {
|
|||||||
client: client,
|
client: client,
|
||||||
state: state,
|
state: state,
|
||||||
userBuffers: make(map[string][]string),
|
userBuffers: make(map[string][]string),
|
||||||
|
dccProgress: make(chan irc.DownloadProgress, 4),
|
||||||
}
|
}
|
||||||
i.initHandlers()
|
i.initHandlers()
|
||||||
return i
|
return i
|
||||||
@ -64,7 +68,7 @@ func (i *ircHandler) run() {
|
|||||||
i.log("Connected")
|
i.log("Connected")
|
||||||
}
|
}
|
||||||
|
|
||||||
case progress := <-i.client.Progress:
|
case progress := <-i.dccProgress:
|
||||||
if progress.Error != nil {
|
if progress.Error != nil {
|
||||||
i.sendDCCInfo("%s: Download failed (%s)", true, progress.File, progress.Error)
|
i.sendDCCInfo("%s: Download failed (%s)", true, progress.File, progress.Error)
|
||||||
} else if progress.PercCompletion == 100 {
|
} else if progress.PercCompletion == 100 {
|
||||||
@ -175,10 +179,46 @@ func (i *ircHandler) mode(msg *irc.Message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ircHandler) message(msg *irc.Message) {
|
func (i *ircHandler) receiveDCCSend(pack *irc.DCCSend, msg *irc.Message) {
|
||||||
if ctcp := msg.ToCTCP(); ctcp != nil && ctcp.Command != "ACTION" {
|
cfg := i.state.srv.Config()
|
||||||
|
|
||||||
|
if cfg.DCC.Enabled {
|
||||||
|
if cfg.DCC.Autoget.Enabled {
|
||||||
|
file, err := os.OpenFile(storage.Path.DownloadedFile(i.state.user.Username, pack.File), os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
irc.DownloadDCC(file, pack, i.dccProgress)
|
||||||
|
} else {
|
||||||
|
i.state.setPendingDCC(pack.File, pack)
|
||||||
|
|
||||||
|
i.state.sendJSON("dcc_send", DCCSend{
|
||||||
|
Server: i.client.Host,
|
||||||
|
From: msg.Nick,
|
||||||
|
Filename: pack.File,
|
||||||
|
URL: fmt.Sprintf("%s://%s/downloads/%s/%s",
|
||||||
|
i.state.String("scheme"), i.state.String("host"), i.state.user.Username, pack.File),
|
||||||
|
})
|
||||||
|
|
||||||
|
time.Sleep(150 * time.Second)
|
||||||
|
i.state.deletePendingDCC(pack.File)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *ircHandler) message(msg *irc.Message) {
|
||||||
|
if ctcp := msg.ToCTCP(); ctcp != nil {
|
||||||
|
if ctcp.Command == "DCC" && strings.HasPrefix(ctcp.Params, "SEND") {
|
||||||
|
if pack := irc.ParseDCCSend(ctcp); pack != nil {
|
||||||
|
go i.receiveDCCSend(pack, msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if ctcp.Command != "ACTION" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
message := Message{
|
message := Message{
|
||||||
ID: betterguid.New(),
|
ID: betterguid.New(),
|
||||||
@ -431,8 +471,7 @@ func (i *ircHandler) initHandlers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *ircHandler) log(v ...interface{}) {
|
func (i *ircHandler) log(v ...interface{}) {
|
||||||
s := fmt.Sprintln(v...)
|
log.Println("[IRC]", i.state.user.ID, i.client.Host, fmt.Sprint(v...))
|
||||||
log.Println("[IRC]", i.state.user.ID, i.client.Host, s[:len(s)-1])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ircHandler) sendDCCInfo(message string, log bool, a ...interface{}) {
|
func (i *ircHandler) sendDCCInfo(message string, log bool, a ...interface{}) {
|
||||||
|
@ -222,6 +222,13 @@ type ChannelForward struct {
|
|||||||
New string
|
New string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DCCSend struct {
|
||||||
|
Server string
|
||||||
|
From string
|
||||||
|
Filename string
|
||||||
|
URL string
|
||||||
|
}
|
||||||
|
|
||||||
type Tab struct {
|
type Tab struct {
|
||||||
storage.Tab
|
storage.Tab
|
||||||
}
|
}
|
||||||
|
@ -3060,7 +3060,110 @@ func (v *Error) UnmarshalJSON(data []byte) error {
|
|||||||
func (v *Error) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
func (v *Error) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||||
easyjson42239ddeDecodeGithubComKhliengDispatchServer27(l, v)
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer27(l, v)
|
||||||
}
|
}
|
||||||
func easyjson42239ddeDecodeGithubComKhliengDispatchServer28(in *jlexer.Lexer, out *ConnectionUpdate) {
|
func easyjson42239ddeDecodeGithubComKhliengDispatchServer28(in *jlexer.Lexer, out *DCCSend) {
|
||||||
|
isTopLevel := in.IsStart()
|
||||||
|
if in.IsNull() {
|
||||||
|
if isTopLevel {
|
||||||
|
in.Consumed()
|
||||||
|
}
|
||||||
|
in.Skip()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
in.Delim('{')
|
||||||
|
for !in.IsDelim('}') {
|
||||||
|
key := in.UnsafeFieldName(false)
|
||||||
|
in.WantColon()
|
||||||
|
if in.IsNull() {
|
||||||
|
in.Skip()
|
||||||
|
in.WantComma()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch key {
|
||||||
|
case "server":
|
||||||
|
out.Server = string(in.String())
|
||||||
|
case "from":
|
||||||
|
out.From = string(in.String())
|
||||||
|
case "filename":
|
||||||
|
out.Filename = string(in.String())
|
||||||
|
case "url":
|
||||||
|
out.URL = string(in.String())
|
||||||
|
default:
|
||||||
|
in.SkipRecursive()
|
||||||
|
}
|
||||||
|
in.WantComma()
|
||||||
|
}
|
||||||
|
in.Delim('}')
|
||||||
|
if isTopLevel {
|
||||||
|
in.Consumed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func easyjson42239ddeEncodeGithubComKhliengDispatchServer28(out *jwriter.Writer, in DCCSend) {
|
||||||
|
out.RawByte('{')
|
||||||
|
first := true
|
||||||
|
_ = first
|
||||||
|
if in.Server != "" {
|
||||||
|
const prefix string = ",\"server\":"
|
||||||
|
first = false
|
||||||
|
out.RawString(prefix[1:])
|
||||||
|
out.String(string(in.Server))
|
||||||
|
}
|
||||||
|
if in.From != "" {
|
||||||
|
const prefix string = ",\"from\":"
|
||||||
|
if first {
|
||||||
|
first = false
|
||||||
|
out.RawString(prefix[1:])
|
||||||
|
} else {
|
||||||
|
out.RawString(prefix)
|
||||||
|
}
|
||||||
|
out.String(string(in.From))
|
||||||
|
}
|
||||||
|
if in.Filename != "" {
|
||||||
|
const prefix string = ",\"filename\":"
|
||||||
|
if first {
|
||||||
|
first = false
|
||||||
|
out.RawString(prefix[1:])
|
||||||
|
} else {
|
||||||
|
out.RawString(prefix)
|
||||||
|
}
|
||||||
|
out.String(string(in.Filename))
|
||||||
|
}
|
||||||
|
if in.URL != "" {
|
||||||
|
const prefix string = ",\"url\":"
|
||||||
|
if first {
|
||||||
|
first = false
|
||||||
|
out.RawString(prefix[1:])
|
||||||
|
} else {
|
||||||
|
out.RawString(prefix)
|
||||||
|
}
|
||||||
|
out.String(string(in.URL))
|
||||||
|
}
|
||||||
|
out.RawByte('}')
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON supports json.Marshaler interface
|
||||||
|
func (v DCCSend) MarshalJSON() ([]byte, error) {
|
||||||
|
w := jwriter.Writer{}
|
||||||
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer28(&w, v)
|
||||||
|
return w.Buffer.BuildBytes(), w.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
|
func (v DCCSend) MarshalEasyJSON(w *jwriter.Writer) {
|
||||||
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer28(w, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
|
func (v *DCCSend) UnmarshalJSON(data []byte) error {
|
||||||
|
r := jlexer.Lexer{Data: data}
|
||||||
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer28(&r, v)
|
||||||
|
return r.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
|
func (v *DCCSend) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||||
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer28(l, v)
|
||||||
|
}
|
||||||
|
func easyjson42239ddeDecodeGithubComKhliengDispatchServer29(in *jlexer.Lexer, out *ConnectionUpdate) {
|
||||||
isTopLevel := in.IsStart()
|
isTopLevel := in.IsStart()
|
||||||
if in.IsNull() {
|
if in.IsNull() {
|
||||||
if isTopLevel {
|
if isTopLevel {
|
||||||
@ -3097,7 +3200,7 @@ func easyjson42239ddeDecodeGithubComKhliengDispatchServer28(in *jlexer.Lexer, ou
|
|||||||
in.Consumed()
|
in.Consumed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func easyjson42239ddeEncodeGithubComKhliengDispatchServer28(out *jwriter.Writer, in ConnectionUpdate) {
|
func easyjson42239ddeEncodeGithubComKhliengDispatchServer29(out *jwriter.Writer, in ConnectionUpdate) {
|
||||||
out.RawByte('{')
|
out.RawByte('{')
|
||||||
first := true
|
first := true
|
||||||
_ = first
|
_ = first
|
||||||
@ -3143,27 +3246,27 @@ func easyjson42239ddeEncodeGithubComKhliengDispatchServer28(out *jwriter.Writer,
|
|||||||
// MarshalJSON supports json.Marshaler interface
|
// MarshalJSON supports json.Marshaler interface
|
||||||
func (v ConnectionUpdate) MarshalJSON() ([]byte, error) {
|
func (v ConnectionUpdate) MarshalJSON() ([]byte, error) {
|
||||||
w := jwriter.Writer{}
|
w := jwriter.Writer{}
|
||||||
easyjson42239ddeEncodeGithubComKhliengDispatchServer28(&w, v)
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer29(&w, v)
|
||||||
return w.Buffer.BuildBytes(), w.Error
|
return w.Buffer.BuildBytes(), w.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
func (v ConnectionUpdate) MarshalEasyJSON(w *jwriter.Writer) {
|
func (v ConnectionUpdate) MarshalEasyJSON(w *jwriter.Writer) {
|
||||||
easyjson42239ddeEncodeGithubComKhliengDispatchServer28(w, v)
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer29(w, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON supports json.Unmarshaler interface
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
func (v *ConnectionUpdate) UnmarshalJSON(data []byte) error {
|
func (v *ConnectionUpdate) UnmarshalJSON(data []byte) error {
|
||||||
r := jlexer.Lexer{Data: data}
|
r := jlexer.Lexer{Data: data}
|
||||||
easyjson42239ddeDecodeGithubComKhliengDispatchServer28(&r, v)
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer29(&r, v)
|
||||||
return r.Error()
|
return r.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
func (v *ConnectionUpdate) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
func (v *ConnectionUpdate) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||||
easyjson42239ddeDecodeGithubComKhliengDispatchServer28(l, v)
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer29(l, v)
|
||||||
}
|
}
|
||||||
func easyjson42239ddeDecodeGithubComKhliengDispatchServer29(in *jlexer.Lexer, out *ClientCert) {
|
func easyjson42239ddeDecodeGithubComKhliengDispatchServer30(in *jlexer.Lexer, out *ClientCert) {
|
||||||
isTopLevel := in.IsStart()
|
isTopLevel := in.IsStart()
|
||||||
if in.IsNull() {
|
if in.IsNull() {
|
||||||
if isTopLevel {
|
if isTopLevel {
|
||||||
@ -3196,7 +3299,7 @@ func easyjson42239ddeDecodeGithubComKhliengDispatchServer29(in *jlexer.Lexer, ou
|
|||||||
in.Consumed()
|
in.Consumed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func easyjson42239ddeEncodeGithubComKhliengDispatchServer29(out *jwriter.Writer, in ClientCert) {
|
func easyjson42239ddeEncodeGithubComKhliengDispatchServer30(out *jwriter.Writer, in ClientCert) {
|
||||||
out.RawByte('{')
|
out.RawByte('{')
|
||||||
first := true
|
first := true
|
||||||
_ = first
|
_ = first
|
||||||
@ -3222,27 +3325,27 @@ func easyjson42239ddeEncodeGithubComKhliengDispatchServer29(out *jwriter.Writer,
|
|||||||
// MarshalJSON supports json.Marshaler interface
|
// MarshalJSON supports json.Marshaler interface
|
||||||
func (v ClientCert) MarshalJSON() ([]byte, error) {
|
func (v ClientCert) MarshalJSON() ([]byte, error) {
|
||||||
w := jwriter.Writer{}
|
w := jwriter.Writer{}
|
||||||
easyjson42239ddeEncodeGithubComKhliengDispatchServer29(&w, v)
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer30(&w, v)
|
||||||
return w.Buffer.BuildBytes(), w.Error
|
return w.Buffer.BuildBytes(), w.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
func (v ClientCert) MarshalEasyJSON(w *jwriter.Writer) {
|
func (v ClientCert) MarshalEasyJSON(w *jwriter.Writer) {
|
||||||
easyjson42239ddeEncodeGithubComKhliengDispatchServer29(w, v)
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer30(w, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON supports json.Unmarshaler interface
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
func (v *ClientCert) UnmarshalJSON(data []byte) error {
|
func (v *ClientCert) UnmarshalJSON(data []byte) error {
|
||||||
r := jlexer.Lexer{Data: data}
|
r := jlexer.Lexer{Data: data}
|
||||||
easyjson42239ddeDecodeGithubComKhliengDispatchServer29(&r, v)
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer30(&r, v)
|
||||||
return r.Error()
|
return r.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
func (v *ClientCert) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
func (v *ClientCert) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||||
easyjson42239ddeDecodeGithubComKhliengDispatchServer29(l, v)
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer30(l, v)
|
||||||
}
|
}
|
||||||
func easyjson42239ddeDecodeGithubComKhliengDispatchServer30(in *jlexer.Lexer, out *ChannelSearchResult) {
|
func easyjson42239ddeDecodeGithubComKhliengDispatchServer31(in *jlexer.Lexer, out *ChannelSearchResult) {
|
||||||
isTopLevel := in.IsStart()
|
isTopLevel := in.IsStart()
|
||||||
if in.IsNull() {
|
if in.IsNull() {
|
||||||
if isTopLevel {
|
if isTopLevel {
|
||||||
@ -3308,7 +3411,7 @@ func easyjson42239ddeDecodeGithubComKhliengDispatchServer30(in *jlexer.Lexer, ou
|
|||||||
in.Consumed()
|
in.Consumed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func easyjson42239ddeEncodeGithubComKhliengDispatchServer30(out *jwriter.Writer, in ChannelSearchResult) {
|
func easyjson42239ddeEncodeGithubComKhliengDispatchServer31(out *jwriter.Writer, in ChannelSearchResult) {
|
||||||
out.RawByte('{')
|
out.RawByte('{')
|
||||||
first := true
|
first := true
|
||||||
_ = first
|
_ = first
|
||||||
@ -3367,25 +3470,25 @@ func easyjson42239ddeEncodeGithubComKhliengDispatchServer30(out *jwriter.Writer,
|
|||||||
// MarshalJSON supports json.Marshaler interface
|
// MarshalJSON supports json.Marshaler interface
|
||||||
func (v ChannelSearchResult) MarshalJSON() ([]byte, error) {
|
func (v ChannelSearchResult) MarshalJSON() ([]byte, error) {
|
||||||
w := jwriter.Writer{}
|
w := jwriter.Writer{}
|
||||||
easyjson42239ddeEncodeGithubComKhliengDispatchServer30(&w, v)
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer31(&w, v)
|
||||||
return w.Buffer.BuildBytes(), w.Error
|
return w.Buffer.BuildBytes(), w.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
func (v ChannelSearchResult) MarshalEasyJSON(w *jwriter.Writer) {
|
func (v ChannelSearchResult) MarshalEasyJSON(w *jwriter.Writer) {
|
||||||
easyjson42239ddeEncodeGithubComKhliengDispatchServer30(w, v)
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer31(w, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON supports json.Unmarshaler interface
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
func (v *ChannelSearchResult) UnmarshalJSON(data []byte) error {
|
func (v *ChannelSearchResult) UnmarshalJSON(data []byte) error {
|
||||||
r := jlexer.Lexer{Data: data}
|
r := jlexer.Lexer{Data: data}
|
||||||
easyjson42239ddeDecodeGithubComKhliengDispatchServer30(&r, v)
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer31(&r, v)
|
||||||
return r.Error()
|
return r.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
func (v *ChannelSearchResult) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
func (v *ChannelSearchResult) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||||
easyjson42239ddeDecodeGithubComKhliengDispatchServer30(l, v)
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer31(l, v)
|
||||||
}
|
}
|
||||||
func easyjson42239ddeDecodeGithubComKhliengDispatchStorage1(in *jlexer.Lexer, out *storage.ChannelListItem) {
|
func easyjson42239ddeDecodeGithubComKhliengDispatchStorage1(in *jlexer.Lexer, out *storage.ChannelListItem) {
|
||||||
isTopLevel := in.IsStart()
|
isTopLevel := in.IsStart()
|
||||||
@ -3454,7 +3557,7 @@ func easyjson42239ddeEncodeGithubComKhliengDispatchStorage1(out *jwriter.Writer,
|
|||||||
}
|
}
|
||||||
out.RawByte('}')
|
out.RawByte('}')
|
||||||
}
|
}
|
||||||
func easyjson42239ddeDecodeGithubComKhliengDispatchServer31(in *jlexer.Lexer, out *ChannelSearch) {
|
func easyjson42239ddeDecodeGithubComKhliengDispatchServer32(in *jlexer.Lexer, out *ChannelSearch) {
|
||||||
isTopLevel := in.IsStart()
|
isTopLevel := in.IsStart()
|
||||||
if in.IsNull() {
|
if in.IsNull() {
|
||||||
if isTopLevel {
|
if isTopLevel {
|
||||||
@ -3489,7 +3592,7 @@ func easyjson42239ddeDecodeGithubComKhliengDispatchServer31(in *jlexer.Lexer, ou
|
|||||||
in.Consumed()
|
in.Consumed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func easyjson42239ddeEncodeGithubComKhliengDispatchServer31(out *jwriter.Writer, in ChannelSearch) {
|
func easyjson42239ddeEncodeGithubComKhliengDispatchServer32(out *jwriter.Writer, in ChannelSearch) {
|
||||||
out.RawByte('{')
|
out.RawByte('{')
|
||||||
first := true
|
first := true
|
||||||
_ = first
|
_ = first
|
||||||
@ -3525,27 +3628,27 @@ func easyjson42239ddeEncodeGithubComKhliengDispatchServer31(out *jwriter.Writer,
|
|||||||
// MarshalJSON supports json.Marshaler interface
|
// MarshalJSON supports json.Marshaler interface
|
||||||
func (v ChannelSearch) MarshalJSON() ([]byte, error) {
|
func (v ChannelSearch) MarshalJSON() ([]byte, error) {
|
||||||
w := jwriter.Writer{}
|
w := jwriter.Writer{}
|
||||||
easyjson42239ddeEncodeGithubComKhliengDispatchServer31(&w, v)
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer32(&w, v)
|
||||||
return w.Buffer.BuildBytes(), w.Error
|
return w.Buffer.BuildBytes(), w.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
func (v ChannelSearch) MarshalEasyJSON(w *jwriter.Writer) {
|
func (v ChannelSearch) MarshalEasyJSON(w *jwriter.Writer) {
|
||||||
easyjson42239ddeEncodeGithubComKhliengDispatchServer31(w, v)
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer32(w, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON supports json.Unmarshaler interface
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
func (v *ChannelSearch) UnmarshalJSON(data []byte) error {
|
func (v *ChannelSearch) UnmarshalJSON(data []byte) error {
|
||||||
r := jlexer.Lexer{Data: data}
|
r := jlexer.Lexer{Data: data}
|
||||||
easyjson42239ddeDecodeGithubComKhliengDispatchServer31(&r, v)
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer32(&r, v)
|
||||||
return r.Error()
|
return r.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
func (v *ChannelSearch) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
func (v *ChannelSearch) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||||
easyjson42239ddeDecodeGithubComKhliengDispatchServer31(l, v)
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer32(l, v)
|
||||||
}
|
}
|
||||||
func easyjson42239ddeDecodeGithubComKhliengDispatchServer32(in *jlexer.Lexer, out *ChannelForward) {
|
func easyjson42239ddeDecodeGithubComKhliengDispatchServer33(in *jlexer.Lexer, out *ChannelForward) {
|
||||||
isTopLevel := in.IsStart()
|
isTopLevel := in.IsStart()
|
||||||
if in.IsNull() {
|
if in.IsNull() {
|
||||||
if isTopLevel {
|
if isTopLevel {
|
||||||
@ -3580,7 +3683,7 @@ func easyjson42239ddeDecodeGithubComKhliengDispatchServer32(in *jlexer.Lexer, ou
|
|||||||
in.Consumed()
|
in.Consumed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func easyjson42239ddeEncodeGithubComKhliengDispatchServer32(out *jwriter.Writer, in ChannelForward) {
|
func easyjson42239ddeEncodeGithubComKhliengDispatchServer33(out *jwriter.Writer, in ChannelForward) {
|
||||||
out.RawByte('{')
|
out.RawByte('{')
|
||||||
first := true
|
first := true
|
||||||
_ = first
|
_ = first
|
||||||
@ -3616,27 +3719,27 @@ func easyjson42239ddeEncodeGithubComKhliengDispatchServer32(out *jwriter.Writer,
|
|||||||
// MarshalJSON supports json.Marshaler interface
|
// MarshalJSON supports json.Marshaler interface
|
||||||
func (v ChannelForward) MarshalJSON() ([]byte, error) {
|
func (v ChannelForward) MarshalJSON() ([]byte, error) {
|
||||||
w := jwriter.Writer{}
|
w := jwriter.Writer{}
|
||||||
easyjson42239ddeEncodeGithubComKhliengDispatchServer32(&w, v)
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer33(&w, v)
|
||||||
return w.Buffer.BuildBytes(), w.Error
|
return w.Buffer.BuildBytes(), w.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
func (v ChannelForward) MarshalEasyJSON(w *jwriter.Writer) {
|
func (v ChannelForward) MarshalEasyJSON(w *jwriter.Writer) {
|
||||||
easyjson42239ddeEncodeGithubComKhliengDispatchServer32(w, v)
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer33(w, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON supports json.Unmarshaler interface
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
func (v *ChannelForward) UnmarshalJSON(data []byte) error {
|
func (v *ChannelForward) UnmarshalJSON(data []byte) error {
|
||||||
r := jlexer.Lexer{Data: data}
|
r := jlexer.Lexer{Data: data}
|
||||||
easyjson42239ddeDecodeGithubComKhliengDispatchServer32(&r, v)
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer33(&r, v)
|
||||||
return r.Error()
|
return r.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
func (v *ChannelForward) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
func (v *ChannelForward) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||||
easyjson42239ddeDecodeGithubComKhliengDispatchServer32(l, v)
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer33(l, v)
|
||||||
}
|
}
|
||||||
func easyjson42239ddeDecodeGithubComKhliengDispatchServer33(in *jlexer.Lexer, out *Away) {
|
func easyjson42239ddeDecodeGithubComKhliengDispatchServer34(in *jlexer.Lexer, out *Away) {
|
||||||
isTopLevel := in.IsStart()
|
isTopLevel := in.IsStart()
|
||||||
if in.IsNull() {
|
if in.IsNull() {
|
||||||
if isTopLevel {
|
if isTopLevel {
|
||||||
@ -3669,7 +3772,7 @@ func easyjson42239ddeDecodeGithubComKhliengDispatchServer33(in *jlexer.Lexer, ou
|
|||||||
in.Consumed()
|
in.Consumed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func easyjson42239ddeEncodeGithubComKhliengDispatchServer33(out *jwriter.Writer, in Away) {
|
func easyjson42239ddeEncodeGithubComKhliengDispatchServer34(out *jwriter.Writer, in Away) {
|
||||||
out.RawByte('{')
|
out.RawByte('{')
|
||||||
first := true
|
first := true
|
||||||
_ = first
|
_ = first
|
||||||
@ -3695,23 +3798,23 @@ func easyjson42239ddeEncodeGithubComKhliengDispatchServer33(out *jwriter.Writer,
|
|||||||
// MarshalJSON supports json.Marshaler interface
|
// MarshalJSON supports json.Marshaler interface
|
||||||
func (v Away) MarshalJSON() ([]byte, error) {
|
func (v Away) MarshalJSON() ([]byte, error) {
|
||||||
w := jwriter.Writer{}
|
w := jwriter.Writer{}
|
||||||
easyjson42239ddeEncodeGithubComKhliengDispatchServer33(&w, v)
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer34(&w, v)
|
||||||
return w.Buffer.BuildBytes(), w.Error
|
return w.Buffer.BuildBytes(), w.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
func (v Away) MarshalEasyJSON(w *jwriter.Writer) {
|
func (v Away) MarshalEasyJSON(w *jwriter.Writer) {
|
||||||
easyjson42239ddeEncodeGithubComKhliengDispatchServer33(w, v)
|
easyjson42239ddeEncodeGithubComKhliengDispatchServer34(w, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON supports json.Unmarshaler interface
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
func (v *Away) UnmarshalJSON(data []byte) error {
|
func (v *Away) UnmarshalJSON(data []byte) error {
|
||||||
r := jlexer.Lexer{Data: data}
|
r := jlexer.Lexer{Data: data}
|
||||||
easyjson42239ddeDecodeGithubComKhliengDispatchServer33(&r, v)
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer34(&r, v)
|
||||||
return r.Error()
|
return r.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
func (v *Away) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
func (v *Away) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||||
easyjson42239ddeDecodeGithubComKhliengDispatchServer33(l, v)
|
easyjson42239ddeDecodeGithubComKhliengDispatchServer34(l, v)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package server
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -10,6 +11,7 @@ import (
|
|||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/khlieng/dispatch/config"
|
"github.com/khlieng/dispatch/config"
|
||||||
"github.com/khlieng/dispatch/pkg/https"
|
"github.com/khlieng/dispatch/pkg/https"
|
||||||
|
"github.com/khlieng/dispatch/pkg/irc"
|
||||||
"github.com/khlieng/dispatch/pkg/session"
|
"github.com/khlieng/dispatch/pkg/session"
|
||||||
"github.com/khlieng/dispatch/storage"
|
"github.com/khlieng/dispatch/storage"
|
||||||
)
|
)
|
||||||
@ -202,9 +204,21 @@ func (d *Dispatch) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
filename := params[2]
|
filename := params[2]
|
||||||
|
|
||||||
w.Header().Set("Content-Disposition", "attachment; filename="+filename)
|
w.Header().Set("Content-Disposition", "attachment; filename="+filename)
|
||||||
http.ServeFile(w, r, storage.Path.DownloadedFile(state.user.Username, filename))
|
|
||||||
|
if pack, ok := state.getPendingDCC(filename); ok {
|
||||||
|
state.deletePendingDCC(filename)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Length", strconv.FormatUint(pack.Length, 10))
|
||||||
|
irc.DownloadDCC(w, pack, nil)
|
||||||
|
} else {
|
||||||
|
file := storage.Path.DownloadedFile(state.user.Username, filename)
|
||||||
|
http.ServeFile(w, r, file)
|
||||||
|
|
||||||
|
if d.Config().DCC.Autoget.Delete {
|
||||||
|
os.Remove(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fail(w, http.StatusNotFound)
|
fail(w, http.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ type State struct {
|
|||||||
|
|
||||||
irc map[string]*irc.Client
|
irc map[string]*irc.Client
|
||||||
connectionState map[string]irc.ConnectionState
|
connectionState map[string]irc.ConnectionState
|
||||||
|
pendingDCCSends map[string]*irc.DCCSend
|
||||||
ircLock sync.Mutex
|
ircLock sync.Mutex
|
||||||
|
|
||||||
ws map[string]*wsConn
|
ws map[string]*wsConn
|
||||||
@ -39,6 +40,7 @@ func NewState(user *storage.User, srv *Dispatch) *State {
|
|||||||
stateData: stateData{m: map[string]interface{}{}},
|
stateData: stateData{m: map[string]interface{}{}},
|
||||||
irc: make(map[string]*irc.Client),
|
irc: make(map[string]*irc.Client),
|
||||||
connectionState: make(map[string]irc.ConnectionState),
|
connectionState: make(map[string]irc.ConnectionState),
|
||||||
|
pendingDCCSends: make(map[string]*irc.DCCSend),
|
||||||
ws: make(map[string]*wsConn),
|
ws: make(map[string]*wsConn),
|
||||||
broadcast: make(chan WSResponse, 32),
|
broadcast: make(chan WSResponse, 32),
|
||||||
srv: srv,
|
srv: srv,
|
||||||
@ -102,6 +104,25 @@ func (s *State) setConnectionState(server string, state irc.ConnectionState) {
|
|||||||
s.ircLock.Unlock()
|
s.ircLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *State) getPendingDCC(filename string) (*irc.DCCSend, bool) {
|
||||||
|
s.ircLock.Lock()
|
||||||
|
pack, ok := s.pendingDCCSends[filename]
|
||||||
|
s.ircLock.Unlock()
|
||||||
|
return pack, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *State) setPendingDCC(filename string, pack *irc.DCCSend) {
|
||||||
|
s.ircLock.Lock()
|
||||||
|
s.pendingDCCSends[filename] = pack
|
||||||
|
s.ircLock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *State) deletePendingDCC(filename string) {
|
||||||
|
s.ircLock.Lock()
|
||||||
|
delete(s.pendingDCCSends, filename)
|
||||||
|
s.ircLock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
func (s *State) setWS(addr string, w *wsConn) {
|
func (s *State) setWS(addr string, w *wsConn) {
|
||||||
s.wsLock.Lock()
|
s.wsLock.Lock()
|
||||||
s.ws[addr] = w
|
s.ws[addr] = w
|
||||||
|
Loading…
Reference in New Issue
Block a user