Strom's Blog


  • 首页

  • 归档

  • 标签

隐私权政策

发表于 2019-03-31   |  

本应用尊重并保护所有使用服务用户的个人隐私权。为了给您提供更准确、更有个性化的服务,本应用会按照本隐私权政策的规定使用和披露您的个人信息。但本应用将以高度的勤勉、审慎义务对待这些信息。除本隐私权政策另有规定外,在未征得您事先许可的情况下,本应用不会将这些信息对外披露或向第三方提供。本应用会不时更新本隐私权政策。 您在同意本应用服务使用协议之时,即视为您已经同意本隐私权政策全部内容。本隐私权政策属于本应用服务使用协议不可分割的一部分。

1. 适用范围

  • 在您注册本应用帐号时,您根据本应用要求提供的个人注册信息;
  • 在您使用本应用网络服务,或访问本应用平台网页时,本应用自动接收并记录的您的浏览器和计算机上的信息,包括但不限于您的IP地址、浏览器的类型、使用的语言、访问日期和时间、软硬件特征信息及您需求的网页记录等数据;
  • 本应用通过合法途径从商业伙伴处取得的用户个人数据。

您了解并同意,以下信息不适用本隐私权政策:

  • 您在使用本应用平台提供的搜索服务时输入的关键字信息;
  • 本应用收集到的您在本应用发布的有关信息数据,包括但不限于参与活动、成交信息及评价详情;
  • 违反法律规定或违反本应用规则行为及本应用已对您采取的措施。

2. 信息使用

  • 本应用不会向任何无关第三方提供、出售、出租、分享或交易您的个人信息,除非事先得到您的许可,或该第三方和本应用(含本应用关联公司)单独或共同为您提供服务,且在该服务结束后,其将被禁止访问包括其以前能够访问的所有这些资料。
  • 本应用亦不允许任何第三方以任何手段收集、编辑、出售或者无偿传播您的个人信息。任何本应用平台用户如从事上述活动,一经发现,本应用有权立即终止与该用户的服务协议。
  • 为服务用户的目的,本应用可能通过使用您的个人信息,向您提供您感兴趣的信息,包括但不限于向您发出产品和服务信息,或者与本应用合作伙伴共享信息以便他们向您发送有关其产品和服务的信息(后者需要您的事先同意)。

3. 信息披露

在如下情况下,本应用将依据您的个人意愿或法律的规定全部或部分的披露您的个人信息:

  • 经您事先同意,向第三方披露;
  • 为提供您所要求的产品和服务,而必须和第三方分享您的个人信息;
  • 根据法律的有关规定,或者行政或司法机构的要求,向第三方或者行政、司法机构披露;
  • 如您出现违反中国有关法律、法规或者本应用服务协议或相关规则的情况,需要向第三方披露;
  • 如您是适格的知识产权投诉人并已提起投诉,应被投诉人要求,向被投诉人披露,以便双方处理可能的权利纠纷;
  • 在本应用平台上创建的某一交易中,如交易任何一方履行或部分履行了交易义务并提出信息披露请求的,本应用有权决定向该用户提供其交易对方的联络方式等必要信息,以促成交易的完成或纠纷的解决。
  • 其它本应用根据法律、法规或者网站政策认为合适的披露。

4. 信息存储和交换

本应用收集的有关您的信息和资料将保存在本应用及(或)其关联公司的服务器上,这些信息和资料可能传送至您所在国家、地区或本应用收集信息和资料所在地的境外并在境外被访问、存储和展示。

5. Cookie的使用

  • 在您未拒绝接受cookies的情况下,本应用会在您的计算机上设定或取用cookies ,以便您能登录或使用依赖于cookies的本应用平台服务或功能。本应用使用cookies可为您提供更加周到的个性化服务,包括推广服务。
  • 您有权选择接受或拒绝接受cookies。您可以通过修改浏览器设置的方式拒绝接受cookies。但如果您选择拒绝接受cookies,则您可能无法登录或使用依赖于cookies的本应用网络服务或功能。
  • 通过本应用所设cookies所取得的有关信息,将适用本政策。

6. 信息安全

  • 本应用帐号均有安全保护功能,请妥善保管您的用户名及密码信息。本应用将通过对用户密码进行加密等安全措施确保您的信息不丢失,不被滥用和变造。尽管有前述安全措施,但同时也请您注意在信息网络上不存在“完善的安全措施”。
  • 在使用本应用网络服务进行网上交易时,您不可避免的要向交易对方或潜在的交易对

7.本隐私政策的更改

  • 如果决定更改隐私政策,我们会在本政策中、本公司网站中以及我们认为适当的位置发布这些更改,以便您了解我们如何收集、使用您的个人信息,哪些人可以访问这些信息,以及在什么情况下我们会透露这些信息。
  • 本公司保留随时修改本政策的权利,因此请经常查看。如对本政策作出重大更改,本公司会通过网站通知的形式告知。
    方披露自己的个人信息,如联络方式或者邮政地址。请您妥善保护自己的个人信息,仅在必要的情形下向他人提供。如您发现自己的个人信息泄密,尤其是本应用用户名及密码发生泄露,请您立即联络本应用客服,以便本应用采取相应措施。

Cocos2d-x 中的四个坐标系转换方法

发表于 2016-07-12   |  
Vec2    convertToNodeSpace (const Vec2 &worldPoint) const
Vec2    convertToNodeSpaceAR (const Vec2 &worldPoint) const
Vec2    convertToWorldSpace (const Vec2 &nodePoint) const
Vec2    convertToWorldSpaceAR (const Vec2 &nodePoint) const

之前用到过坐标系转换的方法,今天写功能把这四个方法放一起时感觉有点混乱了。所以写了个 demo 列出了所有需要的信息,然后把运行时的截图保存了下来,确保自己以后又搞乱了的话看一眼这张图就行了。
demo 是 Creator 做的,确实比 Studio + 代码好用多了。Cocos2d-x 中的节点坐标系和世界坐标系的概念就不写在这里了。

demo 截图:
CoordinateTest

在 CentOS 7 下架设 PPTP VPN 服务器

发表于 2016-05-17   |  

本文介绍了如何在 CentOS 7 下,通过使用 yum 软件仓库的 pptpd 守护进程架设自己的 PPTP VPN 服务器。

VPS

我用的是 Vultr VPS,所以文中的操作都是我基于 Vultr VPS 进行的,经测试我的 VPN 也是正常连接的。不同 VPS 提供商的设置可能有所区别,仅供参考。

架设 VPN 服务器

安装所需的包

yum install -y pptpd iptables-services

配置 PPTP 的设置。”ppp”配置文件对 pptpd 很重要。首先,如下配置 /etc/ppp/options.pptpd 文件,可以根据需要更改 DNS 服务器。

# Network and Routing

# If pppd is acting as a server for Microsoft Windows clients, this
# option allows pppd to supply one or two DNS (Domain Name Server)
# addresses to the clients.  The first instance of this option
# specifies the primary DNS address; the second instance (if given)
# specifies the secondary DNS address.
#ms-dns 10.0.0.1
#ms-dns 10.0.0.2
ms-dns 8.8.8.8
ms-dns 8.8.4.4

下一步,通过编辑 /etc/ppp/chap-secrets 文件添加VPN服务器的用户。即连接 VPN 所用的用户名和密码。client为帐号,server是pptpd服务,secret是密码,*表示是分配任意ip。只需修改账号和密码就可以。

# Secrets for authentication using CHAP
# client  server  secret    IP addresses
vultr1  pptpd   P@$$w0rd2  *
vultr2  pptpd   P@$$w0rd2  *

通过编辑 /etc/pptpd.conf 配置 pptpd 守护进程。下面的配置一般不需要修改,也可以根据用户数量需要修改 IP 地址范围。

#localip 192.168.0.1
#remoteip 192.168.0.234-238,192.168.0.245
localip 192.168.0.1
remoteip 192.168.0.234-238,192.168.0.245

下面编辑 /etc/sysctl.conf ,末尾添加一行 net.ipv4.ip_forward = 1 保存,来启用IP转发(IP forwarding)。之后运行 sysctl -p 命令使内核修改生效。

# System default settings live in /usr/lib/sysctl.d/00-system.conf.
# To override those settings, enter new settings here, or in an /etc/sysctl.d/<name>.conf file
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.ipv4.ip_forward = 1

我想用 iptables 作为防火墙,用下面的命令停止并隐藏 CentOS 7 中的默认防火墙服务 firewalld

systemctl stop firewalld
systemctl mask firewalld

由于开始时已经安装了 iptables,直接运行下面的命令启用 iptables

systemctl enable iptables

向 filter 表的 INPUT 链以及 nat 表的 POSTROUTING 链添加规则

iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 1723 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -j MASQUERADE

保存规则

service iptables save

最后,重启一下pptpd服务和iptables服务

systemctl restart iptables
systemctl restart pptpd

这样 PPTP VPN 服务器就搭建完成了。可以通过 PC 或移动设备连接。

通过 FontLink 改善 Windows 下西文编程字体的中文显示

发表于 2016-05-15   |  

Windows 下的中文字体应该也就是雅黑没别的了;编程字体 Consolas 就很不错但是没中文,中文用默认的宋体显示,感觉瞎眼。网上有基于这两种字体制作的混合字体,但是显示斜体之类的效果时有问题。网上搜索比较后,通过 FontLink 将雅黑中 Consolas 缺少的中文部分链接到 Consolas 字体里可能是最简单效果最好的方法了。

具体操作:

注册表编辑器定位到

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink

然后

新建 -> 多字符串值(M)

命名为

Consolas

修改其值为

MSYH.TTC,Microsoft YaHei UI,128,96
MSYH.TTC,Microsoft YaHei UI
// 我这里是 Win10 的,Win7 下的可能不同

到这里 FontLink 就完成了。

最后只需要修改代码编辑器的字体为上面命名的 Consolas,注销之后就可以看到效果了。两个英文字符的宽度等于一个中文字符的宽度,完美。 ^_^

更新 Cocos2d-x 的 Spine 运行库

发表于 2016-03-28   |  

Cocos2d-x 的 Spine 运行库目录: cocos2d-x/cocos/editor-support/spine
Github 上的 Spine 运行库项目:spine-runtimes

clone 或下载 Github 上 Spine 运行库项目主分支代码,将

spine-runtimes/spine-c/include/spine/
spine-runtimes/spine-c/src/spine/
spine-runtimes/spine-cocos2dx/src/spine/

中的头文件和源文件复制到 Cocos2d-x 的 Spine 运行库目录

cocos2d-x/cocos/editor-support/spine

然后记得删除其中旧运行库的头文件和源文件,不然编译通不过。

字符集、字符编码与 iconv 笔记

发表于 2016-03-24   |  

字符集和字符编码

很多相关文章都模糊了字符集和字符编码的概念。字符集和字符编码(Charset & Encoding)这篇文章非常赞,简明扼要,介绍了两者的概念以及常用字符集和字符编码。

另外,关于所谓 ANSI 编码。ANSI(American National Standards Institute,ANSI)是负责制定美国国家标准的非营利组织。它针对不同的地区与国家,定义了一系列的支持不同语言字符集的代码页。所以各国字符集和字符编码被 统称为 ANSI。

ANSI 不同的语言使用不同的字符集和字符编码,所以跨语言不能通用,会出现乱码。ANSI 没有很明显的特征 Xcode 或一些文本编辑器打开可能乱码。

最通用的编码是 UTF-8 without BOM。Windows 里的软件一般都默认有 BOM,而其它系统都默认没有 BOM。Visual Studio 下可以在 文件 -> 高级保存选项 更改编码。

iconv 的一个类型,三个函数

  • 数据类型:iconv_t
    这是 iconv 中定义的一个抽象类型,不要去对它做任何假设,因为它必须完全地是不明确的。
    当使用 iconv 函数时,该类型的对象会被赋值为 转换 的句柄。对象本身不需要释放,但是句柄所表示的 转换 需要释放。

  • 函数:iconv_t iconv_open (const char* tocode, const char* fromcode);
    转换开始前必须使用该函数初始化。两个参数分别是转换的目标字符集和需要转换的源字符集。如果转换可以执行,返回一个句柄;否则返回 -1。

  • 函数:size_t iconv (iconv_t cd, char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft);
    该函数根据 cd 将 输入缓冲中的文本进行转换,并将结果保存于输出缓冲中。*outbuf 指向一个至少有 *outbytesleft 个字节空间来保存结果的缓冲区的开始处。

  • 函数:int iconv_close (iconv_t cd);
    释放与句柄 cd 相关的全部资源,当然前提是正确调用了 iconv_open 函数。

进一步阅读:Generic Character Set Conversion Interface

gbk -> utf-8 转换示例

bool Chinese::iconvConvert(const char* from_charset, const char* to_charset, char* inbuf, int inlen, char* outbuf, int outlen)
{
    iconv_t cd=iconv_open(to_charset, from_charset);
    if(cd==0)
        return false;
    char** pin=&inbuf;
    char** pout=&outbuf;
    memset(outbuf, 0, outlen);
    size_t ret=iconv(cd, pin, (size_t*)&inlen, pout, (size_t*)&outlen);
    iconv_close(cd);
    return ret==(size_t)(-1)? false: true;
}

string Chinese::iconvGbkToUtf8(const string& str)
{
    string inStr = str;
    char* textIn = (char*)inStr.c_str();
    int inLen = str.length();
    int outLen = inLen * 2 + 1;
    char* textOut = (char*)malloc(outLen);
    bool ret = false;
    if (textOut)
        ret = iconvConvert("gbk", "utf-8", textIn, inLen, textOut, outLen);
    string strOut = ret ? string(textOut) : string();
    free(textOut);

    return strOut;
}

MusicXML 在音乐游戏中的应用---Cocos2d-x xml解析

发表于 2016-02-06   |  

用 tinyxml2 解析 xml

Cocos2d-x 已经加入了tinyxml2用于xml的解析。具体用法用例参见官方文档

需要说明的是不同的乐谱软件导出的 MusicXML 可能有所区别,可能其中有些信息并不是 MusicXML 所规定的,而是乐谱软件根据自身需要出发所添加的。解析的话我根据我游戏的需求以及难度,只解析了必要的信息。

MusicXML 解析思路整理

divisions 这个元素把我搞得很晕,简单来说 divisions 的值确定了整个乐谱的最小单位。而音符的时值 duration 的值就是根据最小单位来的。divisions = 1 的话,则最小单位是四分音符;divisions = 2 的话,则最小单位是四分音符,以此类推。举例来说,同样都是全音符,在 division = 1 的乐谱中,全音符的 duration = 4;在 division = 2 的乐谱中,全音符的 duration = 8.

所以呢:

最小单位 = (4 * divisions)分音符 = 1 / (4 * divisions)

一拍的duration = 一个beat-type分音符的duration = (4 / beat-type)个四分音符的duration = 4 * divisions / beat-type

一小节的duration = beats * 4 * divisions / beat-type

一个全音符的duration = 4 * divisions

tinyxml2 loadFile真机下失败问题(原文链接)

直接用tinyxml2的loadFile,加载一个XML文件,在WIN PC下是可以的,但在真机下失败:

const char* filepath = "test.xml";
tinyxml2::XMLDocument* xmlfile = new tinyxml2::XMLDocument();
auto ret = xmlfile->loadFile(filepath);  //这里失败

改为:

const char* filepath = "test.xml";
tinyxml2::XMLDocument* xmlfile = new tinyxml2::XMLDocument();
auto content = CCFileUtils::getInstance()->getDataFromFile(filepath);
auto ret = xmlfile->Parse((const char*)content.getBytes(), content.getSize());

MusicXML 在音乐游戏中的应用---MusicXML 的 "Hello World"详解

发表于 2016-01-26   |  

本人水平有限,本文主要是记录自己的学习过程,仅供参考。

最近在做的一款游戏是音乐类游戏,引擎版本用的 Cocos2d-X v3.5 。游戏中五线谱按照音乐的节奏在屏幕上方滚动,玩家通过音乐旋律以及五线谱的指示有节奏的敲击按键来得分。之前的方案是用 Tiled Map 手动拼出乐谱层,在对象层上设置每个音符对象的若干数据,这样整首乐谱的信息就都可以通过 Map 文件得到了。但是显然这种方法费时费力,自然想到寻找其他方案来代替。

乐理知识

在这之前需要了解一些乐理知识以便更好的学习 MusicXML ,只需要非常基础的乐理知识就够了。不赘述。

什么是 MusicXML

MusicXML(Music Extensible Markup Language 音乐扩展标记语言)是一个开放的基于XML 的音乐符号文件格式,由Reccordare 公司开发,该技术源于几个现有的基于学术上的关键技术和想法,比如Walter Hewlett 的MuseData 和David Huron 的Humdrum,他被设计用来做为乐谱信息的交换格式,特别是在不同的乐谱显示软件的之间进行交换。MusicXML 将整体乐曲元素和属性信息表示为一份XML 文档,他克服了另外两种格式—-NIFF 格式(基于图片)和SMDL 格式(过于庞大)的兼容性差,结构复杂等许多缺点,目前他已经被很多应用软件的支持。

—Wikipedia

MusicXML 的 “Hello World”

这部分翻译自官方文档(渣翻)

Brian Kernighan 和 Dennis Ritchie 推行了当学习一门新的编程语言时先写一个程序打印”hello, world”这一做法。它是测试如何构建一个程序并显示其结果的最小的程序。

在 MusicXML 中,一首有”hello,World”歌词的歌实际上要比我们期望的简单的 MusicXML 文件更复杂。我们要让事情简单一些:一个只包含一个全音符中央C的 4/4 拍小节:

MusicXML 中是这个样子:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE score-partwise PUBLIC
    "-//Recordare//DTD MusicXML 3.0 Partwise//EN"
    "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="3.0">
  <part-list>
    <score-part id="P1">
      <part-name>Music</part-name>
    </score-part>
  </part-list>
  <part id="P1">
    <measure number="1">
      <attributes>
        <divisions>1</divisions>
        <key>
          <fifths>0</fifths>
        </key>
        <time>
          <beats>4</beats>
          <beat-type>4</beat-type>
        </time>
        <clef>
          <sign>G</sign>
          <line>2</line>
        </clef>
      </attributes>
      <note>
        <pitch>
          <step>C</step>
          <octave>4</octave>
        </pitch>
        <duration>4</duration>
        <type>whole</type>
      </note>
    </measure>
  </part>
</score-partwise>

我们依次来看各个部分:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

这是所有 XML 文档都有的 XML 声明。我们指定了 “UTF-8” 编码格式。这是有 ASCII 子集的 Unicode 版本。设置 standalone 的值为 “no” 意思是我们在另一个文件外部定义文档。

<!DOCTYPE score-partwise PUBLIC
    "-//Recordare//DTD MusicXML 3.0 Partwise//EN"
    "http://www.musicxml.org/dtds/partwise.dtd">

这里是说我们在哪里使用 MusicXML。我们为 DTD 使用了一个包括一个 Internet 位置的 Public 声明。声明中的 URL 只是为了引用。大多数使用 MusicXML 文件的应用都会想要在用户的机器上安装一个 MusicXML DTDs 的本地拷贝。在你的 XML解析器中使用实体解析器来验证本地拷贝,而不是通过网络缓慢地读取 DTDs。如果你的应用想要验证 MusicXML XSD 而不是 DTD,你可以在你的 XML 解析器中用实体解析器来完成。当写入 MusicXML 时,对于所有基于 DTD 或 XSD 的应用来说,写入 DOCTYPE 使得验证 MusicXML 更简单。

<score-partwise version="3.0">

这是根文档类型。元素 score-partwise 是由几部分构成,而每部分由小节构成。这里同样有一个由小节构成的 score-timewise 可选元素,而每小节又是由几部分构成。这个 version 属性让程序更容易分辨出当前使用的 MusicXML 版本。如果你写的是 MusicXML 1.0 文件,那你就不用管它了。

<part-list>
  <score-part id="P1">
    <part-name>Part 1</part-name>
  </score-part>
</part-list>

MusicXML 开始于一个列出了乐谱不同音乐部分的 header(译注:就是上面这段代码) 。上面的例子是尽可能最小的 part-list:它包含了一个拥有 id 属性和 part-name 元素的 score-part 元素。

<part id="P1">

现在我们开始文档的第一部分(这个例子中的唯一一部分)。这里的 id 属性必须引用上面那个 header 中 score-part 元素的 id 属性。

<measure number="1">

我们开始第一部分第一小节。

<attributes>

attributes 元素包含了解析这部分音符和音乐数据所需的关键信息。

<divisions>1</divisions>

MusicXML 中每个音符都有 duration 元素。这个 division 元素为 duration 元素提供了小节的单元,小节的单元以每个四分音符的 divisions 为标准。因为在这里整个文件只有一个全音符,所以我们不用划分四分音符,于是我们把 divisions 的值设为了 1。 音乐上的时值通常用分数表示,比如四分音符、八分音符之类的。MusicXML 的时值也是分数。由于分母很少需要改变,所以在表示 divisions 元素时我们把它分离开不管它。这样就只有分子与每个单独的音符相关。这与 MIDI 中音符时值的表示相似。

<key>
  <fifths>0</fifths>
</key>

key 元素用于表示调号。在这我们是C大调调号没有升降号,所以 fifths 元素是 0 。如果我们是 D大调调号有两个升号, fifths 就应该是 2 。如果我们是 F大调调号有一个降号,那么 fifths 应该是 -1 。 “fifths” 这个名字来自五度圈(译注:这个东西有助于理解Circle of fifths)。它让我们可以用一个元素表示标准调号,而不是用不同的元素表示升降号。

<time>
  <beats>4</beats>
  <beat-type>4</beat-type>
</time>

time 元素表示拍号。它的两个构成元素 beats 和 beat-type 分别是拍号的分子和分母。

<clef>
  <sign>G</sign>
  <line>2</line>
</clef>

MusicXML 允许许多不同的谱号,其中包括许多今天不再用的。这里,标准的高音谱号用一个在五线谱第二条线上的G谱号表示(也就是说五线谱从下往上第二条线是G)。

</attributes>
<note>

我们已经完成了 attributes 元素,准备开始第一个音符。

<pitch>
  <step>C</step>
  <octave>4</octave>
</pitch>

pitch 元素必须有一个 step 和一个 octave 元素。如果涉及到了升降号,还可以有一个可选的 alter 元素。这个元素表示声音,所以如果使用了 alter 元素那么 alter 元素必须总是被包含,即使升降号已经在调号中了。在此例中,我们没有升降号。step 是 C。octaved 的 4 表示 octave 开始于中央C。因此这个音符是中央C。

<duration>4</duration>

我们的 divisions 值为 1,所以 duaration 的 4 是 4 个四分音符的长度。

<type>whole</type>

type 元素告诉我们这是个全音符。在此例中你可能可以通过 duration 推导出来,但是如果应用是乐谱和执行数据分开表示的直接给出来更容易操作。不管怎样,在实际中乐谱和执行的数据并不总是匹配在一起的。比如,你想要接近爵士乐那种摇摆飘忽的感觉你就不会用相等长度的八分音符,而是让音符时值在八分音符的基础上浮动,而音符本身还是八分音符。Bach 的音乐就包含时值并不标准的音符。duration 元素应该反映目的时值,不是有偏差的时值,尤其是在特定的音乐中。note 元素有 attack 和 release 属性,可以从乐谱上表示的时值出发,改变音符的开始和结束时间。

</note>

我们完成了 note 元素。

</measure>

我们完成了 measure 元素。

</part>

我们完成了 part 元素。

</score-partwise>

这样整个乐谱就完成了。

Hello World

发表于 2016-01-21   |  

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

Strom

Strom

9 日志
16 标签
© 2019 Strom
由 Hexo 强力驱动
主题 - NexT.Mist