Compare commits
	
		
			6 Commits
		
	
	
		
			v2.1.0-alp
			...
			v2.1.5-alp
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						2737e23369
	
				 | 
					
					
						|||
| 
						
						
							
						
						b4ec470e2f
	
				 | 
					
					
						|||
| 
						
						
							
						
						6012bccf64
	
				 | 
					
					
						|||
| 
						
						
							
						
						4c631db418
	
				 | 
					
					
						|||
| 
						
						
							
						
						26f354d82d
	
				 | 
					
					
						|||
| 
						
						
							
						
						edc86fb706
	
				 | 
					
					
						
@@ -116,16 +116,8 @@ func handleLogin(sPack *smart.SmartPackage, pack protocol.Package) (err error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	go videoPack.Run()
 | 
						go videoPack.Run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	i := 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	videoPack.AddLiveSource(2, func(data []byte) error {
 | 
						videoPack.AddLiveSource(2, func(data []byte) error {
 | 
				
			||||||
		fmt.Println("Есть контакт!")
 | 
							fmt.Println("Есть контакт!")
 | 
				
			||||||
 | 
					 | 
				
			||||||
		i++
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if i > 10 {
 | 
					 | 
				
			||||||
			return errors.New("я устал")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -88,3 +88,49 @@ type EventModelGetAlarmingResponse struct {
 | 
				
			|||||||
	VideoLossAlarmMask   uint `json:"VL_AT"`
 | 
						VideoLossAlarmMask   uint `json:"VL_AT"`
 | 
				
			||||||
	VideoLossStatusMask  uint `json:"VL_AS"`
 | 
						VideoLossStatusMask  uint `json:"VL_AS"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 3.4.1.3
 | 
				
			||||||
 | 
					type EventModelGetAlarmInfoStatusResponse struct {
 | 
				
			||||||
 | 
						ErrorCode              uint                         `json:"ERRORCODE"`
 | 
				
			||||||
 | 
						ErrorCause             string                       `json:"ERRORCAUSE"`
 | 
				
			||||||
 | 
						MotionDetectionAlarm   []MotionDetectionAlarmStatus `json:"MD"`
 | 
				
			||||||
 | 
						IOAlarm                []IOAlarmStatus              `json:"IO"`
 | 
				
			||||||
 | 
						StorageAlarm           []StorageAlarmStatus         `json:"ST"`
 | 
				
			||||||
 | 
						StorageAlarmParameters []CameraCoveredAlarmStatus   `json:"VS"`
 | 
				
			||||||
 | 
						VideoLossAlarm         []VideoLossAlarmStatus       `json:"VL"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 3.4.1.4.1
 | 
				
			||||||
 | 
					type MotionDetectionAlarmStatus struct {
 | 
				
			||||||
 | 
						Status uint `json:"ISA"`
 | 
				
			||||||
 | 
						Mask   uint `json:"LCH"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 3.4.1.4.2
 | 
				
			||||||
 | 
					type IOAlarmStatus struct {
 | 
				
			||||||
 | 
						Status           uint   `json:"ISA"`
 | 
				
			||||||
 | 
						IONumber         uint   `json:"IONO"`
 | 
				
			||||||
 | 
						Mask             uint   `json:"LCH"`
 | 
				
			||||||
 | 
						Name             string `json:"NAME"`
 | 
				
			||||||
 | 
						NameAbbreviation string `json:"NSER"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 3.4.1.4.4
 | 
				
			||||||
 | 
					type CameraCoveredAlarmStatus struct {
 | 
				
			||||||
 | 
						ChannelMask uint `json:"CH"`
 | 
				
			||||||
 | 
						AlarmMask   uint `json:"AT"`
 | 
				
			||||||
 | 
						StatusMask  uint `json:"AS"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 3.4.1.4.4
 | 
				
			||||||
 | 
					type VideoLossAlarmStatus struct {
 | 
				
			||||||
 | 
						Status uint `json:"ISA"`
 | 
				
			||||||
 | 
						Mask   uint `json:"LCH"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 3.4.1.4.21
 | 
				
			||||||
 | 
					type StorageAlarmStatus struct {
 | 
				
			||||||
 | 
						SID   any  `json:"SID"`
 | 
				
			||||||
 | 
						Type  uint `json:"ST"`
 | 
				
			||||||
 | 
						Error uint `json:"E"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,110 +51,3 @@ type MediaStreamModelControlStreamRequest struct {
 | 
				
			|||||||
	AudioValid uint       `json:"AUDIOVALID,omitempty"`
 | 
						AudioValid uint       `json:"AUDIOVALID,omitempty"`
 | 
				
			||||||
	FrameMode  uint       `json:"FRAMEMODE,omitempty"`
 | 
						FrameMode  uint       `json:"FRAMEMODE,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
var ip string = os.Getenv("SERVER_IP")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *Package) MediaRequestDownloadVideo(token int, serial string, session string, camNo int, date string, begin_time string, end_time string, recordID string, serverId int) {
 | 
					 | 
				
			||||||
	e.Payload = map[string]any{
 | 
					 | 
				
			||||||
		"MODULE":    "MEDIASTREAMMODEL",
 | 
					 | 
				
			||||||
		"OPERATION": "REQUESTDOWNLOADVIDEO",
 | 
					 | 
				
			||||||
		"PARAMETER": map[string]any{
 | 
					 | 
				
			||||||
			"PT":         3,
 | 
					 | 
				
			||||||
			"SSRC":       1,
 | 
					 | 
				
			||||||
			"STREAMNAME": "DOWNLOAD" + "_" + serial + "_" + fmt.Sprint(camNo) + "_" + fmt.Sprint(serverId),
 | 
					 | 
				
			||||||
			"STREAMTYPE": 1, // main stream
 | 
					 | 
				
			||||||
			"RECORDID":   recordID,
 | 
					 | 
				
			||||||
			"CHANNEL":    1 << (camNo - 1),
 | 
					 | 
				
			||||||
			"STARTTIME":  date + begin_time,
 | 
					 | 
				
			||||||
			"ENDTIME":    date + end_time,
 | 
					 | 
				
			||||||
			"OFFSETFLAG": 1,
 | 
					 | 
				
			||||||
			"OFFSET":     0,
 | 
					 | 
				
			||||||
			"IPANDPORT":  ip + ":12092",
 | 
					 | 
				
			||||||
			"SERIAL":     token,
 | 
					 | 
				
			||||||
			"DT":         1, // high speed download
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		"SESSION": session,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// main server util
 | 
					 | 
				
			||||||
func (e *Package) MediaRequestAliveVideo(token int, camNo int64, Sid string, serial string, quality int64) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	channel := 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if camNo == 1 {
 | 
					 | 
				
			||||||
		channel = 1
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		channel = 1 << (camNo - 1)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	e.Payload = map[string]any{
 | 
					 | 
				
			||||||
		"MODULE":    "MEDIASTREAMMODEL",
 | 
					 | 
				
			||||||
		"OPERATION": "REQUESTALIVEVIDEO",
 | 
					 | 
				
			||||||
		"PARAMETER": map[string]any{
 | 
					 | 
				
			||||||
			"AUDIOVALID": 1,
 | 
					 | 
				
			||||||
			"CHANNEL":    channel,
 | 
					 | 
				
			||||||
			"FRAMEMODE":  0,
 | 
					 | 
				
			||||||
			"IPANDPORT":  ip + ":12092",
 | 
					 | 
				
			||||||
			"STREAMNAME": "LIVE" + "_" + serial + "_" + fmt.Sprint(camNo),
 | 
					 | 
				
			||||||
			"STREAMTYPE": quality,
 | 
					 | 
				
			||||||
			"SERIAL":     token,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		"SESSION": Sid,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// main server util
 | 
					 | 
				
			||||||
func (e *Package) MediaRequestRemotePlayback(token int, serial string, session string, camNo int, date string, begin_time string, end_time string, serverId int) {
 | 
					 | 
				
			||||||
	if end_time == "" {
 | 
					 | 
				
			||||||
		e.Payload = map[string]any{
 | 
					 | 
				
			||||||
			"MODULE":    "MEDIASTREAMMODEL",
 | 
					 | 
				
			||||||
			"OPERATION": "REQUESTREMOTEPLAYBACK",
 | 
					 | 
				
			||||||
			"PARAMETER": map[string]any{
 | 
					 | 
				
			||||||
				"STREAMNAME": "PLAYBACK" + "_" + fmt.Sprint(serial) + "_" + fmt.Sprint(camNo) + "_" + fmt.Sprint(serverId),
 | 
					 | 
				
			||||||
				"STREAMTYPE": 1, // main stream
 | 
					 | 
				
			||||||
				"VIDEOTYPE":  2, // common files
 | 
					 | 
				
			||||||
				"CHANNEL":    1 << (camNo - 1),
 | 
					 | 
				
			||||||
				"STARTTIME":  date + begin_time,
 | 
					 | 
				
			||||||
				"IPANDPORT":  ip + ":12092",
 | 
					 | 
				
			||||||
				"SERIAL":     token,
 | 
					 | 
				
			||||||
				"PBST":       0,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			"SESSION": session,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		e.Payload = map[string]any{
 | 
					 | 
				
			||||||
			"MODULE":    "MEDIASTREAMMODEL",
 | 
					 | 
				
			||||||
			"OPERATION": "REQUESTREMOTEPLAYBACK",
 | 
					 | 
				
			||||||
			"PARAMETER": map[string]any{
 | 
					 | 
				
			||||||
				"STREAMNAME": "PLAYBACK" + "_" + fmt.Sprint(serial) + "_" + fmt.Sprint(camNo) + "_" + fmt.Sprint(serverId),
 | 
					 | 
				
			||||||
				"STREAMTYPE": 1, // main stream
 | 
					 | 
				
			||||||
				"VIDEOTYPE":  2, // common files
 | 
					 | 
				
			||||||
				"CHANNEL":    1 << (camNo - 1),
 | 
					 | 
				
			||||||
				"STARTTIME":  date + begin_time,
 | 
					 | 
				
			||||||
				"ENDTIME":    date + end_time,
 | 
					 | 
				
			||||||
				"IPANDPORT":  ip + ":12092",
 | 
					 | 
				
			||||||
				"SERIAL":     token,
 | 
					 | 
				
			||||||
				"PBST":       0,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			"SESSION": session,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// main server util
 | 
					 | 
				
			||||||
func (e *Package) ControlRemotePlayback(token int, serial string, session string, camNo int, date string, begin_time string, end_time string, serverId int) {
 | 
					 | 
				
			||||||
	e.Payload = map[string]any{
 | 
					 | 
				
			||||||
		"MODULE":    "MEDIASTREAMMODEL",
 | 
					 | 
				
			||||||
		"OPERATION": "CONTROLREMOTEPLAYBACK",
 | 
					 | 
				
			||||||
		"PARAMETER": map[string]any{
 | 
					 | 
				
			||||||
			"STREAMNAME":  fmt.Sprint(serial) + "_" + fmt.Sprint(camNo) + "_" + fmt.Sprint(serverId),
 | 
					 | 
				
			||||||
			"SERIAL":      token,
 | 
					 | 
				
			||||||
			"PALYBACKCMD": 5,         // main stream
 | 
					 | 
				
			||||||
			"CHANNEL":     268435455, // common files
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		"SESSION": session,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -152,6 +152,8 @@ type SAP struct {
 | 
				
			|||||||
	UN  int
 | 
						UN  int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 7.24.3
 | 
				
			||||||
 | 
					// Alarm processing parameters
 | 
				
			||||||
type APR struct {
 | 
					type APR struct {
 | 
				
			||||||
	AR ARR
 | 
						AR ARR
 | 
				
			||||||
	SS SS
 | 
						SS SS
 | 
				
			||||||
@@ -167,13 +169,6 @@ type SS struct {
 | 
				
			|||||||
	EN int
 | 
						EN int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type UAP struct {
 | 
					 | 
				
			||||||
	EN  int
 | 
					 | 
				
			||||||
	AS  int
 | 
					 | 
				
			||||||
	VT  int
 | 
					 | 
				
			||||||
	SDT int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type PVLAS struct {
 | 
					type PVLAS struct {
 | 
				
			||||||
	EN  int
 | 
						EN  int
 | 
				
			||||||
	AS  int
 | 
						AS  int
 | 
				
			||||||
@@ -257,8 +252,10 @@ type MCMS struct {
 | 
				
			|||||||
	SP []SP // Параметры сервера
 | 
						SP []SP // Параметры сервера
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 7.12.1
 | 
				
			||||||
 | 
					// Central server configuration
 | 
				
			||||||
type SP struct {
 | 
					type SP struct {
 | 
				
			||||||
	EN     int    // Статус сервера
 | 
						EN     int    // Флаг включения
 | 
				
			||||||
	CP     int    // Протокол подключения
 | 
						CP     int    // Протокол подключения
 | 
				
			||||||
	NWT    int    // Способ подключения
 | 
						NWT    int    // Способ подключения
 | 
				
			||||||
	CS     string // Адрес сервера
 | 
						CS     string // Адрес сервера
 | 
				
			||||||
@@ -269,7 +266,45 @@ type SP struct {
 | 
				
			|||||||
	MUPORT int    // UDP-порт медиасервера
 | 
						MUPORT int    // UDP-порт медиасервера
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 7.28
 | 
				
			||||||
 | 
					// NVR remote device parameters
 | 
				
			||||||
 | 
					type REDEV struct {
 | 
				
			||||||
 | 
						EN      int    // Флаг включения
 | 
				
			||||||
 | 
						LOCK    int    // ???
 | 
				
			||||||
 | 
						CHL     int    // Номер канала на устройстве
 | 
				
			||||||
 | 
						RECHL   int    // ???
 | 
				
			||||||
 | 
						ONLINE  int    // Доступно ли сейчас устройство
 | 
				
			||||||
 | 
						RETYPE  int    // Тип устройства
 | 
				
			||||||
 | 
						PROTYPE int    // Тип протокола
 | 
				
			||||||
 | 
						IPTYPE  int    // Тип IP-адреса (IPv4/IPv6)
 | 
				
			||||||
 | 
						CONTYPE int    // ???
 | 
				
			||||||
 | 
						SW      int    // Источник поступаемого сигнала
 | 
				
			||||||
 | 
						REPORT  int    // Порт камеры
 | 
				
			||||||
 | 
						REIP    string // IP камеры
 | 
				
			||||||
 | 
						ID      int    // Идентификатор камеры
 | 
				
			||||||
 | 
						RENAME  string // Название устройства
 | 
				
			||||||
 | 
						USER    string // Имя пользователя
 | 
				
			||||||
 | 
						PWD     string // Пароль
 | 
				
			||||||
 | 
						URL     string // ???
 | 
				
			||||||
 | 
						CMDPORT uint   // ???
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 7.29
 | 
				
			||||||
 | 
					// Panel emergency alarm
 | 
				
			||||||
 | 
					type UAP struct {
 | 
				
			||||||
 | 
						EN  int    // Флаг включения
 | 
				
			||||||
 | 
						AS  int    // Уровень тревоги
 | 
				
			||||||
 | 
						T   int    // ???
 | 
				
			||||||
 | 
						VT  int    // ???
 | 
				
			||||||
 | 
						UN  string // Имя тревоги
 | 
				
			||||||
 | 
						UO  string // Имя тривоги на экране водителя
 | 
				
			||||||
 | 
						APR APR    // Параметры обработки тревоги
 | 
				
			||||||
 | 
						// AP  AP     // Параметры тревоги
 | 
				
			||||||
 | 
						SDT int // ???
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 7.30
 | 
					// 7.30
 | 
				
			||||||
 | 
					// Network monitoring status parameters
 | 
				
			||||||
type PGDSM struct {
 | 
					type PGDSM struct {
 | 
				
			||||||
	PGPS PGPS `json:"PGPS,omitempty"`
 | 
						PGPS PGPS `json:"PGPS,omitempty"`
 | 
				
			||||||
	PDSM PDSM `json:"PDSM,omitempty"`
 | 
						PDSM PDSM `json:"PDSM,omitempty"`
 | 
				
			||||||
@@ -286,6 +321,7 @@ type PGPS struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 7.30.2
 | 
					// 7.30.2
 | 
				
			||||||
 | 
					// Device status parameter
 | 
				
			||||||
type PDSM struct {
 | 
					type PDSM struct {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -323,6 +359,7 @@ type Setting struct {
 | 
				
			|||||||
	EOSD      []EOSD    `json:"EOSD,omitempty"`
 | 
						EOSD      []EOSD    `json:"EOSD,omitempty"`
 | 
				
			||||||
	IOP       []IOP     `json:"IOP,omitempty"`
 | 
						IOP       []IOP     `json:"IOP,omitempty"`
 | 
				
			||||||
	SAP       SAP       `json:"SAP,omitempty"`
 | 
						SAP       SAP       `json:"SAP,omitempty"`
 | 
				
			||||||
 | 
						REDEV     []REDEV   `json:"REDEV,omitempty"`
 | 
				
			||||||
	UAP       UAP       `json:"UAP,omitempty"`
 | 
						UAP       UAP       `json:"UAP,omitempty"`
 | 
				
			||||||
	PGDSM     PGDSM     `json:"PGDSM,omitempty"`
 | 
						PGDSM     PGDSM     `json:"PGDSM,omitempty"`
 | 
				
			||||||
	PVLAS     PVLAS     `json:"PVLAS,omitempty"`
 | 
						PVLAS     PVLAS     `json:"PVLAS,omitempty"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,16 @@ const (
 | 
				
			|||||||
	length  = 6
 | 
						length  = 6
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewAutoSmartChannelPackage(mainSmartPackage *SmartPackage) (*SmartChannelPackage, error) {
 | 
				
			||||||
 | 
						conn, err := net.Dial(mainSmartPackage.conn.RemoteAddr().Network(), mainSmartPackage.conn.RemoteAddr().String())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NewSmartChannelPackage(conn, mainSmartPackage)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewSmartChannelPackage(conn net.Conn, mainSmartPackage *SmartPackage) (*SmartChannelPackage, error) {
 | 
					func NewSmartChannelPackage(conn net.Conn, mainSmartPackage *SmartPackage) (*SmartChannelPackage, error) {
 | 
				
			||||||
	pack := NewSmartPackage(conn)
 | 
						pack := NewSmartPackage(conn)
 | 
				
			||||||
	pack.pack.Payload.Session = mainSmartPackage.pack.Payload.Session
 | 
						pack.pack.Payload.Session = mainSmartPackage.pack.Payload.Session
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,10 +6,18 @@ import (
 | 
				
			|||||||
	"encoding/hex"
 | 
						"encoding/hex"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GenerateVerifyKey(key string) string {
 | 
					func generateHMAC(key string, data string) string {
 | 
				
			||||||
	mac := hmac.New(md5.New, []byte(key))
 | 
						mac := hmac.New(md5.New, []byte(key))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mac.Write([]byte(key))
 | 
						mac.Write([]byte(data))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return hex.EncodeToString(mac.Sum(nil))
 | 
						return hex.EncodeToString(mac.Sum(nil))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GenerateVerifyKey(key string) string {
 | 
				
			||||||
 | 
						return generateHMAC(key, key)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GeneratePasswordHash(password string) string {
 | 
				
			||||||
 | 
						return generateHMAC("streaming", password)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user