惨案:主题文件爆炸

刚搬完网站,发现了一个小问题,就是最新版chrome无法正常打开博客后台,而且无法正常加载ajax切换的结果,显示加载失败

今天终于发现了原因:是主题的问题,但是我不会修(摔!

所以在新主题完成之前,就先用官方主题凑合吧,所以友链也没有了,大家见谅

基于socket的酷Q机器人与Minecraft消息同步功能的实现

我先放张效果图:

这张图中主要实现的功能就是消息同步,后来我又加了执行命令的功能,有兴趣的可以自己改改玩233

上图插件的介绍地址:http://mcbbs.net/thread-682777-1-1.html

项目开源地址:http://git.oschina.net/chenxuuu/Minecraft-QQGroupPlubin

gitosc的readme中我写了双方通讯的socket格式了,如下:

协议食用指南:

插件通过socket通讯,使用2333端口

客户端:minecraft插件实现

服务端:cq插件实现

===========================

通讯协议举例:

客户端与服务端每秒发送/接收一次数据

客户端→服务端(minecraft插件→cq插件)发送字符串举例:xxxxxxxx]][[ccccc]][[dawdasdasdasdasd]][[asadsdasdasd

分割符号为“]][[”(如果这一秒内有多条消息的话会这样)

服务端→客户端(cq插件→minecraft插件)发送字符串举例:|||||xxxxxxxx|||||command>ccccc|||||<player>dawdasdasdasdasd

分割符号为“|||||”(如果这一秒内有多条消息的话会这样),当分割开后,字符串中包含“<”符号的,将直接在服务器全局发送;字符串中包含“command>”符号且不包含“<”符号的,将作为命令发送到控制台,其他数据将舍弃(如xxxxxxxx那一个字符串)。

我就稍微再贴一下两边的核心代码吧。

java端:

java这个语言我是没接触过的,所以代码基本都是请教的Balrogs_xt大佬(博客地址:http://www.acgxt.com/),还有万能的百度

java端实现的功能是socket的客户端、并且作为minecraft插件输出和执行各种数据,代码不长,我就全部贴在这里了:

package com.sweetcreeper.qqplugin;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

public class Qqplugin extends JavaPlugin implements Listener
{
	public String player="none233";
	public String msg="none233";
	
	@Override//重写父类的方法
	public void onEnable()
	{
		getLogger().info("QQGroupMessagePlugin is started successfully!");
		//注册监听
		Bukkit.getPluginManager().registerEvents(this,this);
		
		new BukkitRunnable(){     
		    int s = 0;//设置定10秒后执行某段代码
		    @Override    
		    public void run(){
		    	if(s>=60)
		    	{
		    		Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "tm abc 发钱啦!");
		    		Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "eco give * 1");
		    		s=0;
		    	}
		    	else
		    	{
		    		s++;
		    	}
		        //s--;//迭代递减,我看官方的教程是没这个的,我没试过,你也可以删除试试
		        //if(s==0){
		            //这个写10秒后执行的代码(假如定义的定时器每次是1秒)
		        //    cancel();//cancel用来取消定时器
		        //}else{
		            //这里可以写每次触发定时器执行的代码
		            try 
		            {
		                //1.创建客户端Socket,指定服务器地址和端口
		                Socket socket=new Socket("localhost", 2333);
		                //2.获取输出流,向服务器端发送信息
		                OutputStream os=socket.getOutputStream();//字节输出流
		                PrintWriter pw=new PrintWriter(os);//将输出流包装为打印流
		                if(player!="none233")
		                {
		                	pw.write(msg);
		                	player="none233";
		                }
		                else
		                {
		                	pw.write("getmsg");
		                }
		                pw.flush();
		                socket.shutdownOutput();//关闭输出流
		                //3.获取输入流,并读取服务器端的响应信息
		                InputStream is=socket.getInputStream();
		                BufferedReader br=new BufferedReader(new InputStreamReader(is));
		                String info=null;
		                info=br.readLine();
		                String[] sourceStrArray=info.split("\\|\\|\\|\\|\\|");
		                for(int i=0;i<sourceStrArray.length;i++)
		                {
		                	if(sourceStrArray[i].indexOf("<")!=-1)
		                	{
		                		Bukkit.broadcastMessage(sourceStrArray[i]);
		                	}
		                	else if(sourceStrArray[i].indexOf("command>")!=-1)
		                	{
		                		Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), sourceStrArray[i].replace("command>", ""));
		                		if(player!="none233")
		                		{
		                			msg+="]][[<提示>"+sourceStrArray[i].replace("command>", "")+"已执行";
		                		}
		                		else
		                		{
		                			player="ok";
		                			msg="<提示>"+sourceStrArray[i].replace("command>", "")+"已执行";
		                		}
		                	}
		                }
		                //Bukkit.broadcastMessage("debug:"+info);
		                //4.关闭资源
		                br.close();
		                is.close();
		                pw.close();
		                os.close();
		                socket.close();
		            } catch (UnknownHostException e) {
		                //e.printStackTrace();
		            } catch (IOException e) {
		                //e.printStackTrace();
		            }
		        //}
		    } 
		}.runTaskTimer(this, 0L, 20L);//参数是,主类、延迟、多少秒运行一次,比如5秒那就是5*20L
	}
	@Override
	public void onDisable()
	{
		getLogger().info("QQGroupMessagePlugin is stoped successfully!");
	}
	
	@EventHandler
	public void onPlayerSay(AsyncPlayerChatEvent event)
	{
		if(player!="none233")
		{
			msg+="]][[<"+event.getPlayer().getName()+">"+event.getMessage();
			//player="ok";
		}
		else
		{
			player="ok";
			msg="<"+event.getPlayer().getName()+">"+event.getMessage();
		}
		//Bukkit.broadcastMessage("player:"+event.getPlayer().getName()+",msg:"+event.getMessage());
	}
	
	@EventHandler
	public void onPlayerJoin(PlayerJoinEvent event)
	{
		if(player!="none233")
		{
			msg+="]][[<消息>"+event.getPlayer().getName()+"上线了";
		}
		else
		{
			player="ok";
			msg="<消息>"+event.getPlayer().getName()+"上线了";
		}
	}
	
	@EventHandler
	public void onPlayerQuit(PlayerQuitEvent event)
	{
		if(player!="none233")
		{
			msg+="]][[<消息>"+event.getPlayer().getName()+"掉线了";
		}
		else
		{
			player="ok";
			msg="<消息>"+event.getPlayer().getName()+"掉线了";
		}
	}
}

基本的思路就是前面写的那个格式:“xxxxxxxx]][[ccccc]][[dawdasdasdasdasd]][[asadsdasdasd”

C#端:

c#端作为酷q插件,在socket通讯中作为服务端

我把网上找来的socket代码稍作修改:

/// <summary>
/// 监听客户端连接
/// </summary>
private static void ListenClientConnect()
{
    while (true)
    {
        Socket clientSocket = serverSocket.Accept();
        //clientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello\r\n"));
        Socket myClientSocket = (Socket)clientSocket;
        int receiveNumber;
        receiveNumber = myClientSocket.Receive(result);
        //Console.WriteLine("接收客户端 {0} 消息{1}", myClientSocket.RemoteEndPoint.ToString(), Encoding.UTF8.GetString(result, 0, receiveNumber));
        string replay = Encoding.UTF8.GetString(result, 0, receiveNumber);
        if (replay.IndexOf("<") != -1)
        {
            if (replay.IndexOf("]][[") != -1)
            {
                try
                {
                    string[] str2;
                    str2 = replay.Split(new string[] { "]][[" }, StringSplitOptions.None);
                    foreach (string i in str2)
                    {
                        CQ.SendGroupMessage(GroupSet, i);
                    }
                }
                catch { }
            }
            else
            {
                CQ.SendGroupMessage(GroupSet, replay);
            }
        }
        clientSocket.Send(Encoding.UTF8.GetBytes("ok233"));
        clientSocket.Send(Encoding.UTF8.GetBytes(mcmsg));
        mcmsg = "";
        myClientSocket.Shutdown(SocketShutdown.Both);
        myClientSocket.Close();
    }
}

上面那段作为多线程部分后台死循环运行。

然后定义几个全局变量:

private static byte[] result = new byte[4096];
private static int myProt = 2333;   // 端口  
static Socket serverSocket;

在插件初始化时,打开该线程:

IPAddress ip = IPAddress.Parse("127.0.0.1");
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(new IPEndPoint(ip, myProt));  // 绑定 IP 地址:端口
serverSocket.Listen(10);    // 设定最多 10 个排队连接请求
// 通过 Clientsoket 发送数据
Thread myThread = new Thread(ListenClientConnect);
myThread.Start();

最后只是消息处理问题了,只要让结果消息+="|||||"和别的东西就可以了。

注意的地方:

如果普通消息中你没有强制插入"<"符号,可能后导致命令输入漏洞,所以我从c#到java输出的普通聊天记录的格式是[群消息]<玩家id>消息内容

其他:没东西啦

记校园网代理中转网站的搭建过程

学校的教务系统从16年开始便只能用校内网或者是宿舍的移动网打开登陆,去年的时候我用树莓搭建了一个中转(毕竟树莓闲置着的,另外科创连的是校内网)

当时采用的是nginx+Glype当作服务端,采用的是花生壳提供的内网穿透服务,不过说实话花生壳提供的免费服务确实不咋地,后来我用了natapp.cn提供的ngrok内网转发,五块钱一个月那个。现在采用的是ngrok.cc提供的免费ngrok服务,网站总体所需流量不大,所以用这个的话效果也还可以。

下面我简单讲一下搭建的流程吧,主要就是两点:搭建nginx+php和运行ngrok服务

我在这里用的是树莓派2B,系统镜像是2015-01-31-raspbian

首先把所有该初始化的东西搞完,我们就可以开始装nginx+php了

首先安装nginx:

sudo apt-get install nginx

启动nginx:

sudo /etc/init.d/nginx start

接下来修改配置文件:

sudo nano /etc/nginx/sites-available/default

在“listen 80”那个大括号里,把“index index.html index.htm”后面加上“index.php”:

listen 80;
root /usr/share/nginx/www;
index index.html index.htm index.php;

然后找到php那一段,改成下面这样:

location ~ .php$ {
 fastcgi_pass unix:/var/run/php5-fpm.sock;
 fastcgi_index index.php;
 include fastcgi_params;
}

改完配置文件之后,保存关闭

安装php和必要组件:

sudo apt-get install php5-fpm php5-sqlite

重启nginx:

sudo /etc/init.d/nginx reload

到这里的话,nginx服务器搭建过程基本上都是抄的“树莓派开发系列教程7——树莓派做web服务器(nginx、Apache)”这篇文章里的东西,但是到后面你会发现Glype无法运行,原因其实就是php里的curl组件没装上,所以我们还需要执行以下命令:

sudo apt-get install php5-curl

你要是不嫌麻烦可以把所有需要的组件都装上:

apt-get install php5-mysql php5-curl php5-gd php5-intl php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl

至此,nginx+php服务器搭建完毕,接下来只要把Glype扔到/usr/share/nginx/www里就能正常运行了,当然我改了好多东西

接下来解决外网访问的问题,我就解释一下ngrok的用法

其实用法很简单(如果你不想自己搭建服务器的话)

用ngrok.cc提供的服务举例:

首先到后台开通一个隧道,隧道协议选择“http”、本地端口写你前面设置的端口(前面配置文件里写的是80)“127.0.0.1:80”其他的按照自己的需求来写就行

然后下载官网提供的软件,树莓的话要选linux arm版,

下载之后先给777权限:

sudo chmod 777 xxxx#文件名

然后按教程运行就行了:

./sunny clientid xxxxxxxxxxxxxx

这样的话其实整个代理已经搭建完了,但是有一个重要的问题没有解决:这个服务一但遇到了停电或者是网络不稳定的情况之后,必须手动重启才可以,这样的话就会变得相当棘手。想象一下,你寒假回家了,但是服务器挂了,你找谁给你开启服务啊

所以我加了两个自动检测的脚本

一个是一分钟运行一次的“autorun.sh”,可以保证ngrok服务一直处于开启状态:

#!/bin/sh
ps -fe|grep sunny |grep -v grep
if [ $? -ne 0 ]
then
echo "start process....."
screen -dm nohup sudo /home/pi/sunny clientid xxxxxxxxxxxxxxxx &
else
echo "runing....."
fi

另一个是十分钟运行一次的“check.sh”,用于保证网站可访问,当打不开时会自动重启软件:

#!/bin/sh
result=`curl http://wfkj.papapoi.com/check.php -s`
if [ $result == "ok" ];then
echo "ok"
else
sudo killall sunny
screen -dm nohup sudo /home/pi/sunny clientid xxxxxxxxxxxxxxxx &
fi

最后打开定时任务列表:

crontab -e

加上这俩货:

* * * * * /home/pi/autorun.sh &
*/10 * * * * sudo sh /home/pi/check.sh &

大功告成!

最后把做好的网址发在这里:http://wfkj.papapoi.com/

从此,随时随地都可以让大家感受到挂科的喜悦了(雾

微软虚拟学院MVA字幕及视频获取方法

微软虚拟学院上面有许多视频,而且见解都十分独特

但是哈,它加载速度慢、只能在线看、字幕特别小、反正各种坑。。

离线下载的视频又没字幕。。。怎么办咧?

看到了一篇文章:微软虚拟学院 MVA 字幕获取方法

然而。。。。没卵用。。网站改版了。。

最后经过我的研究。。。找出了可行的办法

下面以这个链接举例:https://mva.microsoft.com/zh-cn/training-courses/-c-8295

首先打开你的IE11(其他版本不敢保证可行,可以尝试chrome,但是我的会崩溃):

打开首页后,右击空白处–审查元素:

选择“网络”选项卡:

接着打开你要下载的网址,选择你要下载的那个视频:

把“网络”选项卡拉到最下面,从下往上找,找到“video_cc.xml?v=xxxxxxxxx”这一项,右击复制URL:

在新标签打开,按住ctrl+s保存,字幕下载完毕:

然后用网页上自带的那个“下载”按钮下载视频就好(你也可以从“网络”选项卡里找到URL然后扔到qq旋风里下233)

接下来处理xml字幕为ass格式。

下载SubtitleEdit:(百度云传不上,所以大家自己必应找吧)

打开软件,从菜单选择“File-Open”打开下载的xml字幕:

从菜单选择“File-Save As”另存为ass字幕:

然后,一般视频文件名和ass字幕文件名相同的话,就会自动加载(或者自己用小丸工具箱/格式工厂把字幕嵌到视频里):

这样,就下载好了一个带字幕的视频(还有一大堆自己慢慢下载去吧2333

树莓派驱动12464OLED播放Bad Apple

效果查看:

屏幕驱动安装见 http://www.chenxublog.com/2016/08/20/raspi-12864-spi-oled.html

本视频程序下载:https://pan.baidu.com/s/1miMfwM0 密码: f3kx

制作流程:视频经过FFmpeg转换为每帧图片→通过signpics处理为128×64分辨率的图片→转为png→通过pngtopnm命令转为ppm序列图片→程序调用显示

附赠一个可以提高姿势水平的视频程序:

点我预览效果

程序下载:http://chenxublog.ctfile.com/fs/pHJ158469949

用一个小脚本在win/*nix上一键下载bing每日壁纸

昨天在逛zhiyb的github(http://zhiyb.github.io/)的时候。。。点到了他的OneDrive里看了看,结果发现了一个好像很有用的小脚本:

bing.sh

#!/bin/bash -e
url="http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=10"
data="$(curl -so - "$url")"
num="$(echo "$data" | jq -r ".images | length")"
mkdir -p images
cd images
for ((i = 0; i < $num; i++)); do
imgdata="$(echo "$data" | jq -r ".images[$i]")"
url="$(echo "$imgdata" | jq -r ".url")"
[ "${url:0:4}" != "http" ] && url="http://www.bing.com/$url"
echo "$url"
base="$(basename "$url")"
base="${base%%_*}.${base##*.}"
[ -s "$base" ] && continue
curl -o "$base" "$url"
mkdir -p json
echo "$imgdata" > json/"$base.json"
done

然而跑了跑好像少了什么组件,没跑成。。

所以我用powershell改写了一个(毕竟咱用的是windows

花了一点时间就写好了。(才发现powershell简直神器啊

bing.ps1

#by chenxublog.com
mkdir images
cd images
mkdir jsons
cd jsons
$url = "http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=10"
$time = Get-Date
$data = Invoke-WebRequest $url
$data.Content | Out-File $time.DayOfYear
$decode = ConvertFrom-Json($data)
cd ..
$range = 1..8
$count = $range.Count
for($i=0; $i -lt $count; $i++)
{
    $temp = $decode.images.Get($i)
    Invoke-WebRequest $temp.url -OutFile ($temp.hsh + ".jpg")
}

把上面的文件保存为bing.ps1就好啦→_→ 

右击,运行!

啪!

啪啪啪!

这样每天就可以收到八张好看的壁纸啦~~

2017.3.5补充:

必应json改规则了,代码更新~~~

#by chenxublog.com
$x = Split-Path -Parent $MyInvocation.MyCommand.Definition
cd $x
mkdir images
cd images
mkdir jsons
cd jsons
$url = "http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=10"
$time = Get-Date
$data = Invoke-WebRequest $url
$data.Content | Out-File $time.DayOfYear
$decode = ConvertFrom-Json($data)
cd ..
$range = 1..8
$count = $range.Count
for($i=0; $i -lt $count; $i++)
{
    $temp = $decode.images.Get($i)
    $urlsplit = -Join("http://www.bing.com",$temp.url)
    echo $urlsplit
    Invoke-WebRequest $urlsplit -OutFile ($temp.hsh + ".jpg")
}
echo ok!
pause

应该正常了吧。。

win10系统禁用笔记本自带键盘的有效方法

今天看书时想把书放外置键盘前面,但是会压到笔记本键盘,所以我在百度搜了一下禁用笔记本自带键盘方法

然后。。。

有的说是直接拔线,这个方法直接pass,拆机多麻烦,到时候装回去也麻烦

还有最常见的是给自带键盘一个不兼容的驱动。。。我尝试了这个方法

。。。

然后

。。。

。。。

电脑蓝屏了。。。

微软你在玩我呢?win10就这么难伺候吗?。

百度了一下“win10 禁用 笔记本 自带键盘 -(失灵 | 没有反应 | 按键音)”这个关键词。。发现基本上没人能解决这个问题。。。

后来我看到一段代码。。。(http://tieba.baidu.com/p/4596570797

试了试

。。。

诶好像能用!

下面说方法:

首先打开开始菜单,找到windows系统–右击命令提示符–更多–以管理员身份运行

输入以下命令,回车:

sc config i8042prt start= disabled

然后重启电脑,就好啦~

是不是很神奇啊2333

你想恢复的时候,只要重复上面的动作,输入的命令改为:

sc config i8042prt start= auto

就行了

这个教程应该是全网首发吧(捂脸

QQ反向字符/特殊昵称生成

反向字符什么的大家应该很常见了吧,但是今天又看到了一个玩法

看下图:

此效果仅能在安卓手机上才能体现

实现代码:

<script>
document.write("晨旭"+String.fromCharCode(8238)+"并扔了一只苦力怕".split('').reverse().join('')+String.fromCharCode(8237));
</script>

这种群备注的自助生成器:http://qq.papapoi.com

咱就是懒人们和小白们的救星23333