Giter VIP home page Giter VIP logo

lagrangego's Introduction

LagrangeGo

ntqq 协议的golang实现 移植于 Lagrange.Core / lagrange-python / MiraiGo

使用前声明

本项目为协议实现,不推荐直接使用。

使用方法

go get -u github.com/LagrangeDev/LagrangeGo

支持的功能

协议支持

已完成功能/开发计划列表

登录

  • 账号密码登录
  • 二维码登录
  • 验证码提交
  • 设备锁验证
  • 错误信息解析

消息类型

  • 文本
  • 图片
  • 语音
  • 表情
  • At
  • 回复
  • 长消息(仅群聊/私聊)
  • 链接分享
  • 小程序(暂只支持RAW)
  • 短视频
  • 合并转发
  • 群文件(上传与接收信息)

事件

  • 好友消息
  • 群消息
  • 临时会话消息
  • 登录号加群
  • 登录号退群(包含T出)
  • 新成员进群/退群
  • 群/好友消息撤回
  • 群禁言
  • 群成员权限变更
  • 收到邀请进群通知
  • 收到其他用户进群请求
  • 新好友
  • 新好友请求
  • 客户端离线
  • 群提示 (戳一戳/运气王等)

主动操作

为防止滥用,不支持主动邀请新成员进群

  • 发送群消息
  • 发送好友消息
  • 发送临时会话消息
  • 获取/刷新群列表
  • 获取/刷新群成员列表
  • 获取/刷新好友列表
  • 获取群荣誉 (龙王/群聊火焰等)
  • 处理加群请求
  • 处理被邀请加群请求
  • 处理好友请求
  • 撤回群消息
  • 群公告设置
  • 获取群文件下载链接
  • 群设置 (全体禁言/群名)
  • 修改群成员Card
  • 修改群成员头衔
  • 群成员邀请
  • 群成员禁言/解除禁言
  • T出群成员
  • 戳一戳群友
  • 获取陌生人信息

不支持的协议

基于 QQ钱包支付用户服务协议 不支持一切有关QQ钱包的协议

4.13 您不得利用本服务实施下列任一的行为:
(9) 侵害QQ钱包支付服务系統;

  • QQ钱包协议(收款/付款等)

贡献者

Contributors

MiraiGo Contributors

lagrangego's People

Contributors

redmomn avatar fumiama avatar szzrain avatar linwenxuan04 avatar justanotherid avatar kusagumina avatar executor-cheng avatar fripine avatar dependabot[bot] avatar 2mf8 avatar

Stargazers

Amagi_Yukisaki avatar NeP avatar Ran avatar  avatar yun avatar 轩逸飞梦 avatar Android avatar Oちゃん avatar Prankster 199 avatar  avatar XinMu avatar Yu Xin avatar aixichen avatar  avatar WhitePaper233 avatar  avatar Sirian avatar  avatar  avatar  avatar  avatar SnowArk avatar LI avatar  avatar  avatar XieXiLin avatar  avatar sansiny avatar LiangXinYu avatar MK111 avatar Liliya233 avatar Sparrow He avatar  avatar  avatar Roy avatar Andvari avatar Mikage avatar Bakadax avatar xianjun avatar TianMeng avatar DreamOneX avatar  avatar  avatar WDN avatar Mr.N avatar  avatar Lie_Kong avatar snomiao avatar  avatar  avatar  avatar 仑质 avatar Seyana. avatar RainyHallways avatar Lin avatar 謬紗特 avatar Komei_DiSanXian avatar shizuku_nia avatar  avatar weigui404 avatar Aimer Neige avatar Umb avatar 莲宝坏坏坏 avatar Jarred Block avatar scarletborder avatar  avatar Lv Yonghuan avatar wear工程师 avatar  avatar 三千 avatar Ankio avatar  avatar  avatar Noth Amor avatar Junyan Qin avatar Xiangze Li avatar Kernel Jackson avatar Ren Zengqiang avatar scjtqs avatar 药要吃 avatar sumer avatar INSide_734 avatar Maho Shojo Kierkegaard avatar Monine Melolaris avatar  avatar LZY avatar  avatar  avatar  avatar  avatar aicorein avatar 简律纯 avatar  avatar GreenYoshi (Wang Han) avatar Cinte avatar  avatar IllTamer avatar 演变 avatar  avatar  avatar

Watchers

Lucian avatar  avatar TheSnowfield avatar  avatar Lie_Kong avatar  avatar

lagrangego's Issues

禁止登录

今天重新下载后运行发现提示禁止登录了,使用版本:Linux 3.2.10-25765

关于许可证问题及其解决办法

说明

注意到本项目有多处借鉴了 MiraiGo 的代码,现就此向贵方提出如下要求:

  1. 在 README 中注明此项目借鉴了 MiraiGo
  2. 在源代码中所有来源为 MiraiGo 的位置使用注释方式标明出处。
  • 例1:
    package proto
    import (
    "reflect"
    "google.golang.org/protobuf/types/known/anypb"
    "github.com/RomiChan/protobuf/proto"
    )
    // TODO: move to a new package
    const debug = false
    type Message = any
    func Marshal(m Message) ([]byte, error) {
    b, err := proto.Marshal(m)
    if err != nil {
    return b, err
    }
    if debug {
    t := reflect.TypeOf(m).Elem()
    n := reflect.New(t)
    err = Unmarshal(b, n.Interface())
    if err != nil {
    panic(err)
    }
    if reflect.DeepEqual(m, n) {
    panic("not equal")
    }
    }
    return b, err

    中,添加
    package proto
    
    // from https://github.com/Mrs4s/MiraiGo/blob/master/internal/proto/wrapper.go
    
    import (
        "reflect"
    
        "google.golang.org/protobuf/types/known/anypb"
    
        "github.com/RomiChan/protobuf/proto"
    )
    
    // TODO: move to a new package
    const debug = false
    
    ...
  • 例2:
    package client
    import (
    "reflect"
    "runtime/debug"
    "sync"
    "github.com/LagrangeDev/LagrangeGo/event"
    "github.com/LagrangeDev/LagrangeGo/message"
    "github.com/LagrangeDev/LagrangeGo/utils"
    )
    var eventLogger = utils.GetLogger("event")
    // protected all EventHandle, since write is very rare, use
    // only one lock to save memory
    var eventMu sync.RWMutex
    type EventHandle[T any] struct {
    // QQClient?
    handlers []func(client *QQClient, event T)
    }
    func (handle *EventHandle[T]) Subscribe(handler func(client *QQClient, event T)) {
    eventMu.Lock()
    defer eventMu.Unlock()
    // shrink the slice
    newHandlers := make([]func(client *QQClient, event T), len(handle.handlers)+1)
    copy(newHandlers, handle.handlers)
    newHandlers[len(handle.handlers)] = handler
    handle.handlers = newHandlers

    中,添加
    package client
    
    // from https://github.com/Mrs4s/MiraiGo/blob/master/client/events.go
    
    import (
        "reflect"
        "runtime/debug"
        "sync"
    
        "github.com/LagrangeDev/LagrangeGo/event"
        "github.com/LagrangeDev/LagrangeGo/message"
    
        "github.com/LagrangeDev/LagrangeGo/utils"
    )
    
    var eventLogger = utils.GetLogger("event")
  • 如果遇到一个文件中部分借鉴的情况,请分别在相应位置注明。
  1. 由于 MiraiGo 所使用的 GNU Affero General Public License v3.0 协议的传染性,贵方需要将此仓库协议从 GPLv3 变更为 AGPLv3。

其它解决方式

贵方也可选择完全删除仓库中与 MiraiGo 相同或相似的代码,这样便可不必执行上述要求。

使用Windows 9.9.12-25493版本登录提示低版本了

使用Windows 9.9.12-25493版本登录提示低版本了

`// nolint
package main

import (
"fmt"
"os"
"os/signal"
"path"
"strings"
"syscall"
"time"

"github.com/LagrangeDev/LagrangeGo/client"
"github.com/LagrangeDev/LagrangeGo/client/auth"
"github.com/LagrangeDev/LagrangeGo/message"
"github.com/LagrangeDev/LagrangeGo/utils"
"github.com/mattn/go-colorable"
"github.com/sirupsen/logrus"

)

var (
dumpspath = "dump"
)

func main() {
appInfo := auth.AppList["windows"]["9.9.12-25493"]
deviceInfo := &auth.DeviceInfo{
Guid: "cfcd208495d565ef66e7dff9f98764da",
DeviceName: "Lagrange-DCFCD07E",
SystemKernel: "Windows 10.0.22631",
KernelVersion: "10.0.22631",
}

qqclient := client.NewClient(0, "https://sign.lagrangecore.org/api/sign", appInfo)
qqclient.SetLogger(protocolLogger{})
qqclient.UseDevice(deviceInfo)
data, err := os.ReadFile("sig.bin")
if err != nil {
	logrus.Warnln("read sig error:", err)
} else {
	sig, err := auth.UnmarshalSigInfo(data, true)
	if err != nil {
		logrus.Warnln("load sig error:", err)
	} else {
		qqclient.UseSig(sig)
	}
}

qqclient.GroupMessageEvent.Subscribe(func(client *client.QQClient, event *message.GroupMessage) {
	if event.ToString() == "114514" {
		img, _ := message.NewFileImage("testgroup.png")
		_, err := client.SendGroupMessage(event.GroupUin, []message.IMessageElement{img})
		if err != nil {
			return
		}
	}
})

qqclient.PrivateMessageEvent.Subscribe(func(client *client.QQClient, event *message.PrivateMessage) {
	img, _ := message.NewFileImage("testprivate.png")
	_, err := client.SendPrivateMessage(event.Sender.Uin, []message.IMessageElement{img})
	if err != nil {
		return
	}
})

err = qqclient.Login("", "qrcode.png")
if err != nil {
	logrus.Errorln("login err:", err)
	return
}

defer qqclient.Release()

defer func() {
	data, err = qqclient.Sig().Marshal()
	if err != nil {
		logrus.Errorln("marshal sig.bin err:", err)
		return
	}
	err = os.WriteFile("sig.bin", data, 0644)
	if err != nil {
		logrus.Errorln("write sig.bin err:", err)
		return
	}
	logrus.Infoln("sig saved into sig.bin")
}()

// setup the main stop channel
mc := make(chan os.Signal, 2)
signal.Notify(mc, os.Interrupt, syscall.SIGTERM)
for {
	switch <-mc {
	case os.Interrupt, syscall.SIGTERM:
		return
	}
}

}

// protocolLogger from https://github.com/Mrs4s/go-cqhttp/blob/a5923f179b360331786a6509eb33481e775a7bd1/cmd/gocq/main.go#L501
type protocolLogger struct{}

const fromProtocol = "Lgr -> "

func (p protocolLogger) Info(format string, arg ...any) {
logger.Infof(fromProtocol+format, arg...)
}

func (p protocolLogger) Warning(format string, arg ...any) {
logger.Warnf(fromProtocol+format, arg...)
}

func (p protocolLogger) Debug(format string, arg ...any) {
logger.Debugf(fromProtocol+format, arg...)
}

func (p protocolLogger) Error(format string, arg ...any) {
logger.Errorf(fromProtocol+format, arg...)
}

func (p protocolLogger) Dump(data []byte, format string, arg ...any) {
message := fmt.Sprintf(format, arg...)
if _, err := os.Stat(dumpspath); err != nil {
err = os.MkdirAll(dumpspath, 0o755)
if err != nil {
logger.Errorf("出现错误 %v. 详细信息转储失败", message)
return
}
}
dumpFile := path.Join(dumpspath, fmt.Sprintf("%v.dump", time.Now().Unix()))
logger.Errorf("出现错误 %v. 详细信息已转储至文件 %v 请连同日志提交给开发者处理", message, dumpFile)
_ = os.WriteFile(dumpFile, data, 0o644)
}

const (
// 定义颜色代码
colorReset = "\x1b[0m"
colorRed = "\x1b[31m"
colorYellow = "\x1b[33m"
colorGreen = "\x1b[32m"
colorBlue = "\x1b[34m"
colorWhite = "\x1b[37m"
)

var logger = logrus.New()

func init() {
logger.SetLevel(logrus.TraceLevel)
logger.SetFormatter(&ColoredFormatter{})
logger.SetOutput(colorable.NewColorableStdout())
}

type ColoredFormatter struct{}

func (f *ColoredFormatter) Format(entry *logrus.Entry) ([]byte, error) {
// 获取当前时间戳
timestamp := time.Now().Format("2006-01-02 15:04:05")

// 根据日志级别设置相应的颜色
var levelColor string
switch entry.Level {
case logrus.DebugLevel:
	levelColor = colorBlue
case logrus.InfoLevel:
	levelColor = colorGreen
case logrus.WarnLevel:
	levelColor = colorYellow
case logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel:
	levelColor = colorRed
default:
	levelColor = colorWhite
}

return utils.S2B(fmt.Sprintf("[%s] [%s%s%s]: %s\n",
	timestamp, levelColor, strings.ToUpper(entry.Level.String()), colorReset, entry.Message)), nil

}
`

这是使用的登录

大佬, 为什么群聊消息好像没发送出去??

qqclient.GroupMessageEvent.Subscribe(func(client *client.QQClient, event *message.GroupMessage) {
	_, err := client.SendGroupMessage(event.GroupUin, []message.IMessageElement{&message.TextElement{Content: "2"}})
	fmt.Printf("err: %v\n", err)
})

还有对于文档  https://github.com/LagrangeDev/LagrangeGo/blob/master/docs/examples/index.md
qqclient.GroupMessageEvent.Subscribe(func(client *client.QQClient, event *message.GroupMessage) {
	if event.ToString() == "114514" {
		img, _ := os.ReadFile("testgroup.png")
		_, err := client.SendGroupMessage(event.GroupCode, []message.IMessageElement{&message.GroupImageElement{Stream: img}})
		if err != nil {
			return
		}
	}
	GroupCode 这个字段我没有找到是否需要更新一下demo文档?

[Bug] GroupMemberLeaveEvent 的 OperatorUid 解析错误

被踢出群返回的 OperatorUid 似乎不是正常的 Uid 格式并且无法通过缓存找到 Uin
与其他的正常返回的 OperatorUid 进行对比:
禁言事件返回的 OperatorUid:

u_ulFxYKDM9BuGiWlf9_UGDw

踢出事件返回的 OperatorUid:


X
�u_ulFxYKDM9BuGiWlf9_UGDw����    Ա 0*08b16d77d4517427eb047c61447e3bb930ddd70eb63ccc199

我注意到正确的 Uid 包含在这段字符串内,可能是什么地方没有被正确解析?但是我对比了一下C#版本的代码没有发现问题在什么地方

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.