/images/avatar-home.jpeg

小米内测自动答题脚本

为啥要搞这个脚本呢,是真的被恶心到了,我记得我还是从高二开始就用的小米,MIUI从以前的真香,变成BUG一堆、负优化的UI。买了个小米11,到手3个月真心被这系统恶心到了,越更新越辣鸡,什么哈曼音效砍了(MIUI 12.0.22),4600ma的电池用着和老手机没什么区别,1月份首发到手,结果现在4月初所谓的MIUI12.5还没出来,以前可以随便刷开发版,现在也要个申请,关键是tmd不让过,无法了……

这个脚本本来是打算为了答题申请内测,现在搞完反而没想法了,等用坏了以后就不用小米手机。

本脚本仅交流使用,不提供任何技术支持。

https://img.qyi.io/images/2021/04/01/image8c1416e67201de53.png

效果如下:

https://p6.toutiaoimg.com/img/tos-cn-i-0022/e8f8a47b06d74884a4c24844f747bc53~tplv-obj:424:896.gif

脚本运行环境是auto.js免费版4.0,看了半个小时直接开始撸了,附带采集功能,题库中没有的题目自动入库,代码如下:

toast("开始运行!");  
// click("再次答题");  
// click("同意协议并开始答题");  
var myAPP = {};  // 唯一的全局变量myAPP   
myAPP.packageName = "com.xiaomi.vipaccount";  
console.log('查找题目');  
var patt = /,,.*(?=多选题|单选题)/g;

for (let i = 0; i < 40; i++) {  
  let title = textContains("选题").findOne().text();  
  console.log('?????????')  
  var reg=new RegExp(patt);  
  var result = reg.exec(title);  
  // console.log('题目',title);  
  title = result[0].replace(',,','').replace(' ','');  
  console.log(result[0]);  
  // break;  
  if (title == undefined) {  
    continue;  
  }  
  console.log("题目:", title);  
// console.log(title.textMatches(patt));  
  let an;  
  try {  
    an = textContains("未选中").find();  
  } catch (error) {  
    console.log('异常');  
  }

  /*增加题目到题库*/  
  let post = {};  
  post.question = title;  
  for (let i = 0; i < an.length; i++) {  
    let an_t = an[i].text().replace(',未选中', '');  
    if (i === 0) {  
      post.answer_a = an_t;  
    } else if (i === 1) {  
      post.answer_b = an_t;  
    } else if (i === 2) {  
      post.answer_c = an_t;  
    } else if (i === 3) {  
      post.answer_d = an_t;  
    }  
  }  
  // console.log(JSON.stringify(post));  
  let url = "http://192.168.15.227:8012/add_question";  
  let url_select = "http://192.168.15.227:8012/getQuestion?title=" + title;  
  var r = http.get(url_select);  
  var data_j = JSON.parse(r.body.string());  
  console.log('返回结果:', data_j);  
  if(data_j.code === -1){  
    // 没有题库,直接提交到数据库  
    http.postJson(url, post);  
    console.log(post);  
    click(post.answer_a + ",未选中");  
    sleep(1000);  
    click("下一题");  
  }else{  
    // data_j.  
    var nc = Number(data_j.data.answer);  
    console.log('答案',nc);  
    if ((nc & 16) === 16) {  
      console.log('点击',data_j.data.answer_a + ',未选中');  
      click(data_j.data.answer_a);  
    }  
    if ((nc & 32) === 32) {  
      console.log('点击',data_j.data.answer_b + ',未选中');  
      click(data_j.data.answer_b);  
    }  
    if ((nc & 64) === 64) {  
      console.log('点击',data_j.data.answer_c +',未选中');  
      click(data_j.data.answer_c);  
    }  
    if ((nc & 128) === 128) {  
      console.log('点击',data_j.data.answer_d + ',未选中');  
      click(data_j.data.answer_d);  
    }  
    sleep(1000);  
    click("下一题");  
  }

}

不知道为啥,正则那里用了前置断言就报错……

H2 数据库配置DATABASE_TO_UPPER区分大小写无效

背景

刚接触这个h2内存数据库,被这个问题折腾2天了,我使用的是mybatis-plus,而H2默认 表名、列名都是大写,和mybatis plus默认的策略有冲突(SQL大写变小写加下划线),虽然可以配置关闭掉,但全部大写还是看着不习惯……

所以百度搜了下关闭的方法,在url链接上加上 DATABASE_TO_UPPER=FALSE 就行了,但这问题就来了,由于我加了 AUTO_SERVER=TRUE 

也就是混合模式,在idea中修改数据就会

报错:

[90079][90079] org.h2.jdbc.JdbcSQLSyntaxErrorException: Schema "information_schema" not found; SQL statement:  
select catalog_name from information_schema.catalogs [90079-200].  
Schema "information_schema" not found; SQL statement:  
select catalog_name from information_schema.catalogs [90079-200]  
(458 ms)

https://img.qyi.io/images/2021/03/28/image717ee6b902512e2a.png

解决办法

后面搜索到 github同样有人遇到了这个问题,给出的解决方法是使用 DATABASE_TO_LOWER=TRUE

参数。记得删除原来的库重新生成

我的配置如下:

spring.datasource.url=jdbc:h2:./db/qq_bot;DATABASE_TO_LOWER=TRUE;AUTO_SERVER=TRUE;AUTO_SERVER_PORT=9092;USER=sa;PASSWORD=sa;  
#spring.datasource.h2.username=admin  
#spring.datasource.h2.password=admin  
spring.datasource.h2.driver-class-name=org.h2.Driver

至于我为啥把用户名密码配置在url里…….那就是另外个问题了,哈哈哈

关于TDengine使用上一些注意事项(坑) - 未完

第一次使用时序数据库,本来想用influxdb,搜了下说是国产的TDengine 性能更好,sql和原生差不多,所以就想尝试下,但学到现在一路的坑啊……

这里我使用的是TDengine Docker版,安装命令

docker run -d -v /etc/taos:/etc/taos -p 6030:6030 -p 6035:6035 -p 6041:6041 -p 6030-6040:6030-6040/udp tdengine/tdengine:2.0.0.0

注意版本号,默认账户密码为:root/taosdata

常见问题

1、 java.sql.SQLException: TDengine Error: Invalid timestamp 

如果本地时区要和服务端一样

解答:https://github.com/taosdata/TDengine/issues/4345#

2、本地驱动版本、maven TDengine  版本、服务端版本 要一致

3、本地开发需要设置TDengine驱动环境变量

-Djava.library.path=C:\TDengine\driver

https://img.qyi.io/images/2021/03/11/image8956d5d4a4db08ba.png

RabbitMQ Java Client 并发问题思考(一)

此篇文章仅作为个人笔记,由于初学难免有理解错误的地方,请大佬指正~

由于我这个部分没有使用SpringBoot,使用的是RabbitMq java Client API 所以在Springboot上的有些功能用不了,只能手动实现,故在思维上走了一个坑。

测试代码:

    public static void main(String[] args) {  
        //连接工厂  
        ConnectionFactory factory = new ConnectionFactory();  
//        factory.useNio();  
//        factory.setNioParams(new NioParams().setNbIoThreads(4));  
        factory.setHost("xxx.xxx.xxx.xxx");  
        factory.setPort(port);  
        factory.setUsername("username");  
        factory.setPassword("password");  
        factory.setVirtualHost("msgpush");  
//        f.setConnectionTimeout(5000);  
//        f.setHandshakeTimeout(3000);  
        ExecutorService service = Executors.newFixedThreadPool(30);  
        factory.setSharedExecutor(service);  
        // 设置自动恢复  
        factory.setAutomaticRecoveryEnabled(true);  
        factory.setNetworkRecoveryInterval(2);  
        factory.setTopologyRecoveryEnabled(true);// 设置不重新声明交换器,队列等信息。  
        System.out.println("检索请求的最大频道数:" + factory.getRequestedChannelMax());  
//        f.setRequestedChannelMax(10);  
        try {  
//            Channel channel = f.newConnection().createChannel();  
            //建立连接  
            Connection c = factory.newConnection("push Client");  
            c.addShutdownListener(new ShutdownListener() {  
                @Override  
                public void shutdownCompleted(ShutdownSignalException e) {  
                    System.out.println( "断线了......");  
                }  
            });  
            //建立信道  
            Channel ch = c.createChannel();  
            //声明队列,如果该队列已经创建过,则不会重复创建  
            //ch.queueDeclare("QueueWX", false, false, false, null);  
            System.out.println("等待接收数据");  
            // 单条消息的大小限制,一般设为0或不设置,不限制大小  
            int prefecthSize = 0;  
            // 告诉RabbitMQ不要同时给消费端推送n条消息,一旦有n个消息还没ack,则该consumer将block掉,直到有ack;注意在自动应答下不生效  
            int prefecthCount = 5;  
            // 表示是否应用于channel上,即是channel级别还是consumer级别  
            boolean global = true;  
            ch.basicQos(3);  
            //消费者取消时的回调对象1  
            CancelCallback cancelHandel = new CancelCallback() {  
                @Override  
                public void handle(String consumerTag) throws IOException {  
                    System.out.println(consumerTag + "  链接已断开");  
                }  
            };  
            /*微信*/  
            DeliverImpl deliverWx = new DeliverImpl(ch, MQEnum.QUEUE_WX);  
            ch.basicConsume(MQEnum.QUEUE_WX.getData(), false, deliverWx, cancelHandel);  
            /*企业微信*/  
            DeliverImpl deliver = new DeliverImpl(ch, MQEnum.QUEUE_WORKWX);  
            //第二个参数为消息回执,消息确认处理完成,为true为自动确认,只要消息发送到消费者即消息处理成功;为false为,手动发送确认回执,服务器才认为这个消息处理成功  
            ch.basicConsume(MQEnum.QUEUE_WORKWX.getData(), false, deliver, cancelHandel);  
            /*钉钉*/  
            DeliverImpl deliverDing = new DeliverImpl(ch, MQEnum.QUEUE_DINGDING);  
            ch.basicConsume(MQEnum.QUEUE_DINGDING.getData(), false, deliverDing, cancelHandel);  
            /*tg*/  
            DeliverImpl deliverTg = new DeliverImpl(ch, MQEnum.QUEUE_TG);  
            ch.basicConsume(MQEnum.QUEUE_TG.getData(), false, deliverTg, cancelHandel);

        } catch (IOException e) {  
            e.printStackTrace();  
        } catch (TimeoutException e) {  
            e.printStackTrace();  
        }  
    }

 

国内WordPress启用谷歌验证码(noCaptcha )

众所周知,noCaptcha 的验证接口和css是被屏蔽的,所以可以使用 recaptcha.net 这个google在国内的域名。想着有轮子绝不撸代码的想法,试了几款插件,找到一款对代码修改最小的插件(或者直接不用修改,我目前使用的这款主题需要手动修改)。

  1、安装插件

https://cn.wordpress.org/plugins/advanced-nocaptcha-recaptcha/

https://img.qyi.io/images/2021/03/01/576-chrome_yFVaX3SnDo5b51f5c3dea25e85.md.png

2、启用并设置插件

注册 recaptcha 秘钥。https://www.google.com/recaptcha/admin/

https://img.qyi.io/images/2021/03/01/KxwG9cyJBbd57c6a6823092ced.png

 

https://img.qyi.io/images/2021/03/01/yU0yNqx9612510046445b502cf.md.png

https://img.qyi.io/images/2021/03/01/image0241afb19b95aff0.png

 

3、修改主题代码(可选)

 

https://img.qyi.io/images/2021/03/01/image167e565efe297a56.png

 

同理,如果评论的时候没有进行验证,提交没有显示错误信息,那么只需要对提交评论的 g-recaptcha-response 字段就行判断一下就可以了。

每款主题的输错错误方式不一样,所以自己修改~

https://img.qyi.io/images/2021/03/01/imaged254a45e3a766dab.png

Spring Boot 通过SMTP发送电子邮件(ssl/tls)

使用的技术:

  • Spring Boot 2.3.2
  • Java Mail 1.6.2
  • Maven 3
  • Java 8

1、添加依赖

spring-boot-starter-mail
<!-- send email -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

2、配置 application.properties

这里得注意下了,除了邮件服务商说明同时支持tls或者ssl,否则需要将tls/ssl分开配置

,这里我使用得是outlook,所以只支持 tls 587端口,一开始我配置成ssl,走了一个坑。

spring.mail.host=smtp.gmail.com  
spring.mail.port=587  
spring.mail.username=username  
spring.mail.password=password
# Other properties
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.connectiontimeout=5000  
spring.mail.properties.mail.smtp.timeout=5000  
spring.mail.properties.mail.smtp.writetimeout=5000  
# 这里是tls的配置项,如果没有使用587,则要注释掉
# TLS , port 587
spring.mail.properties.mail.smtp.starttls.enable=true
# 这里是ssl的配置项,如果没有使用465,则要注释掉
# SSL, post 465
#spring.mail.properties.mail.smtp.socketFactory.port = 465
#spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory
如果是这个错误,那么就是你把tls/ssl的配置弄反了。  
nested exception is:  
	javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?. Failed messages: javax.mail.MessagingException: Could not connect to SMTP host: smtp.office365.com, port: 587;  
  nested exception is:  
	javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?; message exceptions (1) are:  
Failed message 1: javax.mail.MessagingException: Could not connect to SMTP host: smtp.office365.com, port: 587;  
  nested exception is:  
	javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?] with root cause

3、发送文本邮件

import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;  
    @Autowired
    private JavaMailSender javaMailSender;  
    void sendEmail() {  
        SimpleMailMessage msg = new SimpleMailMessage();  
        msg.setTo("to_1@gmail.com", "to_2@gmail.com", "to_3@yahoo.com");  
        msg.setSubject("Testing from Spring Boot");  
        msg.setText("Hello World \n Spring Boot Email");  
        javaMailSender.send(msg);  
    }

4、发送html格式的邮件

@GetMapping("sendMail")  
void sendMain() throws MessagingException {  
    MimeMessage mimeMessage = mailSender.createMimeMessage();  
    MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);  
    message.setFrom("浅忆博客(系统)<server@curlc.com>");  
    message.setTo("xxxxx@qq.com");  
    message.setSubject("HTML邮件");  
    message.setText("<h1>Check attachment for image!</h1>", true);  
    mailSender.send(mimeMessage);  
}

5、发送HTML电子邮件和文件附件

import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;  
    void sendEmailWithAttachment() throws MessagingException, IOException {  
        MimeMessage msg = javaMailSender.createMimeMessage();  
        // true = multipart message
        MimeMessageHelper helper = new MimeMessageHelper(msg, true);  
        helper.setTo("to_@email");  
        helper.setSubject("Testing from Spring Boot");  
        // default = text/plain
        //helper.setText("Check attachment for image!");
        // true = text/html
        helper.setText("<h1>Check attachment for image!</h1>", true);  
        // hard coded a file path
        //FileSystemResource file = new FileSystemResource(new File("path/android.png"));
        helper.addAttachment("my_photo.png", new ClassPathResource("android.png"));  
        javaMailSender.send(msg);  
    }

https://img.qyi.io/images/2021/02/17/image348ad2b0f08a124e.png