old_blog 《赤印》的文本提取

  《赤印》是我很久之前玩过的一款国产galgame。与其他的galgame不同,该游戏没有选项,所以如果将它的文本放到手机里面当作小说看的话,也是非常方便的。(当然,游戏性与感染力就下降很多了。)在网上没有找到《赤印》的文本,十分不爽,自己动手吧。

  由于游戏是KiriKiri2开发的,我们用软件“crass-0.4.14.0-final”对游戏包文件scenario.xp3进行拆解。对拆解后的文件夹进行文件筛选,将有用的脚本留下,什么函数啊、宏定义啊删掉就行了。


  脚本文件如图所示:



  我们原本想采用编程的方法进行文本提取。但是这之前需要做一下简单的处理。
为什么要做处理呢?我们用winhex打开任意一个ks文件,如prologe.ks,显示如下:




  尼玛字符之间有ASCII为0的字符夹着。这个会让我们的程序运行出错。我们对ks文件先右击—打开方式—记事本。然后全选—复制。新建prologe.txt,粘贴即可。一个复制粘贴就将这种畸形文本编程纯文本了,之后我们的操作对该txt文件操作即可。
  我们研究一下脚本文件。我们发现一些共性:
  对话总是以符号“『”开头;
  对话开头有的时候有[porcessname text="Name"]标签,有点时候没有。
  如图所示:



  我们的目标如下:1.将对话前的姓名保留;2.如果对话前没有姓名,则给出符号提示(如------)。后期我们根据上下文补上说话者的姓名。
  这里我们用Eclipse编写一个java类:WordHandling
  简介一下这个类吧,它提供了两种文字处理方式——按行处理和按字符处理。这里我们选择按行处理。其次,它提供一些常见的处理方法,去除歌词文件lrc开头、是否包含中文、是否所有字符都是可打印字符、删除开头的空格等。输出方式有两种,输出至文件和标准输出至屏幕。这里我只码了第二种方式,即打印至屏幕。
  代码贴出来:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
public class WordHandling {
String address;
int method;
boolean addEnter=false;
boolean deleteMoreEL=false;
int tag=0;
final static int BYTE=0;
final static int LINE=1;
WordHandling()
{
this("",WordHandling.BYTE,false);
}
WordHandling(String address,int method)
{
this(address,method,false);
}
WordHandling(String address,int method,boolean addEnter)
{
this.address=address;
this.method=method;
this.addEnter=addEnter;
}
void setDeleteMoreEMPTYLINE(boolean set)
{
deleteMoreEL=set;
}
char byteHandling(char c)
{
return c;
}
String lineHandling(String s)
{
return s;
}
void setAddress(String address)
{
this.address=address;
}
void setAddEnter(boolean addEnter)
{
this.addEnter=addEnter;
}
void setMethod(int method)
{
this.method=method;
}
int runForPrint()
{
if(method==WordHandling.BYTE)
{
File file=new File(address);
Reader reader=null;
try
{
reader=new InputStreamReader(new FileInputStream(file));
int tempchar;
int cnt=0;
char ch=' ';
while((tempchar=reader.read())!=-1)
{
ch=(char)tempchar;
ch=byteHandling(ch);
if((int)ch!=0)
{
System.out.print(ch);
cnt++;
} 
}
if(addEnter) System.out.println();
reader.close();
return cnt;
}
catch (Exception e)
{
e.printStackTrace();
}
}
else
{
File file=new File(address);
BufferedReader reader = null;
try
{
reader=new BufferedReader(new FileReader(file));
String tempString=null;
int emptyline=0;
int line=0;
while((tempString=reader.readLine())!=null)
{
tempString=lineHandling(tempString);
if(tempString!=null)
{
if(deleteMoreEL=false)
{
System.out.println(tempString);
}
else
{
if(tempString.equals(""))
{
if(emptyline==0)
System.out.println(tempString);
emptyline++;
}
else
{
System.out.println(tempString);
emptyline=0;
}
}
line++;
}
}
reader.close();
return line;
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(reader!=null)
{
try
{
reader.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
return 0;
}
int runForFile(String saveAddress)
{
return 0;
}
static String removeLrcHead(String s)
{
int i,j;
for(i=0;i<s.length();i++)
if(s.charAt(i)==']') break;
if(i==s.length()-1) return "";
for(j=i;j<s.length();j++)
{
if(s.charAt(j)==' ')
{
String t=s.substring(i+1,j);
return t;
}
}
return null;
}
static boolean containsChinese(String s)
{
for(int i=0;i<s.length();i++)
{
int asc=(int)s.charAt(i);
if(asc>128||asc<-1)
return true;
}
return false;
}
static boolean containsAllPritableASCII(String s)
{
for(int i=0;i<s.length();i++)
{
int asc=(int)s.charAt(i);
if(asc>=32&&asc<128)
return true;
}
return false;
}
static String deleteHeadingSpace(String s)
{
int i;
for(i=0;i<s.length();i++)
if(s.charAt(i)!=' ')
break;
return s.substring(i,s.length());
}
}
//下面利用该类处理文本prologe.txt,我们需要继承之并复写lineHandling方法即可。贴出代码(有注释):
public class TestMain {
public static void main(String[] args) throws Exception
{
String path="E:\\scenario\\prologe.txt";
WordHandling wh=new WordHandling(path,WordHandling.LINE,false)
{
String lineHandling(String s)
{
//如果是注释或者无信息 则不输出
if(s.startsWith(";")||s.startsWith("*")||s.startsWith("@")||s.equals(""))
{
return null;
}
int a=0,b=0;
//处理processname text姓名栏
if(s.startsWith("[processname text"))
{
this.tag=1;
for(int i=0;i<s.length();i++)
{
if(a==0&&s.charAt(i)=='\"')
a=i;
if(a!=0&&s.charAt(i)=='\"')
b=i;
}
if(a!=b)
return s.substring(a+1,b)+":";
else
{
for(int i=0;i<s.length();i++)
{
if(a==0&&s.charAt(i)=='=')
a=i;
}
return WordHandling.deleteHeadingSpace(s.substring(a+1,s.length()-1))+":";
}

}
//去除配对的[...]字段
for(int i=0;i<s.length();i++)
{
if(s.charAt(i)=='[')
{
a=i;
for(int j=i+1;j<s.length();j++)
{
if(s.charAt(j)==']')
{
b=j;
break;
}
}
s=s.substring(0,a)+s.substring(b+1,s.length());
i--;
}
}
//处理会话部分 如果之前没有人名则给出信号
if(s.startsWith("『"))
{
if(this.tag==1)
this.tag=0;
else
{
s="-----------------\n"+s;
this.tag=0;
}
}
return s;
}
};
//置多行空格为一行
wh.setDeleteMoreEMPTYLINE(true);
wh.runForPrint();
}
}
  运行后的结果如下:



  复制到记事本文件中,根据上下文将符号“-----------------”改成对应的人名即可。
  秀一下成功之后的《赤印》文本。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值