diff --git a/config.go b/config.go index 99c102f..79cba1c 100644 --- a/config.go +++ b/config.go @@ -6,6 +6,8 @@ import ( "crypto/x509" "encoding/json" "encoding/pem" + "fmt" + "io" "log" "net/http" "os" @@ -14,6 +16,8 @@ import ( "github.com/google/uuid" ) +var NodeToken string + type LocalServerConfig struct { configFilePath string NodeId string `json:"nodeId"` @@ -29,9 +33,13 @@ func NewLocalServerConfig() (localServerConfig *LocalServerConfig, err error) { logger.SetOutput(logFile) logger.SetFlags(log.Ldate | log.LUTC | log.Lshortfile | log.Ltime | log.LstdFlags | log.Lmsgprefix) localServerConfig = &LocalServerConfig{ - configFilePath: filepath.Join("config","node_config.json"), + configFilePath: filepath.Join("config", "node_config.json"), } err = localServerConfig.startup() + if err != nil { + return + } + err = localServerConfig.authenticate() return } @@ -74,6 +82,7 @@ func (l *LocalServerConfig) startup() (err error) { "from": id, "to": "serv", "token": "", + "peerType":"node", "payload": map[string]string{ "nodeId": id, "nodeKey": string(key), @@ -99,6 +108,70 @@ func (l *LocalServerConfig) startup() (err error) { if err != nil { return } - err = json.NewDecoder(file).Decode(&l) + var config map[string]string + err = json.NewDecoder(file).Decode(&config) + if err != nil { + return + } + logger.Println(config) + l.NodeId = config["nodeId"] + l.PrivateKeyPath = config["privKeyPath"] + l.Token = config["token"] + return +} + +func (l *LocalServerConfig) authenticate() (err error) { + f, err := os.Open(l.PrivateKeyPath) + if err != nil { + return + } + var buff []byte + buff, err = io.ReadAll(f) + if err != nil { + return + } + em := NewEncryptionManager() + sig, err := em.SignRequest(string(buff), l.NodeId) + if err != nil { + return + } + body, err := json.Marshal(map[string]interface{}{ + "type": "login_key_node", + "from": l.NodeId, + "peerType":"node", + "payload": map[string]string{ + "id": l.NodeId, + "signature": sig, + }, + }) + if err != nil { + return + } + res, err := http.Post("https://app.zippytal.com/req", "application/json", bytes.NewBuffer(body)) + if err != nil { + return + } + bs, err := io.ReadAll(res.Body) + if err != nil { + return + } + var payload map[string]any + if err = json.Unmarshal(bs, &payload); err != nil { + return + } + err = l.handleLoginResponse(payload) + return +} + +func (l *LocalServerConfig) handleLoginResponse(res map[string]any) (err error) { + if _, ok := res["token"]; !ok { + err = fmt.Errorf("no field token in res") + return + } + if _, ok := res["token"].(string); !ok { + err = fmt.Errorf("field token not string in res") + return + } + NodeToken = res["token"].(string) return } diff --git a/encryption_manager.go b/encryption_manager.go index 3217050..d7f7388 100644 --- a/encryption_manager.go +++ b/encryption_manager.go @@ -2,9 +2,13 @@ package localserver import ( "context" + "crypto" + "crypto/hmac" "crypto/rand" "crypto/rsa" + "crypto/sha256" "crypto/x509" + "encoding/base64" "encoding/pem" "fmt" "io" @@ -110,3 +114,37 @@ func (em *EncryptionManager) LoadPrivKey(privKeyPath string, password string) (e em.PrivKey = privKey return } + +func (em *EncryptionManager) ParsePrivKey(privateKey string) (privKey *rsa.PrivateKey, err error) { + key := []byte(privateKey) + block, _ := pem.Decode(key) + b := block.Bytes + privKey, err = x509.ParsePKCS1PrivateKey(b) + if err != nil { + return + } + return +} + +func (em *EncryptionManager) SignRequest(privKey, id string) (sig string, err error) { + key, err := em.ParsePrivKey(privKey) + if err != nil { + return + } + msg := []byte(id) + hashed := sha256.Sum256(msg) + signature, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, hashed[:]) + if err != nil { + return + } + sig = base64.StdEncoding.EncodeToString(signature) + return +} + +func (em *EncryptionManager) SignRequestHMAC(id string) string { + h := hmac.New(sha256.New, []byte(NodeToken)) + h.Write([]byte(id)) + sha := h.Sum(nil) + sig := base64.StdEncoding.EncodeToString(sha) + return sig +} diff --git a/go.mod b/go.mod index c02baa9..5af58e6 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,9 @@ module github.com/loisBN/zippytal_node/localserver -go 1.17 +go 1.18 require ( github.com/dgraph-io/badger/v3 v3.2103.2 - github.com/golang/protobuf v1.5.2 github.com/google/uuid v1.3.0 github.com/pion/rtcp v1.2.9 github.com/pion/webrtc/v3 v3.1.11 @@ -20,6 +19,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect + github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.3 // indirect github.com/google/flatbuffers v1.12.1 // indirect github.com/klauspost/compress v1.12.3 // indirect diff --git a/grpc_manager.pb.go b/grpc_manager.pb.go deleted file mode 100644 index 3154792..0000000 --- a/grpc_manager.pb.go +++ /dev/null @@ -1,1958 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.25.0 -// protoc v3.14.0 -// source: grpc_manager.proto - -package localserver - -import ( - proto "github.com/golang/protobuf/proto" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -type Request struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` - Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token,omitempty"` - Payload map[string]string `protobuf:"bytes,4,rep,name=payload,proto3" json:"payload,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *Request) Reset() { - *x = Request{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Request) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Request) ProtoMessage() {} - -func (x *Request) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Request.ProtoReflect.Descriptor instead. -func (*Request) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{0} -} - -func (x *Request) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *Request) GetFrom() string { - if x != nil { - return x.From - } - return "" -} - -func (x *Request) GetToken() string { - if x != nil { - return x.Token - } - return "" -} - -func (x *Request) GetPayload() map[string]string { - if x != nil { - return x.Payload - } - return nil -} - -type PeerRegisterRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - PeerId string `protobuf:"bytes,1,opt,name=peerId,proto3" json:"peerId,omitempty"` - PeerKey string `protobuf:"bytes,2,opt,name=peerKey,proto3" json:"peerKey,omitempty"` - PeerUsername string `protobuf:"bytes,3,opt,name=peerUsername,proto3" json:"peerUsername,omitempty"` -} - -func (x *PeerRegisterRequest) Reset() { - *x = PeerRegisterRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PeerRegisterRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PeerRegisterRequest) ProtoMessage() {} - -func (x *PeerRegisterRequest) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PeerRegisterRequest.ProtoReflect.Descriptor instead. -func (*PeerRegisterRequest) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{1} -} - -func (x *PeerRegisterRequest) GetPeerId() string { - if x != nil { - return x.PeerId - } - return "" -} - -func (x *PeerRegisterRequest) GetPeerKey() string { - if x != nil { - return x.PeerKey - } - return "" -} - -func (x *PeerRegisterRequest) GetPeerUsername() string { - if x != nil { - return x.PeerUsername - } - return "" -} - -type PeerRegisterResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` - Log string `protobuf:"bytes,2,opt,name=log,proto3" json:"log,omitempty"` -} - -func (x *PeerRegisterResponse) Reset() { - *x = PeerRegisterResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PeerRegisterResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PeerRegisterResponse) ProtoMessage() {} - -func (x *PeerRegisterResponse) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PeerRegisterResponse.ProtoReflect.Descriptor instead. -func (*PeerRegisterResponse) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{2} -} - -func (x *PeerRegisterResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -func (x *PeerRegisterResponse) GetLog() string { - if x != nil { - return x.Log - } - return "" -} - -type PeerListRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Number int32 `protobuf:"varint,1,opt,name=number,proto3" json:"number,omitempty"` - LastIndex int32 `protobuf:"varint,2,opt,name=lastIndex,proto3" json:"lastIndex,omitempty"` - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` - Filters map[string]string `protobuf:"bytes,4,rep,name=filters,proto3" json:"filters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *PeerListRequest) Reset() { - *x = PeerListRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PeerListRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PeerListRequest) ProtoMessage() {} - -func (x *PeerListRequest) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PeerListRequest.ProtoReflect.Descriptor instead. -func (*PeerListRequest) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{3} -} - -func (x *PeerListRequest) GetNumber() int32 { - if x != nil { - return x.Number - } - return 0 -} - -func (x *PeerListRequest) GetLastIndex() int32 { - if x != nil { - return x.LastIndex - } - return 0 -} - -func (x *PeerListRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *PeerListRequest) GetFilters() map[string]string { - if x != nil { - return x.Filters - } - return nil -} - -type SquadConnectRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - UserId string `protobuf:"bytes,2,opt,name=userId,proto3" json:"userId,omitempty"` - Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` - AuthType string `protobuf:"bytes,4,opt,name=authType,proto3" json:"authType,omitempty"` - NetworkType string `protobuf:"bytes,5,opt,name=networkType,proto3" json:"networkType,omitempty"` -} - -func (x *SquadConnectRequest) Reset() { - *x = SquadConnectRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SquadConnectRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SquadConnectRequest) ProtoMessage() {} - -func (x *SquadConnectRequest) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SquadConnectRequest.ProtoReflect.Descriptor instead. -func (*SquadConnectRequest) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{4} -} - -func (x *SquadConnectRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *SquadConnectRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *SquadConnectRequest) GetPassword() string { - if x != nil { - return x.Password - } - return "" -} - -func (x *SquadConnectRequest) GetAuthType() string { - if x != nil { - return x.AuthType - } - return "" -} - -func (x *SquadConnectRequest) GetNetworkType() string { - if x != nil { - return x.NetworkType - } - return "" -} - -type ProtoSquad struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Members []string `protobuf:"bytes,3,rep,name=members,proto3" json:"members,omitempty"` - SquadType string `protobuf:"bytes,4,opt,name=squadType,proto3" json:"squadType,omitempty"` - Owner string `protobuf:"bytes,5,opt,name=owner,proto3" json:"owner,omitempty"` - Host string `protobuf:"bytes,6,opt,name=host,proto3" json:"host,omitempty"` - AuthType string `protobuf:"bytes,7,opt,name=authType,proto3" json:"authType,omitempty"` - Status bool `protobuf:"varint,8,opt,name=status,proto3" json:"status,omitempty"` -} - -func (x *ProtoSquad) Reset() { - *x = ProtoSquad{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProtoSquad) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProtoSquad) ProtoMessage() {} - -func (x *ProtoSquad) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProtoSquad.ProtoReflect.Descriptor instead. -func (*ProtoSquad) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{5} -} - -func (x *ProtoSquad) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *ProtoSquad) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *ProtoSquad) GetMembers() []string { - if x != nil { - return x.Members - } - return nil -} - -func (x *ProtoSquad) GetSquadType() string { - if x != nil { - return x.SquadType - } - return "" -} - -func (x *ProtoSquad) GetOwner() string { - if x != nil { - return x.Owner - } - return "" -} - -func (x *ProtoSquad) GetHost() string { - if x != nil { - return x.Host - } - return "" -} - -func (x *ProtoSquad) GetAuthType() string { - if x != nil { - return x.AuthType - } - return "" -} - -func (x *ProtoSquad) GetStatus() bool { - if x != nil { - return x.Status - } - return false -} - -type SquadCreateRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - SquadType string `protobuf:"bytes,3,opt,name=squadType,proto3" json:"squadType,omitempty"` - Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` -} - -func (x *SquadCreateRequest) Reset() { - *x = SquadCreateRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SquadCreateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SquadCreateRequest) ProtoMessage() {} - -func (x *SquadCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SquadCreateRequest.ProtoReflect.Descriptor instead. -func (*SquadCreateRequest) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{6} -} - -func (x *SquadCreateRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *SquadCreateRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *SquadCreateRequest) GetSquadType() string { - if x != nil { - return x.SquadType - } - return "" -} - -func (x *SquadCreateRequest) GetPassword() string { - if x != nil { - return x.Password - } - return "" -} - -type SquadListRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Number int32 `protobuf:"varint,1,opt,name=number,proto3" json:"number,omitempty"` - LastIndex int32 `protobuf:"varint,2,opt,name=lastIndex,proto3" json:"lastIndex,omitempty"` - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` - Filters map[string]string `protobuf:"bytes,4,rep,name=filters,proto3" json:"filters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - SquadType string `protobuf:"bytes,5,opt,name=squadType,proto3" json:"squadType,omitempty"` - SquadNetworkType string `protobuf:"bytes,6,opt,name=squadNetworkType,proto3" json:"squadNetworkType,omitempty"` -} - -func (x *SquadListRequest) Reset() { - *x = SquadListRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SquadListRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SquadListRequest) ProtoMessage() {} - -func (x *SquadListRequest) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SquadListRequest.ProtoReflect.Descriptor instead. -func (*SquadListRequest) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{7} -} - -func (x *SquadListRequest) GetNumber() int32 { - if x != nil { - return x.Number - } - return 0 -} - -func (x *SquadListRequest) GetLastIndex() int32 { - if x != nil { - return x.LastIndex - } - return 0 -} - -func (x *SquadListRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *SquadListRequest) GetFilters() map[string]string { - if x != nil { - return x.Filters - } - return nil -} - -func (x *SquadListRequest) GetSquadType() string { - if x != nil { - return x.SquadType - } - return "" -} - -func (x *SquadListRequest) GetSquadNetworkType() string { - if x != nil { - return x.SquadNetworkType - } - return "" -} - -type SquadUpdateRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` - Id string `protobuf:"bytes,5,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - SquadType string `protobuf:"bytes,3,opt,name=squadType,proto3" json:"squadType,omitempty"` - Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` -} - -func (x *SquadUpdateRequest) Reset() { - *x = SquadUpdateRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SquadUpdateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SquadUpdateRequest) ProtoMessage() {} - -func (x *SquadUpdateRequest) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SquadUpdateRequest.ProtoReflect.Descriptor instead. -func (*SquadUpdateRequest) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{8} -} - -func (x *SquadUpdateRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *SquadUpdateRequest) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *SquadUpdateRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *SquadUpdateRequest) GetSquadType() string { - if x != nil { - return x.SquadType - } - return "" -} - -func (x *SquadUpdateRequest) GetPassword() string { - if x != nil { - return x.Password - } - return "" -} - -type SquadDeleteRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` - SquadId string `protobuf:"bytes,2,opt,name=squadId,proto3" json:"squadId,omitempty"` -} - -func (x *SquadDeleteRequest) Reset() { - *x = SquadDeleteRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SquadDeleteRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SquadDeleteRequest) ProtoMessage() {} - -func (x *SquadDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SquadDeleteRequest.ProtoReflect.Descriptor instead. -func (*SquadDeleteRequest) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{9} -} - -func (x *SquadDeleteRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *SquadDeleteRequest) GetSquadId() string { - if x != nil { - return x.SquadId - } - return "" -} - -type Peer struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - PubKey string `protobuf:"bytes,3,opt,name=pubKey,proto3" json:"pubKey,omitempty"` - Active bool `protobuf:"varint,4,opt,name=active,proto3" json:"active,omitempty"` -} - -func (x *Peer) Reset() { - *x = Peer{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Peer) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Peer) ProtoMessage() {} - -func (x *Peer) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Peer.ProtoReflect.Descriptor instead. -func (*Peer) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{10} -} - -func (x *Peer) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Peer) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Peer) GetPubKey() string { - if x != nil { - return x.PubKey - } - return "" -} - -func (x *Peer) GetActive() bool { - if x != nil { - return x.Active - } - return false -} - -type PeerListResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` - LastIndex int32 `protobuf:"varint,2,opt,name=lastIndex,proto3" json:"lastIndex,omitempty"` - Peers []*Peer `protobuf:"bytes,3,rep,name=peers,proto3" json:"peers,omitempty"` -} - -func (x *PeerListResponse) Reset() { - *x = PeerListResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PeerListResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PeerListResponse) ProtoMessage() {} - -func (x *PeerListResponse) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PeerListResponse.ProtoReflect.Descriptor instead. -func (*PeerListResponse) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{11} -} - -func (x *PeerListResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -func (x *PeerListResponse) GetLastIndex() int32 { - if x != nil { - return x.LastIndex - } - return 0 -} - -func (x *PeerListResponse) GetPeers() []*Peer { - if x != nil { - return x.Peers - } - return nil -} - -type SquadConnectResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` - Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` - Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"` - Members []string `protobuf:"bytes,4,rep,name=members,proto3" json:"members,omitempty"` -} - -func (x *SquadConnectResponse) Reset() { - *x = SquadConnectResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SquadConnectResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SquadConnectResponse) ProtoMessage() {} - -func (x *SquadConnectResponse) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SquadConnectResponse.ProtoReflect.Descriptor instead. -func (*SquadConnectResponse) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{12} -} - -func (x *SquadConnectResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -func (x *SquadConnectResponse) GetReason() string { - if x != nil { - return x.Reason - } - return "" -} - -func (x *SquadConnectResponse) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *SquadConnectResponse) GetMembers() []string { - if x != nil { - return x.Members - } - return nil -} - -type SquadLeaveRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` - SquadId string `protobuf:"bytes,2,opt,name=squadId,proto3" json:"squadId,omitempty"` -} - -func (x *SquadLeaveRequest) Reset() { - *x = SquadLeaveRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SquadLeaveRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SquadLeaveRequest) ProtoMessage() {} - -func (x *SquadLeaveRequest) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SquadLeaveRequest.ProtoReflect.Descriptor instead. -func (*SquadLeaveRequest) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{13} -} - -func (x *SquadLeaveRequest) GetUserId() string { - if x != nil { - return x.UserId - } - return "" -} - -func (x *SquadLeaveRequest) GetSquadId() string { - if x != nil { - return x.SquadId - } - return "" -} - -type SquadCreateResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` - Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` - Squad *ProtoSquad `protobuf:"bytes,3,opt,name=squad,proto3" json:"squad,omitempty"` -} - -func (x *SquadCreateResponse) Reset() { - *x = SquadCreateResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SquadCreateResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SquadCreateResponse) ProtoMessage() {} - -func (x *SquadCreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SquadCreateResponse.ProtoReflect.Descriptor instead. -func (*SquadCreateResponse) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{14} -} - -func (x *SquadCreateResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -func (x *SquadCreateResponse) GetReason() string { - if x != nil { - return x.Reason - } - return "" -} - -func (x *SquadCreateResponse) GetSquad() *ProtoSquad { - if x != nil { - return x.Squad - } - return nil -} - -type SquadListResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` - LastIndex int32 `protobuf:"varint,2,opt,name=lastIndex,proto3" json:"lastIndex,omitempty"` - Squads []*ProtoSquad `protobuf:"bytes,3,rep,name=squads,proto3" json:"squads,omitempty"` -} - -func (x *SquadListResponse) Reset() { - *x = SquadListResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SquadListResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SquadListResponse) ProtoMessage() {} - -func (x *SquadListResponse) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SquadListResponse.ProtoReflect.Descriptor instead. -func (*SquadListResponse) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{15} -} - -func (x *SquadListResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -func (x *SquadListResponse) GetLastIndex() int32 { - if x != nil { - return x.LastIndex - } - return 0 -} - -func (x *SquadListResponse) GetSquads() []*ProtoSquad { - if x != nil { - return x.Squads - } - return nil -} - -type SquadUpdateResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` - Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` - Squad *ProtoSquad `protobuf:"bytes,3,opt,name=squad,proto3" json:"squad,omitempty"` -} - -func (x *SquadUpdateResponse) Reset() { - *x = SquadUpdateResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SquadUpdateResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SquadUpdateResponse) ProtoMessage() {} - -func (x *SquadUpdateResponse) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SquadUpdateResponse.ProtoReflect.Descriptor instead. -func (*SquadUpdateResponse) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{16} -} - -func (x *SquadUpdateResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -func (x *SquadUpdateResponse) GetReason() string { - if x != nil { - return x.Reason - } - return "" -} - -func (x *SquadUpdateResponse) GetSquad() *ProtoSquad { - if x != nil { - return x.Squad - } - return nil -} - -type SquadDeleteResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Succes bool `protobuf:"varint,1,opt,name=succes,proto3" json:"succes,omitempty"` - Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` - Squad *ProtoSquad `protobuf:"bytes,3,opt,name=squad,proto3" json:"squad,omitempty"` -} - -func (x *SquadDeleteResponse) Reset() { - *x = SquadDeleteResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SquadDeleteResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SquadDeleteResponse) ProtoMessage() {} - -func (x *SquadDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SquadDeleteResponse.ProtoReflect.Descriptor instead. -func (*SquadDeleteResponse) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{17} -} - -func (x *SquadDeleteResponse) GetSucces() bool { - if x != nil { - return x.Succes - } - return false -} - -func (x *SquadDeleteResponse) GetReason() string { - if x != nil { - return x.Reason - } - return "" -} - -func (x *SquadDeleteResponse) GetSquad() *ProtoSquad { - if x != nil { - return x.Squad - } - return nil -} - -type SquadLeaveResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` - Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` - SquadId string `protobuf:"bytes,3,opt,name=squadId,proto3" json:"squadId,omitempty"` -} - -func (x *SquadLeaveResponse) Reset() { - *x = SquadLeaveResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SquadLeaveResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SquadLeaveResponse) ProtoMessage() {} - -func (x *SquadLeaveResponse) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SquadLeaveResponse.ProtoReflect.Descriptor instead. -func (*SquadLeaveResponse) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{18} -} - -func (x *SquadLeaveResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -func (x *SquadLeaveResponse) GetReason() string { - if x != nil { - return x.Reason - } - return "" -} - -func (x *SquadLeaveResponse) GetSquadId() string { - if x != nil { - return x.SquadId - } - return "" -} - -type Response struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - Success bool `protobuf:"varint,2,opt,name=success,proto3" json:"success,omitempty"` - Payload map[string]string `protobuf:"bytes,3,rep,name=payload,proto3" json:"payload,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *Response) Reset() { - *x = Response{} - if protoimpl.UnsafeEnabled { - mi := &file_grpc_manager_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Response) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Response) ProtoMessage() {} - -func (x *Response) ProtoReflect() protoreflect.Message { - mi := &file_grpc_manager_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Response.ProtoReflect.Descriptor instead. -func (*Response) Descriptor() ([]byte, []int) { - return file_grpc_manager_proto_rawDescGZIP(), []int{19} -} - -func (x *Response) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *Response) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -func (x *Response) GetPayload() map[string]string { - if x != nil { - return x.Payload - } - return nil -} - -var File_grpc_manager_proto protoreflect.FileDescriptor - -var file_grpc_manager_proto_rawDesc = []byte{ - 0x0a, 0x12, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x22, 0xbc, 0x01, - 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, - 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x37, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, - 0x1a, 0x3a, 0x0a, 0x0c, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6b, 0x0a, 0x13, - 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, - 0x65, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x65, - 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x65, 0x65, 0x72, 0x55, 0x73, 0x65, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x65, 0x65, - 0x72, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x42, 0x0a, 0x14, 0x50, 0x65, 0x65, - 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6c, - 0x6f, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x22, 0xd8, 0x01, - 0x0a, 0x0f, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x61, 0x73, - 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6c, 0x61, - 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x07, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x97, 0x01, 0x0a, 0x13, 0x53, 0x71, 0x75, - 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, - 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, - 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x68, 0x54, 0x79, 0x70, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x75, 0x74, 0x68, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x54, 0x79, - 0x70, 0x65, 0x22, 0xc6, 0x01, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x53, 0x71, 0x75, 0x61, - 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, - 0x1c, 0x0a, 0x09, 0x73, 0x71, 0x75, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x73, 0x71, 0x75, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x68, 0x54, - 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x75, 0x74, 0x68, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x7a, 0x0a, 0x12, 0x53, - 0x71, 0x75, 0x61, 0x64, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, - 0x09, 0x73, 0x71, 0x75, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x73, 0x71, 0x75, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0xa4, 0x02, 0x0a, 0x10, 0x53, 0x71, 0x75, 0x61, - 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, - 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, - 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, - 0x65, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x2e, 0x53, 0x71, 0x75, 0x61, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x71, 0x75, 0x61, - 0x64, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x71, 0x75, - 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x73, 0x71, 0x75, 0x61, 0x64, 0x4e, - 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x10, 0x73, 0x71, 0x75, 0x61, 0x64, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x54, 0x79, - 0x70, 0x65, 0x1a, 0x3a, 0x0a, 0x0c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8a, - 0x01, 0x0a, 0x12, 0x53, 0x71, 0x75, 0x61, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x71, 0x75, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x71, 0x75, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x46, 0x0a, 0x12, 0x53, - 0x71, 0x75, 0x61, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x71, 0x75, - 0x61, 0x64, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x71, 0x75, 0x61, - 0x64, 0x49, 0x64, 0x22, 0x5a, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x70, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, - 0x6f, 0x0a, 0x10, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1c, 0x0a, - 0x09, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x23, 0x0a, 0x05, 0x70, - 0x65, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x72, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, - 0x22, 0x72, 0x0a, 0x14, 0x53, 0x71, 0x75, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x22, 0x45, 0x0a, 0x11, 0x53, 0x71, 0x75, 0x61, 0x64, 0x4c, 0x65, 0x61, - 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x71, 0x75, 0x61, 0x64, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x73, 0x71, 0x75, 0x61, 0x64, 0x49, 0x64, 0x22, 0x72, 0x0a, 0x13, 0x53, - 0x71, 0x75, 0x61, 0x64, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, - 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, - 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x05, 0x73, 0x71, 0x75, 0x61, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x53, 0x71, 0x75, 0x61, 0x64, 0x52, 0x05, 0x73, 0x71, 0x75, 0x61, 0x64, 0x22, - 0x78, 0x0a, 0x11, 0x53, 0x71, 0x75, 0x61, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1c, - 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2b, 0x0a, 0x06, - 0x73, 0x71, 0x75, 0x61, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x53, 0x71, 0x75, 0x61, - 0x64, 0x52, 0x06, 0x73, 0x71, 0x75, 0x61, 0x64, 0x73, 0x22, 0x72, 0x0a, 0x13, 0x53, 0x71, 0x75, - 0x61, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, - 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, - 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x05, 0x73, 0x71, 0x75, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x53, 0x71, 0x75, 0x61, 0x64, 0x52, 0x05, 0x73, 0x71, 0x75, 0x61, 0x64, 0x22, 0x70, 0x0a, - 0x13, 0x53, 0x71, 0x75, 0x61, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, - 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, - 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x05, 0x73, 0x71, 0x75, 0x61, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x53, 0x71, 0x75, 0x61, 0x64, 0x52, 0x05, 0x73, 0x71, 0x75, 0x61, 0x64, 0x22, - 0x60, 0x0a, 0x12, 0x53, 0x71, 0x75, 0x61, 0x64, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, - 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x71, 0x75, 0x61, 0x64, - 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x71, 0x75, 0x61, 0x64, 0x49, - 0x64, 0x22, 0xae, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x38, 0x0a, 0x07, - 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x70, - 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x1a, 0x3a, 0x0a, 0x0c, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, - 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x32, 0x83, 0x05, 0x0a, 0x0b, 0x47, 0x72, 0x70, 0x63, 0x4d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x10, 0x2e, 0x6d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, - 0x01, 0x30, 0x01, 0x12, 0x4b, 0x0a, 0x0c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, - 0x65, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x50, 0x65, - 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x50, 0x65, 0x65, 0x72, - 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x40, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x18, 0x2e, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x71, 0x75, 0x61, - 0x64, 0x12, 0x1b, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x71, 0x75, 0x61, - 0x64, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, - 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x71, 0x75, 0x61, 0x64, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x71, 0x75, 0x61, 0x64, 0x12, 0x1b, 0x2e, 0x6d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x71, 0x75, 0x61, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x2e, 0x53, 0x71, 0x75, 0x61, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x53, 0x71, 0x75, 0x61, 0x64, 0x12, 0x1b, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, - 0x53, 0x71, 0x75, 0x61, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x71, 0x75, - 0x61, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x42, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x71, 0x75, 0x61, 0x64, 0x12, 0x19, 0x2e, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x71, 0x75, 0x61, 0x64, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x2e, 0x53, 0x71, 0x75, 0x61, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x53, - 0x71, 0x75, 0x61, 0x64, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, - 0x71, 0x75, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x71, 0x75, - 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x53, 0x71, 0x75, 0x61, 0x64, 0x12, - 0x1a, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x71, 0x75, 0x61, 0x64, 0x4c, - 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x53, 0x71, 0x75, 0x61, 0x64, 0x4c, 0x65, 0x61, 0x76, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x3b, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} - -var ( - file_grpc_manager_proto_rawDescOnce sync.Once - file_grpc_manager_proto_rawDescData = file_grpc_manager_proto_rawDesc -) - -func file_grpc_manager_proto_rawDescGZIP() []byte { - file_grpc_manager_proto_rawDescOnce.Do(func() { - file_grpc_manager_proto_rawDescData = protoimpl.X.CompressGZIP(file_grpc_manager_proto_rawDescData) - }) - return file_grpc_manager_proto_rawDescData -} - -var file_grpc_manager_proto_msgTypes = make([]protoimpl.MessageInfo, 24) -var file_grpc_manager_proto_goTypes = []interface{}{ - (*Request)(nil), // 0: manager.Request - (*PeerRegisterRequest)(nil), // 1: manager.PeerRegisterRequest - (*PeerRegisterResponse)(nil), // 2: manager.PeerRegisterResponse - (*PeerListRequest)(nil), // 3: manager.PeerListRequest - (*SquadConnectRequest)(nil), // 4: manager.SquadConnectRequest - (*ProtoSquad)(nil), // 5: manager.ProtoSquad - (*SquadCreateRequest)(nil), // 6: manager.SquadCreateRequest - (*SquadListRequest)(nil), // 7: manager.SquadListRequest - (*SquadUpdateRequest)(nil), // 8: manager.SquadUpdateRequest - (*SquadDeleteRequest)(nil), // 9: manager.SquadDeleteRequest - (*Peer)(nil), // 10: manager.Peer - (*PeerListResponse)(nil), // 11: manager.PeerListResponse - (*SquadConnectResponse)(nil), // 12: manager.SquadConnectResponse - (*SquadLeaveRequest)(nil), // 13: manager.SquadLeaveRequest - (*SquadCreateResponse)(nil), // 14: manager.SquadCreateResponse - (*SquadListResponse)(nil), // 15: manager.SquadListResponse - (*SquadUpdateResponse)(nil), // 16: manager.SquadUpdateResponse - (*SquadDeleteResponse)(nil), // 17: manager.SquadDeleteResponse - (*SquadLeaveResponse)(nil), // 18: manager.SquadLeaveResponse - (*Response)(nil), // 19: manager.Response - nil, // 20: manager.Request.PayloadEntry - nil, // 21: manager.PeerListRequest.FiltersEntry - nil, // 22: manager.SquadListRequest.FiltersEntry - nil, // 23: manager.Response.PayloadEntry -} -var file_grpc_manager_proto_depIdxs = []int32{ - 20, // 0: manager.Request.payload:type_name -> manager.Request.PayloadEntry - 21, // 1: manager.PeerListRequest.filters:type_name -> manager.PeerListRequest.FiltersEntry - 22, // 2: manager.SquadListRequest.filters:type_name -> manager.SquadListRequest.FiltersEntry - 10, // 3: manager.PeerListResponse.peers:type_name -> manager.Peer - 5, // 4: manager.SquadCreateResponse.squad:type_name -> manager.ProtoSquad - 5, // 5: manager.SquadListResponse.squads:type_name -> manager.ProtoSquad - 5, // 6: manager.SquadUpdateResponse.squad:type_name -> manager.ProtoSquad - 5, // 7: manager.SquadDeleteResponse.squad:type_name -> manager.ProtoSquad - 23, // 8: manager.Response.payload:type_name -> manager.Response.PayloadEntry - 0, // 9: manager.GrpcManager.Link:input_type -> manager.Request - 1, // 10: manager.GrpcManager.RegisterPeer:input_type -> manager.PeerRegisterRequest - 3, // 11: manager.GrpcManager.ListPeers:input_type -> manager.PeerListRequest - 6, // 12: manager.GrpcManager.CreateSquad:input_type -> manager.SquadCreateRequest - 8, // 13: manager.GrpcManager.UpdateSquad:input_type -> manager.SquadUpdateRequest - 9, // 14: manager.GrpcManager.DeleteSquad:input_type -> manager.SquadDeleteRequest - 7, // 15: manager.GrpcManager.ListSquad:input_type -> manager.SquadListRequest - 4, // 16: manager.GrpcManager.ConnectSquad:input_type -> manager.SquadConnectRequest - 13, // 17: manager.GrpcManager.LeaveSquad:input_type -> manager.SquadLeaveRequest - 19, // 18: manager.GrpcManager.Link:output_type -> manager.Response - 2, // 19: manager.GrpcManager.RegisterPeer:output_type -> manager.PeerRegisterResponse - 11, // 20: manager.GrpcManager.ListPeers:output_type -> manager.PeerListResponse - 14, // 21: manager.GrpcManager.CreateSquad:output_type -> manager.SquadCreateResponse - 16, // 22: manager.GrpcManager.UpdateSquad:output_type -> manager.SquadUpdateResponse - 17, // 23: manager.GrpcManager.DeleteSquad:output_type -> manager.SquadDeleteResponse - 15, // 24: manager.GrpcManager.ListSquad:output_type -> manager.SquadListResponse - 12, // 25: manager.GrpcManager.ConnectSquad:output_type -> manager.SquadConnectResponse - 18, // 26: manager.GrpcManager.LeaveSquad:output_type -> manager.SquadLeaveResponse - 18, // [18:27] is the sub-list for method output_type - 9, // [9:18] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name -} - -func init() { file_grpc_manager_proto_init() } -func file_grpc_manager_proto_init() { - if File_grpc_manager_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_grpc_manager_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Request); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeerRegisterRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeerRegisterResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeerListRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SquadConnectRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProtoSquad); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SquadCreateRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SquadListRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SquadUpdateRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SquadDeleteRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Peer); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeerListResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SquadConnectResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SquadLeaveRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SquadCreateResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SquadListResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SquadUpdateResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SquadDeleteResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SquadLeaveResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_grpc_manager_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Response); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_grpc_manager_proto_rawDesc, - NumEnums: 0, - NumMessages: 24, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_grpc_manager_proto_goTypes, - DependencyIndexes: file_grpc_manager_proto_depIdxs, - MessageInfos: file_grpc_manager_proto_msgTypes, - }.Build() - File_grpc_manager_proto = out.File - file_grpc_manager_proto_rawDesc = nil - file_grpc_manager_proto_goTypes = nil - file_grpc_manager_proto_depIdxs = nil -} diff --git a/grpc_manager_grpc.pb.go b/grpc_manager_grpc.pb.go deleted file mode 100644 index cd43f63..0000000 --- a/grpc_manager_grpc.pb.go +++ /dev/null @@ -1,422 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. - -package localserver - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -// GrpcManagerClient is the client API for GrpcManager service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type GrpcManagerClient interface { - Link(ctx context.Context, opts ...grpc.CallOption) (GrpcManager_LinkClient, error) - RegisterPeer(ctx context.Context, in *PeerRegisterRequest, opts ...grpc.CallOption) (*PeerRegisterResponse, error) - ListPeers(ctx context.Context, in *PeerListRequest, opts ...grpc.CallOption) (*PeerListResponse, error) - CreateSquad(ctx context.Context, in *SquadCreateRequest, opts ...grpc.CallOption) (*SquadCreateResponse, error) - UpdateSquad(ctx context.Context, in *SquadUpdateRequest, opts ...grpc.CallOption) (*SquadUpdateResponse, error) - DeleteSquad(ctx context.Context, in *SquadDeleteRequest, opts ...grpc.CallOption) (*SquadDeleteResponse, error) - ListSquad(ctx context.Context, in *SquadListRequest, opts ...grpc.CallOption) (*SquadListResponse, error) - ConnectSquad(ctx context.Context, in *SquadConnectRequest, opts ...grpc.CallOption) (*SquadConnectResponse, error) - LeaveSquad(ctx context.Context, in *SquadLeaveRequest, opts ...grpc.CallOption) (*SquadLeaveResponse, error) -} - -type grpcManagerClient struct { - cc grpc.ClientConnInterface -} - -func NewGrpcManagerClient(cc grpc.ClientConnInterface) GrpcManagerClient { - return &grpcManagerClient{cc} -} - -func (c *grpcManagerClient) Link(ctx context.Context, opts ...grpc.CallOption) (GrpcManager_LinkClient, error) { - stream, err := c.cc.NewStream(ctx, &GrpcManager_ServiceDesc.Streams[0], "/manager.GrpcManager/Link", opts...) - if err != nil { - return nil, err - } - x := &grpcManagerLinkClient{stream} - return x, nil -} - -type GrpcManager_LinkClient interface { - Send(*Request) error - Recv() (*Response, error) - grpc.ClientStream -} - -type grpcManagerLinkClient struct { - grpc.ClientStream -} - -func (x *grpcManagerLinkClient) Send(m *Request) error { - return x.ClientStream.SendMsg(m) -} - -func (x *grpcManagerLinkClient) Recv() (*Response, error) { - m := new(Response) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -func (c *grpcManagerClient) RegisterPeer(ctx context.Context, in *PeerRegisterRequest, opts ...grpc.CallOption) (*PeerRegisterResponse, error) { - out := new(PeerRegisterResponse) - err := c.cc.Invoke(ctx, "/manager.GrpcManager/RegisterPeer", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *grpcManagerClient) ListPeers(ctx context.Context, in *PeerListRequest, opts ...grpc.CallOption) (*PeerListResponse, error) { - out := new(PeerListResponse) - err := c.cc.Invoke(ctx, "/manager.GrpcManager/ListPeers", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *grpcManagerClient) CreateSquad(ctx context.Context, in *SquadCreateRequest, opts ...grpc.CallOption) (*SquadCreateResponse, error) { - out := new(SquadCreateResponse) - err := c.cc.Invoke(ctx, "/manager.GrpcManager/CreateSquad", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *grpcManagerClient) UpdateSquad(ctx context.Context, in *SquadUpdateRequest, opts ...grpc.CallOption) (*SquadUpdateResponse, error) { - out := new(SquadUpdateResponse) - err := c.cc.Invoke(ctx, "/manager.GrpcManager/UpdateSquad", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *grpcManagerClient) DeleteSquad(ctx context.Context, in *SquadDeleteRequest, opts ...grpc.CallOption) (*SquadDeleteResponse, error) { - out := new(SquadDeleteResponse) - err := c.cc.Invoke(ctx, "/manager.GrpcManager/DeleteSquad", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *grpcManagerClient) ListSquad(ctx context.Context, in *SquadListRequest, opts ...grpc.CallOption) (*SquadListResponse, error) { - out := new(SquadListResponse) - err := c.cc.Invoke(ctx, "/manager.GrpcManager/ListSquad", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *grpcManagerClient) ConnectSquad(ctx context.Context, in *SquadConnectRequest, opts ...grpc.CallOption) (*SquadConnectResponse, error) { - out := new(SquadConnectResponse) - err := c.cc.Invoke(ctx, "/manager.GrpcManager/ConnectSquad", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *grpcManagerClient) LeaveSquad(ctx context.Context, in *SquadLeaveRequest, opts ...grpc.CallOption) (*SquadLeaveResponse, error) { - out := new(SquadLeaveResponse) - err := c.cc.Invoke(ctx, "/manager.GrpcManager/LeaveSquad", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// GrpcManagerServer is the server API for GrpcManager service. -// All implementations must embed UnimplementedGrpcManagerServer -// for forward compatibility -type GrpcManagerServer interface { - Link(GrpcManager_LinkServer) error - RegisterPeer(context.Context, *PeerRegisterRequest) (*PeerRegisterResponse, error) - ListPeers(context.Context, *PeerListRequest) (*PeerListResponse, error) - CreateSquad(context.Context, *SquadCreateRequest) (*SquadCreateResponse, error) - UpdateSquad(context.Context, *SquadUpdateRequest) (*SquadUpdateResponse, error) - DeleteSquad(context.Context, *SquadDeleteRequest) (*SquadDeleteResponse, error) - ListSquad(context.Context, *SquadListRequest) (*SquadListResponse, error) - ConnectSquad(context.Context, *SquadConnectRequest) (*SquadConnectResponse, error) - LeaveSquad(context.Context, *SquadLeaveRequest) (*SquadLeaveResponse, error) - mustEmbedUnimplementedGrpcManagerServer() -} - -// UnimplementedGrpcManagerServer must be embedded to have forward compatible implementations. -type UnimplementedGrpcManagerServer struct { -} - -func (UnimplementedGrpcManagerServer) Link(GrpcManager_LinkServer) error { - return status.Errorf(codes.Unimplemented, "method Link not implemented") -} -func (UnimplementedGrpcManagerServer) RegisterPeer(context.Context, *PeerRegisterRequest) (*PeerRegisterResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method RegisterPeer not implemented") -} -func (UnimplementedGrpcManagerServer) ListPeers(context.Context, *PeerListRequest) (*PeerListResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListPeers not implemented") -} -func (UnimplementedGrpcManagerServer) CreateSquad(context.Context, *SquadCreateRequest) (*SquadCreateResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method CreateSquad not implemented") -} -func (UnimplementedGrpcManagerServer) UpdateSquad(context.Context, *SquadUpdateRequest) (*SquadUpdateResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UpdateSquad not implemented") -} -func (UnimplementedGrpcManagerServer) DeleteSquad(context.Context, *SquadDeleteRequest) (*SquadDeleteResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeleteSquad not implemented") -} -func (UnimplementedGrpcManagerServer) ListSquad(context.Context, *SquadListRequest) (*SquadListResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListSquad not implemented") -} -func (UnimplementedGrpcManagerServer) ConnectSquad(context.Context, *SquadConnectRequest) (*SquadConnectResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ConnectSquad not implemented") -} -func (UnimplementedGrpcManagerServer) LeaveSquad(context.Context, *SquadLeaveRequest) (*SquadLeaveResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method LeaveSquad not implemented") -} -func (UnimplementedGrpcManagerServer) mustEmbedUnimplementedGrpcManagerServer() {} - -// UnsafeGrpcManagerServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to GrpcManagerServer will -// result in compilation errors. -type UnsafeGrpcManagerServer interface { - mustEmbedUnimplementedGrpcManagerServer() -} - -func RegisterGrpcManagerServer(s grpc.ServiceRegistrar, srv GrpcManagerServer) { - s.RegisterService(&GrpcManager_ServiceDesc, srv) -} - -func _GrpcManager_Link_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(GrpcManagerServer).Link(&grpcManagerLinkServer{stream}) -} - -type GrpcManager_LinkServer interface { - Send(*Response) error - Recv() (*Request, error) - grpc.ServerStream -} - -type grpcManagerLinkServer struct { - grpc.ServerStream -} - -func (x *grpcManagerLinkServer) Send(m *Response) error { - return x.ServerStream.SendMsg(m) -} - -func (x *grpcManagerLinkServer) Recv() (*Request, error) { - m := new(Request) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -func _GrpcManager_RegisterPeer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PeerRegisterRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(GrpcManagerServer).RegisterPeer(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/manager.GrpcManager/RegisterPeer", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(GrpcManagerServer).RegisterPeer(ctx, req.(*PeerRegisterRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _GrpcManager_ListPeers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PeerListRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(GrpcManagerServer).ListPeers(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/manager.GrpcManager/ListPeers", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(GrpcManagerServer).ListPeers(ctx, req.(*PeerListRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _GrpcManager_CreateSquad_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SquadCreateRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(GrpcManagerServer).CreateSquad(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/manager.GrpcManager/CreateSquad", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(GrpcManagerServer).CreateSquad(ctx, req.(*SquadCreateRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _GrpcManager_UpdateSquad_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SquadUpdateRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(GrpcManagerServer).UpdateSquad(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/manager.GrpcManager/UpdateSquad", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(GrpcManagerServer).UpdateSquad(ctx, req.(*SquadUpdateRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _GrpcManager_DeleteSquad_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SquadDeleteRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(GrpcManagerServer).DeleteSquad(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/manager.GrpcManager/DeleteSquad", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(GrpcManagerServer).DeleteSquad(ctx, req.(*SquadDeleteRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _GrpcManager_ListSquad_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SquadListRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(GrpcManagerServer).ListSquad(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/manager.GrpcManager/ListSquad", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(GrpcManagerServer).ListSquad(ctx, req.(*SquadListRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _GrpcManager_ConnectSquad_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SquadConnectRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(GrpcManagerServer).ConnectSquad(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/manager.GrpcManager/ConnectSquad", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(GrpcManagerServer).ConnectSquad(ctx, req.(*SquadConnectRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _GrpcManager_LeaveSquad_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SquadLeaveRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(GrpcManagerServer).LeaveSquad(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/manager.GrpcManager/LeaveSquad", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(GrpcManagerServer).LeaveSquad(ctx, req.(*SquadLeaveRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// GrpcManager_ServiceDesc is the grpc.ServiceDesc for GrpcManager service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var GrpcManager_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "manager.GrpcManager", - HandlerType: (*GrpcManagerServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "RegisterPeer", - Handler: _GrpcManager_RegisterPeer_Handler, - }, - { - MethodName: "ListPeers", - Handler: _GrpcManager_ListPeers_Handler, - }, - { - MethodName: "CreateSquad", - Handler: _GrpcManager_CreateSquad_Handler, - }, - { - MethodName: "UpdateSquad", - Handler: _GrpcManager_UpdateSquad_Handler, - }, - { - MethodName: "DeleteSquad", - Handler: _GrpcManager_DeleteSquad_Handler, - }, - { - MethodName: "ListSquad", - Handler: _GrpcManager_ListSquad_Handler, - }, - { - MethodName: "ConnectSquad", - Handler: _GrpcManager_ConnectSquad_Handler, - }, - { - MethodName: "LeaveSquad", - Handler: _GrpcManager_LeaveSquad_Handler, - }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "Link", - Handler: _GrpcManager_Link_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "grpc_manager.proto", -} diff --git a/node.pb.go b/node.pb.go new file mode 100644 index 0000000..28e5ba0 --- /dev/null +++ b/node.pb.go @@ -0,0 +1,1658 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.0 +// protoc v3.14.0 +// source: node.proto + +package localserver + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type NodeAuthType int32 + +const ( + NodeAuthType_token NodeAuthType = 0 + NodeAuthType_key NodeAuthType = 1 + NodeAuthType_mac NodeAuthType = 2 + NodeAuthType_none NodeAuthType = 3 +) + +// Enum value maps for NodeAuthType. +var ( + NodeAuthType_name = map[int32]string{ + 0: "token", + 1: "key", + 2: "mac", + 3: "none", + } + NodeAuthType_value = map[string]int32{ + "token": 0, + "key": 1, + "mac": 2, + "none": 3, + } +) + +func (x NodeAuthType) Enum() *NodeAuthType { + p := new(NodeAuthType) + *p = x + return p +} + +func (x NodeAuthType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (NodeAuthType) Descriptor() protoreflect.EnumDescriptor { + return file_node_proto_enumTypes[0].Descriptor() +} + +func (NodeAuthType) Type() protoreflect.EnumType { + return &file_node_proto_enumTypes[0] +} + +func (x NodeAuthType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use NodeAuthType.Descriptor instead. +func (NodeAuthType) EnumDescriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{0} +} + +type NodeAuthParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId string `protobuf:"bytes,1,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + AuthKey string `protobuf:"bytes,2,opt,name=authKey,proto3" json:"authKey,omitempty"` + AuthType NodeAuthType `protobuf:"varint,3,opt,name=authType,proto3,enum=node.NodeAuthType" json:"authType,omitempty"` +} + +func (x *NodeAuthParams) Reset() { + *x = NodeAuthParams{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NodeAuthParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NodeAuthParams) ProtoMessage() {} + +func (x *NodeAuthParams) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NodeAuthParams.ProtoReflect.Descriptor instead. +func (*NodeAuthParams) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{0} +} + +func (x *NodeAuthParams) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +func (x *NodeAuthParams) GetAuthKey() string { + if x != nil { + return x.AuthKey + } + return "" +} + +func (x *NodeAuthParams) GetAuthType() NodeAuthType { + if x != nil { + return x.AuthType + } + return NodeAuthType_token +} + +type OperatorAuthParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OperatorId string `protobuf:"bytes,1,opt,name=operatorId,proto3" json:"operatorId,omitempty"` + AuthKey string `protobuf:"bytes,2,opt,name=authKey,proto3" json:"authKey,omitempty"` + AuthType NodeAuthType `protobuf:"varint,3,opt,name=authType,proto3,enum=node.NodeAuthType" json:"authType,omitempty"` +} + +func (x *OperatorAuthParams) Reset() { + *x = OperatorAuthParams{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OperatorAuthParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OperatorAuthParams) ProtoMessage() {} + +func (x *OperatorAuthParams) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OperatorAuthParams.ProtoReflect.Descriptor instead. +func (*OperatorAuthParams) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{1} +} + +func (x *OperatorAuthParams) GetOperatorId() string { + if x != nil { + return x.OperatorId + } + return "" +} + +func (x *OperatorAuthParams) GetAuthKey() string { + if x != nil { + return x.AuthKey + } + return "" +} + +func (x *OperatorAuthParams) GetAuthType() NodeAuthType { + if x != nil { + return x.AuthType + } + return NodeAuthType_token +} + +type Node struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + PubKey string `protobuf:"bytes,3,opt,name=pubKey,proto3" json:"pubKey,omitempty"` + Active bool `protobuf:"varint,4,opt,name=active,proto3" json:"active,omitempty"` + Operators []string `protobuf:"bytes,5,rep,name=operators,proto3" json:"operators,omitempty"` + OperatorRequests []string `protobuf:"bytes,6,rep,name=operatorRequests,proto3" json:"operatorRequests,omitempty"` +} + +func (x *Node) Reset() { + *x = Node{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Node) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Node) ProtoMessage() {} + +func (x *Node) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Node.ProtoReflect.Descriptor instead. +func (*Node) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{2} +} + +func (x *Node) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Node) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Node) GetPubKey() string { + if x != nil { + return x.PubKey + } + return "" +} + +func (x *Node) GetActive() bool { + if x != nil { + return x.Active + } + return false +} + +func (x *Node) GetOperators() []string { + if x != nil { + return x.Operators + } + return nil +} + +func (x *Node) GetOperatorRequests() []string { + if x != nil { + return x.OperatorRequests + } + return nil +} + +type CreateNodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId string `protobuf:"bytes,1,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + NodeKey string `protobuf:"bytes,2,opt,name=nodeKey,proto3" json:"nodeKey,omitempty"` + NodeUsername string `protobuf:"bytes,3,opt,name=nodeUsername,proto3" json:"nodeUsername,omitempty"` +} + +func (x *CreateNodeRequest) Reset() { + *x = CreateNodeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateNodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateNodeRequest) ProtoMessage() {} + +func (x *CreateNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateNodeRequest.ProtoReflect.Descriptor instead. +func (*CreateNodeRequest) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{3} +} + +func (x *CreateNodeRequest) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +func (x *CreateNodeRequest) GetNodeKey() string { + if x != nil { + return x.NodeKey + } + return "" +} + +func (x *CreateNodeRequest) GetNodeUsername() string { + if x != nil { + return x.NodeUsername + } + return "" +} + +type CreateNodeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + NodeId string `protobuf:"bytes,2,opt,name=nodeId,proto3" json:"nodeId,omitempty"` +} + +func (x *CreateNodeResponse) Reset() { + *x = CreateNodeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateNodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateNodeResponse) ProtoMessage() {} + +func (x *CreateNodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateNodeResponse.ProtoReflect.Descriptor instead. +func (*CreateNodeResponse) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{4} +} + +func (x *CreateNodeResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *CreateNodeResponse) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +type GetNodesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AuthParams *OperatorAuthParams `protobuf:"bytes,1,opt,name=authParams,proto3" json:"authParams,omitempty"` + LastIndex int64 `protobuf:"varint,2,opt,name=lastIndex,proto3" json:"lastIndex,omitempty"` + Limit int64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` +} + +func (x *GetNodesRequest) Reset() { + *x = GetNodesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodesRequest) ProtoMessage() {} + +func (x *GetNodesRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodesRequest.ProtoReflect.Descriptor instead. +func (*GetNodesRequest) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{5} +} + +func (x *GetNodesRequest) GetAuthParams() *OperatorAuthParams { + if x != nil { + return x.AuthParams + } + return nil +} + +func (x *GetNodesRequest) GetLastIndex() int64 { + if x != nil { + return x.LastIndex + } + return 0 +} + +func (x *GetNodesRequest) GetLimit() int64 { + if x != nil { + return x.Limit + } + return 0 +} + +type GetNodesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nodes []*Node `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"` + Success bool `protobuf:"varint,2,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *GetNodesResponse) Reset() { + *x = GetNodesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodesResponse) ProtoMessage() {} + +func (x *GetNodesResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodesResponse.ProtoReflect.Descriptor instead. +func (*GetNodesResponse) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{6} +} + +func (x *GetNodesResponse) GetNodes() []*Node { + if x != nil { + return x.Nodes + } + return nil +} + +func (x *GetNodesResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +type GetNodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId string `protobuf:"bytes,1,opt,name=nodeId,proto3" json:"nodeId,omitempty"` +} + +func (x *GetNodeRequest) Reset() { + *x = GetNodeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodeRequest) ProtoMessage() {} + +func (x *GetNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodeRequest.ProtoReflect.Descriptor instead. +func (*GetNodeRequest) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{7} +} + +func (x *GetNodeRequest) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +type GetNodeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` + Success bool `protobuf:"varint,2,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *GetNodeResponse) Reset() { + *x = GetNodeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetNodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetNodeResponse) ProtoMessage() {} + +func (x *GetNodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetNodeResponse.ProtoReflect.Descriptor instead. +func (*GetNodeResponse) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{8} +} + +func (x *GetNodeResponse) GetNode() *Node { + if x != nil { + return x.Node + } + return nil +} + +func (x *GetNodeResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +type DeleteNodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AuthParams *NodeAuthParams `protobuf:"bytes,1,opt,name=authParams,proto3" json:"authParams,omitempty"` + NodeId string `protobuf:"bytes,2,opt,name=nodeId,proto3" json:"nodeId,omitempty"` +} + +func (x *DeleteNodeRequest) Reset() { + *x = DeleteNodeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteNodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteNodeRequest) ProtoMessage() {} + +func (x *DeleteNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteNodeRequest.ProtoReflect.Descriptor instead. +func (*DeleteNodeRequest) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{9} +} + +func (x *DeleteNodeRequest) GetAuthParams() *NodeAuthParams { + if x != nil { + return x.AuthParams + } + return nil +} + +func (x *DeleteNodeRequest) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +type DeleteNodeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *DeleteNodeResponse) Reset() { + *x = DeleteNodeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteNodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteNodeResponse) ProtoMessage() {} + +func (x *DeleteNodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteNodeResponse.ProtoReflect.Descriptor instead. +func (*DeleteNodeResponse) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{10} +} + +func (x *DeleteNodeResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +type AddPeerOperatorRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AuthParams *OperatorAuthParams `protobuf:"bytes,1,opt,name=authParams,proto3" json:"authParams,omitempty"` + NodeId string `protobuf:"bytes,2,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + OperatorId string `protobuf:"bytes,3,opt,name=operatorId,proto3" json:"operatorId,omitempty"` +} + +func (x *AddPeerOperatorRequest) Reset() { + *x = AddPeerOperatorRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddPeerOperatorRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddPeerOperatorRequest) ProtoMessage() {} + +func (x *AddPeerOperatorRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddPeerOperatorRequest.ProtoReflect.Descriptor instead. +func (*AddPeerOperatorRequest) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{11} +} + +func (x *AddPeerOperatorRequest) GetAuthParams() *OperatorAuthParams { + if x != nil { + return x.AuthParams + } + return nil +} + +func (x *AddPeerOperatorRequest) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +func (x *AddPeerOperatorRequest) GetOperatorId() string { + if x != nil { + return x.OperatorId + } + return "" +} + +type AddPeerOperatorResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *AddPeerOperatorResponse) Reset() { + *x = AddPeerOperatorResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddPeerOperatorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddPeerOperatorResponse) ProtoMessage() {} + +func (x *AddPeerOperatorResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddPeerOperatorResponse.ProtoReflect.Descriptor instead. +func (*AddPeerOperatorResponse) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{12} +} + +func (x *AddPeerOperatorResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +type RejectPeerOperatorRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AuthParams *NodeAuthParams `protobuf:"bytes,1,opt,name=authParams,proto3" json:"authParams,omitempty"` + NodeId string `protobuf:"bytes,2,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + OperatorId string `protobuf:"bytes,3,opt,name=operatorId,proto3" json:"operatorId,omitempty"` +} + +func (x *RejectPeerOperatorRequest) Reset() { + *x = RejectPeerOperatorRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RejectPeerOperatorRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RejectPeerOperatorRequest) ProtoMessage() {} + +func (x *RejectPeerOperatorRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RejectPeerOperatorRequest.ProtoReflect.Descriptor instead. +func (*RejectPeerOperatorRequest) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{13} +} + +func (x *RejectPeerOperatorRequest) GetAuthParams() *NodeAuthParams { + if x != nil { + return x.AuthParams + } + return nil +} + +func (x *RejectPeerOperatorRequest) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +func (x *RejectPeerOperatorRequest) GetOperatorId() string { + if x != nil { + return x.OperatorId + } + return "" +} + +type RejectPeerOperatorResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *RejectPeerOperatorResponse) Reset() { + *x = RejectPeerOperatorResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RejectPeerOperatorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RejectPeerOperatorResponse) ProtoMessage() {} + +func (x *RejectPeerOperatorResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RejectPeerOperatorResponse.ProtoReflect.Descriptor instead. +func (*RejectPeerOperatorResponse) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{14} +} + +func (x *RejectPeerOperatorResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +type AcceptPeerOperatorRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AuthParams *NodeAuthParams `protobuf:"bytes,1,opt,name=authParams,proto3" json:"authParams,omitempty"` + NodeId string `protobuf:"bytes,2,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + OperatorId string `protobuf:"bytes,3,opt,name=operatorId,proto3" json:"operatorId,omitempty"` +} + +func (x *AcceptPeerOperatorRequest) Reset() { + *x = AcceptPeerOperatorRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AcceptPeerOperatorRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AcceptPeerOperatorRequest) ProtoMessage() {} + +func (x *AcceptPeerOperatorRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AcceptPeerOperatorRequest.ProtoReflect.Descriptor instead. +func (*AcceptPeerOperatorRequest) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{15} +} + +func (x *AcceptPeerOperatorRequest) GetAuthParams() *NodeAuthParams { + if x != nil { + return x.AuthParams + } + return nil +} + +func (x *AcceptPeerOperatorRequest) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +func (x *AcceptPeerOperatorRequest) GetOperatorId() string { + if x != nil { + return x.OperatorId + } + return "" +} + +type AcceptPeerOperatorResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *AcceptPeerOperatorResponse) Reset() { + *x = AcceptPeerOperatorResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AcceptPeerOperatorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AcceptPeerOperatorResponse) ProtoMessage() {} + +func (x *AcceptPeerOperatorResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AcceptPeerOperatorResponse.ProtoReflect.Descriptor instead. +func (*AcceptPeerOperatorResponse) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{16} +} + +func (x *AcceptPeerOperatorResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +type RemovePeerOperatorRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AuthParams *OperatorAuthParams `protobuf:"bytes,1,opt,name=authParams,proto3" json:"authParams,omitempty"` + NodeId string `protobuf:"bytes,2,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + OperatorId string `protobuf:"bytes,3,opt,name=operatorId,proto3" json:"operatorId,omitempty"` +} + +func (x *RemovePeerOperatorRequest) Reset() { + *x = RemovePeerOperatorRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemovePeerOperatorRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemovePeerOperatorRequest) ProtoMessage() {} + +func (x *RemovePeerOperatorRequest) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemovePeerOperatorRequest.ProtoReflect.Descriptor instead. +func (*RemovePeerOperatorRequest) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{17} +} + +func (x *RemovePeerOperatorRequest) GetAuthParams() *OperatorAuthParams { + if x != nil { + return x.AuthParams + } + return nil +} + +func (x *RemovePeerOperatorRequest) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +func (x *RemovePeerOperatorRequest) GetOperatorId() string { + if x != nil { + return x.OperatorId + } + return "" +} + +type RemovePeerOperatorResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *RemovePeerOperatorResponse) Reset() { + *x = RemovePeerOperatorResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemovePeerOperatorResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemovePeerOperatorResponse) ProtoMessage() {} + +func (x *RemovePeerOperatorResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemovePeerOperatorResponse.ProtoReflect.Descriptor instead. +func (*RemovePeerOperatorResponse) Descriptor() ([]byte, []int) { + return file_node_proto_rawDescGZIP(), []int{18} +} + +func (x *RemovePeerOperatorResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +var File_node_proto protoreflect.FileDescriptor + +var file_node_proto_rawDesc = []byte{ + 0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x6e, 0x6f, + 0x64, 0x65, 0x22, 0x72, 0x0a, 0x0e, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x75, 0x74, 0x68, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, + 0x61, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, + 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x68, 0x54, 0x79, + 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x75, 0x74, 0x68, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x61, 0x75, + 0x74, 0x68, 0x54, 0x79, 0x70, 0x65, 0x22, 0x7e, 0x0a, 0x12, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x41, 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1e, 0x0a, 0x0a, + 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, + 0x61, 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, + 0x75, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x68, 0x54, 0x79, + 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x75, 0x74, 0x68, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x61, 0x75, + 0x74, 0x68, 0x54, 0x79, 0x70, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, + 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x69, 0x0a, + 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x6f, + 0x64, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x6f, 0x64, + 0x65, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x55, 0x73, 0x65, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x6f, 0x64, 0x65, + 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x46, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, + 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, + 0x22, 0x7f, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1c, 0x0a, + 0x09, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x22, 0x4e, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x4e, 0x6f, 0x64, 0x65, + 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x22, 0x28, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x22, 0x4b, 0x0a, 0x0f, 0x47, + 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, + 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x61, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, + 0x0a, 0x61, 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x75, 0x74, + 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x22, 0x2e, 0x0a, 0x12, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x8a, 0x01, 0x0a, 0x16, + 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x75, 0x74, 0x68, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x22, 0x33, 0x0a, 0x17, 0x41, 0x64, 0x64, 0x50, + 0x65, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x89, 0x01, + 0x0a, 0x19, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x0a, 0x61, + 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x75, 0x74, 0x68, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x22, 0x36, 0x0a, 0x1a, 0x52, 0x65, 0x6a, + 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x22, 0x89, 0x01, 0x0a, 0x19, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x50, 0x65, 0x65, 0x72, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x34, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x41, + 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, + 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x22, 0x36, 0x0a, + 0x1a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x50, 0x65, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x8d, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x50, 0x65, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, + 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x49, 0x64, 0x22, 0x36, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, + 0x65, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2a, 0x35, 0x0a, + 0x0c, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x75, 0x74, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x10, + 0x01, 0x12, 0x07, 0x0a, 0x03, 0x6d, 0x61, 0x63, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x6e, 0x6f, + 0x6e, 0x65, 0x10, 0x03, 0x32, 0xee, 0x04, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x3f, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, + 0x64, 0x65, 0x12, 0x17, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, + 0x73, 0x12, 0x15, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x36, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x15, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x17, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x18, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x6f, 0x64, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x16, 0x4e, 0x65, 0x77, + 0x50, 0x65, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1c, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, + 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x5e, 0x0a, 0x19, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x2e, + 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, + 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x65, 0x65, 0x72, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x5a, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x4e, 0x65, 0x77, 0x50, 0x65, 0x65, + 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, + 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x50, 0x65, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x50, 0x65, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x12, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x65, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x12, 0x1f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x50, 0x65, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x50, 0x65, 0x65, 0x72, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x3b, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_node_proto_rawDescOnce sync.Once + file_node_proto_rawDescData = file_node_proto_rawDesc +) + +func file_node_proto_rawDescGZIP() []byte { + file_node_proto_rawDescOnce.Do(func() { + file_node_proto_rawDescData = protoimpl.X.CompressGZIP(file_node_proto_rawDescData) + }) + return file_node_proto_rawDescData +} + +var file_node_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_node_proto_msgTypes = make([]protoimpl.MessageInfo, 19) +var file_node_proto_goTypes = []interface{}{ + (NodeAuthType)(0), // 0: node.NodeAuthType + (*NodeAuthParams)(nil), // 1: node.NodeAuthParams + (*OperatorAuthParams)(nil), // 2: node.OperatorAuthParams + (*Node)(nil), // 3: node.Node + (*CreateNodeRequest)(nil), // 4: node.CreateNodeRequest + (*CreateNodeResponse)(nil), // 5: node.CreateNodeResponse + (*GetNodesRequest)(nil), // 6: node.GetNodesRequest + (*GetNodesResponse)(nil), // 7: node.GetNodesResponse + (*GetNodeRequest)(nil), // 8: node.GetNodeRequest + (*GetNodeResponse)(nil), // 9: node.GetNodeResponse + (*DeleteNodeRequest)(nil), // 10: node.DeleteNodeRequest + (*DeleteNodeResponse)(nil), // 11: node.DeleteNodeResponse + (*AddPeerOperatorRequest)(nil), // 12: node.AddPeerOperatorRequest + (*AddPeerOperatorResponse)(nil), // 13: node.AddPeerOperatorResponse + (*RejectPeerOperatorRequest)(nil), // 14: node.RejectPeerOperatorRequest + (*RejectPeerOperatorResponse)(nil), // 15: node.RejectPeerOperatorResponse + (*AcceptPeerOperatorRequest)(nil), // 16: node.AcceptPeerOperatorRequest + (*AcceptPeerOperatorResponse)(nil), // 17: node.AcceptPeerOperatorResponse + (*RemovePeerOperatorRequest)(nil), // 18: node.RemovePeerOperatorRequest + (*RemovePeerOperatorResponse)(nil), // 19: node.RemovePeerOperatorResponse +} +var file_node_proto_depIdxs = []int32{ + 0, // 0: node.NodeAuthParams.authType:type_name -> node.NodeAuthType + 0, // 1: node.OperatorAuthParams.authType:type_name -> node.NodeAuthType + 2, // 2: node.GetNodesRequest.authParams:type_name -> node.OperatorAuthParams + 3, // 3: node.GetNodesResponse.nodes:type_name -> node.Node + 3, // 4: node.GetNodeResponse.node:type_name -> node.Node + 1, // 5: node.DeleteNodeRequest.authParams:type_name -> node.NodeAuthParams + 2, // 6: node.AddPeerOperatorRequest.authParams:type_name -> node.OperatorAuthParams + 1, // 7: node.RejectPeerOperatorRequest.authParams:type_name -> node.NodeAuthParams + 1, // 8: node.AcceptPeerOperatorRequest.authParams:type_name -> node.NodeAuthParams + 2, // 9: node.RemovePeerOperatorRequest.authParams:type_name -> node.OperatorAuthParams + 4, // 10: node.NodeService.CreateNode:input_type -> node.CreateNodeRequest + 6, // 11: node.NodeService.GetNodes:input_type -> node.GetNodesRequest + 8, // 12: node.NodeService.GetNode:input_type -> node.GetNodeRequest + 10, // 13: node.NodeService.DeleteNode:input_type -> node.DeleteNodeRequest + 12, // 14: node.NodeService.NewPeerOperatorRequest:input_type -> node.AddPeerOperatorRequest + 14, // 15: node.NodeService.DeletePeerOperatorRequest:input_type -> node.RejectPeerOperatorRequest + 16, // 16: node.NodeService.AcceptNewPeerOperator:input_type -> node.AcceptPeerOperatorRequest + 18, // 17: node.NodeService.RemovePeerOperator:input_type -> node.RemovePeerOperatorRequest + 5, // 18: node.NodeService.CreateNode:output_type -> node.CreateNodeResponse + 7, // 19: node.NodeService.GetNodes:output_type -> node.GetNodesResponse + 9, // 20: node.NodeService.GetNode:output_type -> node.GetNodeResponse + 11, // 21: node.NodeService.DeleteNode:output_type -> node.DeleteNodeResponse + 13, // 22: node.NodeService.NewPeerOperatorRequest:output_type -> node.AddPeerOperatorResponse + 15, // 23: node.NodeService.DeletePeerOperatorRequest:output_type -> node.RejectPeerOperatorResponse + 17, // 24: node.NodeService.AcceptNewPeerOperator:output_type -> node.AcceptPeerOperatorResponse + 19, // 25: node.NodeService.RemovePeerOperator:output_type -> node.RemovePeerOperatorResponse + 18, // [18:26] is the sub-list for method output_type + 10, // [10:18] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name +} + +func init() { file_node_proto_init() } +func file_node_proto_init() { + if File_node_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_node_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NodeAuthParams); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OperatorAuthParams); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Node); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateNodeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateNodeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNodesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNodesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNodeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetNodeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteNodeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteNodeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddPeerOperatorRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddPeerOperatorResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RejectPeerOperatorRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RejectPeerOperatorResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AcceptPeerOperatorRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AcceptPeerOperatorResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemovePeerOperatorRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemovePeerOperatorResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_node_proto_rawDesc, + NumEnums: 1, + NumMessages: 19, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_node_proto_goTypes, + DependencyIndexes: file_node_proto_depIdxs, + EnumInfos: file_node_proto_enumTypes, + MessageInfos: file_node_proto_msgTypes, + }.Build() + File_node_proto = out.File + file_node_proto_rawDesc = nil + file_node_proto_goTypes = nil + file_node_proto_depIdxs = nil +} diff --git a/node_grpc.pb.go b/node_grpc.pb.go new file mode 100644 index 0000000..20dc04d --- /dev/null +++ b/node_grpc.pb.go @@ -0,0 +1,357 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.14.0 +// source: node.proto + +package localserver + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// NodeServiceClient is the client API for NodeService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type NodeServiceClient interface { + CreateNode(ctx context.Context, in *CreateNodeRequest, opts ...grpc.CallOption) (*CreateNodeResponse, error) + GetNodes(ctx context.Context, in *GetNodesRequest, opts ...grpc.CallOption) (*GetNodesResponse, error) + GetNode(ctx context.Context, in *GetNodeRequest, opts ...grpc.CallOption) (*GetNodeResponse, error) + DeleteNode(ctx context.Context, in *DeleteNodeRequest, opts ...grpc.CallOption) (*DeleteNodeResponse, error) + NewPeerOperatorRequest(ctx context.Context, in *AddPeerOperatorRequest, opts ...grpc.CallOption) (*AddPeerOperatorResponse, error) + DeletePeerOperatorRequest(ctx context.Context, in *RejectPeerOperatorRequest, opts ...grpc.CallOption) (*RejectPeerOperatorResponse, error) + AcceptNewPeerOperator(ctx context.Context, in *AcceptPeerOperatorRequest, opts ...grpc.CallOption) (*AcceptPeerOperatorResponse, error) + RemovePeerOperator(ctx context.Context, in *RemovePeerOperatorRequest, opts ...grpc.CallOption) (*RemovePeerOperatorResponse, error) +} + +type nodeServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewNodeServiceClient(cc grpc.ClientConnInterface) NodeServiceClient { + return &nodeServiceClient{cc} +} + +func (c *nodeServiceClient) CreateNode(ctx context.Context, in *CreateNodeRequest, opts ...grpc.CallOption) (*CreateNodeResponse, error) { + out := new(CreateNodeResponse) + err := c.cc.Invoke(ctx, "/node.NodeService/CreateNode", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nodeServiceClient) GetNodes(ctx context.Context, in *GetNodesRequest, opts ...grpc.CallOption) (*GetNodesResponse, error) { + out := new(GetNodesResponse) + err := c.cc.Invoke(ctx, "/node.NodeService/GetNodes", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nodeServiceClient) GetNode(ctx context.Context, in *GetNodeRequest, opts ...grpc.CallOption) (*GetNodeResponse, error) { + out := new(GetNodeResponse) + err := c.cc.Invoke(ctx, "/node.NodeService/GetNode", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nodeServiceClient) DeleteNode(ctx context.Context, in *DeleteNodeRequest, opts ...grpc.CallOption) (*DeleteNodeResponse, error) { + out := new(DeleteNodeResponse) + err := c.cc.Invoke(ctx, "/node.NodeService/DeleteNode", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nodeServiceClient) NewPeerOperatorRequest(ctx context.Context, in *AddPeerOperatorRequest, opts ...grpc.CallOption) (*AddPeerOperatorResponse, error) { + out := new(AddPeerOperatorResponse) + err := c.cc.Invoke(ctx, "/node.NodeService/NewPeerOperatorRequest", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nodeServiceClient) DeletePeerOperatorRequest(ctx context.Context, in *RejectPeerOperatorRequest, opts ...grpc.CallOption) (*RejectPeerOperatorResponse, error) { + out := new(RejectPeerOperatorResponse) + err := c.cc.Invoke(ctx, "/node.NodeService/DeletePeerOperatorRequest", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nodeServiceClient) AcceptNewPeerOperator(ctx context.Context, in *AcceptPeerOperatorRequest, opts ...grpc.CallOption) (*AcceptPeerOperatorResponse, error) { + out := new(AcceptPeerOperatorResponse) + err := c.cc.Invoke(ctx, "/node.NodeService/AcceptNewPeerOperator", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *nodeServiceClient) RemovePeerOperator(ctx context.Context, in *RemovePeerOperatorRequest, opts ...grpc.CallOption) (*RemovePeerOperatorResponse, error) { + out := new(RemovePeerOperatorResponse) + err := c.cc.Invoke(ctx, "/node.NodeService/RemovePeerOperator", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// NodeServiceServer is the server API for NodeService service. +// All implementations must embed UnimplementedNodeServiceServer +// for forward compatibility +type NodeServiceServer interface { + CreateNode(context.Context, *CreateNodeRequest) (*CreateNodeResponse, error) + GetNodes(context.Context, *GetNodesRequest) (*GetNodesResponse, error) + GetNode(context.Context, *GetNodeRequest) (*GetNodeResponse, error) + DeleteNode(context.Context, *DeleteNodeRequest) (*DeleteNodeResponse, error) + NewPeerOperatorRequest(context.Context, *AddPeerOperatorRequest) (*AddPeerOperatorResponse, error) + DeletePeerOperatorRequest(context.Context, *RejectPeerOperatorRequest) (*RejectPeerOperatorResponse, error) + AcceptNewPeerOperator(context.Context, *AcceptPeerOperatorRequest) (*AcceptPeerOperatorResponse, error) + RemovePeerOperator(context.Context, *RemovePeerOperatorRequest) (*RemovePeerOperatorResponse, error) + mustEmbedUnimplementedNodeServiceServer() +} + +// UnimplementedNodeServiceServer must be embedded to have forward compatible implementations. +type UnimplementedNodeServiceServer struct { +} + +func (UnimplementedNodeServiceServer) CreateNode(context.Context, *CreateNodeRequest) (*CreateNodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateNode not implemented") +} +func (UnimplementedNodeServiceServer) GetNodes(context.Context, *GetNodesRequest) (*GetNodesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetNodes not implemented") +} +func (UnimplementedNodeServiceServer) GetNode(context.Context, *GetNodeRequest) (*GetNodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetNode not implemented") +} +func (UnimplementedNodeServiceServer) DeleteNode(context.Context, *DeleteNodeRequest) (*DeleteNodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteNode not implemented") +} +func (UnimplementedNodeServiceServer) NewPeerOperatorRequest(context.Context, *AddPeerOperatorRequest) (*AddPeerOperatorResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method NewPeerOperatorRequest not implemented") +} +func (UnimplementedNodeServiceServer) DeletePeerOperatorRequest(context.Context, *RejectPeerOperatorRequest) (*RejectPeerOperatorResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeletePeerOperatorRequest not implemented") +} +func (UnimplementedNodeServiceServer) AcceptNewPeerOperator(context.Context, *AcceptPeerOperatorRequest) (*AcceptPeerOperatorResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AcceptNewPeerOperator not implemented") +} +func (UnimplementedNodeServiceServer) RemovePeerOperator(context.Context, *RemovePeerOperatorRequest) (*RemovePeerOperatorResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemovePeerOperator not implemented") +} +func (UnimplementedNodeServiceServer) mustEmbedUnimplementedNodeServiceServer() {} + +// UnsafeNodeServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to NodeServiceServer will +// result in compilation errors. +type UnsafeNodeServiceServer interface { + mustEmbedUnimplementedNodeServiceServer() +} + +func RegisterNodeServiceServer(s grpc.ServiceRegistrar, srv NodeServiceServer) { + s.RegisterService(&NodeService_ServiceDesc, srv) +} + +func _NodeService_CreateNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateNodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).CreateNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/node.NodeService/CreateNode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).CreateNode(ctx, req.(*CreateNodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NodeService_GetNodes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetNodesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).GetNodes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/node.NodeService/GetNodes", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).GetNodes(ctx, req.(*GetNodesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NodeService_GetNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetNodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).GetNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/node.NodeService/GetNode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).GetNode(ctx, req.(*GetNodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NodeService_DeleteNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteNodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).DeleteNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/node.NodeService/DeleteNode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).DeleteNode(ctx, req.(*DeleteNodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NodeService_NewPeerOperatorRequest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddPeerOperatorRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).NewPeerOperatorRequest(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/node.NodeService/NewPeerOperatorRequest", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).NewPeerOperatorRequest(ctx, req.(*AddPeerOperatorRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NodeService_DeletePeerOperatorRequest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RejectPeerOperatorRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).DeletePeerOperatorRequest(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/node.NodeService/DeletePeerOperatorRequest", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).DeletePeerOperatorRequest(ctx, req.(*RejectPeerOperatorRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NodeService_AcceptNewPeerOperator_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AcceptPeerOperatorRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).AcceptNewPeerOperator(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/node.NodeService/AcceptNewPeerOperator", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).AcceptNewPeerOperator(ctx, req.(*AcceptPeerOperatorRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _NodeService_RemovePeerOperator_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemovePeerOperatorRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodeServiceServer).RemovePeerOperator(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/node.NodeService/RemovePeerOperator", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodeServiceServer).RemovePeerOperator(ctx, req.(*RemovePeerOperatorRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// NodeService_ServiceDesc is the grpc.ServiceDesc for NodeService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var NodeService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "node.NodeService", + HandlerType: (*NodeServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateNode", + Handler: _NodeService_CreateNode_Handler, + }, + { + MethodName: "GetNodes", + Handler: _NodeService_GetNodes_Handler, + }, + { + MethodName: "GetNode", + Handler: _NodeService_GetNode_Handler, + }, + { + MethodName: "DeleteNode", + Handler: _NodeService_DeleteNode_Handler, + }, + { + MethodName: "NewPeerOperatorRequest", + Handler: _NodeService_NewPeerOperatorRequest_Handler, + }, + { + MethodName: "DeletePeerOperatorRequest", + Handler: _NodeService_DeletePeerOperatorRequest_Handler, + }, + { + MethodName: "AcceptNewPeerOperator", + Handler: _NodeService_AcceptNewPeerOperator_Handler, + }, + { + MethodName: "RemovePeerOperator", + Handler: _NodeService_RemovePeerOperator_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "node.proto", +} diff --git a/proto/node.proto b/proto/node.proto new file mode 100644 index 0000000..55fa834 --- /dev/null +++ b/proto/node.proto @@ -0,0 +1,120 @@ +syntax = "proto3"; +package node; +option go_package = ".;localserver"; + +enum NodeAuthType { + token = 0; + key = 1; + mac = 2; + none = 3; +} + +message NodeAuthParams { + string nodeId = 1; + string authKey = 2; + NodeAuthType authType = 3; +} + +message OperatorAuthParams { + string operatorId = 1; + string authKey = 2; + NodeAuthType authType = 3; +} + +message Node { + string id = 1; + string name = 2; + string pubKey = 3; + bool active = 4; + repeated string operators = 5; + repeated string operatorRequests = 6; +} + +message CreateNodeRequest { + string nodeId = 1; + string nodeKey = 2; + string nodeUsername = 3; +} + +message CreateNodeResponse { + bool success = 1; + string nodeId = 2; +} + +message GetNodesRequest { + OperatorAuthParams authParams = 1; + int64 lastIndex = 2; + int64 limit = 3; +} +message GetNodesResponse { + repeated Node nodes = 1; + bool success = 2; +} + +message GetNodeRequest { + string nodeId = 1; +} + +message GetNodeResponse { + Node node = 1; + bool success = 2; +} + +message DeleteNodeRequest { + NodeAuthParams authParams = 1; + string nodeId = 2; +} +message DeleteNodeResponse { + bool success = 1; +} + +message AddPeerOperatorRequest { + OperatorAuthParams authParams = 1; + string nodeId = 2; + string operatorId = 3; +} + +message AddPeerOperatorResponse { + bool success = 1; +} + +message RejectPeerOperatorRequest { + NodeAuthParams authParams = 1; + string nodeId = 2; + string operatorId = 3; +} + +message RejectPeerOperatorResponse { + bool success = 1; +} + +message AcceptPeerOperatorRequest { + NodeAuthParams authParams = 1; + string nodeId = 2; + string operatorId = 3; +} + +message AcceptPeerOperatorResponse { + bool success = 1; +} + +message RemovePeerOperatorRequest { + OperatorAuthParams authParams = 1; + string nodeId = 2; + string operatorId = 3; +} + +message RemovePeerOperatorResponse { + bool success = 1; +} + +service NodeService { + rpc CreateNode (CreateNodeRequest) returns (CreateNodeResponse); + rpc GetNodes (GetNodesRequest) returns (GetNodesResponse); + rpc GetNode (GetNodeRequest) returns (GetNodeResponse); + rpc DeleteNode (DeleteNodeRequest) returns (DeleteNodeResponse); + rpc NewPeerOperatorRequest (AddPeerOperatorRequest) returns (AddPeerOperatorResponse); + rpc DeletePeerOperatorRequest (RejectPeerOperatorRequest) returns (RejectPeerOperatorResponse); + rpc AcceptNewPeerOperator (AcceptPeerOperatorRequest) returns (AcceptPeerOperatorResponse); + rpc RemovePeerOperator (RemovePeerOperatorRequest) returns (RemovePeerOperatorResponse); +} \ No newline at end of file diff --git a/proto/signaling.proto b/proto/signaling.proto new file mode 100644 index 0000000..08d141d --- /dev/null +++ b/proto/signaling.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; +package signaling; +option go_package = ".;localserver"; + +message NotifyRequest { + string from = 1; + string to = 2; + string type = 3; + bytes payload = 4; +} + +message NotifyResponse { + bool success = 1; +} + +message SignalingMessage { + string type = 1; + string from = 2; + string to = 3; + bytes payload = 4; +} + +service SignalingService { + rpc Notify (NotifyRequest) returns (NotifyResponse); + rpc Link (stream SignalingMessage) returns (stream SignalingMessage); +} \ No newline at end of file diff --git a/server.go b/server.go index fe1781d..5e06ea8 100644 --- a/server.go +++ b/server.go @@ -2,6 +2,8 @@ package localserver import ( "context" + "encoding/json" + "fmt" "log" "net/http" "path/filepath" @@ -41,8 +43,8 @@ type ( Process(ctx context.Context, req *http.Request, w http.ResponseWriter) (err error) } - GrpcClientManagerMiddleware interface { - Process(ctx context.Context, req *Response, stream GrpcManager_LinkClient) (err error) + SignalingClientManagerMiddleware interface { + Process(ctx context.Context, req *SignalingMessage, stream SignalingService_LinkClient) (err error) } LocalServerHandler struct { @@ -51,14 +53,14 @@ type ( LocalServer struct { ID string - GrpcClientManager *GrpcClientManager + GrpcClientManager *SignalingClientManager } - GrpcClientManager struct { - GrpcConn grpc.ClientConnInterface - GrpcManagerClient GrpcManagerClient - GrpcLinkClient GrpcManager_LinkClient - middlewares []GrpcClientManagerMiddleware + SignalingClientManager struct { + GrpcConn grpc.ClientConnInterface + SignalingManagerClient SignalingServiceClient + GrpcLinkClient SignalingService_LinkClient + middlewares []SignalingClientManagerMiddleware } CustomMenuItem struct { @@ -77,72 +79,89 @@ type ( } ) -func NewLocalServer(addr string, grpcAddr string, id string, token string) (localServer *LocalServer, err error) { +func NewLocalServer(_ string, grpcAddr string, id string, token string) (localServer *LocalServer, err error) { webRTCCallManager, err := NewWebRTCCallManager(id, token, NewWebrtcCallSoundManager(), NewWebrtcCallChatManager(), NewWebrtcCallVideoManager(), NewWebrtcCallFileManager()) if err != nil { + err = fmt.Errorf("error from call manager") return } zoneManager, err := NewZoneManager(id, token) if err != nil { + err = fmt.Errorf("error from zone manager") return } webrtcFsManager, err := NewWebrtcFsManager(NewP2PFSDatachannelManager()) if err != nil { + err = fmt.Errorf("error from fs manager") return } webrtcGrpcMiddleware := NewWebRTCGrpcMiddleware(webRTCCallManager) ZoneGrpcMiddleware := NewZoneGrpcMiddleware(zoneManager) webrtcFsMiddleware := NewWebRTCFsMiddleware(webrtcFsManager) - grpcClientManager, err := NewGrpcClientManager(grpcAddr, id, webrtcGrpcMiddleware, ZoneGrpcMiddleware) - webrtcGrpcMiddleware.stream = grpcClientManager.GrpcLinkClient - webRTCCallManager.stream = grpcClientManager.GrpcLinkClient - zoneManager.stream = grpcClientManager.GrpcLinkClient - webrtcFsMiddleware.stream = grpcClientManager.GrpcLinkClient - webrtcFsManager.stream = grpcClientManager.GrpcLinkClient - ZoneGrpcMiddleware.stream = grpcClientManager.GrpcLinkClient - localServer = &LocalServer{ - ID: id, - GrpcClientManager: grpcClientManager, - } - return -} - -func NewGrpcClientManager(addr string, id string, middleware ...GrpcClientManagerMiddleware) (grpcClientManager *GrpcClientManager, err error) { - conn, grpcClient, grpcLinkClient, err := NewGrpcConn(addr, id) + signalingClientManager, err := NewGrpcClientManager(grpcAddr, id, webrtcGrpcMiddleware, ZoneGrpcMiddleware) if err != nil { return } - grpcClientManager = &GrpcClientManager{ - GrpcConn: conn, - GrpcManagerClient: grpcClient, - GrpcLinkClient: grpcLinkClient, - middlewares: middleware, + webrtcGrpcMiddleware.stream = signalingClientManager.GrpcLinkClient + webRTCCallManager.stream = signalingClientManager.GrpcLinkClient + zoneManager.stream = signalingClientManager.GrpcLinkClient + webrtcFsMiddleware.stream = signalingClientManager.GrpcLinkClient + webrtcFsManager.stream = signalingClientManager.GrpcLinkClient + ZoneGrpcMiddleware.stream = signalingClientManager.GrpcLinkClient + localServer = &LocalServer{ + ID: id, + GrpcClientManager: signalingClientManager, } return } -func NewGrpcConn(addr string, id string) (conn grpc.ClientConnInterface, grpcClient GrpcManagerClient, grpcLinkClient GrpcManager_LinkClient, err error) { - var cert = filepath.Join("config", "cert.pem") +func NewGrpcClientManager(addr string, id string, middleware ...SignalingClientManagerMiddleware) (signalingClientManager *SignalingClientManager, err error) { + conn, signalingClient, signalingLinkClient, err := NewGrpcConn(addr, id) + if err != nil { + return + } + signalingClientManager = &SignalingClientManager{ + GrpcConn: conn, + SignalingManagerClient: signalingClient, + GrpcLinkClient: signalingLinkClient, + middlewares: middleware, + } + return +} + +func NewGrpcConn(addr string, id string) (conn grpc.ClientConnInterface, signalingClient SignalingServiceClient, signalingLinkClient SignalingService_LinkClient, err error) { + var cert = filepath.Join("config", "fullchain.pem") creds, err := credentials.NewClientTLSFromFile(cert, "dev.zippytal.com") if err != nil { + fmt.Println("there") return } var opts []grpc.DialOption = []grpc.DialOption{grpc.WithTransportCredentials(creds)} conn, err = grpc.Dial(addr, opts...) if err != nil { + fmt.Println("over there") return } - grpcClient = NewGrpcManagerClient(conn) - grpcLinkClient, err = grpcClient.Link(context.Background()) + signalingClient = NewSignalingServiceClient(conn) + signalingLinkClient, err = signalingClient.Link(context.Background()) + if err != nil { + fmt.Println("really there") + logger.Println(err) + return + } + payload := map[string]any{ + "init": "init", + } + bs, err := json.Marshal(payload) if err != nil { logger.Println(err) return } - if err = grpcLinkClient.Send(&Request{ + if err = signalingLinkClient.Send(&SignalingMessage{ Type: "init", From: id, - Payload: map[string]string{}, - Token: "none", + To: "server", + Payload: bs, }); err != nil { return } @@ -180,7 +199,7 @@ func (lsh *LocalServerHandler) ServeHTTP(w http.ResponseWriter, req *http.Reques } } -func (gcm *GrpcClientManager) Handle(ctx context.Context) (err error) { +func (gcm *SignalingClientManager) Handle(ctx context.Context) (err error) { done, errCh := make(chan struct{}), make(chan error) go func() { wg := new(sync.WaitGroup) @@ -192,11 +211,11 @@ func (gcm *GrpcClientManager) Handle(ctx context.Context) (err error) { } for _, middleware := range gcm.middlewares { wg.Add(1) - go func(m GrpcClientManagerMiddleware) { + go func(m SignalingClientManagerMiddleware) { + defer wg.Done() if err := m.Process(ctx, res, gcm.GrpcLinkClient); err != nil { logger.Println(err) } - wg.Done() }(middleware) } wg.Wait() @@ -212,8 +231,10 @@ func (gcm *GrpcClientManager) Handle(ctx context.Context) (err error) { err = ctx.Err() return case <-done: + logger.Println("done") return case err = <-errCh: + logger.Println("done with error") if closeErr := gcm.GrpcLinkClient.CloseSend(); closeErr != nil { return closeErr } diff --git a/signaling.pb.go b/signaling.pb.go new file mode 100644 index 0000000..e659f6c --- /dev/null +++ b/signaling.pb.go @@ -0,0 +1,337 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.0 +// protoc v3.14.0 +// source: signaling.proto + +package localserver + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type NotifyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + From string `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` + To string `protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"` + Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` + Payload []byte `protobuf:"bytes,4,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (x *NotifyRequest) Reset() { + *x = NotifyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_signaling_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NotifyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotifyRequest) ProtoMessage() {} + +func (x *NotifyRequest) ProtoReflect() protoreflect.Message { + mi := &file_signaling_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NotifyRequest.ProtoReflect.Descriptor instead. +func (*NotifyRequest) Descriptor() ([]byte, []int) { + return file_signaling_proto_rawDescGZIP(), []int{0} +} + +func (x *NotifyRequest) GetFrom() string { + if x != nil { + return x.From + } + return "" +} + +func (x *NotifyRequest) GetTo() string { + if x != nil { + return x.To + } + return "" +} + +func (x *NotifyRequest) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *NotifyRequest) GetPayload() []byte { + if x != nil { + return x.Payload + } + return nil +} + +type NotifyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` +} + +func (x *NotifyResponse) Reset() { + *x = NotifyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_signaling_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NotifyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotifyResponse) ProtoMessage() {} + +func (x *NotifyResponse) ProtoReflect() protoreflect.Message { + mi := &file_signaling_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NotifyResponse.ProtoReflect.Descriptor instead. +func (*NotifyResponse) Descriptor() ([]byte, []int) { + return file_signaling_proto_rawDescGZIP(), []int{1} +} + +func (x *NotifyResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +type SignalingMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` + To string `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"` + Payload []byte `protobuf:"bytes,4,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (x *SignalingMessage) Reset() { + *x = SignalingMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_signaling_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignalingMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignalingMessage) ProtoMessage() {} + +func (x *SignalingMessage) ProtoReflect() protoreflect.Message { + mi := &file_signaling_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignalingMessage.ProtoReflect.Descriptor instead. +func (*SignalingMessage) Descriptor() ([]byte, []int) { + return file_signaling_proto_rawDescGZIP(), []int{2} +} + +func (x *SignalingMessage) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *SignalingMessage) GetFrom() string { + if x != nil { + return x.From + } + return "" +} + +func (x *SignalingMessage) GetTo() string { + if x != nil { + return x.To + } + return "" +} + +func (x *SignalingMessage) GetPayload() []byte { + if x != nil { + return x.Payload + } + return nil +} + +var File_signaling_proto protoreflect.FileDescriptor + +var file_signaling_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x22, 0x61, 0x0a, 0x0d, + 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, + 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, + 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, + 0x2a, 0x0a, 0x0e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x64, 0x0a, 0x10, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, + 0x64, 0x32, 0x97, 0x01, 0x0a, 0x10, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, + 0x12, 0x18, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x2e, 0x4e, 0x6f, 0x74, + 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x1b, 0x2e, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, + 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1b, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x69, 0x6e, 0x67, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, + 0x3b, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_signaling_proto_rawDescOnce sync.Once + file_signaling_proto_rawDescData = file_signaling_proto_rawDesc +) + +func file_signaling_proto_rawDescGZIP() []byte { + file_signaling_proto_rawDescOnce.Do(func() { + file_signaling_proto_rawDescData = protoimpl.X.CompressGZIP(file_signaling_proto_rawDescData) + }) + return file_signaling_proto_rawDescData +} + +var file_signaling_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_signaling_proto_goTypes = []interface{}{ + (*NotifyRequest)(nil), // 0: signaling.NotifyRequest + (*NotifyResponse)(nil), // 1: signaling.NotifyResponse + (*SignalingMessage)(nil), // 2: signaling.SignalingMessage +} +var file_signaling_proto_depIdxs = []int32{ + 0, // 0: signaling.SignalingService.Notify:input_type -> signaling.NotifyRequest + 2, // 1: signaling.SignalingService.Link:input_type -> signaling.SignalingMessage + 1, // 2: signaling.SignalingService.Notify:output_type -> signaling.NotifyResponse + 2, // 3: signaling.SignalingService.Link:output_type -> signaling.SignalingMessage + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_signaling_proto_init() } +func file_signaling_proto_init() { + if File_signaling_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_signaling_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NotifyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_signaling_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NotifyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_signaling_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignalingMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_signaling_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_signaling_proto_goTypes, + DependencyIndexes: file_signaling_proto_depIdxs, + MessageInfos: file_signaling_proto_msgTypes, + }.Build() + File_signaling_proto = out.File + file_signaling_proto_rawDesc = nil + file_signaling_proto_goTypes = nil + file_signaling_proto_depIdxs = nil +} diff --git a/signaling_grpc.pb.go b/signaling_grpc.pb.go new file mode 100644 index 0000000..fedf0f6 --- /dev/null +++ b/signaling_grpc.pb.go @@ -0,0 +1,174 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.14.0 +// source: signaling.proto + +package localserver + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// SignalingServiceClient is the client API for SignalingService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type SignalingServiceClient interface { + Notify(ctx context.Context, in *NotifyRequest, opts ...grpc.CallOption) (*NotifyResponse, error) + Link(ctx context.Context, opts ...grpc.CallOption) (SignalingService_LinkClient, error) +} + +type signalingServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewSignalingServiceClient(cc grpc.ClientConnInterface) SignalingServiceClient { + return &signalingServiceClient{cc} +} + +func (c *signalingServiceClient) Notify(ctx context.Context, in *NotifyRequest, opts ...grpc.CallOption) (*NotifyResponse, error) { + out := new(NotifyResponse) + err := c.cc.Invoke(ctx, "/signaling.SignalingService/Notify", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *signalingServiceClient) Link(ctx context.Context, opts ...grpc.CallOption) (SignalingService_LinkClient, error) { + stream, err := c.cc.NewStream(ctx, &SignalingService_ServiceDesc.Streams[0], "/signaling.SignalingService/Link", opts...) + if err != nil { + return nil, err + } + x := &signalingServiceLinkClient{stream} + return x, nil +} + +type SignalingService_LinkClient interface { + Send(*SignalingMessage) error + Recv() (*SignalingMessage, error) + grpc.ClientStream +} + +type signalingServiceLinkClient struct { + grpc.ClientStream +} + +func (x *signalingServiceLinkClient) Send(m *SignalingMessage) error { + return x.ClientStream.SendMsg(m) +} + +func (x *signalingServiceLinkClient) Recv() (*SignalingMessage, error) { + m := new(SignalingMessage) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// SignalingServiceServer is the server API for SignalingService service. +// All implementations must embed UnimplementedSignalingServiceServer +// for forward compatibility +type SignalingServiceServer interface { + Notify(context.Context, *NotifyRequest) (*NotifyResponse, error) + Link(SignalingService_LinkServer) error + mustEmbedUnimplementedSignalingServiceServer() +} + +// UnimplementedSignalingServiceServer must be embedded to have forward compatible implementations. +type UnimplementedSignalingServiceServer struct { +} + +func (UnimplementedSignalingServiceServer) Notify(context.Context, *NotifyRequest) (*NotifyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Notify not implemented") +} +func (UnimplementedSignalingServiceServer) Link(SignalingService_LinkServer) error { + return status.Errorf(codes.Unimplemented, "method Link not implemented") +} +func (UnimplementedSignalingServiceServer) mustEmbedUnimplementedSignalingServiceServer() {} + +// UnsafeSignalingServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to SignalingServiceServer will +// result in compilation errors. +type UnsafeSignalingServiceServer interface { + mustEmbedUnimplementedSignalingServiceServer() +} + +func RegisterSignalingServiceServer(s grpc.ServiceRegistrar, srv SignalingServiceServer) { + s.RegisterService(&SignalingService_ServiceDesc, srv) +} + +func _SignalingService_Notify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(NotifyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SignalingServiceServer).Notify(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/signaling.SignalingService/Notify", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SignalingServiceServer).Notify(ctx, req.(*NotifyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SignalingService_Link_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(SignalingServiceServer).Link(&signalingServiceLinkServer{stream}) +} + +type SignalingService_LinkServer interface { + Send(*SignalingMessage) error + Recv() (*SignalingMessage, error) + grpc.ServerStream +} + +type signalingServiceLinkServer struct { + grpc.ServerStream +} + +func (x *signalingServiceLinkServer) Send(m *SignalingMessage) error { + return x.ServerStream.SendMsg(m) +} + +func (x *signalingServiceLinkServer) Recv() (*SignalingMessage, error) { + m := new(SignalingMessage) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// SignalingService_ServiceDesc is the grpc.ServiceDesc for SignalingService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var SignalingService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "signaling.SignalingService", + HandlerType: (*SignalingServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Notify", + Handler: _SignalingService_Notify_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "Link", + Handler: _SignalingService_Link_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "signaling.proto", +} diff --git a/webrtcCallManager.go b/webrtcCallManager.go index cfdd76b..e43b8e1 100644 --- a/webrtcCallManager.go +++ b/webrtcCallManager.go @@ -36,7 +36,7 @@ type Squad struct { } type WebRTCCallManager struct { - stream GrpcManager_LinkClient + stream SignalingService_LinkClient middlewares []WebrtcCallEventManager ID string LocalSD map[string]*webrtc.SessionDescription @@ -65,6 +65,7 @@ type IncomingCandidate struct { type RTCPeerConnection struct { *webrtc.PeerConnection + id string makingOffer bool negotiate func(string, string) makingOfferLock *sync.Mutex @@ -131,10 +132,13 @@ func NewWebRTCCallManager(id string, token string, eventHandlers ...WebrtcCallEv } func loadHostedSquads(token string, hostId string) (squads []*Squad, err error) { + em := NewEncryptionManager() + sig := em.SignRequestHMAC(hostId) body, err := json.Marshal(map[string]interface{}{ - "type": LIST_HOSTED_SQUADS_BY_HOST, - "token": token, - "from": hostId, + "type": LIST_HOSTED_SQUADS_BY_HOST, + "mac": sig, + "from": hostId, + "peerType":"node", "payload": map[string]string{ "host": hostId, "lastIndex": "0", @@ -143,7 +147,6 @@ func loadHostedSquads(token string, hostId string) (squads []*Squad, err error) if err != nil { return } - res, err := http.Post("https://app.zippytal.com/req", "application/json", bytes.NewBuffer(body)) if err != nil { logger.Println("error come from there in webrtc call manager") @@ -153,7 +156,29 @@ func loadHostedSquads(token string, hostId string) (squads []*Squad, err error) if err != nil { return } - err = json.Unmarshal(bs, &squads) + var payload map[string]any + if err = json.Unmarshal(bs, &payload); err != nil { + return + } + b, err := json.Marshal(payload["squads"]) + if err != nil { + return + } + err = json.Unmarshal(b, &squads) + return +} + +func (wm *WebRTCCallManager) sendSignalingMessage(messageType, from, to string, payload map[string]interface{}) (err error) { + bs, err := json.Marshal(payload) + if err != nil { + return + } + err = wm.stream.Send(&SignalingMessage{ + Type: messageType, + From: from, + To: to, + Payload: bs, + }) return } @@ -179,20 +204,15 @@ func (wm *WebRTCCallManager) CreateOffer(ctx context.Context, target string, fro negotiate: wm.negotiate, } wm.RTCPeerConnectionMapMux.Unlock() - err = wm.stream.Send(&Request{ - Type: string(HOSTED_SQUAD_WEBRTC_OFFER), - From: wm.ID, - Token: "none", - Payload: map[string]string{ - "to": target, - "from": wm.ID, - "sdp": rawOffer.SDP, - }, + err = wm.sendSignalingMessage(string(HOSTED_SQUAD_WEBRTC_OFFER), wm.ID, target, map[string]interface{}{ + "to": target, + "from": wm.ID, + "sdp": rawOffer.SDP, }) return } -func (wm *WebRTCCallManager) HandleOffer(ctx context.Context, req map[string]string, cb OnICECandidateFunc) (err error) { +func (wm *WebRTCCallManager) HandleOffer(ctx context.Context, from, to string, req map[string]string, cb OnICECandidateFunc) (err error) { done, errCh := make(chan struct{}), make(chan error) go func() { if _, ok := wm.Squads[req[SQUAD_ID]]; !ok { @@ -200,13 +220,13 @@ func (wm *WebRTCCallManager) HandleOffer(ctx context.Context, req map[string]str errCh <- err return } - peerConnection, err := wm.createPeerConnection(req[FROM], req[TO], req[SQUAD_ID], webrtc.SDPTypeAnswer, cb) + peerConnection, err := wm.createPeerConnection(from, to, req[SQUAD_ID], webrtc.SDPTypeAnswer, cb) if err != nil { errCh <- err return } wm.RTCPeerConnectionMapMux.Lock() - wm.RTCPeerConnections[req[FROM]] = &RTCPeerConnection{ + wm.RTCPeerConnections[from] = &RTCPeerConnection{ PeerConnection: peerConnection, makingOffer: false, makingOfferLock: &sync.Mutex{}, @@ -227,20 +247,19 @@ func (wm *WebRTCCallManager) HandleOffer(ctx context.Context, req map[string]str return } wm.LocalSDMapMux.Lock() - wm.LocalSD[req[FROM]] = &rawAnswer + wm.LocalSD[from] = &rawAnswer wm.LocalSDMapMux.Unlock() + if err = peerConnection.SetLocalDescription(rawAnswer); err != nil { + errCh <- err + return + } wm.SquadMapMux.Lock() - wm.Squads[req[SQUAD_ID]].Members = append(wm.Squads[req[SQUAD_ID]].Members, req[FROM]) + wm.Squads[req[SQUAD_ID]].Members = append(wm.Squads[req[SQUAD_ID]].Members, from) wm.SquadMapMux.Unlock() - if err = wm.stream.Send(&Request{ - Type: string(HOSTED_SQUAD_WEBRTC_ANSWER), - From: wm.ID, - Token: "none", - Payload: map[string]string{ - "to": req[FROM], - "from": wm.ID, - "sdp": rawAnswer.SDP, - }, + if err = wm.sendSignalingMessage(string(HOSTED_SQUAD_WEBRTC_ANSWER), wm.ID, from, map[string]interface{}{ + "to": from, + "from": wm.ID, + "sdp": rawAnswer.SDP, }); err != nil { errCh <- err return @@ -258,7 +277,7 @@ func (wm *WebRTCCallManager) HandleOffer(ctx context.Context, req map[string]str } } -func (wm *WebRTCCallManager) HandleAnswer(ctx context.Context, req map[string]string) (err error) { +func (wm *WebRTCCallManager) HandleAnswer(ctx context.Context, from, to string, req map[string]string) (err error) { wm.RTCPeerConnectionMapMux.Lock() defer wm.RTCPeerConnectionMapMux.Unlock() defer func() { @@ -266,11 +285,11 @@ func (wm *WebRTCCallManager) HandleAnswer(ctx context.Context, req map[string]st logger.Printf("recover from panic in handle answer : %v\n", r) } }() - if _, ok := wm.RTCPeerConnections[req[FROM]]; !ok { - err = fmt.Errorf("no corresponding peer connection for id : %s", req[FROM]) + if _, ok := wm.RTCPeerConnections[from]; !ok { + err = fmt.Errorf("no corresponding peer connection for id : %s", from) return } - peerConnnection := wm.RTCPeerConnections[req[FROM]] + peerConnnection := wm.RTCPeerConnections[from] logger.Println("---------------------") logger.Println(req[SDP]) logger.Println("---------------------") @@ -281,31 +300,21 @@ func (wm *WebRTCCallManager) HandleAnswer(ctx context.Context, req map[string]st logger.Println("error occured while setting remote description in handle answer") return } - if err = wm.stream.Send(&Request{ - Type: string(HOSTED_SQUAD_WEBRTC_COUNTER_OFFER), - From: wm.ID, - Token: "none", - Payload: map[string]string{ - "from": wm.ID, - "to": req[FROM], - }, + if err = wm.sendSignalingMessage(string(HOSTED_SQUAD_WEBRTC_COUNTER_OFFER), wm.ID, from, map[string]interface{}{ + "from": wm.ID, + "to": from, }); err != nil { return } wm.CandidateMux.Lock() - for _, candidate := range wm.PendingCandidates[req[FROM]] { - logger.Println("sending candidate from answer to", req[FROM]) - if err = wm.stream.Send(&Request{ - Type: string(HOSTED_SQUAD_WEBRTC_CANDIDATE), - From: wm.ID, - Token: "none", - Payload: map[string]string{ - "from": wm.ID, - "to": req[FROM], - "candidate": candidate.ToJSON().Candidate, - "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), - }, + for _, candidate := range wm.PendingCandidates[from] { + logger.Println("sending candidate from answer to", from) + if err = wm.sendSignalingMessage(string(HOSTED_SQUAD_WEBRTC_CANDIDATE), wm.ID, from, map[string]interface{}{ + "from": wm.ID, + "to": from, + "candidate": candidate.ToJSON().Candidate, + "sdpMid": *candidate.ToJSON().SDPMid, + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), }); err != nil { wm.CandidateMux.Unlock() return @@ -313,53 +322,48 @@ func (wm *WebRTCCallManager) HandleAnswer(ctx context.Context, req map[string]st } wm.CandidateMux.Unlock() wm.CandidateMux.Lock() - delete(wm.PendingCandidates, req[FROM]) + delete(wm.PendingCandidates, from) wm.CandidateMux.Unlock() wm.LocalSDMapMux.Lock() - delete(wm.LocalSD, req[FROM]) + delete(wm.LocalSD, from) wm.LocalSDMapMux.Unlock() return } -func (wm *WebRTCCallManager) HandleCounterOffer(ctx context.Context, req map[string]string) (err error) { +func (wm *WebRTCCallManager) HandleCounterOffer(ctx context.Context, from, to string, req map[string]string) (err error) { wm.RTCPeerConnectionMapMux.Lock() - if _, ok := wm.RTCPeerConnections[req[FROM]]; !ok { - err = fmt.Errorf("no field corresponding peer connection for id %s", req[FROM]) + if _, ok := wm.RTCPeerConnections[from]; !ok { + err = fmt.Errorf("no field corresponding peer connection for id %s", from) wm.RTCPeerConnectionMapMux.Unlock() return } logger.Println("handling counter offer") - connection := wm.RTCPeerConnections[req[FROM]] + //connection := wm.RTCPeerConnections[from] wm.RTCPeerConnectionMapMux.Unlock() - wm.LocalSDMapMux.Lock() - if err = connection.SetLocalDescription(*wm.LocalSD[req[FROM]]); err != nil { - wm.LocalSDMapMux.Unlock() - return - } - wm.LocalSDMapMux.Unlock() + // wm.LocalSDMapMux.Lock() + // if err = connection.SetLocalDescription(*wm.LocalSD[from]); err != nil { + // wm.LocalSDMapMux.Unlock() + // return + // } + // wm.LocalSDMapMux.Unlock() wm.CandidateMux.Lock() - for _, candidate := range wm.PendingCandidates[req[FROM]] { - logger.Println("sending candidate to", req[FROM]) - if err = wm.stream.Send(&Request{ - Type: string(HOSTED_SQUAD_WEBRTC_CANDIDATE), - From: wm.ID, - Token: "none", - Payload: map[string]string{ - "from": wm.ID, - "to": req[FROM], - "candidate": candidate.ToJSON().Candidate, - "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), - }, + for _, candidate := range wm.PendingCandidates[from] { + logger.Println("sending candidate to", from) + if err = wm.sendSignalingMessage(string(HOSTED_SQUAD_WEBRTC_CANDIDATE), wm.ID, from, map[string]interface{}{ + "from": wm.ID, + "to": from, + "candidate": candidate.ToJSON().Candidate, + "sdpMid": *candidate.ToJSON().SDPMid, + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), }); err != nil { wm.CandidateMux.Unlock() return } } - delete(wm.PendingCandidates, req[FROM]) + delete(wm.PendingCandidates, from) wm.CandidateMux.Unlock() wm.LocalSDMapMux.Lock() - delete(wm.LocalSD, req[FROM]) + delete(wm.LocalSD, from) wm.LocalSDMapMux.Unlock() return } @@ -645,14 +649,9 @@ func (wm *WebRTCCallManager) HandleRennegotiationOffer(from string, sdp string) if err = wm.RTCPeerConnections[from].SetLocalDescription(localSd); err != nil { return } - if err = wm.stream.Send(&Request{ - Type: string(HOSTED_SQUAD_WEBRTC_RENNEGOTIATION_ANSWER), - From: wm.ID, - Token: "", - Payload: map[string]string{ - "to": from, - "sdp": localSd.SDP, - }, + if err = wm.sendSignalingMessage(string(HOSTED_SQUAD_WEBRTC_RENNEGOTIATION_ANSWER), wm.ID, from, map[string]interface{}{ + "to": from, + "sdp": localSd.SDP, }); err != nil { logger.Println(err) return @@ -828,14 +827,9 @@ func (wm *WebRTCCallManager) negotiate(target string, squadId string) { logger.Println(err) return } - if err = wm.stream.Send(&Request{ - Type: string(HOSTED_SQUAD_WEBRTC_RENNEGOTIATION_OFFER), - From: wm.ID, - Token: "", - Payload: map[string]string{ - "to": id, - "sdp": localSd.SDP, - }, + if err = wm.sendSignalingMessage(string(HOSTED_SQUAD_WEBRTC_RENNEGOTIATION_OFFER), wm.ID, id, map[string]interface{}{ + "to": id, + "sdp": localSd.SDP, }); err != nil { logger.Println(err) return diff --git a/webrtcFsManager.go b/webrtcFsManager.go index 18d74f9..937e443 100644 --- a/webrtcFsManager.go +++ b/webrtcFsManager.go @@ -5,14 +5,13 @@ import ( "encoding/json" "fmt" "io" - "strconv" sync "sync" "github.com/pion/webrtc/v3" ) type WebrtcFsManager struct { - stream GrpcManager_LinkClient + stream SignalingService_LinkClient DatachannelManager DataChannelManager LocalSD map[string]*webrtc.SessionDescription RTCPeerConnections map[string]*webrtc.PeerConnection @@ -40,6 +39,20 @@ func NewWebrtcFsManager(dataChannelManager DataChannelManager) (webrtcFsManager return } +func (wf *WebrtcFsManager) sendSignalingMessage(messageType, from, to string, payload map[string]interface{}) (err error) { + bs, err := json.Marshal(payload) + if err != nil { + return + } + err = wf.stream.Send(&SignalingMessage{ + Type: messageType, + From: from, + To: to, + Payload: bs, + }) + return +} + func (wf *WebrtcFsManager) CreateOffer(ctx context.Context, target string, from string, cb OnICECandidateFunc) (err error) { peerConnection, err := wf.createPeerConnection(target, from, webrtc.SDPTypeOffer, cb) if err != nil { @@ -56,15 +69,10 @@ func (wf *WebrtcFsManager) CreateOffer(ctx context.Context, target string, from logger.Println("adding for target", target) wf.RTCPeerConnections[target] = peerConnection wf.RTCPeerConnectionMapMux.Unlock() - err = wf.stream.Send(&Request{ - Type: string(WEBRTC_OFFER_FS), - From: "lolo_local_serv", - Token: "none", - Payload: map[string]string{ - "to": target, - "from": "lolo_local_serv", - "sdp": rawOffer.SDP, - }, + err = wf.sendSignalingMessage(string(WEBRTC_OFFER_FS), "lolo_local_serv", target, map[string]any{ + "to": target, + "from": "lolo_local_serv", + "sdp": rawOffer.SDP, }) return } @@ -96,19 +104,19 @@ func (wf *WebrtcFsManager) HandleOffer(ctx context.Context, req map[string]strin wf.LocalSDMapMux.Lock() wf.LocalSD[req[FROM]] = &rawAnswer wf.LocalSDMapMux.Unlock() - if err = wf.stream.Send(&Request{ - Type: string(WEBRTC_ANSWER_FS), - From: "lolo_local_serv", - Token: "none", - Payload: map[string]string{ - "to": req[FROM], - "from": "lolo_local_serv", - "sdp": rawAnswer.SDP, - }, - }); err != nil { - errCh <- err - return - } + // if err = wf.stream.Send(&Request{ + // Type: string(WEBRTC_ANSWER_FS), + // From: "lolo_local_serv", + // Token: "none", + // Payload: map[string]string{ + // "to": req[FROM], + // "from": "lolo_local_serv", + // "sdp": rawAnswer.SDP, + // }, + // }); err != nil { + // errCh <- err + // return + // } done <- struct{}{} }() select { @@ -141,34 +149,34 @@ func (wf *WebrtcFsManager) HandleAnswer(ctx context.Context, req map[string]stri }); err != nil { return } - if err = wf.stream.Send(&Request{ - Type: string(WEBRTC_COUNTER_OFFER_FS), - From: "lolo_local_serv", - Token: "none", - Payload: map[string]string{ - "from": "lolo_local_serv", - "to": req[FROM], - }, - }); err != nil { - return - } + // if err = wf.stream.Send(&Request{ + // Type: string(WEBRTC_COUNTER_OFFER_FS), + // From: "lolo_local_serv", + // Token: "none", + // Payload: map[string]string{ + // "from": "lolo_local_serv", + // "to": req[FROM], + // }, + // }); err != nil { + // return + // } wf.CandidateMux.RLock() - for _, candidate := range wf.PendingCandidates[req[FROM]] { + for range wf.PendingCandidates[req[FROM]] { logger.Println("sending candidate to", req[FROM]) - if err = wf.stream.Send(&Request{ - Type: string(WEBRTC_CANDIDATE_FS), - From: "lolo_local_serv", - Token: "none", - Payload: map[string]string{ - "from": "lolo_local_serv", - "to": req[FROM], - "candidate": candidate.ToJSON().Candidate, - "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), - }, - }); err != nil { - return - } + // if err = wf.stream.Send(&Request{ + // Type: string(WEBRTC_CANDIDATE_FS), + // From: "lolo_local_serv", + // Token: "none", + // Payload: map[string]string{ + // "from": "lolo_local_serv", + // "to": req[FROM], + // "candidate": candidate.ToJSON().Candidate, + // "sdpMid": *candidate.ToJSON().SDPMid, + // "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), + // }, + // }); err != nil { + // return + // } } wf.CandidateMux.RUnlock() wf.CandidateMux.Lock() @@ -194,22 +202,22 @@ func (wf *WebrtcFsManager) HandleCounterOffer(ctx context.Context, req map[strin } wf.LocalSDMapMux.RUnlock() wf.CandidateMux.RLock() - for _, candidate := range wf.PendingCandidates[req[FROM]] { - logger.Println("sending candidate to", req[FROM]) - if err = wf.stream.Send(&Request{ - Type: string(WEBRTC_CANDIDATE_FS), - From: "lolo_local_serv", - Token: "none", - Payload: map[string]string{ - "from": "lolo_local_serv", - "to": req[FROM], - "candidate": candidate.ToJSON().Candidate, - "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), - }, - }); err != nil { - return - } + for range wf.PendingCandidates[req[FROM]] { + // logger.Println("sending candidate to", req[FROM]) + // if err = wf.stream.Send(&Request{ + // Type: string(WEBRTC_CANDIDATE_FS), + // From: "lolo_local_serv", + // Token: "none", + // Payload: map[string]string{ + // "from": "lolo_local_serv", + // "to": req[FROM], + // "candidate": candidate.ToJSON().Candidate, + // "sdpMid": *candidate.ToJSON().SDPMid, + // "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), + // }, + // }); err != nil { + // return + // } } wf.CandidateMux.RUnlock() return @@ -356,7 +364,7 @@ func (wf *WebrtcFsManager) createPeerConnection(target string, from string, peer if peerConnection.SignalingState() != webrtc.SignalingStateHaveLocalOffer && peerConnection.SignalingState() != webrtc.SignalingStateHaveRemoteOffer { wf.RTCPeerConnectionMapMux.Lock() defer wf.RTCPeerConnectionMapMux.Unlock() - for id, connection := range wf.RTCPeerConnections { + for _, connection := range wf.RTCPeerConnections { if connection.SignalingState() != webrtc.SignalingStateHaveLocalOffer && connection.SignalingState() != webrtc.SignalingStateHaveRemoteOffer { localSd, err := connection.CreateOffer(nil) if err != nil { @@ -367,18 +375,18 @@ func (wf *WebrtcFsManager) createPeerConnection(target string, from string, peer logger.Println(err) return } - if err = wf.stream.Send(&Request{ - Type: string(WEBRTC_RENNEGOTIATION_OFFER_FS), - From: "lolo_local_serv", - Token: "", - Payload: map[string]string{ - "to": id, - "sdp": localSd.SDP, - }, - }); err != nil { - logger.Println(err) - return - } + // if err = wf.stream.Send(&Request{ + // Type: string(WEBRTC_RENNEGOTIATION_OFFER_FS), + // From: "lolo_local_serv", + // Token: "", + // Payload: map[string]string{ + // "to": id, + // "sdp": localSd.SDP, + // }, + // }); err != nil { + // logger.Println(err) + // return + // } } } } @@ -407,18 +415,18 @@ func (wf *WebrtcFsManager) HandleRennegotiationOffer(from string, dst string, sd if err = wf.RTCPeerConnections[from].SetLocalDescription(localSd); err != nil { return } - if err = wf.stream.Send(&Request{ - Type: string(WEBRTC_RENNEGOTIATION_ANSWER_FS), - From: "lolo_local_serv", - Token: "", - Payload: map[string]string{ - "to": from, - "sdp": localSd.SDP, - }, - }); err != nil { - logger.Println(err) - return - } + // if err = wf.stream.Send(&Request{ + // Type: string(WEBRTC_RENNEGOTIATION_ANSWER_FS), + // From: "lolo_local_serv", + // Token: "", + // Payload: map[string]string{ + // "to": from, + // "sdp": localSd.SDP, + // }, + // }); err != nil { + // logger.Println(err) + // return + // } return } diff --git a/webrtcFsMiddleware.go b/webrtcFsMiddleware.go index 62617b5..0affb24 100644 --- a/webrtcFsMiddleware.go +++ b/webrtcFsMiddleware.go @@ -2,6 +2,7 @@ package localserver import ( context "context" + "encoding/json" "strconv" "github.com/pion/webrtc/v3" @@ -20,7 +21,7 @@ const ( type WebRTCFsMiddleware struct { Manager *WebrtcFsManager - stream GrpcManager_LinkClient + stream SignalingService_LinkClient } func NewWebRTCFsMiddleware(manager *WebrtcFsManager) (webrtcFsMiddleware *WebRTCFsMiddleware) { @@ -31,111 +32,119 @@ func NewWebRTCFsMiddleware(manager *WebrtcFsManager) (webrtcFsMiddleware *WebRTC } func (wfm *WebRTCFsMiddleware) signalCandidate(to string, candidate *webrtc.ICECandidate) (err error) { - err = wfm.stream.Send(&Request{ - Type: string(WEBRTC_CANDIDATE_FS), - From: "lolo_local_serv", - Token: "none", - Payload: map[string]string{ - "from": "lolo_local_serv", - "to": to, - "candidate": candidate.ToJSON().Candidate, - "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), - }, + bs, err := json.Marshal(map[string]string{ + "from": "lolo_local_serv", + "to": to, + "candidate": candidate.ToJSON().Candidate, + "sdpMid": *candidate.ToJSON().SDPMid, + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), + }) + if err != nil { + return + } + err = wfm.stream.Send(&SignalingMessage{ + Type: string(WEBRTC_CANDIDATE_FS), + From: "lolo_local_serv", + Payload: bs, }) return } -func (wfm *WebRTCFsMiddleware) Process(ctx context.Context, req *Response, stream GrpcManager_LinkClient) (err error) { +func (wfm *WebRTCFsMiddleware) Process(ctx context.Context, req *SignalingMessage, stream SignalingService_LinkClient) (err error) { done, errCh := make(chan struct{}), make(chan error) go func() { + var payload map[string]string + if e := json.Unmarshal(req.Payload, &payload); err != nil { + errCh <- e + return + } switch req.Type { case string(INCOMING_PEER_FS): logger.Println("quit squad called") - if from, ok := req.Payload[FROM]; ok { + if from, ok := payload[FROM]; ok { logger.Println(from) //wfm.Manager.HandleLeavingMember(from) done <- struct{}{} } case string(PEER_CONNECTION_REQUEST): - if err := validateRequest(req.Payload, FROM, TO); err != nil { + if err := validateRequest(payload, FROM, TO); err != nil { errCh <- err return } - // if err := wfm.Manager.CreateOffer(ctx, req.Payload[FROM], req.Payload[TO], wfm.signalCandidate); err != nil { + // if err := wfm.Manager.CreateOffer(ctx, payload[FROM], payload[TO], wfm.signalCandidate); err != nil { // errCh <- err // return // } done <- struct{}{} case string(WEBRTC_OFFER_FS): - if err := validateRequest(req.GetPayload(), FROM, TO, SDP); err != nil { + if err := validateRequest(payload, FROM, TO, SDP); err != nil { errCh <- err return } - if err := wfm.Manager.HandleOffer(ctx, req.GetPayload(), wfm.signalCandidate); err != nil { + if err := wfm.Manager.HandleOffer(ctx, payload, wfm.signalCandidate); err != nil { errCh <- err return } done <- struct{}{} case string(WEBRTC_ANSWER_FS): - if err := validateRequest(req.GetPayload(), FROM, TO, SDP); err != nil { + if err := validateRequest(payload, FROM, TO, SDP); err != nil { errCh <- err return } - if err := wfm.Manager.HandleAnswer(ctx, req.GetPayload()); err != nil { + if err := wfm.Manager.HandleAnswer(ctx, payload); err != nil { errCh <- err return } done <- struct{}{} case string(WEBRTC_COUNTER_OFFER_FS): - if err := validateRequest(req.GetPayload(), FROM); err != nil { + if err := validateRequest(payload, FROM); err != nil { errCh <- err return } - if err := wfm.Manager.HandleCounterOffer(ctx, req.Payload); err != nil { + if err := wfm.Manager.HandleCounterOffer(ctx, payload); err != nil { errCh <- err return } done <- struct{}{} case string(WEBRTC_RENNEGOTIATION_ANSWER_FS): - if err := validateRequest(req.GetPayload(), FROM, SDP); err != nil { + if err := validateRequest(payload, FROM, SDP); err != nil { errCh <- err return } - if err := wfm.Manager.HandleRennegotiationAnswer(req.Payload[FROM], "lolo_local_serv", req.Payload[SDP]); err != nil { + if err := wfm.Manager.HandleRennegotiationAnswer(payload[FROM], "lolo_local_serv", payload[SDP]); err != nil { errCh <- err return } done <- struct{}{} case string(WEBRTC_RENNEGOTIATION_OFFER_FS): - if err := validateRequest(req.GetPayload(), FROM, SDP); err != nil { + if err := validateRequest(payload, FROM, SDP); err != nil { errCh <- err return } - if err := wfm.Manager.HandleRennegotiationOffer(req.Payload[FROM], "", req.Payload[SDP]); err != nil { + if err := wfm.Manager.HandleRennegotiationOffer(payload[FROM], "", payload[SDP]); err != nil { errCh <- err return } done <- struct{}{} case string(WEBRTC_CANDIDATE_FS): - if err := validateRequest(req.GetPayload(), FROM, "candidate", "sdpMlineIndex", "sdpMid"); err != nil { + if err := validateRequest(payload, FROM, "candidate", "sdpMLineIndex", "sdpMid"); err != nil { errCh <- err return } - logger.Println(req.Payload) - i, err := strconv.Atoi(req.Payload["sdpMlineIndex"]) + logger.Println(payload) + i, err := strconv.Atoi(payload["sdpMLineIndex"]) if err != nil { errCh <- err return } - sdpMlineIndex := uint16(i) - sdpMid := req.Payload["sdpMid"] - logger.Println(sdpMid, sdpMlineIndex) + SDPMLineIndex := uint16(i) + sdpMid := payload["sdpMid"] + logger.Println(sdpMid, SDPMLineIndex) if err := wfm.Manager.AddCandidate(&webrtc.ICECandidateInit{ - Candidate: req.Payload["candidate"], + Candidate: payload["candidate"], SDPMid: &sdpMid, - SDPMLineIndex: &sdpMlineIndex, - }, req.Payload[FROM]); err != nil { + SDPMLineIndex: &SDPMLineIndex, + }, payload[FROM]); err != nil { errCh <- err return } diff --git a/webrtcGrpcMiddleware.go b/webrtcGrpcMiddleware.go index 346b597..8f089d1 100644 --- a/webrtcGrpcMiddleware.go +++ b/webrtcGrpcMiddleware.go @@ -2,6 +2,7 @@ package localserver import ( "context" + "encoding/json" "fmt" "strconv" @@ -38,7 +39,7 @@ const ( type WebRTCGrpcMiddleware struct { Manager *WebRTCCallManager - stream GrpcManager_LinkClient + stream SignalingService_LinkClient } func NewWebRTCGrpcMiddleware(manager *WebRTCCallManager) (webrtcGrpcMiddleware *WebRTCGrpcMiddleware) { @@ -59,124 +60,125 @@ func validateRequest(req map[string]string, entries ...string) (err error) { } func (wgm *WebRTCGrpcMiddleware) signalCandidate(to string, candidate *webrtc.ICECandidate) (err error) { - err = wgm.stream.Send(&Request{ - Type: string(HOSTED_SQUAD_WEBRTC_CANDIDATE), - From: wgm.Manager.ID, - Token: "none", - Payload: map[string]string{ - "from": wgm.Manager.ID, - "to": to, - "candidate": candidate.ToJSON().Candidate, - "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), - }, + bs, err := json.Marshal(map[string]string{ + "from": wgm.Manager.ID, + "to": to, + "candidate": candidate.ToJSON().Candidate, + "sdpMid": *candidate.ToJSON().SDPMid, + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), + }) + if err != nil { + return + } + err = wgm.stream.Send(&SignalingMessage{ + Type: string(HOSTED_SQUAD_WEBRTC_CANDIDATE), + From: wgm.Manager.ID, + To: to, + Payload: bs, }) return } -func (wgm *WebRTCGrpcMiddleware) Process(ctx context.Context, req *Response, stream GrpcManager_LinkClient) (err error) { +func (wgm *WebRTCGrpcMiddleware) Process(ctx context.Context, req *SignalingMessage, stream SignalingService_LinkClient) (err error) { done, errCh := make(chan struct{}), make(chan error) go func() { defer func() { done <- struct{}{} }() + var payload map[string]string + if e := json.Unmarshal(req.Payload, &payload); err != nil { + errCh <- e + return + } switch req.Type { case NEW_HOSTED_SQUAD: - if err := validateRequest(req.Payload, "ID"); err != nil { + if err := validateRequest(payload, "ID"); err != nil { errCh <- err return } logger.Println("new squad incoming") wgm.Manager.SquadMapMux.Lock() - wgm.Manager.Squads[req.Payload["ID"]] = &Squad{ - ID: req.Payload["ID"], + wgm.Manager.Squads[payload["ID"]] = &Squad{ + ID: payload["ID"], Members: []string{}, } wgm.Manager.SquadMapMux.Unlock() case string(HOSTED_SQUAD_STOP_CALL): logger.Println("quit squad called") - if err := validateRequest(req.Payload, FROM, "squadId"); err != nil { + if err := validateRequest(payload, "squadId"); err != nil { errCh <- err return } - wgm.Manager.HandleLeavingMember(req.Payload[FROM], req.Payload["squadId"]) + wgm.Manager.HandleLeavingMember(req.GetFrom(), payload["squadId"]) done <- struct{}{} case string(PEER_CONNECTION_REQUEST): - if err := validateRequest(req.Payload, FROM, TO); err != nil { - errCh <- err - return - } logger.Println("creating offer for peer") - if err := wgm.Manager.CreateOffer(ctx, req.Payload[FROM], req.Payload[TO], wgm.signalCandidate); err != nil { + if err := wgm.Manager.CreateOffer(ctx, req.GetFrom(), req.GetTo(), wgm.signalCandidate); err != nil { errCh <- err return } case string(HOSTED_SQUAD_WEBRTC_OFFER): - if err := validateRequest(req.GetPayload(), FROM, TO, SDP, SQUAD_ID); err != nil { + if err := validateRequest(payload, SDP, SQUAD_ID); err != nil { errCh <- err return } - if err := wgm.Manager.HandleOffer(ctx, req.GetPayload(), wgm.signalCandidate); err != nil { + if err := wgm.Manager.HandleOffer(ctx, req.GetFrom(), req.GetTo(), payload, wgm.signalCandidate); err != nil { errCh <- err return } case string(HOSTED_SQUAD_WEBRTC_ANSWER): - if err := validateRequest(req.GetPayload(), FROM, TO, SDP); err != nil { + if err := validateRequest(payload, SDP); err != nil { errCh <- err return } - if err := wgm.Manager.HandleAnswer(ctx, req.GetPayload()); err != nil { + if err := wgm.Manager.HandleAnswer(ctx, req.GetFrom(), req.GetTo(), payload); err != nil { errCh <- err return } case string(HOSTED_SQUAD_WEBRTC_COUNTER_OFFER): - if err := validateRequest(req.GetPayload(), FROM); err != nil { - errCh <- err - return - } - if err := wgm.Manager.HandleCounterOffer(ctx, req.Payload); err != nil { + if err := wgm.Manager.HandleCounterOffer(ctx, req.GetFrom(), req.GetTo(), payload); err != nil { errCh <- err return } case string(HOSTED_SQUAD_WEBRTC_RENNEGOTIATION_ANSWER): logger.Println("received negotiation answer") - if err := validateRequest(req.GetPayload(), FROM, SDP); err != nil { + if err := validateRequest(payload, SDP); err != nil { errCh <- err return } - if err := wgm.Manager.HandleRennegotiationAnswer(req.Payload[FROM], req.Payload[SDP]); err != nil { + if err := wgm.Manager.HandleRennegotiationAnswer(req.GetFrom(), payload[SDP]); err != nil { errCh <- err return } case string(HOSTED_SQUAD_WEBRTC_RENNEGOTIATION_OFFER): logger.Println("received negotiation offer") - if err := validateRequest(req.GetPayload(), FROM, SDP); err != nil { + if err := validateRequest(payload, SDP); err != nil { errCh <- err return } - if err := wgm.Manager.HandleRennegotiationOffer(req.Payload[FROM], req.Payload[SDP]); err != nil { + if err := wgm.Manager.HandleRennegotiationOffer(req.GetFrom(), payload[SDP]); err != nil { errCh <- err return } case string(HOSTED_SQUAD_WEBRTC_CANDIDATE): - if err := validateRequest(req.GetPayload(), FROM, "candidate", "sdpMlineIndex", "sdpMid"); err != nil { + if err := validateRequest(payload, "candidate", "sdpMLineIndex", "sdpMid"); err != nil { errCh <- err return } - logger.Println(req.Payload) - i, err := strconv.Atoi(req.Payload["sdpMlineIndex"]) + logger.Println(payload) + i, err := strconv.Atoi(payload["sdpMLineIndex"]) if err != nil { errCh <- err return } - sdpMlineIndex := uint16(i) - sdpMid := req.Payload["sdpMid"] - logger.Println(sdpMid, sdpMlineIndex) + SDPMLineIndex := uint16(i) + sdpMid := payload["sdpMid"] + logger.Println(sdpMid, SDPMLineIndex) if err := wgm.Manager.AddCandidate(&webrtc.ICECandidateInit{ - Candidate: req.Payload["candidate"], + Candidate: payload["candidate"], SDPMid: &sdpMid, - SDPMLineIndex: &sdpMlineIndex, - }, req.Payload[FROM]); err != nil { + SDPMLineIndex: &SDPMLineIndex, + }, req.GetFrom()); err != nil { errCh <- err return } diff --git a/zoneAudioChannel.go b/zoneAudioChannel.go index bf6b540..119f4ac 100644 --- a/zoneAudioChannel.go +++ b/zoneAudioChannel.go @@ -129,10 +129,10 @@ func (ac *AudioChannel) HandleOffer(ctx context.Context, channelId string, userI errCh <- err return } - _ = atomicallyExecute(ac.localSDMapFlag, func() (err error) { - ac.localSD[userId] = &rawAnswer + if err = peerConnection.SetLocalDescription(rawAnswer); err != nil { + errCh <- err return - }) + } _, _ = sendDCMessage(string(AUDIO_CHANNEL_WEBRTC_ANSWER), hostId, userId, map[string]interface{}{ "to": userId, "from": ac.ID, @@ -146,25 +146,25 @@ func (ac *AudioChannel) HandleOffer(ctx context.Context, channelId string, userI } func (ac *AudioChannel) HandleCounterOffer(ctx context.Context, userId string, sendDCMessage SendDCMessageFunc) (err error) { - if err = atomicallyExecute(ac.rtcPeerConnectionMapFlag, func() (err error) { - if _, ok := ac.rtcPeerConnections[userId]; !ok { - err = fmt.Errorf("no field corresponding peer connection for id %s", userId) - return - } - logger.Println("handling counter offer") - connection := ac.rtcPeerConnections[userId] - err = atomicallyExecute(ac.localSDMapFlag, func() (err error) { - err = connection.SetLocalDescription(*ac.localSD[userId]) - return - }) - return - }); err != nil { - return - } - _ = atomicallyExecute(ac.localSDMapFlag, func() (err error) { - delete(ac.localSD, userId) - return - }) + // if err = atomicallyExecute(ac.rtcPeerConnectionMapFlag, func() (err error) { + // if _, ok := ac.rtcPeerConnections[userId]; !ok { + // err = fmt.Errorf("no field corresponding peer connection for id %s", userId) + // return + // } + // logger.Println("handling counter offer") + // connection := ac.rtcPeerConnections[userId] + // err = atomicallyExecute(ac.localSDMapFlag, func() (err error) { + // err = connection.SetLocalDescription(*ac.localSD[userId]) + // return + // }) + // return + // }); err != nil { + // return + // } + // _ = atomicallyExecute(ac.localSDMapFlag, func() (err error) { + // delete(ac.localSD, userId) + // return + // }) if err = atomicallyExecute(ac.candidateFlag, func() (err error) { for _, candidate := range ac.pendingCandidates[userId] { logger.Println("sending candidate to", userId, candidate) @@ -173,7 +173,7 @@ func (ac *AudioChannel) HandleCounterOffer(ctx context.Context, userId string, s "to": userId, "candidate": candidate.ToJSON().Candidate, "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), }) select { case <-d: @@ -508,39 +508,39 @@ func (ac *AudioChannel) createPeerConnection(target string, from string, peerTyp return }) }) - peerConnection.OnNegotiationNeeded(func() { - logger.Println("---------------- rennego is needed -----------") - // _ = atomicallyExecute(ac.rtcPeerConnectionMapFlag, func() (err error) { - // for _, id := range ac.CurrentMembersId { - // logger.Println("----------------- sending renego to peer with id", id) - // if _, ok := ac.rtcPeerConnections[id]; !ok { - // continue - // } - // if peerConnection.SignalingState() == webrtc.SignalingStateStable { - // localSd, localSdErr := peerConnection.CreateOffer(nil) - // if localSdErr != nil { - // logger.Println(localSdErr) - // return localSdErr - // } - // if err = peerConnection.SetLocalDescription(localSd); err != nil { - // logger.Println(err) - // return - // } - // d, e := sendDCMessage(string(AUDIO_CHANNEL_WEBRTC_RENNEGOTIATION_OFFER), ac.ID, id, map[string]interface{}{ - // "from": ac.ID, - // "to": id, - // "sdp": localSd.SDP, - // }) - // select { - // case <-d: - // case err = <-e: - // logger.Println(err) - // } - // } - // } - // return - // }) - }) + //peerConnection.OnNegotiationNeeded(func() { + //logger.Println("---------------- rennego is needed -----------") + // _ = atomicallyExecute(ac.rtcPeerConnectionMapFlag, func() (err error) { + // for _, id := range ac.CurrentMembersId { + // logger.Println("----------------- sending renego to peer with id", id) + // if _, ok := ac.rtcPeerConnections[id]; !ok { + // continue + // } + // if peerConnection.SignalingState() == webrtc.SignalingStateStable { + // localSd, localSdErr := peerConnection.CreateOffer(nil) + // if localSdErr != nil { + // logger.Println(localSdErr) + // return localSdErr + // } + // if err = peerConnection.SetLocalDescription(localSd); err != nil { + // logger.Println(err) + // return + // } + // d, e := sendDCMessage(string(AUDIO_CHANNEL_WEBRTC_RENNEGOTIATION_OFFER), ac.ID, id, map[string]interface{}{ + // "from": ac.ID, + // "to": id, + // "sdp": localSd.SDP, + // }) + // select { + // case <-d: + // case err = <-e: + // logger.Println(err) + // } + // } + // } + // return + // }) + //}) return } diff --git a/zoneAudioChannelshandler.go b/zoneAudioChannelshandler.go index 73d0726..af7e38d 100644 --- a/zoneAudioChannelshandler.go +++ b/zoneAudioChannelshandler.go @@ -27,8 +27,14 @@ const ( ) const ( - USER_JOINED_AUDIO_CHANNEL = "user_joined_audio_channel" - USER_LEFT_AUDIO_CHANNEL = "user_left_audio_channel" + USER_JOINED_AUDIO_CHANNEL = "user_joined_audio_channel" + USER_LEFT_AUDIO_CHANNEL = "user_left_audio_channel" + AUDIO_CHANNNEL_NAME_EDITED = "audio_channel_name_edited" + AUDIO_CHANNNEL_TYPE_EDITED = "audio_channel_type_edited" + AUDIO_CHANNEL_MEMBER_REMOVED = "audio_channel_member_removed" + AUDIO_CHANNEL_MEMBER_ADDED = "audio_channel_member_added" + ADDED_IN_AUDIO_CHANNEL = "added_in_audio_channel" + REMOVED_FROM_AUDIO_CHANNEL = "removed_from_audio_channel" ) type AudioChannelMember struct { @@ -195,7 +201,7 @@ func (zach *ZoneAudioChannelsHandler) signalCandidate(from string, to string, ca "to": to, "candidate": candidate.ToJSON().Candidate, "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), }) select { case <-d: @@ -270,15 +276,15 @@ func (zach *ZoneAudioChannelsHandler) AddNewAudioChannel(channelName string, own } m := make([]string, 0, len(members)) for _, member := range members { - if _, ok := member.(string); ok { - m = append(m, member.(string)) + if mbr, ok := member.(string); ok && mbr != owner { + m = append(m, mbr) } } baseConfig := &AudioChannelConfig{ ID: channelName, Owner: owner, ChannelType: channelType, - Members: m, + Members: append(m,owner), } bs, jsonErr := json.Marshal(baseConfig) if jsonErr != nil { @@ -344,7 +350,7 @@ func (zach *ZoneAudioChannelsHandler) DeleteAudioChannel(channelId string) (err "userId": member, "channelId": channelId, }) - done, e := zach.sendDataChannelMessage(REMOVED_FROM_CHAT, "node", member, map[string]interface{}{ + done, e := zach.sendDataChannelMessage(REMOVED_FROM_AUDIO_CHANNEL, "node", member, map[string]interface{}{ "channelId": channelId, "userId": member, }) @@ -419,7 +425,7 @@ func (zach *ZoneAudioChannelsHandler) EditAudioChannelName(channelId string, new "userId": member, "channelId": channelId, }) - done, e := zach.sendDataChannelMessage(CHAT_NAME_EDITED, "node", member, map[string]interface{}{ + done, e := zach.sendDataChannelMessage(AUDIO_CHANNNEL_NAME_EDITED, "node", member, map[string]interface{}{ "formerAudioChannelId": channelId, "newAudioChannelId": newAudioChannelId, }) @@ -449,7 +455,7 @@ func (zach *ZoneAudioChannelsHandler) EditAudioChannelType(channelId string, cha err = fmt.Errorf("no coresponding audioChannel") return } - bs, err := os.ReadFile(filepath.Join("data", "zones", zach.ZoneId, "audioChannels", channelId)) + bs, err := os.ReadFile(filepath.Join("data", "zones", zach.ZoneId, "audioChannels", channelId, "audioChannelConfig.json")) if err != nil { return } @@ -483,6 +489,10 @@ func (zach *ZoneAudioChannelsHandler) EditAudioChannelType(channelId string, cha if pubErr := zach.SetAudioChannelPublicForUser(channelId, member); pubErr != nil { logger.Println(pubErr) } + zach.sendDataChannelMessage(AUDIO_CHANNNEL_TYPE_EDITED, "node", member, map[string]interface{}{ + "channelId": channelId, + "channelType": channelType, + }) } case PRIVATE: var members = []string{} @@ -494,6 +504,10 @@ func (zach *ZoneAudioChannelsHandler) EditAudioChannelType(channelId string, cha if pubErr := zach.SetAudioChannelPrivateForUser(channelId, member); pubErr != nil { logger.Println(pubErr) } + zach.sendDataChannelMessage(AUDIO_CHANNNEL_TYPE_EDITED, "node", member, map[string]interface{}{ + "channelId": channelId, + "channelType": channelType, + }) } } _ = atomicallyExecute(zach.AudioChannelsFlag, func() (err error) { @@ -549,38 +563,38 @@ memberLoop: if _, err = f.Write(bs); err != nil { return err } - ac := NewAudioChannel(audioChannelConfig.ID, audioChannelConfig.Owner, audioChannelConfig.ChannelType, audioChannelConfig.Members, make([]string, 0), make(map[string]*AudioChannelMember)) _ = atomicallyExecute(zach.AudioChannelsFlag, func() (err error) { - zach.AudioChannels[channelId] = ac - return - }) -broadcastLoop: - for _, member := range ac.Members { - for _, m := range addedMembers { - if member == m { - done, e := zach.sendDataChannelMessage(ADDED_IN_CHAT, "node", member, map[string]interface{}{ - "audioChannel": ac, - }) - select { - case <-done: - case err = <-e: - logger.Println(err) + zach.AudioChannels[channelId].Members = audioChannelConfig.Members + ac := zach.AudioChannels[channelId] + broadcastLoop: + for _, member := range ac.Members { + for _, m := range addedMembers { + if member == m { + done, e := zach.sendDataChannelMessage(ADDED_IN_AUDIO_CHANNEL, "node", member, map[string]interface{}{ + "audioChannel": ac, + }) + select { + case <-done: + case err = <-e: + logger.Println(err) + } + continue broadcastLoop } - continue broadcastLoop - } - if _, ok := zach.DataChannels[member]; ok { - done, e := zach.sendDataChannelMessage(CHAT_MEMBER_ADDED, "node", member, map[string]interface{}{ - "userId": m, - "channelId": ac.ID, - }) - select { - case <-done: - case err = <-e: - logger.Println(err) + if _, ok := zach.DataChannels[member]; ok { + done, e := zach.sendDataChannelMessage(AUDIO_CHANNEL_MEMBER_ADDED, "node", member, map[string]interface{}{ + "userId": m, + "channelId": ac.ID, + }) + select { + case <-done: + case err = <-e: + logger.Println(err) + } } } } - } + return + }) return } @@ -633,17 +647,31 @@ func (zach *ZoneAudioChannelsHandler) RemoveAudioChannelMember(channelId string, if _, err = f.Write(bs); err != nil { return } - var ac *AudioChannel _ = atomicallyExecute(zach.AudioChannelsFlag, func() (err error) { - ac := NewAudioChannel(audioChannelConfig.ID, audioChannelConfig.Owner, audioChannelConfig.ChannelType, audioChannelConfig.Members, make([]string, 0), make(map[string]*AudioChannelMember)) - zach.AudioChannels[channelId] = ac + zach.AudioChannels[channelId].Members = audioChannelConfig.Members + ac := zach.AudioChannels[channelId] + broadcastLoop: + for _, member := range ac.Members { + if member == channelMember { + continue broadcastLoop + } + done, e := zach.sendDataChannelMessage(AUDIO_CHANNEL_MEMBER_REMOVED, "node", member, map[string]interface{}{ + "userId": channelMember, + "channelId": ac.ID, + }) + select { + case <-done: + case err = <-e: + logger.Println(err) + } + } return }) zach.sendZoneRequest(REMOVE_KNOWN_AUDIO_CHANNEL, "node", map[string]interface{}{ "userId": channelMember, "channelId": channelId, }) - done, e := zach.sendDataChannelMessage(REMOVED_FROM_CHAT, "node", channelMember, map[string]interface{}{ + done, e := zach.sendDataChannelMessage(REMOVED_FROM_AUDIO_CHANNEL, "node", channelMember, map[string]interface{}{ "channelId": channelId, "userId": channelMember, }) @@ -652,21 +680,6 @@ func (zach *ZoneAudioChannelsHandler) RemoveAudioChannelMember(channelId string, case err = <-e: logger.Println(err) } -broadcastLoop: - for _, member := range ac.Members { - if member == channelMember { - continue broadcastLoop - } - done, e := zach.sendDataChannelMessage(CHAT_MEMBER_REMOVED, "node", member, map[string]interface{}{ - "userId": channelMember, - "channelId": ac.ID, - }) - select { - case <-done: - case err = <-e: - logger.Println(err) - } - } return } @@ -685,7 +698,7 @@ func (zach *ZoneAudioChannelsHandler) SetAudioChannelPrivateForUser(channelId st "userId": member, "channelId": channelId, }) - done, e := zach.sendDataChannelMessage(REMOVED_FROM_CHAT, "node", member, map[string]interface{}{ + done, e := zach.sendDataChannelMessage(REMOVED_FROM_AUDIO_CHANNEL, "node", member, map[string]interface{}{ "channelId": channelId, "userId": member, }) @@ -715,7 +728,7 @@ func (zach *ZoneAudioChannelsHandler) SetAudioChannelPublicForUser(channelId str "userId": member, "channelId": channelId, }) - done, e := zach.sendDataChannelMessage(ADDED_IN_CHAT, "node", member, map[string]interface{}{ + done, e := zach.sendDataChannelMessage(ADDED_IN_AUDIO_CHANNEL, "node", member, map[string]interface{}{ "audioChannel": audioChannel, }) select { @@ -788,7 +801,7 @@ func (zach *ZoneAudioChannelsHandler) JoinAudioChannel(channelId string, userId audioChannel.CurrentMembersId = append(audioChannel.CurrentMembersId, userId) audioChannel.CurrentMembers[userId] = &AudioChannelMember{} signalMembers := func(members []string) { - for _, u := range audioChannel.Members { + for _, u := range members { done, e := zach.sendDataChannelMessage(USER_JOINED_AUDIO_CHANNEL, "node", u, map[string]interface{}{ "userId": userId, "channelId": channelId, @@ -842,7 +855,7 @@ func (zach *ZoneAudioChannelsHandler) LeaveAudioChannel(channelId string, userId } delete(audioChannel.CurrentMembers, userId) signalMembers := func(members []string) { - for _, u := range audioChannel.Members { + for _, u := range members { done, e := zach.sendDataChannelMessage(USER_LEFT_AUDIO_CHANNEL, "node", u, map[string]interface{}{ "userId": userId, "channelId": channelId, @@ -1008,17 +1021,17 @@ func (zach *ZoneAudioChannelsHandler) handleZoneRequest(ctx context.Context, req case string(AUDIO_CHANNEL_WEBRTC_CANDIDATE): logger.Println("handling audio channel webrtc candidate") logger.Println(req.Payload) - if err = verifyFieldsString(req.Payload, FROM, "candidate", "sdpMlineIndex", "sdpMid", "channelId", "userId"); err != nil { + if err = verifyFieldsString(req.Payload, FROM, "candidate", "sdpMLineIndex", "sdpMid", "channelId", "userId"); err != nil { return } logger.Println(req.Payload) - i, convErr := strconv.Atoi(req.Payload["sdpMlineIndex"].(string)) + i, convErr := strconv.Atoi(req.Payload["sdpMLineIndex"].(string)) if convErr != nil { return convErr } - sdpMlineIndex := uint16(i) + SDPMLineIndex := uint16(i) sdpMid := req.Payload["sdpMid"].(string) - logger.Println(sdpMid, sdpMlineIndex) + logger.Println(sdpMid, SDPMLineIndex) err = atomicallyExecute(zach.AudioChannelsFlag, func() (err error) { if _, ok := zach.AudioChannels[req.Payload["channelId"].(string)]; !ok { err = fmt.Errorf("no channel corresponging the one requested") @@ -1027,7 +1040,7 @@ func (zach *ZoneAudioChannelsHandler) handleZoneRequest(ctx context.Context, req err = zach.AudioChannels[req.Payload["channelId"].(string)].AddCandidate(&webrtc.ICECandidateInit{ Candidate: req.Payload["candidate"].(string), SDPMid: &sdpMid, - SDPMLineIndex: &sdpMlineIndex, + SDPMLineIndex: &SDPMLineIndex, }, req.Payload["userId"].(string)) return }) diff --git a/zoneChatFileInstance.go b/zoneChatFileInstance.go new file mode 100644 index 0000000..7f9beef --- /dev/null +++ b/zoneChatFileInstance.go @@ -0,0 +1,707 @@ +package localserver + +import ( + "bufio" + "context" + "encoding/json" + "fmt" + "io" + "os" + "path/filepath" + "strconv" + sync "sync" + "time" + + "github.com/pion/webrtc/v3" +) + +const ( + ZONE_CHAT_WEBRTC_OFFER ReqType = "zone_chat_offer" + ZONE_CHAT_WEBRTC_ANSWER ReqType = "zone_chat_answer" + ZONE_CHAT_WEBRTC_RENNEGOTIATION_OFFER ReqType = "zone_chat_rennegotiation_offer" + ZONE_CHAT_WEBRTC_RENNEGOTIATION_ANSWER ReqType = "zone_chat_rennegotiation_answer" + ZONE_CHAT_WEBRTC_COUNTER_OFFER ReqType = "zone_chat_webrtc_counter_offer" + ZONE_CHAT_WEBRTC_CANDIDATE ReqType = "zone_chat_webrtc_candidate" +) + +type ChatFSInstance struct { + ZoneID string `json:"id"` + Owner string `json:"owner"` + Members []string `json:"members"` + OpenFiles map[string]*os.File `json:"-"` + OpenFilesForUser map[string][]string `json:"-"` + localSD map[string]*webrtc.SessionDescription `json:"-"` + rtcPeerConnections map[string]*ZoneRTCPeerConnection `json:"-"` + zoneFSDataChannels map[string]map[string]*DataChannel `json:"-"` + pendingCandidates map[string][]*webrtc.ICECandidate `json:"-"` + middlewares []interface{} `json:"-"` + candidateFlag *uint32 `json:"-"` + filesFlag *uint32 `json:"-"` + rtcPeerConnectionMapFlag *uint32 `json:"-"` + dataChannelMapFlag *uint32 `json:"-"` + localSDMapFlag *uint32 `json:"-"` +} + +type ChatFSInstanceOnICECandidateFunc = func(string, string, *webrtc.ICECandidate) error + +func NewChatFSInstance(id, owner string, members []string) (audioChannel *ChatFSInstance) { + candidateFlag := uint32(0) + rtcPeerConnectionMapFlag := uint32(0) + dataChannelMapFlag := uint32(0) + filesFlag := uint32(0) + localSDMapFlag := uint32(0) + audioChannel = &ChatFSInstance{ + ZoneID: id, + Owner: owner, + Members: members, + OpenFiles: make(map[string]*os.File), + OpenFilesForUser: make(map[string][]string), + localSD: make(map[string]*webrtc.SessionDescription), + rtcPeerConnections: make(map[string]*ZoneRTCPeerConnection), + zoneFSDataChannels: make(map[string]map[string]*DataChannel), + pendingCandidates: make(map[string][]*webrtc.ICECandidate), + middlewares: make([]interface{}, 0), + candidateFlag: &candidateFlag, + filesFlag: &filesFlag, + rtcPeerConnectionMapFlag: &rtcPeerConnectionMapFlag, + dataChannelMapFlag: &dataChannelMapFlag, + localSDMapFlag: &localSDMapFlag, + } + return +} + +func (fs *ChatFSInstance) SetupFileUpload(chatId, filename, userId string) (err error) { + concretePath := filepath.Join("data", "zones", fs.ZoneID, "chats", chatId, "__files__", filename) + if _, rErr := os.ReadDir(filepath.Join("data", "zones", fs.ZoneID, "chats", chatId, "__files__")); os.IsNotExist(rErr) { + if err = os.MkdirAll(filepath.Join("data", "zones", fs.ZoneID, "chats", chatId, "__files__"), 0700); err != nil { + return + } + } else if rErr != nil { + return rErr + } + // if err = os.Remove(concretePath); err != nil { + // logger.Println(err) + // } + file, err := os.OpenFile(concretePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0755) + if err != nil { + return + } + _ = atomicallyExecute(fs.filesFlag, func() (err error) { + fs.OpenFiles[fmt.Sprintf("%s/%s", filename, userId)] = file + if _, ok := fs.OpenFilesForUser[userId]; !ok { + fs.OpenFilesForUser[userId] = []string{} + } + fs.OpenFilesForUser[userId] = append(fs.OpenFilesForUser[userId], fmt.Sprintf("%s/%s", filename, userId)) + return + }) + var dc *webrtc.DataChannel + if err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { + if pc, ok := fs.rtcPeerConnections[userId]; ok { + maxRetransmits := uint16(100) + dc, err = pc.CreateDataChannel(filename, &webrtc.DataChannelInit{ + MaxRetransmits: &maxRetransmits, + }) + if err != nil { + return + } + } else { + err = fmt.Errorf("no peerconnection for id %s", userId) + } + return + }); err != nil { + return + } + go func() { + dc.SetBufferedAmountLowThreshold(15000000) + dc.OnMessage(func(msg webrtc.DataChannelMessage) { + logger.Println(msg.Data) + _, _ = file.Write(msg.Data) + }) + dc.OnOpen(func() { + + logger.Println("updated") + err = dc.SendText("yooooo man this channel is open you should be able to send stuff") + logger.Println("!-----------------------------!") + logger.Printf("datachannel with id %s is now open\n", dc.Label()) + logger.Println(*dc.ID()) + logger.Println(err) + logger.Println("!-----------------------------!") + + }) + dc.OnClose(func() { + logger.Println("channel closed") + _ = atomicallyExecute(fs.filesFlag, func() (err error) { + if f, ok := fs.OpenFiles[fmt.Sprintf("%s/%s", filename, userId)]; ok { + err = f.Close() + } + delete(fs.OpenFiles, fmt.Sprintf("%s/%s", filename, userId)) + if _, ok := fs.OpenFilesForUser[userId]; ok { + var index int + for i, v := range fs.OpenFilesForUser[userId] { + if v == fmt.Sprintf("%s/%s", filename, userId) { + index = i + break + } + } + if len(fs.OpenFilesForUser[userId]) > 1 { + fs.OpenFilesForUser[userId] = append(fs.OpenFilesForUser[userId][:index], fs.OpenFilesForUser[userId][:index+1]...) + } else { + delete(fs.OpenFilesForUser, userId) + } + } + return + }) + _ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + delete(fs.zoneFSDataChannels[userId], fmt.Sprintf("%s/%s", filename, userId)) + return + }) + + }) + }() + err = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + if _, ok := fs.zoneFSDataChannels[userId]; !ok { + fs.zoneFSDataChannels[userId] = make(map[string]*DataChannel) + } + l := int32(0) + fs.zoneFSDataChannels[userId][dc.Label()] = &DataChannel{ + DataChannel: dc, + l: &l, + } + return + }) + return +} + +func (fs *ChatFSInstance) FileUploadDone(chatId, filename, userId string) (err error) { + err = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + if _, ok := fs.zoneFSDataChannels[userId]; ok { + if dc, ok := fs.zoneFSDataChannels[userId][filename]; ok { + err = dc.DataChannel.Close() + return + } + } + return + }) + return +} + +func (fs *ChatFSInstance) FileUploadFailed(chatId, filename, userId string) (err error) { + concretePath := filepath.Join("data", "zones", fs.ZoneID, "chats", chatId, "__files__", filename) + if err = os.Remove(concretePath); err != nil { + return + } + err = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + if _, ok := fs.zoneFSDataChannels[userId]; ok { + if dc, ok := fs.zoneFSDataChannels[userId][filename]; ok { + err = dc.DataChannel.Close() + return + } + } + return + }) + return +} + +func (fs *ChatFSInstance) SetupFileDownload(chatId, filename, userId string) (err error) { + concretePath := filepath.Join("data", "zones", fs.ZoneID, "chats", chatId, "__files__", filename) + file, err := os.OpenFile(concretePath, os.O_RDONLY, 0755) + if err != nil { + return + } + _ = atomicallyExecute(fs.filesFlag, func() (err error) { + fs.OpenFiles[fmt.Sprintf("%s/%s", filename, userId)] = file + if _, ok := fs.OpenFilesForUser[userId]; !ok { + fs.OpenFilesForUser[userId] = []string{} + } + fs.OpenFilesForUser[userId] = append(fs.OpenFilesForUser[userId], fmt.Sprintf("%s/%s", filename, userId)) + return + }) + var dc *webrtc.DataChannel + if err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { + if pc, ok := fs.rtcPeerConnections[userId]; ok { + maxRetransmits := uint16(100) + dc, err = pc.CreateDataChannel(filename, &webrtc.DataChannelInit{ + MaxRetransmits: &maxRetransmits, + }) + if err != nil { + return + } + } else { + err = fmt.Errorf("no peerconnection for id %s", userId) + } + return + }); err != nil { + return + } + if dc != nil { + dc.SetBufferedAmountLowThreshold(15000000) + bufferedAmountLock := make(chan struct{}) + dc.OnOpen(func() { + go func() { + defer func() { + close(bufferedAmountLock) + bufferedAmountLock = nil + _ = atomicallyExecute(fs.filesFlag, func() (err error) { + if f, ok := fs.OpenFiles[fmt.Sprintf("%s/%s", filename, userId)]; ok { + err = f.Close() + } + delete(fs.OpenFiles, fmt.Sprintf("%s/%s", filename, userId)) + if _, ok := fs.OpenFilesForUser[userId]; ok { + var index int + for i, v := range fs.OpenFilesForUser[userId] { + if v == fmt.Sprintf("%s/%s", filename, userId) { + index = i + break + } + } + if len(fs.OpenFilesForUser[userId]) > 1 { + fs.OpenFilesForUser[userId] = append(fs.OpenFilesForUser[userId][:index], fs.OpenFilesForUser[userId][:index+1]...) + } else { + delete(fs.OpenFilesForUser, userId) + } + } + return + }) + }() + r := bufio.NewReader(file) + buf := make([]byte, 0, 50000) + sendingLoop: + for { + n, readErr := r.Read(buf[:cap(buf)]) + buf = buf[:n] + if n == 0 { + if err == nil { + logger.Println("n is 0 weird") + break sendingLoop + } + if err == io.EOF { + break sendingLoop + } + logger.Println(readErr) + return + } + if err = dc.Send(buf); err != nil { + dc.Close() + logger.Println(err) + break sendingLoop + } + if dc.BufferedAmount() > dc. + BufferedAmountLowThreshold() { + <-bufferedAmountLock + } + } + logger.Println("done") + <-time.After(time.Second * 4) + if err = dc.SendText("done"); err != nil { + logger.Println(err) + } + dc.Close() + _ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + if _, ok := fs.zoneFSDataChannels[userId]; ok { + delete(fs.zoneFSDataChannels[userId], dc.Label()) + } + return + }) + logger.Println("done 2") + }() + }) + dc.OnBufferedAmountLow(func() { + if bufferedAmountLock != nil { + bufferedAmountLock <- struct{}{} + } + }) + dc.OnClose(func() { + _ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + if _, ok := fs.zoneFSDataChannels[userId]; ok { + delete(fs.zoneFSDataChannels[userId], dc.Label()) + //fs.HandleLeavingMember(target) + } + return + }) + }) + err = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + if _, ok := fs.zoneFSDataChannels[userId]; !ok { + fs.zoneFSDataChannels[userId] = make(map[string]*DataChannel) + } + l := int32(0) + fs.zoneFSDataChannels[userId][dc.Label()] = &DataChannel{ + DataChannel: dc, + l: &l, + } + return + }) + } else { + err = fmt.Errorf("datachannel not created") + _ = atomicallyExecute(fs.filesFlag, func() (err error) { + if file, ok := fs.OpenFiles[fmt.Sprintf("%s/%s", filename, userId)]; ok { + file.Close() + } + delete(fs.OpenFiles, fmt.Sprintf("%s/%s", filename, userId)) + return + }) + } + return +} + +func (fs *ChatFSInstance) HandleOffer(ctx context.Context, channelId, userId, sdp, hostId string, sendDCMessage SendDCMessageFunc, cb ChatFSInstanceOnICECandidateFunc) (done chan struct{}, errCh chan error) { + done, errCh = make(chan struct{}), make(chan error) + go func() { + peerConnection, err := fs.createPeerConnection(userId, fs.ZoneID, webrtc.SDPTypeAnswer, cb, sendDCMessage) + if err != nil { + errCh <- err + return + } + _ = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { + fs.rtcPeerConnections[userId] = &ZoneRTCPeerConnection{ + PeerConnection: peerConnection, + makingOffer: false, + makingOfferLock: &sync.Mutex{}, + } + return + }) + offer := webrtc.SessionDescription{ + Type: webrtc.SDPTypeOffer, + SDP: sdp, + } + if err = peerConnection.SetRemoteDescription(offer); err != nil { + errCh <- err + return + } + rawAnswer, err := peerConnection.CreateAnswer(nil) + if err != nil { + errCh <- err + return + } + if err = peerConnection.SetLocalDescription(rawAnswer); err != nil { + errCh <- err + return + } + _, _ = sendDCMessage(string(ZONE_CHAT_WEBRTC_ANSWER), hostId, userId, map[string]interface{}{ + "to": userId, + "from": fs.ZoneID, + "channelId": channelId, + "sdp": rawAnswer.SDP, + }) + done <- struct{}{} + logger.Println("handle offer done") + }() + return +} + +func (fs *ChatFSInstance) HandleCounterOffer(ctx context.Context, userId string, sendDCMessage SendDCMessageFunc) (err error) { + // if err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { + // if _, ok := fs.rtcPeerConnections[userId]; !ok { + // err = fmt.Errorf("no field corresponding peer connection for id %s", userId) + // return + // } + // logger.Println("handling counter offer") + // connection := fs.rtcPeerConnections[userId] + // err = atomicallyExecute(fs.localSDMapFlag, func() (err error) { + // err = connection.SetLocalDescription(*fs.localSD[userId]) + // return + // }) + // return + // }); err != nil { + // return + // } + // _ = atomicallyExecute(fs.localSDMapFlag, func() (err error) { + // delete(fs.localSD, userId) + // return + // }) + if err = atomicallyExecute(fs.candidateFlag, func() (err error) { + for _, candidate := range fs.pendingCandidates[userId] { + logger.Println("sending candidate to", userId, candidate) + d, e := sendDCMessage(string(ZONE_CHAT_WEBRTC_CANDIDATE), "", userId, map[string]interface{}{ + "from": fs.ZoneID, + "to": userId, + "candidate": candidate.ToJSON().Candidate, + "sdpMid": *candidate.ToJSON().SDPMid, + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), + }) + select { + case <-d: + case err = <-e: + return + } + } + delete(fs.pendingCandidates, userId) + return + }); err != nil { + return + } + return +} + +func (fs *ChatFSInstance) HandleRennegotiationOffer(from, sdp string, sendDCMessage SendDCMessageFunc) (err error) { + err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { + if _, ok := fs.rtcPeerConnections[from]; !ok { + err = fmt.Errorf("no corresponding peer connection for id %s", from) + return + } + //fs.rtcPeerConnections[from].makingOfferLock.Lock() + if fs.rtcPeerConnections[from].makingOffer { + //fs.rtcPeerConnections[from].makingOfferLock.Unlock() + return fmt.Errorf("already making an offer or state is stable") + } + //fs.rtcPeerConnections[from].makingOfferLock.Unlock() + if err = fs.rtcPeerConnections[from].SetRemoteDescription(webrtc.SessionDescription{SDP: sdp, Type: webrtc.SDPTypeOffer}); err != nil { + return + } + localSd, err := fs.rtcPeerConnections[from].CreateAnswer(nil) + if err != nil { + return + } + if err = fs.rtcPeerConnections[from].SetLocalDescription(localSd); err != nil { + return + } + d, e := sendDCMessage(string(ZONE_CHAT_WEBRTC_RENNEGOTIATION_ANSWER), fs.ZoneID, from, map[string]interface{}{ + "from": fs.ZoneID, + "to": from, + "sdp": localSd.SDP, + }) + select { + case <-d: + case err = <-e: + } + return + }) + return +} + +func (fs *ChatFSInstance) HandleRennegotiationAnswer(from, sdp string) (err error) { + logger.Println("---------------------handling rennego answer") + err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { + err = fs.rtcPeerConnections[from].SetRemoteDescription(webrtc.SessionDescription{SDP: sdp, Type: webrtc.SDPTypeAnswer}) + return + }) + return +} + +func (fs *ChatFSInstance) AddCandidate(candidate *webrtc.ICECandidateInit, from string) (err error) { + logger.Println("adding ice candidate", candidate) + err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { + if _, ok := fs.rtcPeerConnections[from]; ok && candidate != nil { + err = fs.rtcPeerConnections[from].AddICECandidate(*candidate) + } + return + }) + return +} + +func (fs *ChatFSInstance) createPeerConnection(target, from string, peerType webrtc.SDPType, cb ChatFSInstanceOnICECandidateFunc, sendDCMessage SendDCMessageFunc) (peerConnection *webrtc.PeerConnection, err error) { + defer func() { + if r := recover(); err != nil { + logger.Printf("recover from panic : %v\n", r) + } + }() + config := webrtc.Configuration{ + ICEServers: []webrtc.ICEServer{ + { + URLs: []string{"stun:stun.l.google.com:19302", "stun:stunserver.org:3478"}, + }, + }, + } + + peerConnection, err = webrtc.NewPeerConnection(config) + if err != nil { + return + } + logger.Println("---------------------------------------------------") + if peerType == webrtc.SDPTypeAnswer { + maxRetransmits := uint16(1) + channel, err := peerConnection.CreateDataChannel("data", &webrtc.DataChannelInit{ + MaxRetransmits: &maxRetransmits, + }) + if err != nil { + return nil, err + } + channel.OnOpen(func() { + logger.Println("channel opened") + if chanErr := channel.SendText("yooo man this is open"); chanErr != nil { + logger.Println(chanErr) + } + }) + channel.OnMessage(func(msg webrtc.DataChannelMessage) { + var event CallEvent + if err := json.Unmarshal(msg.Data, &event); err != nil { + logger.Println(err) + return + } + if e := fs.HandleDataChannelEvents(event.From, event.EventId, event.Payload); e != nil { + logger.Println("*-------------- datachannel error: ", e) + } + }) + logger.Println("new channel for target : ", target) + channel.SetBufferedAmountLowThreshold(bufferedAmountLowThreshold) + channel.OnBufferedAmountLow(func() { + + }) + channel.OnClose(func() { + + }) + _ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + logger.Println(target) + l := int32(0) + if _, ok := fs.zoneFSDataChannels[target]; !ok { + fs.zoneFSDataChannels[target] = make(map[string]*DataChannel) + } + fs.zoneFSDataChannels[target][channel.Label()] = &DataChannel{ + DataChannel: channel, + l: &l, + } + return + }) + } else { + peerConnection.OnDataChannel(func(dc *webrtc.DataChannel) { + _ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + l := int32(0) + if _, ok := fs.zoneFSDataChannels[target]; !ok { + fs.zoneFSDataChannels[target] = make(map[string]*DataChannel) + } + fs.zoneFSDataChannels[target][dc.Label()] = &DataChannel{ + DataChannel: dc, + l: &l, + } + return + }) + dc.OnOpen(func() { + logger.Printf("got a new open datachannel %s\n", dc.Label()) + }) + dc.OnMessage(func(msg webrtc.DataChannelMessage) { + var event CallEvent + if err := json.Unmarshal(msg.Data, &event); err != nil { + logger.Println(err) + return + } + if e := fs.HandleDataChannelEvents(event.From, event.EventId, event.Payload); e != nil { + logger.Println("*-------------- datachannel error: ", e) + } + }) + dc.OnClose(func() { + _ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + if _, ok := fs.zoneFSDataChannels[target]; ok { + delete(fs.zoneFSDataChannels[target], dc.Label()) + fs.HandleLeavingMember(target) + } + return + }) + }) + _ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + logger.Println(target) + l := int32(0) + if _, ok := fs.zoneFSDataChannels[target]; !ok { + fs.zoneFSDataChannels[target] = make(map[string]*DataChannel) + } + fs.zoneFSDataChannels[target][dc.Label()] = &DataChannel{ + DataChannel: dc, + l: &l, + } + return + }) + }) + } + peerConnection.OnConnectionStateChange(func(pcs webrtc.PeerConnectionState) { + if pcs == webrtc.PeerConnectionStateClosed || pcs == webrtc.PeerConnectionStateDisconnected || pcs == webrtc.PeerConnectionStateFailed { + logger.Println(pcs) + fs.HandleLeavingMember(target) + } + }) + peerConnection.OnICEConnectionStateChange(func(is webrtc.ICEConnectionState) { + logger.Printf("ICE connection state has changed %s\n", is.String()) + if is == webrtc.ICEConnectionStateDisconnected || is == webrtc.ICEConnectionStateFailed { + logger.Println(is) + fs.HandleLeavingMember(target) + } + }) + peerConnection.OnICECandidate(func(i *webrtc.ICECandidate) { + if i == nil { + return + } + _ = atomicallyExecute(fs.candidateFlag, func() (err error) { + desc := peerConnection.RemoteDescription() + if desc == nil { + logger.Println("generated candidate appended to list : ", i) + fs.pendingCandidates[target] = append(fs.pendingCandidates[target], i) + } else { + logger.Println("generated candidate : ", i) + if iceCandidateErr := cb(from, target, i); iceCandidateErr != nil { + logger.Println(iceCandidateErr) + } + } + return + }) + }) + // peerConnection.OnNegotiationNeeded(func() { + // logger.Println("---------------- rennego is needed -----------") + // _ = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { + // logger.Println("----------------- sending renego to peer with id", target) + // if peerConnection.SignalingState() == webrtc.SignalingStateStable { + // localSd, localSdErr := peerConnection.CreateOffer(nil) + // if localSdErr != nil { + // logger.Println(localSdErr) + // return localSdErr + // } + // if err = peerConnection.SetLocalDescription(localSd); err != nil { + // logger.Println(err) + // return + // } + // d, e := sendDCMessage(string(ZONE_CHAT_WEBRTC_RENNEGOTIATION_OFFER), fs.ZoneID, target, map[string]interface{}{ + // "from": fs.ZoneID, + // "to": target, + // "sdp": localSd.SDP, + // }) + // select { + // case <-d: + // case err = <-e: + // logger.Println(err) + // } + // } + // return + // }) + // }) + return +} + +func (fs *ChatFSInstance) HandleLeavingMember(id string) { + _ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + if _, ok := fs.zoneFSDataChannels[id]; ok { + for _, dc := range fs.zoneFSDataChannels[id] { + dc.DataChannel.Close() + } + } + delete(fs.zoneFSDataChannels, id) + return + }) + logger.Println("chatfs datachannels cleaned") + _ = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { + if pc, ok := fs.rtcPeerConnections[id]; ok { + if closeErr := pc.Close(); closeErr != nil { + err = closeErr + logger.Println("peer connection close error", closeErr) + } + } + delete(fs.rtcPeerConnections, id) + return + }) + logger.Println("chats perrconnections cleaned") + _ = atomicallyExecute(fs.candidateFlag, func() (err error) { + delete(fs.pendingCandidates, id) + return + }) + _ = atomicallyExecute(fs.filesFlag, func() (err error) { + for _, openFile := range fs.OpenFilesForUser[id] { + if f, ok := fs.OpenFiles[openFile]; ok { + _ = f.Close() + } + delete(fs.OpenFiles, openFile) + } + delete(fs.OpenFilesForUser, id) + return + }) +} + +func (fs *ChatFSInstance) HandleDataChannelEvents(from, eventId string, payload map[string]interface{}) (err error) { + switch eventId { + } + return +} diff --git a/zoneChatTracking.go b/zoneChatTracking.go new file mode 100644 index 0000000..4ae7838 --- /dev/null +++ b/zoneChatTracking.go @@ -0,0 +1,150 @@ +package localserver + +import ( + "encoding/binary" + "os" + "path/filepath" + "sync" + + "github.com/dgraph-io/badger/v3" +) + +type ZoneChatTrackingDB struct { + db func(cb func(*badger.DB) (err error)) (err error) + lock *sync.RWMutex +} + +func NewZoneChatTracking(zoneId,chatId string,members ...string) (*ZoneChatTrackingDB,error) { + if _,dirErr := os.ReadDir(filepath.Join("data", "zones", zoneId, "chats", chatId,"__tracking__")); os.IsNotExist(dirErr) { + _ = os.MkdirAll(filepath.Join("data", "zones", zoneId, "chats", chatId,"__tracking__"),0700) + } + db := func(f func(*badger.DB) (err error)) (err error) { + db, err := badger.Open(badger.DefaultOptions(filepath.Join("data", "zones", zoneId, "chats", chatId,"__tracking__")).WithLogger(dbLogger)) + if err != nil { + return + } + defer db.Close() + err = f(db) + return + } + lock := new(sync.RWMutex) + if err := db(func(d *badger.DB) (err error) { + err = d.Update(func(txn *badger.Txn) error { + b := make([]byte,bufferSize) + binary.BigEndian.PutUint64(b,0) + for _, member := range members { + if _,rerr := txn.Get([]byte(member)); rerr == badger.ErrKeyNotFound { + txn.Set([]byte(member),b) + } else if rerr != nil { + return rerr + } + } + return nil + }) + if err != nil { + return + } + return + });err != nil { + return nil,err + } + return &ZoneChatTrackingDB{db,lock},nil +} + +func (zctdb *ZoneChatTrackingDB) Initialize(lastIndex uint64,users ...string) (err error) { + for _, user := range users { + if err = zctdb.SetUserLastIndex(user,lastIndex);err != nil { + return + } + } + return +} + +func (zctdb *ZoneChatTrackingDB) RevertTrackingLastIndex(lastIndex uint64) (err error) { + zctdb.lock.Lock() + defer zctdb.lock.Unlock() + err = zctdb.db(func(d *badger.DB) (err error) { + keys := [][]byte{} + err = d.View(func(txn *badger.Txn) error { + opt := badger.DefaultIteratorOptions + it := txn.NewIterator(opt) + defer it.Close() + for it.Rewind();it.Valid();it.Next() { + item := it.Item() + if err = item.Value(func(val []byte) error { + li := binary.BigEndian.Uint64(val) + if li >= lastIndex { + keys = append(keys, item.Key()) + } + return nil + }); err != nil { + return err + } + } + return nil + }) + if err != nil { + return + } + err = d.Update(func(txn *badger.Txn) error { + for _, key := range keys { + b := make([]byte,bufferSize) + binary.BigEndian.PutUint64(b,lastIndex) + if updateErr := txn.Set(key,b); updateErr != nil { + return updateErr + } + } + return nil + }) + return + }) + return +} + +func (zctdb *ZoneChatTrackingDB) SetUserLastIndex(userId string,lastIndex uint64) (err error) { + zctdb.lock.Lock() + defer zctdb.lock.Unlock() + err = zctdb.db(func(d *badger.DB) (err error) { + err = d.Update(func(txn *badger.Txn) error { + b := make([]byte,bufferSize) + binary.BigEndian.PutUint64(b,lastIndex) + updateErr := txn.Set([]byte(userId),b) + return updateErr + }) + return + }) + return +} + +func (zctdb *ZoneChatTrackingDB) GetUserLastIndex(userId string) (index uint,err error) { + zctdb.lock.Lock() + defer zctdb.lock.Unlock() + err = zctdb.db(func(d *badger.DB) (err error) { + err = d.Update(func(txn *badger.Txn) error { + item,rerr := txn.Get([]byte(userId)) + if rerr != nil { + return rerr + } + item.Value(func(val []byte) error { + index = uint(binary.BigEndian.Uint64(val)) + return nil + }) + return nil + }) + return + }) + return +} + +func (zctdb *ZoneChatTrackingDB) DeleteUserTracking(userId string) (err error) { + zctdb.lock.Lock() + defer zctdb.lock.Unlock() + err = zctdb.db(func(d *badger.DB) (err error) { + err = d.Update(func(txn *badger.Txn) error { + updateErr := txn.Delete([]byte(userId)) + return updateErr + }) + return + }) + return +} \ No newline at end of file diff --git a/zoneChatsDBHandler.go b/zoneChatsDBHandler.go index 47c58dc..77127be 100644 --- a/zoneChatsDBHandler.go +++ b/zoneChatsDBHandler.go @@ -3,22 +3,26 @@ package localserver import ( "encoding/binary" "encoding/json" + "os" "path/filepath" + "sync" "github.com/dgraph-io/badger/v3" ) type ChatFile struct { - Path string `json:"path"` + ChatId string `json:"chatId"` + Owner string `json:"owner"` Name string `json:"name"` Size int `json:"size"` - UploadTime string `json:"uploadTime` + UploadTime string `json:"uploadTime"` } type ChatMessage struct { ID uint64 `json:"id"` From string `json:"from"` - ResponseOf *ChatMessage `json:"ResponseOf"` + IsResponse bool `json:"isResponse"` + ResponseOf *ChatMessage `json:"responseOf"` Tags []string `json:"tags"` Content string `json:"content"` Date string `json:"date"` @@ -29,9 +33,13 @@ type ZoneChatDBHandler struct { ChatID string ZoneID string PreviousId uint64 + ItemCount uint64 db func(func(*badger.DB) (err error)) (err error) + lock *sync.RWMutex } +const bufferSize = 8 + func NewZoneChatDBHandler(zoneId string, chatID string) (zoneChatDBHandler *ZoneChatDBHandler, err error) { zoneChatDBHandler = &ZoneChatDBHandler{ db: func(f func(*badger.DB) (err error)) (err error) { @@ -45,18 +53,95 @@ func NewZoneChatDBHandler(zoneId string, chatID string) (zoneChatDBHandler *Zone }, ChatID: chatID, ZoneID: zoneId, + lock: new(sync.RWMutex), } err = zoneChatDBHandler.db(func(d *badger.DB) (err error) { err = d.View(func(txn *badger.Txn) error { opt := badger.DefaultIteratorOptions it := txn.NewIterator(opt) defer it.Close() - counter := 0 + var counter uint64 = 1 + var itemCounter uint64 = 0 for it.Rewind(); it.Valid(); it.Next() { - counter++ + item := it.Item() + if err = item.Value(func(val []byte) (err error) { + var chatMessage *ChatMessage + if err = json.Unmarshal(val, &chatMessage); err != nil { + return err + } + counter = chatMessage.ID + itemCounter++ + return + }); err != nil { + return err + } + } + zoneChatDBHandler.PreviousId = counter + zoneChatDBHandler.ItemCount = itemCounter + return nil + }) + return + }) + return +} + +func (zcdbh *ZoneChatDBHandler) calculateNewChatCount(previousId uint64) ( count uint,err error) { + err = zcdbh.db(func(d *badger.DB) (err error) { + err = d.View(func(txn *badger.Txn) error { + opt := badger.DefaultIteratorOptions + it := txn.NewIterator(opt) + defer it.Close() + count = 0 + b := make([]byte,bufferSize) + binary.BigEndian.PutUint64(b,previousId) + for it.Seek(b); it.Valid(); it.Next() { + item := it.Item() + if err = item.Value(func(val []byte) (err error) { + var chatMessage *ChatMessage + if err = json.Unmarshal(val, &chatMessage); err != nil { + return err + } + count++ + return + }); err != nil { + return err + } + } + if count > 0 { + count-- + } + return nil + }) + return + }) + return +} + +func (zcdbh *ZoneChatDBHandler) revertPreviousId() (err error) { + zcdbh.lock.Lock() + defer zcdbh.lock.Unlock() + err = zcdbh.db(func(d *badger.DB) (err error) { + err = d.View(func(txn *badger.Txn) error { + opt := badger.DefaultIteratorOptions + opt.Reverse = true + it := txn.NewIterator(opt) + defer it.Close() + it.Rewind() + if it.Valid() { + item := it.Item() + if err = item.Value(func(val []byte) (err error) { + var chatMessage *ChatMessage + if err = json.Unmarshal(val, &chatMessage); err != nil { + return err + } + zcdbh.PreviousId = chatMessage.ID + return + }); err != nil { + return err + } + } else { + zcdbh.PreviousId = 1 } - logger.Println(counter) - zoneChatDBHandler.PreviousId = uint64(counter) return nil }) return @@ -77,10 +162,12 @@ func (zcdbh *ZoneChatDBHandler) updateDbCallbackFolder(newChatId string) { } func (zcdbh *ZoneChatDBHandler) AddNewChatMessage(chatMessage *ChatMessage) (err error) { - b := make([]byte, 100) - binary.LittleEndian.PutUint64(b, zcdbh.PreviousId+1) - chatMessage.ID = zcdbh.PreviousId + zcdbh.lock.Lock() + defer zcdbh.lock.Unlock() + b := make([]byte, bufferSize) zcdbh.PreviousId++ + binary.BigEndian.PutUint64(b, zcdbh.PreviousId) + chatMessage.ID = zcdbh.PreviousId bs, err := json.Marshal(chatMessage) if err != nil { return @@ -100,34 +187,54 @@ func (zcdbh *ZoneChatDBHandler) AddNewChatMessage(chatMessage *ChatMessage) (err } func (zcdbh *ZoneChatDBHandler) DeleteChatMessage(key uint64) (err error) { + if err = zcdbh.db(func(d *badger.DB) (err error) { + zcdbh.lock.Lock() + defer zcdbh.lock.Unlock() + err = d.Update(func(txn *badger.Txn) (err error) { + b := make([]byte, bufferSize) + binary.BigEndian.PutUint64(b, key) + if err = txn.Delete(b); err != nil { + return + } + zcdbh.ItemCount-- + return + }) + return + }); err != nil { + return + } return } -func (zcdbh *ZoneChatDBHandler) ListChatMessages(lastIndex int, limit int) (chatMessages []*ChatMessage, l int, err error) { +func (zcdbh *ZoneChatDBHandler) DeleteChatFile(filename string, key uint64) (err error) { + zcdbh.lock.Lock() + defer zcdbh.lock.Unlock() + if err = zcdbh.DeleteChatMessage(key); err != nil { + return + } + err = os.Remove(filepath.Join("data", "zones", zcdbh.ZoneID, "chats", zcdbh.ChatID, "__files__", filename)) + return +} + +func (zcdbh *ZoneChatDBHandler) ListChatMessages(lastIndex int, limit int) (chatMessages []*ChatMessage, l int, done bool, err error) { + zcdbh.lock.RLock() + defer zcdbh.lock.RUnlock() err = zcdbh.db(func(d *badger.DB) (err error) { err = d.View(func(txn *badger.Txn) (err error) { opt := badger.DefaultIteratorOptions opt.Reverse = true it := txn.NewIterator(opt) - b := make([]byte, 100) + b := make([]byte, bufferSize) if lastIndex <= 0 { - binary.LittleEndian.PutUint64(b, uint64(zcdbh.PreviousId)) + binary.BigEndian.PutUint64(b, uint64(zcdbh.PreviousId)) } else { - binary.LittleEndian.PutUint64(b, uint64(lastIndex)) + binary.BigEndian.PutUint64(b, uint64(lastIndex)) } x := 0 defer it.Close() defer func() { - if lastIndex > limit { - l = lastIndex - limit - 1 - } else if lastIndex == 0 { - if zcdbh.PreviousId > uint64(limit) { - l = int(zcdbh.PreviousId) - limit - 1 - } else { - l = 0 - } - } else { - l = 0 + if x < limit { + done = true } }() chatMessages = make([]*ChatMessage, 0) @@ -141,6 +248,7 @@ func (zcdbh *ZoneChatDBHandler) ListChatMessages(lastIndex int, limit int) (chat if err = json.Unmarshal(val, &chatMessage); err != nil { return err } + l = int(chatMessage.ID) chatMessages = append(chatMessages, chatMessage) return }); err != nil { @@ -155,11 +263,75 @@ func (zcdbh *ZoneChatDBHandler) ListChatMessages(lastIndex int, limit int) (chat return } -func (zcdbh *ZoneChatDBHandler) GetChatMessage(index uint64) (chatMessage *ChatMessage, err error) { +func (zcdbh *ZoneChatDBHandler) ListChatFiles(lastIndex int, limit int) (chatMessages []*ChatFile, l int, err error) { + zcdbh.lock.RLock() + defer zcdbh.lock.RUnlock() err = zcdbh.db(func(d *badger.DB) (err error) { err = d.View(func(txn *badger.Txn) (err error) { - b := make([]byte, 100) - binary.LittleEndian.PutUint64(b, uint64(zcdbh.PreviousId)) + opt := badger.DefaultIteratorOptions + opt.Reverse = true + it := txn.NewIterator(opt) + b := make([]byte, bufferSize) + var li int + if lastIndex <= 0 { + binary.BigEndian.PutUint64(b, uint64(zcdbh.PreviousId)) + li = int(zcdbh.PreviousId) + } else { + binary.BigEndian.PutUint64(b, uint64(lastIndex)) + li = lastIndex + } + x := 0 + y := 0 + defer func() { + if li > x { + l = li - x + } else if li == 0 { + if zcdbh.PreviousId > uint64(x) { + l = int(zcdbh.PreviousId) - x + } else { + l = 0 + } + } else { + l = 0 + } + }() + defer it.Close() + chatMessages = make([]*ChatFile, 0) + for it.Seek(b); it.Valid(); it.Next() { + if y >= limit || x >= int(zcdbh.PreviousId) { + break + } + item := it.Item() + if err = item.Value(func(val []byte) (err error) { + var chatMessage *ChatMessage + if err = json.Unmarshal(val, &chatMessage); err != nil { + return err + } + if chatMessage.File != nil { + chatMessages = append(chatMessages, chatMessage.File) + l = lastIndex - x + y++ + } + return + }); err != nil { + return err + } + x++ + } + return + }) + return + }) + return +} + +func (zcdbh *ZoneChatDBHandler) GetChatMessage(index uint64) (chatMessage *ChatMessage, err error) { + zcdbh.lock.RLock() + defer zcdbh.lock.RUnlock() + err = zcdbh.db(func(d *badger.DB) (err error) { + err = d.View(func(txn *badger.Txn) (err error) { + b := make([]byte, bufferSize) + binary.BigEndian.PutUint64(b, uint64(index)) item, err := txn.Get(b) if err != nil { return @@ -174,6 +346,30 @@ func (zcdbh *ZoneChatDBHandler) GetChatMessage(index uint64) (chatMessage *ChatM return } -func (zcdbh *ZoneChatDBHandler) ModifyChatMessage(id string, chatMessage *ChatMessage) (err error) { +func (zcdbh *ZoneChatDBHandler) ModifyChatMessage(key uint64, newContent string) (err error) { + zcdbh.lock.Lock() + defer zcdbh.lock.Unlock() + b := make([]byte, bufferSize) + binary.BigEndian.PutUint64(b, key) + chatMessage, err := zcdbh.GetChatMessage(key) + if err != nil { + return + } + chatMessage.Content = newContent + bs, err := json.Marshal(chatMessage) + if err != nil { + return + } + if err = zcdbh.db(func(d *badger.DB) (err error) { + err = d.Update(func(txn *badger.Txn) (err error) { + if updateErr := txn.Set(b, bs); updateErr != nil { + return updateErr + } + return nil + }) + return + }); err != nil { + return + } return } diff --git a/zoneChatsHandler.go b/zoneChatsHandler.go index 1cbe982..8e2bfe2 100644 --- a/zoneChatsHandler.go +++ b/zoneChatsHandler.go @@ -7,34 +7,50 @@ import ( "io/fs" "os" "path/filepath" + "strconv" "time" "github.com/dgraph-io/badger/v3" + "github.com/pion/webrtc/v3" ) const ( - LIST_LATEST_CHATS = "list_latest_chats" - LIST_CHATS = "list_chats" - GET_CHATS = "get_chats" - GET_CHAT = "get_chat" - CREATE_CHAT = "create_chat" - DELETE_CHAT = "delete_chat" - EDIT_CHAT_TYPE = "edit_chat_type" - EDIT_CHAT_NAME = "edit_chat_name" - ADD_CHAT_MEMBERS = "add_chat_members" - REMOVE_CHAT_MEMBER = "remove_chat_member" - ADD_CHAT_MESSAGE = "add_chat_message" + LIST_LATEST_CHATS = "list_latest_chats" + READ_LATEST_MESSAGE = "read_latest_message" + LIST_LATEST_FILES = "list_latest_files" + LIST_CHATS = "list_chats" + GET_CHATS = "get_chats" + GET_CHAT = "get_chat" + CREATE_CHAT = "create_chat" + DELETE_CHAT = "delete_chat" + EDIT_CHAT_TYPE = "edit_chat_type" + EDIT_CHAT_NAME = "edit_chat_name" + ADD_CHAT_MEMBERS = "add_chat_members" + REMOVE_CHAT_MEMBER = "remove_chat_member" + ADD_CHAT_MESSAGE = "add_chat_message" + ZONE_UPLOAD_CHAT_FILE = "zone_upload_chat_file" + ZONE_DOWNLOAD_CHAT_FILE = "zone_download_chat_file" + DELETE_CHAT_FILE = "delete_chat_file" + DELETE_CHAT_MESSAGE = "delete_chat_message" + EDIT_CHAT_MESSAGE = "edit_chat_message" + ZONE_UPLOAD_CHAT_FILE_DONE = "zone_upload_chat_file_done" ) const ( - CHAT_NAME_EDITED = "chat_name_edited" - CHAT_MEMBER_LIST = "chat_messages_list" - CHAT_MEMBER_ADDED = "chat_member_added" - CHAT_MEMBER_REMOVED = "chat_member_removed" - REMOVED_FROM_CHAT = "removed_from_chat" - ADDED_IN_CHAT = "added_in_chat" - GET_CHATS_RESPONSE = "get_chats_response" - NEW_CHAT_MESSAGE = "new_chat_message" + CHAT_NAME_EDITED = "chat_name_edited" + CHAT_TYPE_EDITED = "chat_type_edited" + CHAT_MESSAGE_LIST = "chat_messages_list" + CHAT_FILES_LIST = "chat_files_list" + CHAT_MEMBER_ADDED = "chat_member_added" + CHAT_MEMBER_REMOVED = "chat_member_removed" + REMOVED_FROM_CHAT = "removed_from_chat" + ADDED_IN_CHAT = "added_in_chat" + GET_CHATS_RESPONSE = "get_chats_response" + NEW_CHAT_MESSAGE = "new_chat_message" + CHAT_MESSAGE_DELETED = "chat_message_deleted" + CHAT_MESSAGE_EDITED = "chat_message_edited" + CHAT_FILE_DELETED = "chat_file_deleted" + NEW_CHAT_FILE = "new_chat_file" ) const ( @@ -56,21 +72,27 @@ type Chat struct { ChatType string `json:"chatType"` Owner string `json:"owner"` Members []string `json:"members"` + LastReadIndex uint `json:"lastReadIndex"` + Unread uint `json:"unread"` DB *ZoneChatDBHandler `json:"-"` + Tracking *ZoneChatTrackingDB `json:"-"` } type ZoneChatsHandler struct { - ZoneId string - ZoneMembersId []string - DataChannels map[string]*DataChannel - Flag *uint32 - ChatFlag *uint32 - Chats map[string]*Chat - reqChans []chan<- *ZoneRequest - init bool + ZoneId string + HostId string + ChatFSInstance *ChatFSInstance + ZoneMembersId []string + DataChannels map[string]*DataChannel + Flag *uint32 + ChatFSInstanceFlag *uint32 + ChatFlag *uint32 + Chats map[string]*Chat + reqChans []chan<- *ZoneRequest + init bool } -func NewZoneChatsHandler(zoneId string, owner string, authorizedMembers []string, dataChannels map[string]*DataChannel, flag *uint32) (zoneChatsHandler *ZoneChatsHandler, err error) { +func NewZoneChatsHandler(hostId, zoneId, owner string, authorizedMembers []string, dataChannels map[string]*DataChannel, flag *uint32) (zoneChatsHandler *ZoneChatsHandler, err error) { var dirs []fs.DirEntry dirs, err = os.ReadDir(filepath.Join("data", "zones", zoneId, "chats")) if err != nil { @@ -112,6 +134,10 @@ func NewZoneChatsHandler(zoneId string, owner string, authorizedMembers []string if err != nil { return nil, err } + zoneChatTracking,err := NewZoneChatTracking(zoneId, chat.Name()) + if err != nil { + return nil, err + } var bs []byte bs, err = os.ReadFile(filepath.Join("data", "zones", zoneId, "chats", chat.Name(), "chatConfig.json")) if err != nil { @@ -122,19 +148,27 @@ func NewZoneChatsHandler(zoneId string, owner string, authorizedMembers []string if err = json.Unmarshal(bs, &c); err != nil { return nil, err } + if err = zoneChatTracking.Initialize(0,c.Members...); err != nil { + return nil,err + } logger.Println("chats data :", c.ChatId, c.ChatType, c.Owner, c.Members) c.DB = zoneChatDBHandler + c.Tracking = zoneChatTracking chats[c.ChatId] = &c } chatFlag := uint32(0) + chatFSFlag := uint32(0) zoneChatsHandler = &ZoneChatsHandler{ - ZoneId: zoneId, - ZoneMembersId: authorizedMembers, - DataChannels: dataChannels, - Flag: flag, - Chats: chats, - ChatFlag: &chatFlag, - init: false, + HostId: hostId, + ChatFSInstance: NewChatFSInstance(zoneId, owner, authorizedMembers), + ChatFSInstanceFlag: &chatFSFlag, + ZoneId: zoneId, + ZoneMembersId: authorizedMembers, + DataChannels: dataChannels, + Flag: flag, + Chats: chats, + ChatFlag: &chatFlag, + init: false, } return } @@ -206,6 +240,21 @@ func (zch *ZoneChatsHandler) Subscribe(ctx context.Context, publisher <-chan *Zo return } +func (zch *ZoneChatsHandler) signalCandidate(from string, to string, candidate *webrtc.ICECandidate) (err error) { + d, e := zch.sendDataChannelMessage(string(ZONE_CHAT_WEBRTC_CANDIDATE), from, to, map[string]interface{}{ + "from": from, + "to": to, + "candidate": candidate.ToJSON().Candidate, + "sdpMid": *candidate.ToJSON().SDPMid, + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), + }) + select { + case <-d: + case err = <-e: + } + return +} + func (zch *ZoneChatsHandler) GetChats(userId string, chatsId ...interface{}) (err error) { chats := make([]*Chat, 0, len(chatsId)) for _, id := range chatsId { @@ -213,7 +262,7 @@ func (zch *ZoneChatsHandler) GetChats(userId string, chatsId ...interface{}) (er err = fmt.Errorf("id of wrong type") return } - logger.Println("chat from get chats", id.(string)) + fmt.Println("chat from get chats", id.(string)) _ = atomicallyExecute(zch.ChatFlag, func() (err error) { if _, ok := zch.Chats[id.(string)]; ok { logger.Println(zch.Chats[id.(string)]) @@ -222,27 +271,36 @@ func (zch *ZoneChatsHandler) GetChats(userId string, chatsId ...interface{}) (er return }) } - answer := &ZoneResponse{ - Type: GET_CHATS_RESPONSE, - From: "", - To: "", - Payload: map[string]interface{}{ - "chats": chats, - }, - } - bs, jsonErr := json.Marshal(answer) - if jsonErr != nil { - return jsonErr - } - _ = atomicallyExecute(zch.Flag, func() (err error) { - if _, ok := zch.DataChannels[userId]; ok { - err = zch.DataChannels[userId].DataChannel.SendText(string(bs)) - if err != nil { - return - } + fmt.Println("first loop done") + for _, chat := range chats { + fmt.Println(chat.ChatId) + index,err := chat.Tracking.GetUserLastIndex(userId) + if err != nil { + fmt.Println("there") + fmt.Println(err) + return err + } + chat.DB.lock.RLock() + defer chat.DB.lock.RUnlock() + unread,err := chat.DB.calculateNewChatCount(uint64(index)) + if err != nil { + fmt.Println("over there") + fmt.Println(err) + return err + } + chat.LastReadIndex = index + chat.Unread = unread + } + fmt.Println(chats) + done,e := zch.sendDataChannelMessage(GET_CHATS_RESPONSE,"node",userId,map[string]interface{}{ + "chats": chats, + }) + select { + case <-done: + fmt.Println("done") + case terr :=<-e: + fmt.Println(terr) } - return - }) return } @@ -266,21 +324,25 @@ func (zch *ZoneChatsHandler) AddNewChat(chatName string, owner string, chatType if mkdirErr != nil { return mkdirErr } + mkdirErr = os.Mkdir(filepath.Join("data", "zones", zch.ZoneId, "chats", chatName,"__tracking__"), 0700) + if mkdirErr != nil { + return mkdirErr + } file, ferr := os.Create(filepath.Join("data", "zones", zch.ZoneId, "chats", chatName, "chatConfig.json")) if ferr != nil { return ferr } m := make([]string, 0, len(members)) for _, member := range members { - if _, ok := member.(string); ok { - m = append(m, member.(string)) + if mbr, ok := member.(string); ok && mbr != owner { + m = append(m, mbr) } } baseConfig := &ChatConfig{ ChatId: chatName, Owner: owner, ChatType: chatType, - Members: m, + Members: append(m,owner), } bs, jsonErr := json.Marshal(baseConfig) if jsonErr != nil { @@ -297,11 +359,19 @@ func (zch *ZoneChatsHandler) AddNewChat(chatName string, owner string, chatType if err != nil { return err } + zoneChatTrackingDB,err := NewZoneChatTracking(zch.ZoneId,chatName) + if err != nil { + return err + } + if err = zoneChatTrackingDB.Initialize(1,baseConfig.Members...); err != nil { + return err + } var c Chat if err = json.Unmarshal(bs, &c); err != nil { return err } c.DB = zoneChatDBHandler + c.Tracking = zoneChatTrackingDB _ = atomicallyExecute(zch.ChatFlag, func() (err error) { zch.Chats[c.ChatId] = &c return @@ -396,10 +466,10 @@ func (zch *ZoneChatsHandler) EditChatName(chatId string, newChatId string) (err } chatConfig.ChatId = newChatId bs, err = json.Marshal(&chatConfig) - if err = os.Rename(filepath.Join("data", "zones", zch.ZoneId, "chats", chatId), filepath.Join("data", "zones", zch.ZoneId, "chats", chatId)); err != nil { + if err = os.Rename(filepath.Join("data", "zones", zch.ZoneId, "chats", chatId), filepath.Join("data", "zones", zch.ZoneId, "chats", newChatId)); err != nil { return } - f, err := os.OpenFile(filepath.Join("data", "zones", zch.ZoneId, "chats", chatId, "chatConfig.json"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755) + f, err := os.OpenFile(filepath.Join("data", "zones", zch.ZoneId, "chats", newChatId, "chatConfig.json"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755) defer func() { _ = f.Close() }() @@ -415,6 +485,7 @@ func (zch *ZoneChatsHandler) EditChatName(chatId string, newChatId string) (err ChatType: chatConfig.ChatType, Members: chatConfig.Members, DB: zch.Chats[chatId].DB, + Tracking:zch.Chats[chatId].Tracking, } chat.DB.updateDbCallbackFolder(newChatId) _ = atomicallyExecute(zch.ChatFlag, func() (err error) { @@ -483,9 +554,10 @@ func (zch *ZoneChatsHandler) EditChatType(chatId string, chatType string) (err e chat := &Chat{ Owner: chatConfig.Owner, ChatId: chatConfig.ChatId, - ChatType: chatConfig.ChatType, + ChatType: chatType, Members: chatConfig.Members, DB: zch.Chats[chatId].DB, + Tracking:zch.Chats[chatId].Tracking, } switch chatType { case BROADCAST: @@ -500,6 +572,10 @@ func (zch *ZoneChatsHandler) EditChatType(chatId string, chatType string) (err e if pubErr := zch.SetChatPublicForUser(chatId, member); pubErr != nil { logger.Println(pubErr) } + zch.sendDataChannelMessage(CHAT_TYPE_EDITED, "node", member, map[string]interface{}{ + "chatId": chatId, + "chatType": chatType, + }) } case PRIVATE: var members = []string{} @@ -511,6 +587,10 @@ func (zch *ZoneChatsHandler) EditChatType(chatId string, chatType string) (err e if pubErr := zch.SetChatPrivateForUser(chatId, member); pubErr != nil { logger.Println(pubErr) } + zch.sendDataChannelMessage(CHAT_TYPE_EDITED, "node", member, map[string]interface{}{ + "chatId": chatId, + "chatType": chatType, + }) } } _ = atomicallyExecute(zch.ChatFlag, func() (err error) { @@ -573,14 +653,27 @@ memberLoop: ChatType: chatConfig.ChatType, Members: chatConfig.Members, DB: zch.Chats[chatId].DB, + Tracking: zch.Chats[chatId].Tracking, } + chat.DB.lock.Lock() + lastIndex := chat.DB.PreviousId + chat.DB.lock.Unlock() _ = atomicallyExecute(zch.ChatFlag, func() (err error) { zch.Chats[chatId] = chat return }) + var chmb []string + if chat.ChatType == PRIVATE { + chmb = chat.Members + } else { + chmb = zch.ZoneMembersId + } broadcastLoop: - for _, member := range chat.Members { + for _, member := range chmb { for _, m := range addedMembers { + if err = chat.Tracking.SetUserLastIndex(member,lastIndex); err != nil { + return + } if member == m { done, e := zch.sendDataChannelMessage(ADDED_IN_CHAT, "node", member, map[string]interface{}{ "chat": chat, @@ -665,10 +758,14 @@ func (zch *ZoneChatsHandler) RemoveChatMember(chatId string, chatMember string) ChatType: chatConfig.ChatType, Members: chatConfig.Members, DB: zch.Chats[chatId].DB, + Tracking: zch.Chats[chatId].Tracking, } zch.Chats[chatId] = chat return }) + if err = chat.Tracking.DeleteUserTracking(chatMember); err != nil { + return + } zch.sendZoneRequest(REMOVE_KNOWN_CHAT, "node", map[string]interface{}{ "userId": chatMember, "chatId": chatId, @@ -682,8 +779,14 @@ func (zch *ZoneChatsHandler) RemoveChatMember(chatId string, chatMember string) case err = <-e: logger.Println(err) } + var chmb []string + if chat.ChatType == PRIVATE { + chmb = chat.Members + } else { + chmb = zch.ZoneMembersId + } broadcastLoop: - for _, member := range chat.Members { + for _, member := range chmb { if member == chatMember { continue broadcastLoop } @@ -700,19 +803,58 @@ broadcastLoop: return } -func (zch *ZoneChatsHandler) ListLatestChatMessages(userId string, chatId string, lastIndex float64, limit float64) (err error) { +func(zch *ZoneChatsHandler) ReadLastMessage(userId,chatId string) (err error) { + err = atomicallyExecute(zch.ChatFlag, func() (err error) { + if chat, ok := zch.Chats[chatId]; ok { + err = chat.Tracking.SetUserLastIndex(userId,chat.DB.PreviousId) + } + return + }) + return +} + +func (zch *ZoneChatsHandler) ListLatestChatMessages(userId, chatId string, lastIndex, limit float64) (err error) { var list []*ChatMessage var i int + var done bool if err = atomicallyExecute(zch.ChatFlag, func() (err error) { - if _, ok := zch.Chats[chatId]; ok { - list, i, err = zch.Chats[chatId].DB.ListChatMessages(int(lastIndex), int(limit)) + if chat, ok := zch.Chats[chatId]; ok { + list, i, done, err = zch.Chats[chatId].DB.ListChatMessages(int(lastIndex), int(limit)) + if err != nil { + return + } + err = chat.Tracking.SetUserLastIndex(userId,chat.DB.PreviousId) } return }); err != nil { return } - done, e := zch.sendDataChannelMessage(CHAT_MEMBER_LIST, "node", userId, map[string]interface{}{ - "done": i == 0, + success, e := zch.sendDataChannelMessage(CHAT_MESSAGE_LIST, "node", userId, map[string]interface{}{ + "done": done || i <= 0, + "lastIndex": i - 1, + "chatId": chatId, + "chatMessages": list, + }) + select { + case <-success: + case err = <-e: + } + return +} + +func (zch *ZoneChatsHandler) ListLatestChatFiles(userId, chatId string, lastIndex, limit float64) (err error) { + var list []*ChatFile + var i int + if err = atomicallyExecute(zch.ChatFlag, func() (err error) { + if _, ok := zch.Chats[chatId]; ok { + list, i, err = zch.Chats[chatId].DB.ListChatFiles(int(lastIndex), int(limit)) + } + return + }); err != nil { + return + } + done, e := zch.sendDataChannelMessage(CHAT_FILES_LIST, "node", userId, map[string]interface{}{ + "done": i <= 0, "lastIndex": i, "chatId": chatId, "chatMessages": list, @@ -724,27 +866,33 @@ func (zch *ZoneChatsHandler) ListLatestChatMessages(userId string, chatId string return } -func (zch *ZoneChatsHandler) AddChatMessage(userId string, chatId string, content string, chatResponseId uint64, file *ChatFile) (err error) { +func (zch *ZoneChatsHandler) AddChatMessage(userId, chatId, content string, isResponse bool, chatResponseId uint64, file *ChatFile) (err error) { chatMessage := &ChatMessage{ Content: content, From: userId, + IsResponse: isResponse, ResponseOf: nil, File: file, Tags: make([]string, 0), Date: time.Now().Format("Mon, 02 Jan 2006 15:04:05 MST"), } + if err = atomicallyExecute(zch.ChatFlag, func() (err error) { - if _, ok := zch.Chats[chatId]; ok { - parentMessage, getErr := zch.Chats[chatId].DB.GetChatMessage(chatResponseId) - if err != nil { - if getErr != badger.ErrKeyNotFound { - return getErr + if chat, ok := zch.Chats[chatId]; ok { + if isResponse { + parentMessage, getErr := chat.DB.GetChatMessage(chatResponseId) + if err != nil { + if getErr != badger.ErrKeyNotFound { + return getErr + } } + chatMessage.ResponseOf = parentMessage } - chatMessage.ResponseOf = parentMessage if err = zch.Chats[chatId].DB.AddNewChatMessage(chatMessage); err != nil { return } + chatMessage.ID = zch.Chats[chatId].DB.PreviousId + } else { err = fmt.Errorf("no corresponding chats") } @@ -752,7 +900,6 @@ func (zch *ZoneChatsHandler) AddChatMessage(userId string, chatId string, conten }); err != nil { return } - chatMessage.ID = zch.Chats[chatId].DB.PreviousId _ = atomicallyExecute(zch.ChatFlag, func() (err error) { chat := zch.Chats[chatId] logger.Println(chat.ChatType) @@ -896,9 +1043,166 @@ func (zch *ZoneChatsHandler) RemoveAllUserChat(userId string) (err error) { return } +func (zch *ZoneChatsHandler) ConnectToChatFSInstance(channelId string, userId string, sdp string) (err error) { + err = atomicallyExecute(zch.ChatFSInstanceFlag, func() (err error) { + d, e := zch.ChatFSInstance.HandleOffer(context.Background(), channelId, userId, sdp, zch.HostId, zch.sendDataChannelMessage, zch.signalCandidate) + select { + case <-d: + case err = <-e: + } + return + }) + return +} + +func (zch *ZoneChatsHandler) LeaveChatFSInstance( + userId string) (err error) { + zch.ChatFSInstance.HandleLeavingMember(userId) + return +} + +func (zch *ZoneChatsHandler) DeleteChatMessage(key uint64, chatId string) (err error) { + err = atomicallyExecute(zch.ChatFlag, func() (err error) { + if _, ok := zch.Chats[chatId]; !ok { + err = fmt.Errorf("no file corresponding to id %s", chatId) + return + } + if err = zch.Chats[chatId].DB.DeleteChatMessage(key); err != nil { + return + } + if zch.Chats[chatId].ChatType == PRIVATE { + for _, member := range zch.Chats[chatId].Members { + d, e := zch.sendDataChannelMessage(CHAT_MESSAGE_DELETED, "node", member, map[string]interface{}{ + "chatId": chatId, + "messageId": key, + }) + select { + case <-d: + case tempErr := <-e: + logger.Println(tempErr) + } + } + } else { + for _, member := range zch.ZoneMembersId { + d, e := zch.sendDataChannelMessage(CHAT_MESSAGE_DELETED, "node", member, map[string]interface{}{ + "chatId": chatId, + "messageId": key, + }) + select { + case <-d: + case tempErr := <-e: + logger.Println(tempErr) + } + } + } + previousId := zch.Chats[chatId].DB.PreviousId + if previousId == key { + if err = zch.Chats[chatId].DB.revertPreviousId(); err != nil { + return + } + previousId = zch.Chats[chatId].DB.PreviousId + if previousId == 1 { + previousId = 0 + } + if err = zch.Chats[chatId].Tracking.RevertTrackingLastIndex(previousId); err != nil { + return + } + } + return + }) + return +} + +func (zch *ZoneChatsHandler) UpdateChatMessage(key uint64, chatId, newContent string) (err error) { + err = atomicallyExecute(zch.ChatFlag, func() (err error) { + if _, ok := zch.Chats[chatId]; !ok { + err = fmt.Errorf("no file corresponding to id %s", chatId) + return + } + if err = zch.Chats[chatId].DB.ModifyChatMessage(key, newContent); err != nil { + return + } + if zch.Chats[chatId].ChatType == PRIVATE { + for _, member := range zch.Chats[chatId].Members { + d, e := zch.sendDataChannelMessage(CHAT_MESSAGE_EDITED, "node", member, map[string]interface{}{ + "chatId": chatId, + "messageId": key, + "newContent": newContent, + }) + select { + case <-d: + case tempErr := <-e: + logger.Println(tempErr) + } + } + } else { + for _, member := range zch.ZoneMembersId { + d, e := zch.sendDataChannelMessage(CHAT_MESSAGE_EDITED, "node", member, map[string]interface{}{ + "chatId": chatId, + "messageId": key, + "newContent": newContent, + }) + select { + case <-d: + case tempErr := <-e: + logger.Println(tempErr) + } + } + } + return + }) + return +} + +func (zch *ZoneChatsHandler) DeleteChatFile(key uint64, fileName, chatId string) (err error) { + err = atomicallyExecute(zch.ChatFlag, func() (err error) { + if _, ok := zch.Chats[chatId]; !ok { + err = fmt.Errorf("no file corresponding to id %s", chatId) + return + } + if err = zch.Chats[chatId].DB.DeleteChatFile(fileName, key); err != nil { + return + } + if zch.Chats[chatId].ChatType == PRIVATE { + for _, member := range zch.Chats[chatId].Members { + d, e := zch.sendDataChannelMessage(CHAT_FILE_DELETED, "node", member, map[string]interface{}{ + "chatId": chatId, + "fileId": key, + "fileName": fileName, + }) + select { + case <-d: + case tempErr := <-e: + logger.Println(tempErr) + } + } + } else { + for _, member := range zch.ZoneMembersId { + d, e := zch.sendDataChannelMessage(CHAT_FILE_DELETED, "node", member, map[string]interface{}{ + "chatId": chatId, + "fileId": key, + "fileName": fileName, + }) + select { + case <-d: + case tempErr := <-e: + logger.Println(tempErr) + } + } + } + return + }) + return +} + func (zch *ZoneChatsHandler) handleZoneRequest(ctx context.Context, req *ZoneRequest) (err error) { logger.Println("got request in zone chat handler", req) switch req.ReqType { + case LEAVE_ZONE: + if err = verifyFieldsString(req.Payload, "userId"); err != nil { + return + } + err = zch.LeaveChatFSInstance(req.Payload["userId"].(string)) case string(REMOVED_ZONE_AUTHORIZED_MEMBER): if err = verifyFieldsString(req.Payload, "userId"); err != nil { return @@ -975,10 +1279,13 @@ func (zch *ZoneChatsHandler) handleZoneRequest(ctx context.Context, req *ZoneReq } err = zch.AddNewChat(req.Payload["chatId"].(string), req.Payload["owner"].(string), req.Payload["chatType"].(string), req.Payload["members"].([]interface{})) case GET_CHATS: + fmt.Println("got a get chat req") if err = verifyFieldsSliceInterface(req.Payload, "chatsId"); err != nil { return } + fmt.Println("calling get chat") err = zch.GetChats(req.From, req.Payload["chatsId"].([]interface{})...) + fmt.Println("get chat done") case LIST_LATEST_CHATS: if err = verifyFieldsString(req.Payload, "chatId"); err != nil { return @@ -988,16 +1295,37 @@ func (zch *ZoneChatsHandler) handleZoneRequest(ctx context.Context, req *ZoneReq } err = zch.ListLatestChatMessages(req.From, req.Payload["chatId"].(string), req.Payload["lastIndex"].(float64), req.Payload["limit"].(float64)) return + case LIST_LATEST_FILES: + if err = verifyFieldsString(req.Payload, "chatId"); err != nil { + return + } + if err = verifyFieldsFloat64(req.Payload, "lastIndex", "limit"); err != nil { + return + } + err = zch.ListLatestChatFiles(req.From, req.Payload["chatId"].(string), req.Payload["lastIndex"].(float64), req.Payload["limit"].(float64)) + return + case READ_LATEST_MESSAGE: + if err = verifyFieldsString(req.Payload, "chatId"); err != nil { + return + } + err = zch.ReadLastMessage(req.From,req.Payload["chatId"].(string)) case ADD_CHAT_MESSAGE: logger.Println("got request in zone chat handler", req) if err = verifyFieldsString(req.Payload, "chatId", "content"); err != nil { return } - if err = verifyFieldsFloat64(req.Payload, "parentChatId"); err != nil { + if err = verifyFieldsBool(req.Payload, "isResponse"); err != nil { return } + var parentChatId uint64 + if req.Payload["isResponse"].(bool) { + if err = verifyFieldsFloat64(req.Payload, "parentChatId"); err != nil { + return + } + parentChatId = uint64(req.Payload["parentChatId"].(float64)) + } var file *ChatFile = nil - if _,ok := req.Payload["file"]; ok { + if _, ok := req.Payload["file"]; ok { bs, jsonErr := json.Marshal(req.Payload["file"]) if jsonErr != nil { return jsonErr @@ -1009,7 +1337,114 @@ func (zch *ZoneChatsHandler) handleZoneRequest(ctx context.Context, req *ZoneReq } file = &f } - err = zch.AddChatMessage(req.From, req.Payload["chatId"].(string), req.Payload["content"].(string),uint64(req.Payload["parentChatId"].(float64)),file) + err = zch.AddChatMessage(req.From, req.Payload["chatId"].(string), req.Payload["content"].(string), req.Payload["isResponse"].(bool), parentChatId, file) + case DELETE_CHAT_MESSAGE: + if err = verifyFieldsString(req.Payload, "chatId"); err != nil { + return + } + if err = verifyFieldsFloat64(req.Payload, "messageId"); err != nil { + return + } + err = zch.DeleteChatMessage(uint64(req.Payload["messageId"].(float64)), req.Payload["chatId"].(string)) + case EDIT_CHAT_MESSAGE: + if err = verifyFieldsString(req.Payload, "chatId", "newContent"); err != nil { + return + } + if err = verifyFieldsFloat64(req.Payload, "messageId"); err != nil { + return + } + err = zch.UpdateChatMessage(uint64(req.Payload["messageId"].(float64)), req.Payload["chatId"].(string), req.Payload["newContent"].(string)) + case DELETE_CHAT_FILE: + if err = verifyFieldsString(req.Payload, "chatId", "fileName"); err != nil { + return + } + if err = verifyFieldsFloat64(req.Payload, "fileId"); err != nil { + return + } + err = zch.DeleteChatFile(uint64(req.Payload["fileId"].(float64)), req.Payload["fileName"].(string), req.Payload["chatId"].(string)) + case ZONE_UPLOAD_CHAT_FILE: + if err = verifyFieldsString(req.Payload, "chatId", "userId", "fileName"); err != nil { + return + } + err = zch.ChatFSInstance.SetupFileUpload(req.Payload["chatId"].(string), req.Payload["fileName"].(string), req.Payload["userId"].(string)) + case ZONE_DOWNLOAD_CHAT_FILE: + if err = verifyFieldsString(req.Payload, "chatId", "userId", "fileName"); err != nil { + return + } + err = zch.ChatFSInstance.SetupFileDownload(req.Payload["chatId"].(string), req.Payload["fileName"].(string), req.Payload["userId"].(string)) + case ZONE_UPLOAD_CHAT_FILE_DONE: + if err = verifyFieldsBool(req.Payload, "failed"); err != nil { + return + } + if err = verifyFieldsString(req.Payload, "path", "userId", "fileName", "type"); err != nil { + return + } + if err = verifyFieldsFloat64(req.Payload, "size"); err != nil { + return + } + if _, ok := req.Payload["chatFile"]; !ok { + err = fmt.Errorf("no field chatFile in request payload") + return + } + if req.Payload["failed"].(bool) { + logger.Println(zch.ChatFSInstance.FileUploadFailed(req.Payload["path"].(string), req.Payload["fileName"].(string), req.Payload["userId"].(string))) + } else { + defer func() { + logger.Println(zch.ChatFSInstance.FileUploadDone(req.Payload["path"].(string), req.Payload["fileName"].(string), req.Payload["userId"].(string))) + }() + } + case string(ZONE_CHAT_WEBRTC_OFFER): + if err = verifyFieldsString(req.Payload, "channelId", "userId", "sdp"); err != nil { + return + } + err = zch.ConnectToChatFSInstance(req.Payload["channelId"].(string), req.Payload["userId"].(string), req.Payload["sdp"].(string)) + case string(ZONE_CHAT_WEBRTC_COUNTER_OFFER): + logger.Println("handling fs instance counter offer") + if err = verifyFieldsString(req.Payload, "channelId", "userId"); err != nil { + return + } + err = atomicallyExecute(zch.ChatFSInstanceFlag, func() (err error) { + err = zch.ChatFSInstance.HandleCounterOffer(context.Background(), req.Payload["userId"].(string), zch.sendDataChannelMessage) + return + }) + case string(ZONE_CHAT_WEBRTC_RENNEGOTIATION_OFFER): + if err = verifyFieldsString(req.Payload, "channelId", "userId", "sdp"); err != nil { + return + } + err = atomicallyExecute(zch.ChatFSInstanceFlag, func() (err error) { + err = zch.ChatFSInstance.HandleRennegotiationOffer(req.Payload["userId"].(string), req.Payload["sdp"].(string), zch.sendDataChannelMessage) + return + }) + case string(ZONE_CHAT_WEBRTC_RENNEGOTIATION_ANSWER): + if err = verifyFieldsString(req.Payload, "channelId", "userId", "sdp"); err != nil { + return + } + err = atomicallyExecute(zch.ChatFSInstanceFlag, func() (err error) { + err = zch.ChatFSInstance.HandleRennegotiationAnswer(req.Payload["userId"].(string), req.Payload["sdp"].(string)) + return + }) + case string(ZONE_CHAT_WEBRTC_CANDIDATE): + logger.Println("handling fs instance webrtc candidate") + logger.Println(req.Payload) + if err = verifyFieldsString(req.Payload, FROM, "candidate", "sdpMLineIndex", "sdpMid", "channelId", "userId"); err != nil { + return + } + logger.Println(req.Payload) + i, convErr := strconv.Atoi(req.Payload["sdpMLineIndex"].(string)) + if convErr != nil { + return convErr + } + SDPMLineIndex := uint16(i) + sdpMid := req.Payload["sdpMid"].(string) + logger.Println(sdpMid, SDPMLineIndex) + err = atomicallyExecute(zch.ChatFSInstanceFlag, func() (err error) { + err = zch.ChatFSInstance.AddCandidate(&webrtc.ICECandidateInit{ + Candidate: req.Payload["candidate"].(string), + SDPMid: &sdpMid, + SDPMLineIndex: &SDPMLineIndex, + }, req.Payload["userId"].(string)) + return + }) } return -} +} \ No newline at end of file diff --git a/zoneFSHandler.go b/zoneFSHandler.go index f4e6737..df141b1 100644 --- a/zoneFSHandler.go +++ b/zoneFSHandler.go @@ -96,7 +96,7 @@ type ZoneFSEntity struct { } // NewZoneFileHandler: factory function to create a zone file handler the name of the parameters are explicit, this is the only way to safely create a ZoneFSEntity -func NewZoneFileHandler(hostId string, zoneId string, owner string, authorizedMembers []string, dataChannels map[string]*DataChannel, flag *uint32) (zoneFileHandler *ZoneFileHandler, err error) { +func NewZoneFileHandler(_ string, zoneId string, owner string, authorizedMembers []string, dataChannels map[string]*DataChannel, flag *uint32) (zoneFileHandler *ZoneFileHandler, err error) { db, err := NewZoneFilesDBHandler(zoneId) if err != nil { return @@ -219,7 +219,7 @@ func (zfh *ZoneFileHandler) signalCandidate(from string, to string, candidate *w "to": to, "candidate": candidate.ToJSON().Candidate, "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), }) select { case <-d: @@ -560,6 +560,18 @@ func (zfh *ZoneFileHandler) RemoveFolderMember(userId string, path string, folde logger.Println(sendErr) } } + for _, member := range members { + if _, ok := member.(string); ok { + done, errCh := zfh.sendDataChannelMessage(REMOVE_FS_ENTITY_MEMBERS_DONE, "node", member.(string), map[string]interface{}{ + "path": filepath.Join(path, folderName), + }) + select { + case <-done: + case sendErr := <-errCh: + logger.Println(sendErr) + } + } + } return } @@ -789,14 +801,16 @@ func (zfh *ZoneFileHandler) CopyDir(src, dst string, init bool, fsEntity *ZoneFS } } } - for member := range fsEntity.Members { - done, errCh := zfh.sendDataChannelMessage(COPY_FOLDER_DONE, "node", member, map[string]interface{}{ - "path": dst, - }) - select { - case <-done: - case sendErr := <-errCh: - logger.Println(sendErr) + if fsEntity != nil { + for member := range fsEntity.Members { + done, errCh := zfh.sendDataChannelMessage(COPY_FOLDER_DONE, "node", member, map[string]interface{}{ + "path": dst, + }) + select { + case <-done: + case sendErr := <-errCh: + logger.Println(sendErr) + } } } return @@ -845,27 +859,41 @@ func (zch *ZoneFileHandler) SetPublicRootFolders(user string) (err error) { func (zfh *ZoneFileHandler) handleZoneRequest(c context.Context, req *ZoneRequest) (err error) { switch req.ReqType { - case LEAVE_ZONE: - logger.Println("*-----------------handling leaving zone---------------*") + case string(REMOVED_ZONE_AUTHORIZED_MEMBER): if err = verifyFieldsString(req.Payload, "userId"); err != nil { return } - err = zfh.LeaveFSInstance(req.Payload["userId"].(string)) - case ZONE_UPLOAD_FILE_DONE: - if err = verifyFieldsString(req.Payload, "path", "userId", "fileName", "type"); err != nil { + var index int + for i, m := range zfh.ZoneMembersId { + if m == req.Payload["userId"].(string) { + index = i + break + } + } + zfh.ZoneMembersId = append(zfh.ZoneMembersId[:index], zfh.ZoneMembersId[index+1:]...) + err = zfh.DeleteFolder("", req.Payload["userId"].(string)) + case string(NEW_AUTHORIZED_ZONE_MEMBER): + if err = verifyFieldsString(req.Payload, "userId"); err != nil { return } - if err = verifyFieldsFloat64(req.Payload, "size"); err != nil { - return + var contain bool + for _, m := range zfh.ZoneMembersId { + if m == req.Payload["userId"].(string) { + contain = true + break + } } - err = zfh.CreateFile(req.Payload["path"].(string), req.Payload["fileName"].(string), &ZoneFSEntity{ - Name: req.Payload["fileName"].(string), + if !contain { + zfh.ZoneMembersId = append(zfh.ZoneMembersId, req.Payload["userId"].(string)) + } + err = zfh.DB.AddNewFSEntity("", &ZoneFSEntity{ + Name: req.Payload["userId"].(string), Owner: req.Payload["userId"].(string), - Type: req.Payload["type"].(string), - Size: uint64(req.Payload["size"].(float64)), + Type: PRIVATE, + Folder: true, ModTime: time.Now().Format(time.UnixDate), CreationTime: time.Now().Format(time.UnixDate), - Folder: false, + Size: 0, Members: map[string]*FSEntityAccessRights{ req.Payload["userId"].(string): { Read: true, @@ -875,6 +903,46 @@ func (zfh *ZoneFileHandler) handleZoneRequest(c context.Context, req *ZoneReques }, }, }) + case LEAVE_ZONE: + logger.Println("*-----------------handling leaving zone---------------*") + if err = verifyFieldsString(req.Payload, "userId"); err != nil { + return + } + err = zfh.LeaveFSInstance(req.Payload["userId"].(string)) + case ZONE_UPLOAD_FILE_DONE: + if err = verifyFieldsBool(req.Payload, "failed"); err != nil { + return + } + if err = verifyFieldsString(req.Payload, "path", "userId", "fileName", "type"); err != nil { + return + } + if err = verifyFieldsFloat64(req.Payload, "size"); err != nil { + return + } + if req.Payload["failed"].(bool) { + logger.Println(zfh.FSInstance.FileUploadFailed(req.Payload["path"].(string), req.Payload["fileName"].(string), req.Payload["userId"].(string))) + } else { + defer func() { + logger.Println(zfh.FSInstance.FileUploadDone(req.Payload["path"].(string), req.Payload["fileName"].(string), req.Payload["userId"].(string))) + }() + err = zfh.CreateFile(req.Payload["path"].(string), req.Payload["fileName"].(string), &ZoneFSEntity{ + Name: req.Payload["fileName"].(string), + Owner: req.Payload["userId"].(string), + Type: req.Payload["type"].(string), + Size: uint64(req.Payload["size"].(float64)), + ModTime: time.Now().Format(time.UnixDate), + CreationTime: time.Now().Format(time.UnixDate), + Folder: false, + Members: map[string]*FSEntityAccessRights{ + req.Payload["userId"].(string): { + Read: true, + Write: true, + Download: true, + Rename: true, + }, + }, + }) + } case ZONE_UPLOAD_FILE: if err = verifyFieldsString(req.Payload, "path", "userId", "fileName"); err != nil { return @@ -1087,22 +1155,22 @@ func (zfh *ZoneFileHandler) handleZoneRequest(c context.Context, req *ZoneReques case string(ZONE_FS_WEBRTC_CANDIDATE): logger.Println("handling fs instance webrtc candidate") logger.Println(req.Payload) - if err = verifyFieldsString(req.Payload, FROM, "candidate", "sdpMlineIndex", "sdpMid", "channelId", "userId"); err != nil { + if err = verifyFieldsString(req.Payload, FROM, "candidate", "sdpMLineIndex", "sdpMid", "channelId", "userId"); err != nil { return } logger.Println(req.Payload) - i, convErr := strconv.Atoi(req.Payload["sdpMlineIndex"].(string)) + i, convErr := strconv.Atoi(req.Payload["sdpMLineIndex"].(string)) if convErr != nil { return convErr } - sdpMlineIndex := uint16(i) + SDPMLineIndex := uint16(i) sdpMid := req.Payload["sdpMid"].(string) - logger.Println(sdpMid, sdpMlineIndex) + logger.Println(sdpMid, SDPMLineIndex) err = atomicallyExecute(zfh.FSInstanceFlag, func() (err error) { err = zfh.FSInstance.AddCandidate(&webrtc.ICECandidateInit{ Candidate: req.Payload["candidate"].(string), SDPMid: &sdpMid, - SDPMLineIndex: &sdpMlineIndex, + SDPMLineIndex: &SDPMLineIndex, }, req.Payload["userId"].(string)) return }) diff --git a/zoneFSInstance.go b/zoneFSInstance.go index 559e6af..c030a44 100644 --- a/zoneFSInstance.go +++ b/zoneFSInstance.go @@ -24,13 +24,12 @@ const ( ZONE_FS_WEBRTC_CANDIDATE ReqType = "zone_fs_webrtc_candidate" ) -const () - type FSInstance struct { ZoneID string `json:"id"` Owner string `json:"owner"` Members []string `json:"members"` OpenFiles map[string]*os.File `json:"-"` + OpenFilesForUser map[string][]string `json:"-"` localSD map[string]*webrtc.SessionDescription `json:"-"` rtcPeerConnections map[string]*ZoneRTCPeerConnection `json:"-"` zoneFSDataChannels map[string]map[string]*DataChannel `json:"-"` @@ -56,6 +55,7 @@ func NewFSInstance(id, owner string, members []string) (audioChannel *FSInstance Owner: owner, Members: members, OpenFiles: make(map[string]*os.File), + OpenFilesForUser: make(map[string][]string), localSD: make(map[string]*webrtc.SessionDescription), rtcPeerConnections: make(map[string]*ZoneRTCPeerConnection), zoneFSDataChannels: make(map[string]map[string]*DataChannel), @@ -79,6 +79,9 @@ func (fs *FSInstance) SetupFileUpload(path, filename, userId string) (err error) } else if rErr != nil { return rErr } + if err = os.Remove(concretePath); err != nil { + logger.Println(err) + } file, err := os.OpenFile(concretePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0755) if err != nil { return @@ -87,11 +90,11 @@ func (fs *FSInstance) SetupFileUpload(path, filename, userId string) (err error) fs.OpenFiles[filename] = file return }) - err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { - if pc, ok := fs.rtcPeerConnections[userId]; ok { + setupDataChan := func(id, fileName string) (err error) { + if pc, ok := fs.rtcPeerConnections[id]; ok { maxRetransmits := uint16(100) var dc *webrtc.DataChannel - dc, err = pc.CreateDataChannel(filename, &webrtc.DataChannelInit{ + dc, err = pc.CreateDataChannel(fileName, &webrtc.DataChannelInit{ MaxRetransmits: &maxRetransmits, }) if err != nil { @@ -100,34 +103,75 @@ func (fs *FSInstance) SetupFileUpload(path, filename, userId string) (err error) dc.OnOpen(func() { logger.Println("!-----------------------------!") logger.Printf("datachannel with id %s is now open\n", dc.Label()) + logger.Println("updated") logger.Println("!-----------------------------!") }) dc.OnMessage(func(msg webrtc.DataChannelMessage) { + logger.Println(msg) _, _ = file.Write(msg.Data) }) dc.OnClose(func() { + //fmt.Println("closing datachannel with id", dc.Label()) _ = atomicallyExecute(fs.filesFlag, func() (err error) { - if f, ok := fs.OpenFiles[filename]; ok { + if f, ok := fs.OpenFiles[fileName]; ok { err = f.Close() } - delete(fs.OpenFiles, filename) + delete(fs.OpenFiles, fileName) return }) + _ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + delete(fs.zoneFSDataChannels[userId], fileName) + return + }) + dc.Close() }) err = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { - if _, ok := fs.zoneFSDataChannels[userId]; !ok { - err = fmt.Errorf("no corresponding map entry in zoneFSDataChannels for id %s", userId) - return + if _, ok := fs.zoneFSDataChannels[id]; !ok { + fs.zoneFSDataChannels[id] = make(map[string]*DataChannel) } l := int32(0) - fs.zoneFSDataChannels[userId][dc.Label()] = &DataChannel{ + fs.zoneFSDataChannels[id][dc.Label()] = &DataChannel{ DataChannel: dc, l: &l, } return }) } else { - err = fmt.Errorf("no peerconnection for id %s", userId) + err = fmt.Errorf("no peerconnection for id %s", id) + } + return + } + err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { + err = setupDataChan(userId, filename) + return + }) + return +} + +func (fs *FSInstance) FileUploadDone(path, filename, userId string) (err error) { + err = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + if _, ok := fs.zoneFSDataChannels[userId]; ok { + if dc, ok := fs.zoneFSDataChannels[userId][filename]; ok { + err = dc.DataChannel.Close() + return + } + } + return + }) + return +} + +func (fs *FSInstance) FileUploadFailed(path, filename, userId string) (err error) { + concretePath := filepath.Join("data", "zones", fs.ZoneID, "fs", path, "__files__", filename) + if err = os.Remove(concretePath); err != nil { + return + } + err = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + if _, ok := fs.zoneFSDataChannels[userId]; ok { + if dc, ok := fs.zoneFSDataChannels[userId][filename]; ok { + err = dc.DataChannel.Close() + return + } } return }) @@ -142,76 +186,133 @@ func (fs *FSInstance) SetupFileDownload(path, filename, userId string) (err erro } _ = atomicallyExecute(fs.filesFlag, func() (err error) { fs.OpenFiles[filename] = file + if _, ok := fs.OpenFilesForUser[userId]; !ok { + fs.OpenFilesForUser[userId] = []string{} + } + fs.OpenFilesForUser[userId] = append(fs.OpenFilesForUser[userId], filename) return }) + var dc *webrtc.DataChannel err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { if pc, ok := fs.rtcPeerConnections[userId]; ok { maxRetransmits := uint16(100) - var dc *webrtc.DataChannel dc, err = pc.CreateDataChannel(filename, &webrtc.DataChannelInit{ MaxRetransmits: &maxRetransmits, }) if err != nil { return } - dc.SetBufferedAmountLowThreshold(16000000) - bufferedAmountLock := make(chan struct{}) - done := make(chan struct{}) - dc.OnOpen(func() { - go func() { - defer func() { - bufferedAmountLock = nil - }() - r := bufio.NewReader(file) - buf := make([]byte, 0, 60000) - for { - n, readErr := r.Read(buf[:cap(buf)]) - buf = buf[:n] - if n == 0 { - if err == nil { - logger.Println("n is 0 weird") - break - } - if err == io.EOF { - break - } - logger.Println(readErr) - return - } - if err = dc.Send(buf); err != nil { - logger.Println(err) - } - if dc.BufferedAmount() > dc. - BufferedAmountLowThreshold() { - <-bufferedAmountLock - } - } - logger.Println("done") - _ = dc.SendText("done") - <-time.After(time.Second * 5) - _ = dc.Close() - }() - }) - dc.OnBufferedAmountLow(func() { - bufferedAmountLock <- struct{}{} - }) - dc.OnClose(func() { - done <- struct{}{} - defer close(done) - _ = atomicallyExecute(fs.filesFlag, func() (err error) { - if f, ok := fs.OpenFiles[filename]; ok { - err = f.Close() - } - delete(fs.OpenFiles, filename) - return - }) - - }) - } else { - err = fmt.Errorf("no peerconnection for id %s", userId) } return }) + if dc != nil { + dc.SetBufferedAmountLowThreshold(15000000) + bufferedAmountLock := make(chan struct{}) + done := make(chan struct{}) + dc.OnOpen(func() { + go func() { + defer func() { + close(bufferedAmountLock) + bufferedAmountLock = nil + _ = atomicallyExecute(fs.filesFlag, func() (err error) { + if f, ok := fs.OpenFiles[filename]; ok { + err = f.Close() + } + delete(fs.OpenFiles, filename) + if _, ok := fs.OpenFilesForUser[userId]; ok { + var index int + for i, v := range fs.OpenFilesForUser[userId] { + if v == filename { + index = i + break + } + } + if len(fs.OpenFilesForUser[userId]) > 1 { + fs.OpenFilesForUser[userId] = append(fs.OpenFilesForUser[userId][:index], fs.OpenFilesForUser[userId][:index+1]...) + } else { + delete(fs.OpenFilesForUser, userId) + } + } + return + }) + }() + r := bufio.NewReader(file) + buf := make([]byte, 0, 15000) + sendingLoop: + for { + n, readErr := r.Read(buf[:cap(buf)]) + buf = buf[:n] + if n == 0 { + if err == nil { + logger.Println("n is 0 weird") + break + } + if err == io.EOF { + break + } + logger.Println(readErr) + return + } + if err = dc.Send(buf); err != nil { + dc.Close() + logger.Println(err) + break sendingLoop + } + if dc.BufferedAmount() > dc. + BufferedAmountLowThreshold() { + <-bufferedAmountLock + } + } + logger.Println("done") + <-time.After(4*time.Second) + _ = dc.SendText("done") + <-time.After(time.Second) + _ = dc.Close() + _ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + if _, ok := fs.zoneFSDataChannels[userId]; ok { + delete(fs.zoneFSDataChannels[userId], dc.Label()) + } + return + }) + }() + }) + dc.OnBufferedAmountLow(func() { + if bufferedAmountLock != nil { + bufferedAmountLock <- struct{}{} + } + }) + dc.OnClose(func() { + done <- struct{}{} + defer close(done) + _ = atomicallyExecute(fs.filesFlag, func() (err error) { + if f, ok := fs.OpenFiles[filename]; ok { + err = f.Close() + } + delete(fs.OpenFiles, filename) + return + }) + }) + err = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { + if _, ok := fs.zoneFSDataChannels[userId]; !ok { + fs.zoneFSDataChannels[userId] = make(map[string]*DataChannel) + } + l := int32(0) + fs.zoneFSDataChannels[userId][dc.Label()] = &DataChannel{ + DataChannel: dc, + l: &l, + } + return + }) + } else { + err = fmt.Errorf("datachannel not created") + _ = atomicallyExecute(fs.filesFlag, func() (err error) { + if file, ok := fs.OpenFiles[filename]; ok { + file.Close() + } + delete(fs.OpenFiles, filename) + return + }) + } return } @@ -244,10 +345,10 @@ func (fs *FSInstance) HandleOffer(ctx context.Context, channelId, userId, sdp, h errCh <- err return } - _ = atomicallyExecute(fs.localSDMapFlag, func() (err error) { - fs.localSD[userId] = &rawAnswer + if err = peerConnection.SetLocalDescription(rawAnswer); err != nil { + errCh <- err return - }) + } _, _ = sendDCMessage(string(ZONE_FS_WEBRTC_ANSWER), hostId, userId, map[string]interface{}{ "to": userId, "from": fs.ZoneID, @@ -261,25 +362,25 @@ func (fs *FSInstance) HandleOffer(ctx context.Context, channelId, userId, sdp, h } func (fs *FSInstance) HandleCounterOffer(ctx context.Context, userId string, sendDCMessage SendDCMessageFunc) (err error) { - if err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { - if _, ok := fs.rtcPeerConnections[userId]; !ok { - err = fmt.Errorf("no field corresponding peer connection for id %s", userId) - return - } - logger.Println("handling counter offer") - connection := fs.rtcPeerConnections[userId] - err = atomicallyExecute(fs.localSDMapFlag, func() (err error) { - err = connection.SetLocalDescription(*fs.localSD[userId]) - return - }) - return - }); err != nil { - return - } - _ = atomicallyExecute(fs.localSDMapFlag, func() (err error) { - delete(fs.localSD, userId) - return - }) + // if err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { + // if _, ok := fs.rtcPeerConnections[userId]; !ok { + // err = fmt.Errorf("no field corresponding peer connection for id %s", userId) + // return + // } + // logger.Println("handling counter offer") + // connection := fs.rtcPeerConnections[userId] + // err = atomicallyExecute(fs.localSDMapFlag, func() (err error) { + // err = connection.SetLocalDescription(*fs.localSD[userId]) + // return + // }) + // return + // }); err != nil { + // return + // } + // _ = atomicallyExecute(fs.localSDMapFlag, func() (err error) { + // delete(fs.localSD, userId) + // return + // }) if err = atomicallyExecute(fs.candidateFlag, func() (err error) { for _, candidate := range fs.pendingCandidates[userId] { logger.Println("sending candidate to", userId, candidate) @@ -288,7 +389,7 @@ func (fs *FSInstance) HandleCounterOffer(ctx context.Context, userId string, sen "to": userId, "candidate": candidate.ToJSON().Candidate, "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), }) select { case <-d: @@ -310,12 +411,12 @@ func (fs *FSInstance) HandleRennegotiationOffer(from, sdp string, sendDCMessage err = fmt.Errorf("no corresponding peer connection for id %s", from) return } - fs.rtcPeerConnections[from].makingOfferLock.Lock() - if fs.rtcPeerConnections[from].makingOffer { - fs.rtcPeerConnections[from].makingOfferLock.Unlock() - return fmt.Errorf("already making an offer or state is stable") - } - fs.rtcPeerConnections[from].makingOfferLock.Unlock() + // fs.rtcPeerConnections[from].makingOfferLock.Lock() + // if fs.rtcPeerConnections[from].makingOffer { + // fs.rtcPeerConnections[from].makingOfferLock.Unlock() + // return fmt.Errorf("already making an offer or state is stable") + // } + // fs.rtcPeerConnections[from].makingOfferLock.Unlock() if err = fs.rtcPeerConnections[from].SetRemoteDescription(webrtc.SessionDescription{SDP: sdp, Type: webrtc.SDPTypeOffer}); err != nil { return } @@ -452,7 +553,7 @@ func (fs *FSInstance) createPeerConnection(target, from string, peerType webrtc. peerConnection.OnConnectionStateChange(func(pcs webrtc.PeerConnectionState) { if pcs == webrtc.PeerConnectionStateClosed || pcs == webrtc.PeerConnectionStateDisconnected || pcs == webrtc.PeerConnectionStateFailed { logger.Println(pcs) - fs.HandleLeavingMember(target) + //fs.HandleLeavingMember(target) } }) peerConnection.OnICEConnectionStateChange(func(is webrtc.ICEConnectionState) { @@ -479,60 +580,38 @@ func (fs *FSInstance) createPeerConnection(target, from string, peerType webrtc. return }) }) - peerConnection.OnNegotiationNeeded(func() { - logger.Println("---------------- rennego is needed -----------") - _ = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { - logger.Println("----------------- sending renego to peer with id", target) - if peerConnection.SignalingState() == webrtc.SignalingStateStable { - localSd, localSdErr := peerConnection.CreateOffer(nil) - if localSdErr != nil { - logger.Println(localSdErr) - return localSdErr - } - if err = peerConnection.SetLocalDescription(localSd); err != nil { - logger.Println(err) - return - } - d, e := sendDCMessage(string(ZONE_FS_WEBRTC_RENNEGOTIATION_OFFER), fs.ZoneID, target, map[string]interface{}{ - "from": fs.ZoneID, - "to": target, - "sdp": localSd.SDP, - }) - select { - case <-d: - case err = <-e: - logger.Println(err) - } - } - return - }) - }) + // peerConnection.OnNegotiationNeeded(func() { + // logger.Println("---------------- rennego is needed -----------") + // _ = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { + // logger.Println("----------------- sending renego to peer with id", target) + // if peerConnection.SignalingState() == webrtc.SignalingStateStable { + // localSd, localSdErr := peerConnection.CreateOffer(nil) + // if localSdErr != nil { + // logger.Println(localSdErr) + // return localSdErr + // } + // if err = peerConnection.SetLocalDescription(localSd); err != nil { + // logger.Println(err) + // return + // } + // d, e := sendDCMessage(string(ZONE_FS_WEBRTC_RENNEGOTIATION_OFFER), fs.ZoneID, target, map[string]interface{}{ + // "from": fs.ZoneID, + // "to": target, + // "sdp": localSd.SDP, + // }) + // select { + // case <-d: + // case err = <-e: + // logger.Println(err) + // } + // } + // return + // }) + // }) return } func (fs *FSInstance) HandleLeavingMember(id string) { - if err := atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { - if _, ok := fs.rtcPeerConnections[id]; !ok { - err = fmt.Errorf("no corresponding peerconnection for audio channel leaving member") - } - return - }); err != nil { - logger.Println(err) - } else { - defer func() { - _ = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { - if _, ok := fs.rtcPeerConnections[id]; ok { - if closeErr := fs.rtcPeerConnections[id].Close(); closeErr != nil { - err = closeErr - logger.Println("peer connection close error", closeErr) - } - } - delete(fs.rtcPeerConnections, id) - return - }) - }() - } - logger.Printf("peer %s is leaving the squad\n", id) _ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) { if _, ok := fs.zoneFSDataChannels[id]; ok { for _, dc := range fs.zoneFSDataChannels[id] { @@ -542,14 +621,32 @@ func (fs *FSInstance) HandleLeavingMember(id string) { delete(fs.zoneFSDataChannels, id) return }) - _ = atomicallyExecute(fs.localSDMapFlag, func() (err error) { - delete(fs.localSD, id) + logger.Println("chatfs datachannels cleaned") + _ = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) { + if pc, ok := fs.rtcPeerConnections[id]; ok { + if closeErr := pc.Close(); closeErr != nil { + err = closeErr + logger.Println("peer connection close error", closeErr) + } + } + delete(fs.rtcPeerConnections, id) return }) + logger.Println("chats perrconnections cleaned") _ = atomicallyExecute(fs.candidateFlag, func() (err error) { delete(fs.pendingCandidates, id) return }) + _ = atomicallyExecute(fs.filesFlag, func() (err error) { + for _, openFile := range fs.OpenFilesForUser[id] { + if f, ok := fs.OpenFiles[openFile]; ok { + _ = f.Close() + } + delete(fs.OpenFiles, openFile) + } + delete(fs.OpenFilesForUser, id) + return + }) } func (fs *FSInstance) HandleDataChannelEvents(from, eventId string, payload map[string]interface{}) (err error) { diff --git a/zoneGrpcMiddleware.go b/zoneGrpcMiddleware.go index 6b20c4b..6de6a93 100644 --- a/zoneGrpcMiddleware.go +++ b/zoneGrpcMiddleware.go @@ -2,6 +2,7 @@ package localserver import ( "context" + "encoding/json" "strconv" "github.com/pion/webrtc/v3" @@ -23,11 +24,13 @@ const ( NEW_ZONE ReqType = "new_zone" NEW_AUTHORIZED_ZONE_MEMBER ReqType = "new_authorized_zone_member" REMOVED_ZONE_AUTHORIZED_MEMBER ReqType = "removed_zone_authorized_member" + DELETE_ZONE = "delete_zone" + DISCONNECT_ZONE_MEMBER = "disconnect_zone_member" ) type ZoneGrpcMiddleware struct { Manager *ZoneManager - stream GrpcManager_LinkClient + stream SignalingService_LinkClient } func NewZoneGrpcMiddleware(manager *ZoneManager) (zoneGrpcMiddleware *ZoneGrpcMiddleware) { @@ -38,55 +41,72 @@ func NewZoneGrpcMiddleware(manager *ZoneManager) (zoneGrpcMiddleware *ZoneGrpcMi } func (zm *ZoneGrpcMiddleware) signalCandidate(to string, candidate *webrtc.ICECandidate) (err error) { - err = zm.stream.Send(&Request{ - Type: string(ZONE_WEBRTC_CANDIDATE), - From: zm.Manager.ID, - Token: "none", - Payload: map[string]string{ - "from": zm.Manager.ID, - "to": to, - "candidate": candidate.ToJSON().Candidate, - "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), - }, + bs, err := json.Marshal(map[string]string{ + "from": zm.Manager.ID, + "to": to, + "candidate": candidate.ToJSON().Candidate, + "sdpMid": *candidate.ToJSON().SDPMid, + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), + }) + if err != nil { + return + } + err = zm.stream.Send(&SignalingMessage{ + Type: string(ZONE_WEBRTC_CANDIDATE), + From: zm.Manager.ID, + To: to, + Payload: bs, }) return } -func (zm *ZoneGrpcMiddleware) Process(ctx context.Context, req *Response, stream GrpcManager_LinkClient) (err error) { +func (zm *ZoneGrpcMiddleware) Process(ctx context.Context, req *SignalingMessage, stream SignalingService_LinkClient) (err error) { done, errCh := make(chan struct{}), make(chan error) go func() { + var payload map[string]string + if e := json.Unmarshal(req.Payload, &payload); err != nil { + errCh <- e + return + } switch req.Type { case string(INCOMING_ZONE_MEMBER): - case string(LEAVING_ZONE_MEMBER): - if err := validateRequest(req.GetPayload(), "zoneId", "userId"); err != nil { + case string(DELETE_ZONE): + if err := validateRequest(payload, "zoneId"); err != nil { return } - if err := zm.Manager.HandleLeavingMember(req.Payload["userId"], req.Payload["zoneId"]); err != nil { + if err := zm.Manager.DeleteZone(payload["zoneId"]); err != nil { + errCh <- err + return + } + case string(LEAVING_ZONE_MEMBER): + if err := validateRequest(payload, "zoneId"); err != nil { + return + } + if err := zm.Manager.HandleLeavingMember(req.GetFrom(), payload["zoneId"]); err != nil { errCh <- err return } case string(REMOVED_ZONE_AUTHORIZED_MEMBER): - if err := validateRequest(req.GetPayload(), "zoneId", "userId"); err != nil { + if err := validateRequest(payload, "zoneId", "userId"); err != nil { return } if err = atomicallyExecute(zm.Manager.zoneFlag, func() (err error) { reqChan := make(chan *ZoneRequest) - done, e := zm.Manager.Zones[req.Payload["zoneId"]].ZoneRequestScheduler.Schedule(reqChan) + done, e := zm.Manager.Zones[payload["zoneId"]].ZoneRequestScheduler.Schedule(reqChan) go func() { defer close(reqChan) reqChan <- &ZoneRequest{ ReqType: string(REMOVE_USER), - From: req.Payload["userId"], + From: payload["userId"], Payload: map[string]interface{}{ - "userId": req.Payload["userId"], + "userId": payload["userId"], }, } reqChan <- &ZoneRequest{ ReqType: string(REMOVED_ZONE_AUTHORIZED_MEMBER), - From: req.Payload["userId"], + From: payload["userId"], Payload: map[string]interface{}{ - "userId": req.Payload["userId"], + "userId": payload["userId"], }, } }() @@ -100,26 +120,26 @@ func (zm *ZoneGrpcMiddleware) Process(ctx context.Context, req *Response, stream return } case string(NEW_AUTHORIZED_ZONE_MEMBER): - if err := validateRequest(req.GetPayload(), "zoneId", "userId"); err != nil { + if err := validateRequest(payload, "zoneId", "userId"); err != nil { return } if err = atomicallyExecute(zm.Manager.zoneFlag, func() (err error) { reqChan := make(chan *ZoneRequest) - done, e := zm.Manager.Zones[req.Payload["zoneId"]].ZoneRequestScheduler.Schedule(reqChan) + done, e := zm.Manager.Zones[payload["zoneId"]].ZoneRequestScheduler.Schedule(reqChan) go func() { defer close(reqChan) reqChan <- &ZoneRequest{ ReqType: string(ADD_USER), - From: req.Payload["userId"], + From: payload["userId"], Payload: map[string]interface{}{ - "userId": req.Payload["userId"], + "userId": payload["userId"], }, } reqChan <- &ZoneRequest{ ReqType: string(NEW_AUTHORIZED_ZONE_MEMBER), - From: req.Payload["userId"], + From: payload["userId"], Payload: map[string]interface{}{ - "userId": req.Payload["userId"], + "userId": payload["userId"], }, } }() @@ -133,12 +153,12 @@ func (zm *ZoneGrpcMiddleware) Process(ctx context.Context, req *Response, stream return } case string(NEW_ZONE): - logger.Println(req.Payload) - if err := validateRequest(req.GetPayload(), "zoneId", "zoneName", "zoneImageURL", "zoneOwner", "zoneCreationDate"); err != nil { + logger.Println(payload) + if err := validateRequest(payload, "zoneId", "zoneName", "zoneImageURL", "zoneOwner", "zoneCreationDate"); err != nil { errCh <- err return } - zone, err := NewZone(zm.Manager.ID, req.Payload["zoneId"], req.Payload["zoneName"], req.Payload["zoneImageURL"], req.Payload["zoneOwner"], req.Payload["zoneCreationDate"], true, []string{req.Payload["zoneOwner"]}) + zone, err := NewZone(zm.Manager.ID, payload["zoneId"], payload["zoneName"], payload["zoneImageURL"], payload["zoneOwner"], payload["zoneCreationDate"], true, []string{payload["zoneOwner"]}) if err != nil { errCh <- err return @@ -148,77 +168,73 @@ func (zm *ZoneGrpcMiddleware) Process(ctx context.Context, req *Response, stream return }) case string(ZONE_OFFER): - if err := validateRequest(req.GetPayload(), FROM, TO, SDP); err != nil { + if err := validateRequest(payload, SDP); err != nil { errCh <- err return } - if err := zm.Manager.HandleOffer(ctx, req.GetPayload(), zm.signalCandidate); err != nil { + if err := zm.Manager.HandleOffer(ctx, req.GetFrom(), req.GetTo(), payload, zm.signalCandidate); err != nil { errCh <- err return } case string(ZONE_ANSWER): - if err := validateRequest(req.GetPayload(), FROM, TO, SDP); err != nil { + if err := validateRequest(payload, SDP); err != nil { errCh <- err return } - if err := zm.Manager.HandleAnswer(ctx, req.GetPayload()); err != nil { + if err := zm.Manager.HandleAnswer(ctx, req.GetFrom(), req.GetTo(), payload); err != nil { errCh <- err return } case string(ZONE_COUNTER_OFFER): - if err := validateRequest(req.GetPayload(), FROM); err != nil { - errCh <- err - return - } - if err := zm.Manager.HandleCounterOffer(ctx, req.Payload); err != nil { + if err := zm.Manager.HandleCounterOffer(ctx, req.GetFrom(), req.GetTo(), payload); err != nil { errCh <- err return } case string(ZONE_WEBRTC_RENNEGOTIATION_OFFER): logger.Println("received negotiation offer") - if err := validateRequest(req.GetPayload(), FROM, SDP); err != nil { + if err := validateRequest(payload, SDP); err != nil { errCh <- err return } - if err := zm.Manager.HandleRennegotiationOffer(req.Payload[FROM], req.Payload[SDP]); err != nil { + if err := zm.Manager.HandleRennegotiationOffer(req.GetFrom(), payload[SDP]); err != nil { errCh <- err return } case string(ZONE_WEBRTC_RENNEGOTIATION_ANSWER): logger.Println("received negotiation answer") - if err := validateRequest(req.GetPayload(), FROM, SDP); err != nil { + if err := validateRequest(payload, SDP); err != nil { errCh <- err return } - if err := zm.Manager.HandleRennegotiationAnswer(req.Payload[FROM], req.Payload[SDP]); err != nil { + if err := zm.Manager.HandleRennegotiationAnswer(req.GetFrom(), payload[SDP]); err != nil { errCh <- err return } case string(ZONE_WEBRTC_CANDIDATE): - if err := validateRequest(req.GetPayload(), FROM, "candidate", "sdpMlineIndex", "sdpMid"); err != nil { + if err := validateRequest(payload, "candidate", "sdpMLineIndex", "sdpMid"); err != nil { errCh <- err return } - logger.Println(req.Payload) - i, err := strconv.Atoi(req.Payload["sdpMlineIndex"]) + logger.Println(payload) + i, err := strconv.Atoi(payload["sdpMLineIndex"]) if err != nil { errCh <- err return } - sdpMlineIndex := uint16(i) - sdpMid := req.Payload["sdpMid"] - logger.Println(sdpMid, sdpMlineIndex) + SDPMLineIndex := uint16(i) + sdpMid := payload["sdpMid"] + logger.Println(sdpMid, SDPMLineIndex) if err := zm.Manager.AddCandidate(&webrtc.ICECandidateInit{ - Candidate: req.Payload["candidate"], + Candidate: payload["candidate"], SDPMid: &sdpMid, - SDPMLineIndex: &sdpMlineIndex, - }, req.Payload[FROM]); err != nil { + SDPMLineIndex: &SDPMLineIndex, + }, req.GetFrom()); err != nil { errCh <- err return } default: logger.Println("no request for zon grpc middleware") - logger.Println(req.GetPayload()) + logger.Println(payload) logger.Println(req.Type) } done <- struct{}{} diff --git a/zoneManager.go b/zoneManager.go index c66cae1..29a7e60 100644 --- a/zoneManager.go +++ b/zoneManager.go @@ -7,10 +7,13 @@ import ( "fmt" "io" "net/http" + "os" + "path/filepath" "strconv" sync "sync" "sync/atomic" + "github.com/google/uuid" "github.com/pion/webrtc/v3" ) @@ -26,7 +29,7 @@ type ZoneManager struct { RTCPeerConnections map[string]*RTCPeerConnection DataChannels map[string]*DataChannel PendingCandidates map[string][]*webrtc.ICECandidate - stream GrpcManager_LinkClient + stream SignalingService_LinkClient zoneFlag *uint32 peerConnectionFlag *uint32 localSDFlag *uint32 @@ -49,7 +52,7 @@ type Zone struct { func NewZone(hostId string, zoneId string, zoneName string, imageUrl string, owner string, creationDate string, initialized bool, authorizedMembers []string) (zone *Zone, err error) { dataChannels, dataChannelFlag := make(map[string]*DataChannel), uint32(0) - zoneChatHandler, err := NewZoneChatsHandler(zoneId, owner, authorizedMembers, dataChannels, &dataChannelFlag) + zoneChatHandler, err := NewZoneChatsHandler(hostId, zoneId, owner, authorizedMembers, dataChannels, &dataChannelFlag) if err != nil { return nil, err } @@ -69,7 +72,7 @@ func NewZone(hostId string, zoneId string, zoneName string, imageUrl string, own if err != nil { return } - zoneScheduler, e := NewZoneRequestScheduler(authorizedMembers, zoneUsersHandler, zoneChatHandler, zoneAudioChannelsHandler, zoneVideoChannelsHandler, zoneFileHandler) + zoneScheduler, e := NewZoneRequestScheduler(authorizedMembers, zoneUsersHandler, zoneAudioChannelsHandler, zoneVideoChannelsHandler, zoneFileHandler, zoneChatHandler) go func() { for schedErr := range e { logger.Println("from scheduler :", schedErr) @@ -108,6 +111,10 @@ func NewZoneManager(id string, token string) (zoneManager *ZoneManager, err erro } zoneMap[zone.ID] = z } + zonesFolder,err := os.ReadDir(filepath.Join("data", "zones")) + if err != nil { + return nil, err + } logger.Println(zoneMap) zoneManager = &ZoneManager{ ID: id, @@ -122,6 +129,11 @@ func NewZoneManager(id string, token string) (zoneManager *ZoneManager, err erro dataChannelFlag: &dataChannelFlag, candidateFlag: &candidateFlag, } + for _, z := range zonesFolder { + if _,ok := zoneMap[z.Name()]; !ok { + logger.Println(zoneManager.DeleteZone(z.Name())) + } + } return } @@ -136,13 +148,32 @@ func atomicallyExecute(flag *uint32, job func() (err error)) (err error) { return } -func (zm *ZoneManager) DeleteZone(zoneId string) {} +func (zm *ZoneManager) sendSignalingMessage(messageType, from, to string, payload map[string]interface{}) (err error) { + bs, err := json.Marshal(payload) + if err != nil { + return + } + err = zm.stream.Send(&SignalingMessage{ + Type: messageType, + From: from, + To: to, + Payload: bs, + }) + return +} + +func (zm *ZoneManager) DeleteZone(zoneId string) error { + return os.RemoveAll(filepath.Join("data", "zones",zoneId)) +} func (zm *ZoneManager) fetchZones(nodeId string, token string) (zones []*Zone, err error) { + em := NewEncryptionManager() + sig := em.SignRequestHMAC(nodeId) body, err := json.Marshal(map[string]interface{}{ - "type": LIST_ZONES_BY_HOST, - "token": token, - "from": nodeId, + "type": LIST_ZONES_BY_HOST, + "mac": sig, + "from": nodeId, + "peerType":"node", "payload": map[string]string{ "host": nodeId, "lastIndex": "0", @@ -160,7 +191,15 @@ func (zm *ZoneManager) fetchZones(nodeId string, token string) (zones []*Zone, e if err != nil { return } - err = json.Unmarshal(bs, &zones) + var payload map[string]any + if err = json.Unmarshal(bs, &payload); err != nil { + return + } + b, err := json.Marshal(payload["zones"]) + if err != nil { + return + } + err = json.Unmarshal(b, &zones) return } @@ -178,8 +217,10 @@ func (zm *ZoneManager) CreateOffer(ctx context.Context, target string, from stri return } _ = atomicallyExecute(zm.peerConnectionFlag, func() (err error) { + id := uuid.New().String() logger.Println("adding for target", target) zm.RTCPeerConnections[target] = &RTCPeerConnection{ + id: id, PeerConnection: peerConnection, makingOffer: true, makingOfferLock: &sync.Mutex{}, @@ -187,20 +228,15 @@ func (zm *ZoneManager) CreateOffer(ctx context.Context, target string, from stri } return }) - err = zm.stream.Send(&Request{ - Type: string(ZONE_OFFER), - From: zm.ID, - Token: "none", - Payload: map[string]string{ - "to": target, - "from": zm.ID, - "sdp": rawOffer.SDP, - }, + err = zm.sendSignalingMessage(string(ZONE_OFFER), zm.ID, target, map[string]any{ + "to": target, + "from": zm.ID, + "sdp": rawOffer.SDP, }) return } -func (zm *ZoneManager) HandleOffer(ctx context.Context, req map[string]string, cb OnICECandidateFunc) (err error) { +func (zm *ZoneManager) HandleOffer(ctx context.Context, from string, to string, req map[string]string, cb OnICECandidateFunc) (err error) { done, errCh := make(chan struct{}), make(chan error) go func() { if _, ok := zm.Zones[req["zoneId"]]; !ok { @@ -209,21 +245,31 @@ func (zm *ZoneManager) HandleOffer(ctx context.Context, req map[string]string, c return } logger.Println("handling zone offer") - peerConnection, err := zm.createPeerConnection(req[FROM], req[TO], req["zoneId"], webrtc.SDPTypeAnswer, cb) + + if _,ok := zm.RTCPeerConnections[from]; ok { + if e := zm.HandleLeavingMember(from,req["zoneId"]); e != nil { + logger.Println(e) + } + } + + peerConnection, err := zm.createPeerConnection(from, to, req["zoneId"], webrtc.SDPTypeAnswer, cb) if err != nil { errCh <- err return } logger.Println("peer connection created") _ = atomicallyExecute(zm.peerConnectionFlag, func() (err error) { - zm.RTCPeerConnections[req[FROM]] = &RTCPeerConnection{ + id := uuid.New().String() + zm.RTCPeerConnections[from] = &RTCPeerConnection{ PeerConnection: peerConnection, + id: id, makingOffer: false, makingOfferLock: &sync.Mutex{}, negotiate: zm.negotiate, } return }) + logger.Println("peer connection added to map") offer := webrtc.SessionDescription{ Type: webrtc.SDPTypeOffer, SDP: req[SDP], @@ -238,23 +284,17 @@ func (zm *ZoneManager) HandleOffer(ctx context.Context, req map[string]string, c return } _ = atomicallyExecute(zm.localSDFlag, func() (err error) { - zm.LocalSD[req[FROM]] = &rawAnswer + zm.LocalSD[from] = &rawAnswer return }) - - _ = atomicallyExecute(zm.zoneFlag, func() (err error) { - //zm.Zones[req[SQUAD_ID]].Members = append(zm.Squads[req[SQUAD_ID]].Members, req[FROM]) + if err = peerConnection.SetLocalDescription(rawAnswer); err != nil { + errCh <- err return - }) - if err = zm.stream.Send(&Request{ - Type: string(ZONE_ANSWER), - From: zm.ID, - Token: "none", - Payload: map[string]string{ - "to": req[FROM], - "from": zm.ID, - "sdp": rawAnswer.SDP, - }, + } + if err = zm.sendSignalingMessage(string(ZONE_ANSWER), zm.ID, from, map[string]any{ + "to": from, + "from": zm.ID, + "sdp": rawAnswer.SDP, }); err != nil { errCh <- err return @@ -272,18 +312,18 @@ func (zm *ZoneManager) HandleOffer(ctx context.Context, req map[string]string, c } } -func (zm *ZoneManager) HandleAnswer(ctx context.Context, req map[string]string) (err error) { +func (zm *ZoneManager) HandleAnswer(ctx context.Context, from string, to string, req map[string]string) (err error) { defer func() { if r := recover(); err != nil { logger.Printf("recover from panic in handle answer : %v\n", r) } }() if err = atomicallyExecute(zm.peerConnectionFlag, func() (err error) { - if _, ok := zm.RTCPeerConnections[req[FROM]]; !ok { - err = fmt.Errorf("no corresponding peer connection for id : %s", req[FROM]) + if _, ok := zm.RTCPeerConnections[from]; !ok { + err = fmt.Errorf("no corresponding peer connection for id : %s", from) return } - peerConnnection := zm.RTCPeerConnections[req[FROM]] + peerConnnection := zm.RTCPeerConnections[from] logger.Println("---------------------") logger.Println(req[SDP]) logger.Println("---------------------") @@ -298,92 +338,77 @@ func (zm *ZoneManager) HandleAnswer(ctx context.Context, req map[string]string) }); err != nil { return } - if err = zm.stream.Send(&Request{ - Type: string(ZONE_COUNTER_OFFER), - From: zm.ID, - Token: "none", - Payload: map[string]string{ - "from": zm.ID, - "to": req[FROM], - }, + if err = zm.sendSignalingMessage(string(ZONE_COUNTER_OFFER), zm.ID, from, map[string]any{ + "from": zm.ID, + "to": from, }); err != nil { return } _ = atomicallyExecute(zm.candidateFlag, func() (err error) { - for _, candidate := range zm.PendingCandidates[req[FROM]] { - logger.Println("sending candidate from answer to", req[FROM]) - if err = zm.stream.Send(&Request{ - Type: string(ZONE_WEBRTC_CANDIDATE), - From: zm.ID, - Token: "none", - Payload: map[string]string{ - "from": zm.ID, - "to": req[FROM], - "candidate": candidate.ToJSON().Candidate, - "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), - }, + for _, candidate := range zm.PendingCandidates[from] { + logger.Println("sending candidate from answer to", from) + if err = zm.sendSignalingMessage(string(ZONE_WEBRTC_CANDIDATE), zm.ID, from, map[string]any{ + "from": zm.ID, + "to": from, + "candidate": candidate.ToJSON().Candidate, + "sdpMid": *candidate.ToJSON().SDPMid, + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), }); err != nil { logger.Println(err) continue } } - delete(zm.PendingCandidates, req[FROM]) + delete(zm.PendingCandidates, from) return }) _ = atomicallyExecute(zm.localSDFlag, func() (err error) { - delete(zm.LocalSD, req[FROM]) + delete(zm.LocalSD, from) return }) return } -func (zm *ZoneManager) HandleCounterOffer(ctx context.Context, req map[string]string) (err error) { +func (zm *ZoneManager) HandleCounterOffer(ctx context.Context, from string, to string, req map[string]string) (err error) { logger.Println("handling counter offer 1") - if err = atomicallyExecute(zm.peerConnectionFlag, func() (err error) { - logger.Println("start job") - if _, ok := zm.RTCPeerConnections[req[FROM]]; !ok { - logger.Println("error here") - err = fmt.Errorf("no field corresponding peer connection for id %s", req[FROM]) - return - } - logger.Println("handling counter offer") - connection := zm.RTCPeerConnections[req[FROM]] - err = atomicallyExecute(zm.localSDFlag, func() (err error) { - if err = connection.SetLocalDescription(*zm.LocalSD[req[FROM]]); err != nil { - logger.Println(err) - return - } - return - }) - return - }); err != nil { - return - } + // if err = atomicallyExecute(zm.peerConnectionFlag, func() (err error) { + // logger.Println("start job") + // if _, ok := zm.RTCPeerConnections[from]; !ok { + // logger.Println("error here") + // err = fmt.Errorf("no field corresponding peer connection for id %s", from) + // return + // } + // logger.Println("handling counter offer") + // connection := zm.RTCPeerConnections[from] + // err = atomicallyExecute(zm.localSDFlag, func() (err error) { + // if err = connection.SetLocalDescription(*zm.LocalSD[from]); err != nil { + // logger.Println(err) + // return + // } + // return + // }) + // return + // }); err != nil { + // return + // } logger.Println("handling counter offer 2") _ = atomicallyExecute(zm.candidateFlag, func() (err error) { - for _, candidate := range zm.PendingCandidates[req[FROM]] { - logger.Println("sending candidate to", req[FROM]) - if err = zm.stream.Send(&Request{ - Type: string(ZONE_WEBRTC_CANDIDATE), - From: zm.ID, - Token: "none", - Payload: map[string]string{ - "from": zm.ID, - "to": req[FROM], - "candidate": candidate.ToJSON().Candidate, - "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), - }, + for _, candidate := range zm.PendingCandidates[from] { + logger.Println("sending candidate to", from) + if err = zm.sendSignalingMessage(string(ZONE_WEBRTC_CANDIDATE), zm.ID, from, map[string]any{ + "from": zm.ID, + "to": from, + "candidate": candidate.ToJSON().Candidate, + "sdpMid": *candidate.ToJSON().SDPMid, + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), }); err != nil { return } } - delete(zm.PendingCandidates, req[FROM]) + delete(zm.PendingCandidates, from) return }) _ = atomicallyExecute(zm.localSDFlag, func() (err error) { - delete(zm.LocalSD, req[FROM]) + delete(zm.LocalSD, from) return }) return @@ -409,7 +434,7 @@ func (zm *ZoneManager) createPeerConnection(target string, from string, zoneId s return } logger.Println("---------------------------------------------------") - if peerType == webrtc.SDPTypeAnswer { + if peerType == webrtc.SDPTypeOffer { maxRetransmits := uint16(100) channel, err := peerConnection.CreateDataChannel("data", &webrtc.DataChannelInit{ MaxRetransmits: &maxRetransmits, @@ -446,13 +471,16 @@ func (zm *ZoneManager) createPeerConnection(target string, from string, zoneId s logger.Println("error in open channel send", sendErr) return } - for { - select { - case <-done: - return - case <-err: + go func() { + for { + select { + case <-done: + return + case e := <-err: + logger.Println("----- error from scheduler:", e) + } } - } + }() } }) channel.OnClose(func() { @@ -494,11 +522,17 @@ func (zm *ZoneManager) createPeerConnection(target string, from string, zoneId s if _, ok := zm.Zones[zoneId]; ok { logger.Println("this zone exist") _ = atomicallyExecute(zm.Zones[zoneId].DataChannelsFlag, func() (err error) { + logger.Println("adding dc to dc map") x := int32(0) zm.Zones[zoneId].DataChannels[target] = &DataChannel{DataChannel: dc, bufferedAmountLowThresholdReached: make(<-chan struct{}), l: &x} return }) + if _, ok := zm.Zones[zoneId]; !ok { + err = fmt.Errorf("no corresponding zones") + return + } done, err := zm.Zones[zoneId].ZoneRequestScheduler.Schedule(reqChan) + bs, jsonErr := json.Marshal(&ZoneResponse{ Type: "user_zone_init", From: zoneId, @@ -513,18 +547,24 @@ func (zm *ZoneManager) createPeerConnection(target string, from string, zoneId s logger.Println("error in open channel send", sendErr) return } - for { - select { - case <-done: - return - case <-err: + go func() { + for { + select { + case <-done: + return + case <-err: + } } - } + }() } }) dc.OnClose(func() { close(reqChan) }) + dc.OnError(func(err error) { + logger.Println("--------------- error in dc:", err) + close(reqChan) + }) dc.OnMessage(func(msg webrtc.DataChannelMessage) { var req ZoneRequest if err := json.Unmarshal(msg.Data, &req); err != nil { @@ -534,44 +574,53 @@ func (zm *ZoneManager) createPeerConnection(target string, from string, zoneId s logger.Println("incoming request", req) reqChan <- &req }) + _ = atomicallyExecute(zm.dataChannelFlag, func() (err error) { + l := int32(0) + zm.DataChannels[target] = &DataChannel{ + DataChannel: dc, + bufferedAmountLowThresholdReached: make(<-chan struct{}), + l: &l, + } + return + }) }) } peerConnection.OnConnectionStateChange(func(pcs webrtc.PeerConnectionState) { - if pcs == webrtc.PeerConnectionStateClosed || pcs == webrtc.PeerConnectionStateDisconnected || pcs == webrtc.PeerConnectionStateFailed { + if pcs == webrtc.PeerConnectionStateDisconnected || pcs == webrtc.PeerConnectionStateFailed { logger.Println(pcs) if err = zm.HandleLeavingMember(target, zoneId); err != nil { logger.Println(err) } } }) - peerConnection.OnNegotiationNeeded(func() { - logger.Println("------------------- negotiation is needed --------------------") - if pc, ok := zm.RTCPeerConnections[target]; ok { - if pc.SignalingState() == webrtc.ICETransportStateConnected { - localSd, err := pc.CreateOffer(nil) - if err != nil { - logger.Println(err) - return - } - if err = pc.SetLocalDescription(localSd); err != nil { - logger.Println(err) - return - } - if err = zm.stream.Send(&Request{ - Type: string(ZONE_WEBRTC_RENNEGOTIATION_OFFER), - From: zm.ID, - Token: "", - Payload: map[string]string{ - "to": target, - "sdp": localSd.SDP, - }, - }); err != nil { - logger.Println(err) - return - } - } - } - }) + // peerConnection.OnNegotiationNeeded(func() { + // logger.Println("------------------- negotiation is needed --------------------") + // if pc, ok := zm.RTCPeerConnections[target]; ok { + // if pc.SignalingState() == webrtc.ICETransportStateConnected { + // localSd, err := pc.CreateOffer(nil) + // if err != nil { + // logger.Println(err) + // return + // } + // if err = pc.SetLocalDescription(localSd); err != nil { + // logger.Println(err) + // return + // } + // if err = zm.stream.Send(&Request{ + // Type: string(ZONE_WEBRTC_RENNEGOTIATION_OFFER), + // From: zm.ID, + // Token: "", + // Payload: map[string]string{ + // "to": target, + // "sdp": localSd.SDP, + // }, + // }); err != nil { + // logger.Println(err) + // return + // } + // } + // } + // }) peerConnection.OnICEConnectionStateChange(func(is webrtc.ICEConnectionState) { logger.Printf("ICE connection state has changed %s\n", is.String()) if is == webrtc.ICEConnectionStateDisconnected || is == webrtc.ICEConnectionStateFailed { @@ -605,13 +654,13 @@ func (zm *ZoneManager) HandleRennegotiationOffer(from string, sdp string) (err e err = fmt.Errorf("no corresponding peer connection for id %s", from) return } - zm.RTCPeerConnections[from].makingOfferLock.Lock() - if zm.RTCPeerConnections[from].makingOffer { - zm.RTCPeerConnections[from].makingOfferLock.Unlock() - err = fmt.Errorf("already making an offer or state is stable") - return - } - zm.RTCPeerConnections[from].makingOfferLock.Unlock() + //zm.RTCPeerConnections[from].makingOfferLock.Lock() + // if zm.RTCPeerConnections[from].makingOffer { + // //zm.RTCPeerConnections[from].makingOfferLock.Unlock() + // err = fmt.Errorf("already making an offer or state is stable") + // return + // } + //zm.RTCPeerConnections[from].makingOfferLock.Unlock() if err = zm.RTCPeerConnections[from].SetRemoteDescription(webrtc.SessionDescription{SDP: sdp, Type: webrtc.SDPTypeOffer}); err != nil { return } @@ -622,14 +671,9 @@ func (zm *ZoneManager) HandleRennegotiationOffer(from string, sdp string) (err e if err = zm.RTCPeerConnections[from].SetLocalDescription(localSd); err != nil { return } - if err = zm.stream.Send(&Request{ - Type: string(ZONE_WEBRTC_RENNEGOTIATION_ANSWER), - From: zm.ID, - Token: "", - Payload: map[string]string{ - "to": from, - "sdp": localSd.SDP, - }, + if err = zm.sendSignalingMessage(string(ZONE_WEBRTC_RENNEGOTIATION_ANSWER), zm.ID, from, map[string]any{ + "to": from, + "sdp": localSd.SDP, }); err != nil { logger.Println(err) return @@ -664,6 +708,10 @@ func (zm *ZoneManager) AddCandidate(candidate *webrtc.ICECandidateInit, from str } func (zm *ZoneManager) HandleLeavingMember(id string, zoneId string) (err error) { + defer func () { + logger.Println(zm.notifyLeavingMember(id,zoneId,zm.ID)) + }() + logger.Println("---------------- handling leaving member", id) if err = atomicallyExecute(zm.peerConnectionFlag, func() (err error) { if _, ok := zm.RTCPeerConnections[id]; !ok { err = fmt.Errorf("no correponding peerconnection for id %s", id) @@ -673,17 +721,21 @@ func (zm *ZoneManager) HandleLeavingMember(id string, zoneId string) (err error) }); err != nil { return } - if err = atomicallyExecute(zm.zoneFlag, func() (err error) { + logger.Println(err) + err = atomicallyExecute(zm.zoneFlag, func() (err error) { + logger.Println("---------------- cleaning zone handlers", id) if zone, ok := zm.Zones[zoneId]; ok { - for _, handlersPublishers := range zone.ZoneRequestScheduler.handlersPublishers { - handlersPublishers <- &ZoneRequest{ - ReqType: LEAVE_ZONE, - From: "node", - Payload: map[string]interface{}{ - "userId": id, - }, + go func() { + for _, handlersPublishers := range zone.ZoneRequestScheduler.handlersPublishers { + handlersPublishers <- &ZoneRequest{ + ReqType: LEAVE_ZONE, + From: id, + Payload: map[string]interface{}{ + "userId": id, + }, + } } - } + }() if err = atomicallyExecute(zone.DataChannelsFlag, func() (err error) { defer delete(zone.DataChannels, id) if dataChannel, ok := zone.DataChannels[id]; ok { @@ -695,14 +747,14 @@ func (zm *ZoneManager) HandleLeavingMember(id string, zoneId string) (err error) }); err != nil { return } + logger.Println("datachannels cleaned", id) } else { err = fmt.Errorf("no corresponding zone for zoneId %s", zoneId) } return - }); err != nil { - return - } - if err = atomicallyExecute(zm.peerConnectionFlag, func() (err error) { + }) + logger.Println(err) + err = atomicallyExecute(zm.peerConnectionFlag, func() (err error) { if _, ok := zm.RTCPeerConnections[id]; ok { defer delete(zm.RTCPeerConnections, id) if err = zm.RTCPeerConnections[id].Close(); err != nil { @@ -710,7 +762,34 @@ func (zm *ZoneManager) HandleLeavingMember(id string, zoneId string) (err error) } } return - }); err != nil { + }) + logger.Println(err) + _ = atomicallyExecute(zm.candidateFlag, func() (err error) { + delete(zm.PendingCandidates, id) + return + }) + return +} + +func (zm *ZoneManager) notifyLeavingMember(userId,zoneId,hostId string) (err error) { + em := NewEncryptionManager() + sig := em.SignRequestHMAC(hostId) + body, err := json.Marshal(map[string]interface{}{ + "type": DISCONNECT_ZONE_MEMBER, + "mac": sig, + "from": hostId, + "peerType":"node", + "payload": map[string]string{ + "zoneId": zoneId, + "userId": userId, + }, + }) + if err != nil { + return + } + _, err = http.Post("https://app.zippytal.com/req", "application/json", bytes.NewBuffer(body)) + if err != nil { + logger.Println("error come from there in zone manager") return } return @@ -721,13 +800,13 @@ func (zm *ZoneManager) negotiate(target string, zoneId string) { if _, ok := zm.RTCPeerConnections[target]; !ok { return } - zm.RTCPeerConnections[target].makingOfferLock.Lock() - zm.RTCPeerConnections[target].makingOffer = true - zm.RTCPeerConnections[target].makingOfferLock.Unlock() + //zm.RTCPeerConnections[target].makingOfferLock.Lock() + //zm.RTCPeerConnections[target].makingOffer = true + //zm.RTCPeerConnections[target].makingOfferLock.Unlock() defer func() { - zm.RTCPeerConnections[target].makingOfferLock.Lock() - zm.RTCPeerConnections[target].makingOffer = false - zm.RTCPeerConnections[target].makingOfferLock.Unlock() + //zm.RTCPeerConnections[target].makingOfferLock.Lock() + //zm.RTCPeerConnections[target].makingOffer = false + //zm.RTCPeerConnections[target].makingOfferLock.Unlock() }() return }) diff --git a/zoneNotificationsHandler.go b/zoneNotificationsHandler.go new file mode 100644 index 0000000..ba5ee6b --- /dev/null +++ b/zoneNotificationsHandler.go @@ -0,0 +1,10 @@ +package localserver + +type ZoneNotificationsHandler struct { + ZoneId string + ZoneMembersId []string + DataChannels map[string]*DataChannel + Flag *uint32 + Publishers []<-chan *ZoneRequest + reqChans []chan<- *ZoneRequest +} \ No newline at end of file diff --git a/zoneUsersDBHandler.go b/zoneUsersDBHandler.go index 9cfba67..7df1499 100644 --- a/zoneUsersDBHandler.go +++ b/zoneUsersDBHandler.go @@ -2,26 +2,52 @@ package localserver import ( "encoding/json" + "os" "path/filepath" "github.com/dgraph-io/badger/v3" ) +type BasicRights struct { + Create bool `json:"create"` +} + +type ChatRights struct { + *BasicRights +} + +type AudioChannelRights struct { + *BasicRights +} + +type VideoChannelRights struct { + *BasicRights +} + +type MediaRights struct { + *BasicRights +} + +type FileRights struct { + *BasicRights + CreateAtRoot bool `json:"createAtRoot"` +} + type User struct { - ID string `json:"id"` - Name string `json:"name"` - ChatRights string `json:"chatRights"` - AudioChannelRights string `json:"audioChannelRights"` - VideoChannelRights string `json:"videoChannelRights"` - MediaRights string `json:"mediaRights"` - FileRights string `json:"fileRights"` - KnownChatsId []string `json:"knownChatsId"` - KnownAudioChannelsId []string `json:"knownAudioChannelsId"` - KnownVideoChannelsId []string `json:"knownVideoChannelsId"` - KnownMediaFolderId []string `json:"knownMediaFolderId"` - KnownFileFolderId []string `json:"knownFileFolderId"` - Admin bool `json:"admin"` - Owner bool `json:"owner"` + ID string `json:"id"` + Name string `json:"name"` + ChatRights *ChatRights `json:"chatRights"` + AudioChannelRights *AudioChannelRights `json:"audioChannelRights"` + VideoChannelRights *VideoChannelRights `json:"videoChannelRights"` + MediaRights *MediaRights `json:"mediaRights"` + FileRights *FileRights `json:"fileRights"` + KnownChatsId []string `json:"knownChatsId"` + KnownAudioChannelsId []string `json:"knownAudioChannelsId"` + KnownVideoChannelsId []string `json:"knownVideoChannelsId"` + KnownMediaFolderId []string `json:"knownMediaFolderId"` + KnownFileFolderId []string `json:"knownFileFolderId"` + Admin bool `json:"admin"` + Owner bool `json:"owner"` } type ZoneUsersDBHandler struct { @@ -29,6 +55,46 @@ type ZoneUsersDBHandler struct { db func(func(*badger.DB) (err error)) (err error) } +func NewChatRights(create bool) *ChatRights { + return &ChatRights{ + BasicRights: &BasicRights{ + Create: create, + }, + } +} + +func NewAudioChannelRights(create bool) *AudioChannelRights { + return &AudioChannelRights{ + BasicRights: &BasicRights{ + Create: create, + }, + } +} + +func NewVideoChannelRights(create bool) *VideoChannelRights { + return &VideoChannelRights{ + BasicRights: &BasicRights{ + Create: create, + }, + } +} + +func NewMediaRights(create bool) *MediaRights { + return &MediaRights{ + BasicRights: &BasicRights{ + Create: create, + }, + } +} + +func NewFileRights(create bool) *FileRights { + return &FileRights{ + BasicRights: &BasicRights{ + Create: create, + }, + } +} + func NewZoneUsersDBHandler(zoneId string, owner string, authorizedMembers []string, init bool) (zoneChatDBHandler *ZoneUsersDBHandler, err error) { db := func(f func(*badger.DB) (err error)) (err error) { db, err := badger.Open(badger.DefaultOptions(filepath.Join("data", "zones", zoneId, "users")).WithLogger(dbLogger)) @@ -43,11 +109,11 @@ func NewZoneUsersDBHandler(zoneId string, owner string, authorizedMembers []stri admin := &User{ ID: owner, Name: owner, - ChatRights: "", - AudioChannelRights: "", - VideoChannelRights: "", - MediaRights: "", - FileRights: "", + ChatRights: NewChatRights(true), + AudioChannelRights: NewAudioChannelRights(true), + VideoChannelRights: NewVideoChannelRights(true), + MediaRights: NewMediaRights(true), + FileRights: NewFileRights(true), KnownChatsId: []string{}, KnownAudioChannelsId: []string{}, KnownVideoChannelsId: []string{}, @@ -70,6 +136,14 @@ func NewZoneUsersDBHandler(zoneId string, owner string, authorizedMembers []stri return } } + bs, err := os.ReadFile(filepath.Join("data", "zones", zoneId, "users", "usersConfig.json")) + if err != nil { + return + } + var baseUserConfig ZoneUserConfig + if err = json.Unmarshal(bs, &baseUserConfig); err != nil { + return + } if err = db(func(d *badger.DB) (err error) { err = d.Update(func(txn *badger.Txn) (err error) { for _, member := range authorizedMembers { @@ -79,11 +153,11 @@ func NewZoneUsersDBHandler(zoneId string, owner string, authorizedMembers []stri user := &User{ ID: member, Name: member, - ChatRights: "", - AudioChannelRights: "", - VideoChannelRights: "", - MediaRights: "", - FileRights: "", + ChatRights: baseUserConfig.DefaultChatRights, + AudioChannelRights: baseUserConfig.DefaultAudioChannelRights, + VideoChannelRights: baseUserConfig.DefaultVideoChannelRights, + MediaRights: baseUserConfig.DefaultMediaRights, + FileRights: baseUserConfig.DefaultFileRights, KnownChatsId: []string{}, KnownAudioChannelsId: []string{}, KnownVideoChannelsId: []string{}, @@ -154,7 +228,7 @@ func (zcdbh *ZoneUsersDBHandler) ListUsers(lastIndex int, limit int) (users []*U opt.Reverse = true it := txn.NewIterator(opt) defer it.Close() - users = make([]*User, 0) + users = []*User{} for it.Rewind(); it.Valid(); it.Next() { item := it.Item() if err = item.Value(func(val []byte) error { diff --git a/zoneUsersHandler.go b/zoneUsersHandler.go index dc724ae..097a7b7 100644 --- a/zoneUsersHandler.go +++ b/zoneUsersHandler.go @@ -9,9 +9,12 @@ import ( ) const ( + EDIT_DEFAULT_RIGHTS = "edit_default_rights" + EDIT_USERS_RIGHTS = "edit_users_rights" LIST_ZONE_MEMBERS = "list_zone_members" LIST_ZONE_MEMBERS_RESPONSE = "list_zone_members_response" GET_USER = "get_user" + GET_DEFAULT_RIGHTS = "get_default_rights" MODIFY_USER_CHAT_RIGHTS = "modify_user_chat_rights" ADD_KNOWN_CHAT = "add_known_chat" REMOVE_KNOWN_CHAT = "remove_known_chat" @@ -24,8 +27,12 @@ const ( ) const ( - NEW_ZONE_USER = "new_zone_user" - REMOVED_ZONE_USER = "removed_zone_user" + NEW_ZONE_USER = "new_zone_user" + GET_CURRENT_USER_RESPONSE = "get_current_user_response" + GET_USER_RESPONSE = "get_user_response" + REMOVED_ZONE_USER = "removed_zone_user" + DEFAULT_RIGHTS_EDITED = "default_rights_edited" + USER_RIGHTS_EDITED = "user_rights_edited" ) type ZoneUsersHandler struct { @@ -38,13 +45,19 @@ type ZoneUsersHandler struct { reqChans []chan<- *ZoneRequest } +type ZoneMember struct { + ID string `json:"id"` + Admin bool `json:"admin"` + Owner bool `json:"owner"` + Config *ZoneUserConfig `json:"config"` +} + type ZoneUserConfig struct { - DefaultChatsRights string `json:"defaultChatsRights"` - DefaultAudioChannelsRights string `json:"defaultAudioChannelsRights"` - DefaultVideoChannelsRights string `json:"defaultVideoChannelsRights"` - DefaultMediaRights string `json:"defaultMediaRights"` - DefaultFileRights string `json:"defaultFileRights"` - AdminRights string `json:"adminRights"` + DefaultChatRights *ChatRights `json:"defaultChatsRights"` + DefaultAudioChannelRights *AudioChannelRights `json:"defaultAudioChannelsRights"` + DefaultVideoChannelRights *VideoChannelRights `json:"defaultVideoChannelsRights"` + DefaultMediaRights *MediaRights `json:"defaultMediaRights"` + DefaultFileRights *FileRights `json:"defaultFileRights"` } func NewZoneUsersHandler(zoneId string, owner string, authorizedMembers []string, dataChannels map[string]*DataChannel, flag *uint32) (zoneUsersHandler *ZoneUsersHandler, err error) { @@ -57,21 +70,16 @@ func NewZoneUsersHandler(zoneId string, owner string, authorizedMembers []string if mkdirErr != nil { return nil, mkdirErr } - zoneUsersDBHandler, err = NewZoneUsersDBHandler(zoneId, owner, authorizedMembers, true) - if err != nil { - return - } file, ferr := os.Create(filepath.Join("data", "zones", zoneId, "users", "usersConfig.json")) if ferr != nil { return nil, ferr } baseConfig := ZoneUserConfig{ - DefaultChatsRights: "", - DefaultAudioChannelsRights: "", - DefaultVideoChannelsRights: "", - DefaultMediaRights: "", - DefaultFileRights: "", - AdminRights: "", + DefaultChatRights: NewChatRights(true), + DefaultAudioChannelRights: NewAudioChannelRights(true), + DefaultVideoChannelRights: NewVideoChannelRights(true), + DefaultMediaRights: NewMediaRights(true), + DefaultFileRights: NewFileRights(true), } bs, jsonErr := json.Marshal(baseConfig) if jsonErr != nil { @@ -80,7 +88,11 @@ func NewZoneUsersHandler(zoneId string, owner string, authorizedMembers []string if _, writeErr := file.WriteString(string(bs)); writeErr != nil { return nil, writeErr } - _ = file.Close() + err = file.Close() + if err != nil { + return + } + zoneUsersDBHandler, err = NewZoneUsersDBHandler(zoneId, owner, authorizedMembers, true) if err != nil { return } @@ -139,6 +151,34 @@ func (zuh *ZoneUsersHandler) Init(ctx context.Context, authorizedMembers []strin return } +func (zuh *ZoneUsersHandler) sendDataChannelMessage(reqType string, from string, to string, payload map[string]interface{}) (<-chan struct{}, <-chan error) { + done, errCh := make(chan struct{}, 10), make(chan error, 10) + go func() { + if err := atomicallyExecute(zuh.Flag, func() (err error) { + if _, ok := zuh.DataChannels[to]; ok { + bs, jsonErr := json.Marshal(&ZoneResponse{ + Type: reqType, + From: from, + To: to, + Payload: payload, + }) + if jsonErr != nil { + return jsonErr + } + logger.Println(string(bs)) + err = zuh.DataChannels[to].DataChannel.SendText(string(bs)) + } + return + }); err != nil { + errCh <- err + return + } + done <- struct{}{} + logger.Printf("sending %v done\n", payload) + }() + return done, errCh +} + func (zuh *ZoneUsersHandler) Subscribe(ctx context.Context, publisher <-chan *ZoneRequest) (reqChan chan *ZoneRequest, done chan struct{}, errCh chan error) { reqChan, done, errCh = make(chan *ZoneRequest), make(chan struct{}), make(chan error) zuh.reqChans = append(zuh.reqChans, reqChan) @@ -159,14 +199,22 @@ func (zuh *ZoneUsersHandler) Subscribe(ctx context.Context, publisher <-chan *Zo } func (zuh *ZoneUsersHandler) AddUser(userId string) (err error) { + bs, err := os.ReadFile(filepath.Join("data", "zones", zuh.ZoneId, "users", "usersConfig.json")) + if err != nil { + return + } + var baseUserConfig ZoneUserConfig + if err = json.Unmarshal(bs, &baseUserConfig); err != nil { + return + } newUser := &User{ ID: userId, Name: userId, - ChatRights: "", - AudioChannelRights: "", - VideoChannelRights: "", - MediaRights: "", - FileRights: "", + ChatRights: baseUserConfig.DefaultChatRights, + AudioChannelRights: baseUserConfig.DefaultAudioChannelRights, + VideoChannelRights: baseUserConfig.DefaultVideoChannelRights, + MediaRights: baseUserConfig.DefaultMediaRights, + FileRights: baseUserConfig.DefaultFileRights, KnownChatsId: []string{}, KnownAudioChannelsId: []string{}, KnownVideoChannelsId: make([]string, 0), @@ -418,9 +466,137 @@ func (zuh *ZoneUsersHandler) RemoveKnownFolder(folderId string, userId string) ( return } +func (zuh *ZoneUsersHandler) GetDefaultRights(userId string) (err error) { + bs, err := os.ReadFile(filepath.Join("data", "zones", zuh.ZoneId, "users", "usersConfig.json")) + if err != nil { + return + } + var defaultRights ZoneUserConfig + if err = json.Unmarshal(bs, &defaultRights); err != nil { + return + } + d, e := zuh.sendDataChannelMessage(GET_DEFAULT_RIGHTS, "node", userId, map[string]interface{}{ + "defaultRights": defaultRights, + }) + select { + case <-d: + case err = <-e: + } + return +} + +func (zuh *ZoneUsersHandler) EditDefaultRights(defaultChatRights *ChatRights, defaultAudioChannelRights *AudioChannelRights, defaultVideoChannelRights *VideoChannelRights, defaultMediaRights *MediaRights, defaultFileRights *FileRights) (err error) { + bs, err := os.ReadFile(filepath.Join("data", "zones", zuh.ZoneId, "users", "usersConfig.json")) + if err != nil { + return + } + var baseUserConfig ZoneUserConfig + if err = json.Unmarshal(bs, &baseUserConfig); err != nil { + return + } + baseUserConfig.DefaultChatRights = defaultChatRights + baseUserConfig.DefaultAudioChannelRights = defaultAudioChannelRights + baseUserConfig.DefaultVideoChannelRights = defaultVideoChannelRights + baseUserConfig.DefaultMediaRights = defaultMediaRights + baseUserConfig.DefaultFileRights = defaultFileRights + bs, err = json.Marshal(baseUserConfig) + if err != nil { + return + } + file, err := os.OpenFile(filepath.Join("data", "zones", zuh.ZoneId, "users", "usersConfig.json"), os.O_WRONLY|os.O_TRUNC, os.ModeAppend) + if err != nil { + return + } + if _, err = file.WriteString(string(bs)); err != nil { + return + } + err = file.Close() + for _, member := range zuh.ZoneMembersId { + done, err := zuh.sendDataChannelMessage(DEFAULT_RIGHTS_EDITED, "node", member, map[string]interface{}{ + "defaultRights": baseUserConfig, + }) + select { + case <-done: + case e := <-err: + logger.Println(e) + } + } + return +} + +func (zuh *ZoneUsersHandler) EditUsersRights(users []interface{}, chatRights *ChatRights, audioChannelRights *AudioChannelRights, videoChannelRights *VideoChannelRights, mediaRights *MediaRights, fileRights *FileRights) (err error) { + for _, u := range users { + if user, ok := u.(string); ok { + if err = zuh.editUserRights(user, chatRights, audioChannelRights, videoChannelRights, mediaRights, fileRights); err != nil { + logger.Println(err) + } + } + } + return +} + +func (zuh *ZoneUsersHandler) editUserRights(userId string, chatRights *ChatRights, audioChannelRights *AudioChannelRights, videoChannelRights *VideoChannelRights, mediaRights *MediaRights, fileRights *FileRights) (err error) { + user, err := zuh.DB.GetUser(userId) + if err != nil { + return + } + user.ChatRights = chatRights + user.AudioChannelRights = audioChannelRights + user.VideoChannelRights = videoChannelRights + user.MediaRights = mediaRights + user.FileRights = fileRights + if err = zuh.DB.ModifyUser(userId, user); err != nil { + return + } + for _, id := range zuh.ZoneMembersId { + d, e := zuh.sendDataChannelMessage(USER_RIGHTS_EDITED, "node", userId, map[string]interface{}{ + "userId": id, + "user": user, + }) + select { + case <-d: + case err = <-e: + } + } + return +} + func (zuh *ZoneUsersHandler) handleZoneRequest(ctx context.Context, req *ZoneRequest) (err error) { logger.Println("got request in zone users handler", req) switch req.ReqType { + case EDIT_DEFAULT_RIGHTS: + if _, ok := req.Payload["defaultRights"]; !ok { + err = fmt.Errorf("no field defaultRights in request payload") + return + } + bs, jsonErr := json.Marshal(req.Payload["defaultRights"]) + if jsonErr != nil { + return jsonErr + } + var config ZoneUserConfig + if err = json.Unmarshal(bs, &config); err != nil { + err = fmt.Errorf("the defaultRights payload dont match ZoneFSEntity struct pattern : %v", err) + return + } + err = zuh.EditDefaultRights(config.DefaultChatRights, config.DefaultAudioChannelRights, config.DefaultVideoChannelRights, config.DefaultMediaRights, config.DefaultFileRights) + case EDIT_USERS_RIGHTS: + if err = verifyFieldsSliceInterface(req.Payload, "users"); err != nil { + return + } + if _, ok := req.Payload["defaultRights"]; !ok { + err = fmt.Errorf("no field defaultRights in request payload") + return + } + bs, jsonErr := json.Marshal(req.Payload["defaultRights"]) + if jsonErr != nil { + return jsonErr + } + var config ZoneUserConfig + if err = json.Unmarshal(bs, &config); err != nil { + err = fmt.Errorf("the defaultRights payload dont match ZoneFSEntity struct pattern : %v", err) + return + } + err = zuh.EditUsersRights(req.Payload["users"].([]interface{}), config.DefaultChatRights, config.DefaultAudioChannelRights, config.DefaultVideoChannelRights, config.DefaultMediaRights, config.DefaultFileRights) case REMOVE_USER: if err = verifyFieldsString(req.Payload, "userId"); err != nil { return @@ -461,6 +637,11 @@ func (zuh *ZoneUsersHandler) handleZoneRequest(ctx context.Context, req *ZoneReq return } err = zuh.AddKnownVideoChannel(req.Payload["channelId"].(string), req.Payload["userId"].(string)) + case GET_DEFAULT_RIGHTS: + if err = verifyFieldsString(req.Payload, "userId"); err != nil { + return + } + err = zuh.GetDefaultRights(req.Payload["userId"].(string)) case GET_USER: if err = verifyFieldsString(req.Payload, "userId"); err != nil { return @@ -477,57 +658,58 @@ func (zuh *ZoneUsersHandler) handleZoneRequest(ctx context.Context, req *ZoneReq if err != nil { return err } - var answer *ZoneResponse + logger.Println("get user done") + if req.Payload["init"].(bool) { - answer = &ZoneResponse{ - Type: "get_current_user_response", - To: "", - From: "", - Payload: map[string]interface{}{ - "user": user, - }, + done, errCh := zuh.sendDataChannelMessage(GET_CURRENT_USER_RESPONSE, "node", req.Payload["userId"].(string), map[string]interface{}{ + "user": user, + }) + select { + case <-done: + case err = <-errCh: + return err } + } else { - answer = &ZoneResponse{ - Type: "get_user_response", - To: "", - From: "", - Payload: map[string]interface{}{ - "user": user, - }, - } - } - bs, err := json.Marshal(answer) - if err != nil { - return err - } - logger.Println(string(bs)) - if _, ok := zuh.DataChannels[req.From]; ok { - if err = zuh.DataChannels[req.From].DataChannel.SendText(string(bs)); err != nil { + done, errCh := zuh.sendDataChannelMessage(GET_USER_RESPONSE, "node", req.Payload["userId"].(string), map[string]interface{}{ + "user": user, + }) + select { + case <-done: + case err = <-errCh: return err } } case LIST_ZONE_MEMBERS: - users, err := zuh.DB.ListUsers(0, 0) + users, err := zuh.DB.ListUsers(0, 1000) if err != nil { return err } - bs, err := json.Marshal(&ZoneResponse{ - Type: LIST_ZONE_MEMBERS_RESPONSE, - To: "", - From: "", - Payload: map[string]interface{}{ - "users": users, - }, + usersIds := []*ZoneMember{} + for _, user := range users { + usersIds = append(usersIds, &ZoneMember{ + ID: user.ID, + Admin: user.Admin, + Owner: user.Owner, + Config: &ZoneUserConfig{ + DefaultChatRights: user.ChatRights, + DefaultAudioChannelRights: user.AudioChannelRights, + DefaultVideoChannelRights: user.VideoChannelRights, + DefaultMediaRights: user.MediaRights, + DefaultFileRights: user.FileRights, + }, + }) + } + logger.Println("get user done") + done, errCh := zuh.sendDataChannelMessage(LIST_ZONE_MEMBERS_RESPONSE, zuh.ZoneId, req.From, map[string]interface{}{ + "users": usersIds, }) - if err != nil { + select { + case <-done: + logger.Println("send get user done") + case err = <-errCh: return err } - if _, ok := zuh.DataChannels[req.From]; ok { - if err = zuh.DataChannels[req.From].DataChannel.SendText(string(bs)); err != nil { - return err - } - } case MODIFY_USER_CHAT_RIGHTS: } return diff --git a/zoneVideoChannel.go b/zoneVideoChannel.go index 4fc7fb9..289a3f1 100644 --- a/zoneVideoChannel.go +++ b/zoneVideoChannel.go @@ -129,10 +129,10 @@ func (vc *VideoChannel) HandleOffer(ctx context.Context, channelId string, userI errCh <- err return } - _ = atomicallyExecute(vc.localSDMapFlag, func() (err error) { - vc.localSD[userId] = &rawAnswer + if err = peerConnection.SetLocalDescription(rawAnswer); err != nil { + errCh <- err return - }) + } _, _ = sendDCMessage(string(VIDEO_CHANNEL_WEBRTC_ANSWER), hostId, userId, map[string]interface{}{ "to": userId, "from": vc.ID, @@ -146,25 +146,25 @@ func (vc *VideoChannel) HandleOffer(ctx context.Context, channelId string, userI } func (vc *VideoChannel) HandleCounterOffer(ctx context.Context, userId string, sendDCMessage SendDCMessageFunc) (err error) { - if err = atomicallyExecute(vc.rtcPeerConnectionMapFlag, func() (err error) { - if _, ok := vc.rtcPeerConnections[userId]; !ok { - err = fmt.Errorf("no field corresponding peer connection for id %s", userId) - return - } - logger.Println("handling counter offer") - connection := vc.rtcPeerConnections[userId] - err = atomicallyExecute(vc.localSDMapFlag, func() (err error) { - err = connection.SetLocalDescription(*vc.localSD[userId]) - return - }) - return - }); err != nil { - return - } - _ = atomicallyExecute(vc.localSDMapFlag, func() (err error) { - delete(vc.localSD, userId) - return - }) + // if err = atomicallyExecute(vc.rtcPeerConnectionMapFlag, func() (err error) { + // if _, ok := vc.rtcPeerConnections[userId]; !ok { + // err = fmt.Errorf("no field corresponding peer connection for id %s", userId) + // return + // } + // logger.Println("handling counter offer") + // connection := vc.rtcPeerConnections[userId] + // err = atomicallyExecute(vc.localSDMapFlag, func() (err error) { + // err = connection.SetLocalDescription(*vc.localSD[userId]) + // return + // }) + // return + // }); err != nil { + // return + // } + // _ = atomicallyExecute(vc.localSDMapFlag, func() (err error) { + // delete(vc.localSD, userId) + // return + // }) if err = atomicallyExecute(vc.candidateFlag, func() (err error) { for _, candidate := range vc.pendingCandidates[userId] { logger.Println("sending candidate to", userId, candidate) @@ -173,7 +173,7 @@ func (vc *VideoChannel) HandleCounterOffer(ctx context.Context, userId string, s "to": userId, "candidate": candidate.ToJSON().Candidate, "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), }) select { case <-d: @@ -195,12 +195,12 @@ func (vc *VideoChannel) HandleRennegotiationOffer(from string, sdp string, sendD err = fmt.Errorf("no corresponding peer connection for id %s", from) return } - vc.rtcPeerConnections[from].makingOfferLock.Lock() - if vc.rtcPeerConnections[from].makingOffer { - vc.rtcPeerConnections[from].makingOfferLock.Unlock() - return fmt.Errorf("already making an offer or state is stable") - } - vc.rtcPeerConnections[from].makingOfferLock.Unlock() + // vc.rtcPeerConnections[from].makingOfferLock.Lock() + // if vc.rtcPeerConnections[from].makingOffer { + // vc.rtcPeerConnections[from].makingOfferLock.Unlock() + // return fmt.Errorf("already making an offer or state is stable") + // } + // vc.rtcPeerConnections[from].makingOfferLock.Unlock() if err = vc.rtcPeerConnections[from].SetRemoteDescription(webrtc.SessionDescription{SDP: sdp, Type: webrtc.SDPTypeOffer}); err != nil { return } @@ -670,13 +670,13 @@ func (vc *VideoChannel) negotiate(target string, sendDCMessage SendDCMessageFunc if _, ok := vc.rtcPeerConnections[target]; !ok { return } - vc.rtcPeerConnections[target].makingOfferLock.Lock() - vc.rtcPeerConnections[target].makingOffer = true - vc.rtcPeerConnections[target].makingOfferLock.Unlock() + // vc.rtcPeerConnections[target].makingOfferLock.Lock() + // vc.rtcPeerConnections[target].makingOffer = true + // vc.rtcPeerConnections[target].makingOfferLock.Unlock() defer func() { - vc.rtcPeerConnections[target].makingOfferLock.Lock() - vc.rtcPeerConnections[target].makingOffer = false - vc.rtcPeerConnections[target].makingOfferLock.Unlock() + // vc.rtcPeerConnections[target].makingOfferLock.Lock() + // vc.rtcPeerConnections[target].makingOffer = false + // vc.rtcPeerConnections[target].makingOfferLock.Unlock() }() for _, id := range vc.CurrentMembersId { diff --git a/zoneVideoChannelsHandler.go b/zoneVideoChannelsHandler.go index d7b2077..fbebd33 100644 --- a/zoneVideoChannelsHandler.go +++ b/zoneVideoChannelsHandler.go @@ -27,8 +27,14 @@ const ( ) const ( - USER_JOINED_VIDEO_CHANNEL = "user_joined_video_channel" - USER_LEFT_VIDEO_CHANNEL = "user_left_video_channel" + USER_JOINED_VIDEO_CHANNEL = "user_joined_video_channel" + USER_LEFT_VIDEO_CHANNEL = "user_left_video_channel" + VIDEO_CHANNNEL_NAME_EDITED = "video_channel_name_edited" + VIDEO_CHANNNEL_TYPE_EDITED = "video_channel_type_edited" + VIDEO_CHANNEL_MEMBER_REMOVED = "video_channel_member_removed" + VIDEO_CHANNEL_MEMBER_ADDED = "video_channel_member_added" + ADDED_IN_VIDEO_CHANNEL = "added_in_video_channel" + REMOVED_FROM_VIDEO_CHANNEL = "removed_from_video_channel" ) type VideoChannelMember struct { @@ -193,7 +199,7 @@ func (zvch *ZoneVideoChannelsHandler) signalCandidate(from string, to string, ca "to": to, "candidate": candidate.ToJSON().Candidate, "sdpMid": *candidate.ToJSON().SDPMid, - "sdpMlineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), + "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)), }) select { case <-d: @@ -268,15 +274,15 @@ func (zvch *ZoneVideoChannelsHandler) AddNewVideoChannel(channelName string, own } m := make([]string, 0, len(members)) for _, member := range members { - if _, ok := member.(string); ok { - m = append(m, member.(string)) + if mbr, ok := member.(string); ok && mbr != owner { + m = append(m, mbr) } } baseConfig := &VideoChannelConfig{ ID: channelName, Owner: owner, ChannelType: channelType, - Members: m, + Members: append(m,owner), } bs, jsonErr := json.Marshal(baseConfig) if jsonErr != nil { @@ -343,7 +349,7 @@ func (zvch *ZoneVideoChannelsHandler) DeleteVideoChannel(channelId string) (err "userId": member, "channelId": channelId, }) - done, e := zvch.sendDataChannelMessage(REMOVED_FROM_CHAT, "node", member, map[string]interface{}{ + done, e := zvch.sendDataChannelMessage(REMOVED_FROM_VIDEO_CHANNEL, "node", member, map[string]interface{}{ "channelId": channelId, "userId": member, }) @@ -379,7 +385,7 @@ func (zvch *ZoneVideoChannelsHandler) EditVideoChannelName(channelId string, new err = fmt.Errorf("no coresponding videoChannel") return } - bs, err := os.ReadFile(filepath.Join("data", "zones", zvch.ZoneId, "videoChannels", channelId)) + bs, err := os.ReadFile(filepath.Join("data", "zones", zvch.ZoneId, "videoChannels", channelId, "videoChannelConfig.json")) if err != nil { return } @@ -392,7 +398,7 @@ func (zvch *ZoneVideoChannelsHandler) EditVideoChannelName(channelId string, new if err = os.Rename(filepath.Join("data", "zones", zvch.ZoneId, "videoChannels", channelId), filepath.Join("data", "zones", zvch.ZoneId, "videoChannels", newVideoChannelId)); err != nil { return } - f, err := os.OpenFile(filepath.Join("data", "zones", zvch.ZoneId, "videoChannels", newVideoChannelId), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755) + f, err := os.OpenFile(filepath.Join("data", "zones", zvch.ZoneId, "videoChannels", newVideoChannelId, "videoChannelConfig.json"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755) defer func() { _ = f.Close() }() @@ -416,7 +422,7 @@ func (zvch *ZoneVideoChannelsHandler) EditVideoChannelName(channelId string, new "userId": member, "channelId": channelId, }) - done, e := zvch.sendDataChannelMessage(CHAT_NAME_EDITED, "node", member, map[string]interface{}{ + done, e := zvch.sendDataChannelMessage(VIDEO_CHANNNEL_NAME_EDITED, "node", member, map[string]interface{}{ "formerVideoChannelId": channelId, "newVideoChannelId": newVideoChannelId, }) @@ -480,6 +486,10 @@ func (zvch *ZoneVideoChannelsHandler) EditVideoChannelType(channelId string, cha if pubErr := zvch.SetVideoChannelPublicForUser(channelId, member); pubErr != nil { logger.Println(pubErr) } + zvch.sendDataChannelMessage(VIDEO_CHANNNEL_TYPE_EDITED, "node", member, map[string]interface{}{ + "channelId": channelId, + "channelType": channelType, + }) } case PRIVATE: var members = []string{} @@ -491,6 +501,10 @@ func (zvch *ZoneVideoChannelsHandler) EditVideoChannelType(channelId string, cha if pubErr := zvch.SetVideoChannelPrivateForUser(channelId, member); pubErr != nil { logger.Println(pubErr) } + zvch.sendDataChannelMessage(VIDEO_CHANNNEL_TYPE_EDITED, "node", member, map[string]interface{}{ + "channelId": channelId, + "channelType": channelType, + }) } } _ = atomicallyExecute(zvch.VideoChannelsFlag, func() (err error) { @@ -558,7 +572,7 @@ broadcastLoop: for _, member := range vc.Members { for _, m := range addedMembers { if member == m { - done, e := zvch.sendDataChannelMessage(ADDED_IN_CHAT, "node", member, map[string]interface{}{ + done, e := zvch.sendDataChannelMessage(ADDED_IN_VIDEO_CHANNEL, "node", member, map[string]interface{}{ "videoChannel": vc, }) select { @@ -569,7 +583,7 @@ broadcastLoop: continue broadcastLoop } if _, ok := zvch.DataChannels[member]; ok { - done, e := zvch.sendDataChannelMessage(CHAT_MEMBER_ADDED, "node", member, map[string]interface{}{ + done, e := zvch.sendDataChannelMessage(VIDEO_CHANNEL_MEMBER_ADDED, "node", member, map[string]interface{}{ "userId": m, "channelId": vc.ID, }) @@ -635,7 +649,7 @@ func (zvch *ZoneVideoChannelsHandler) RemoveVideoChannelMember(channelId string, } var vc *VideoChannel _ = atomicallyExecute(zvch.VideoChannelsFlag, func() (err error) { - vc := NewVideoChannel(videoChannelConfig.ID, videoChannelConfig.Owner, videoChannelConfig.ChannelType, videoChannelConfig.Members, make([]string, 0), make(map[string]*VideoChannelMember)) + vc = NewVideoChannel(videoChannelConfig.ID, videoChannelConfig.Owner, videoChannelConfig.ChannelType, videoChannelConfig.Members, make([]string, 0), make(map[string]*VideoChannelMember)) zvch.VideoChannels[channelId] = vc return }) @@ -643,7 +657,7 @@ func (zvch *ZoneVideoChannelsHandler) RemoveVideoChannelMember(channelId string, "userId": channelMember, "channelId": channelId, }) - done, e := zvch.sendDataChannelMessage(REMOVED_FROM_CHAT, "node", channelMember, map[string]interface{}{ + done, e := zvch.sendDataChannelMessage(REMOVED_FROM_VIDEO_CHANNEL, "node", channelMember, map[string]interface{}{ "channelId": channelId, "userId": channelMember, }) @@ -657,7 +671,7 @@ broadcastLoop: if member == channelMember { continue broadcastLoop } - done, e := zvch.sendDataChannelMessage(CHAT_MEMBER_REMOVED, "node", member, map[string]interface{}{ + done, e := zvch.sendDataChannelMessage(VIDEO_CHANNEL_MEMBER_REMOVED, "node", member, map[string]interface{}{ "userId": channelMember, "channelId": vc.ID, }) @@ -685,7 +699,7 @@ func (zvch *ZoneVideoChannelsHandler) SetVideoChannelPrivateForUser(channelId st "userId": member, "channelId": channelId, }) - done, e := zvch.sendDataChannelMessage(REMOVED_FROM_CHAT, "node", member, map[string]interface{}{ + done, e := zvch.sendDataChannelMessage(REMOVED_FROM_VIDEO_CHANNEL, "node", member, map[string]interface{}{ "channelId": channelId, "userId": member, }) @@ -715,7 +729,7 @@ func (zvch *ZoneVideoChannelsHandler) SetVideoChannelPublicForUser(channelId str "userId": member, "channelId": channelId, }) - done, e := zvch.sendDataChannelMessage(ADDED_IN_CHAT, "node", member, map[string]interface{}{ + done, e := zvch.sendDataChannelMessage(ADDED_IN_VIDEO_CHANNEL, "node", member, map[string]interface{}{ "videoChannel": videoChannel, }) select { @@ -788,7 +802,7 @@ func (zvch *ZoneVideoChannelsHandler) JoinVideoChannel(channelId string, userId videoChannel.CurrentMembersId = append(videoChannel.CurrentMembersId, userId) videoChannel.CurrentMembers[userId] = &VideoChannelMember{} signalMembers := func(members []string) { - for _, u := range videoChannel.Members { + for _, u := range members { done, e := zvch.sendDataChannelMessage(USER_JOINED_VIDEO_CHANNEL, "node", u, map[string]interface{}{ "userId": userId, "channelId": channelId, @@ -842,7 +856,7 @@ func (zvch *ZoneVideoChannelsHandler) LeaveVideoChannel(channelId string, userId } delete(videoChannel.CurrentMembers, userId) signalMembers := func(members []string) { - for _, u := range videoChannel.Members { + for _, u := range members { done, e := zvch.sendDataChannelMessage(USER_LEFT_VIDEO_CHANNEL, "node", u, map[string]interface{}{ "userId": userId, "channelId": channelId, @@ -1008,17 +1022,17 @@ func (zvch *ZoneVideoChannelsHandler) handleZoneRequest(ctx context.Context, req case string(VIDEO_CHANNEL_WEBRTC_CANDIDATE): logger.Println("handling video channel webrtc candidate") logger.Println(req.Payload) - if err = verifyFieldsString(req.Payload, FROM, "candidate", "sdpMlineIndex", "sdpMid", "channelId", "userId"); err != nil { + if err = verifyFieldsString(req.Payload, FROM, "candidate", "sdpMLineIndex", "sdpMid", "channelId", "userId"); err != nil { return } logger.Println(req.Payload) - i, convErr := strconv.Atoi(req.Payload["sdpMlineIndex"].(string)) + i, convErr := strconv.Atoi(req.Payload["sdpMLineIndex"].(string)) if convErr != nil { return convErr } - sdpMlineIndex := uint16(i) + SDPMLineIndex := uint16(i) sdpMid := req.Payload["sdpMid"].(string) - logger.Println(sdpMid, sdpMlineIndex) + logger.Println(sdpMid, SDPMLineIndex) err = atomicallyExecute(zvch.VideoChannelsFlag, func() (err error) { if _, ok := zvch.VideoChannels[req.Payload["channelId"].(string)]; !ok { err = fmt.Errorf("no channel corresponging the one requested") @@ -1027,7 +1041,7 @@ func (zvch *ZoneVideoChannelsHandler) handleZoneRequest(ctx context.Context, req err = zvch.VideoChannels[req.Payload["channelId"].(string)].AddCandidate(&webrtc.ICECandidateInit{ Candidate: req.Payload["candidate"].(string), SDPMid: &sdpMid, - SDPMLineIndex: &sdpMlineIndex, + SDPMLineIndex: &SDPMLineIndex, }, req.Payload["userId"].(string)) return })