亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

用C++制作自己的游戲修改器(下)

2019-11-17 05:35:13
字體:
來源:轉載
供稿:網友

  本文旨在說明修改游戲存檔的思路、編程方法和一點技巧,上篇內容分別為前言、手工修改游戲存檔文件的方法、自動檢查游戲存檔中的數值、改進1:對地址文件取得交集等內容。本期向讀者介紹下篇部分內容。

  改進2:相對值查找

  游戲中的某些數值并沒有明確告訴你多少,但是觸發事件后會增加或者減少,比如仙劍3中間女主角的好感度。游戲中間有對話,根據對話的內容可以增加對男主角的好感度。好感度影響著結局,想玩出多種結局的家伙還是“玩弄”一下女主角的感情吧!

  方法還是比較簡單的,只要同時讀取兩個文件,每次讀取一個字符后比較兩者之差是否符合指定的相對值,假如符合的話,保留信息。

template<class T>
void RelativeValue()
{
 typedef fstream::off_type AddressType;
 EInputStream CIN(cin);
 string FN;
 cout<<"First binary file name:/t";
 CIN>>FN;
 ifstream Read1(FN.c_str(),ios::in ios::binary);
 //讀+二進制模式
 if(!Read1)
 {
  cerr<<"Open "<<FN<<" failed./n";
  return;
 }
 cout<<"Second binary file name:/t";
 CIN>>FN;
 ifstream Read2(FN.c_str(),ios::in ios::binary);
 if(!Read2)
 {
  cerr<<"Open "<<FN<<" failed./n";
  return;
 }
 int ByteNumber;
 cout<<"Byte number:/t";
 CIN>>ByteNumber;//字節數
 int RV;//指定的相對值
 cout<<"Relative value(value1-value2):/t";
 cin>>RV;
 const int MaxByte=sizeof(T);
 const int CharSize=sizeof(char);
 if(ByteNumber<1ByteNumber>MaxByte)
  ByteNumber=MaxByte;
  T Value1,Value2;//兩個文件中的數值
  char* P1=reinterPRet_cast<char*>(&Value1);
  char* P2=reinterpret_cast<char*>(&Value2);
  //先全部清0
  memset(P1,0,MaxByte*CharSize);
  memset(P2,0,MaxByte*CharSize);
  AddressType Address=0;
  //填布滿P1
  Read1.read(P1,CharSize*ByteNumber);
  //填布滿P2
  Read2.read(P2,CharSize*ByteNumber);
  //保存信息的鏈表
  typedef list<pair<AddressType,pair<T,T> > > InfoList;
  InfoList IL;
  int Occurs=0;
  //當兩個文件都還沒有讀完
  while(Read1 && Read2)
  {
   if(Value1-Value2==RV)//符合條件了
   {
    //保存信息
    IL.push_back(make_pair(Address,make_pair(Value1, Value2)));
    ++Occurs;
   }
   //除舊
   memcpy(P1,&P1[1],CharSize*(ByteNumber-1));
   memcpy(P2,&P2[1],CharSize*(ByteNumber-1));
   //迎新
   Read1.read(&P1[ByteNumber-1],CharSize);
   Read2.read(&P2[ByteNumber-1],CharSize);
   ++Address;
  }//while(Read1 && Read2)
  cout<<Occurs<<" different addresses were found./n";
  if(Occurs==0) return;
  cout<<"Input save filename:/t";
  CIN>>FN;
  //保存至文件
  ofstream SaveFile(FN.c_str());
  if(!SaveFile)
  {
   cerr<<"Create "<<FN<<" failed./n";
   return;
  }
  SaveFile<<"Relative value is " <<RV<<"/nAddress/tValue1/tValue2/n";
  for(InfoList::const_iterator Beg=IL.begin(), End=IL.end();Beg!=End;++Beg)
  {
   SaveFile<<(*Beg).first<<’/t’ <<(*Beg).second.first <<’/t’<<(*Beg).second.second <<’/n’;
  }
 }
  這里的新面孔是pair。pair是一個相當簡單的模板結構,一共就兩個變量(first和second),都是公開的。

  由于是模板,所以pair的構造必須指定兩個變量所屬類型,為了簡單,設立了一個make_pair 的函數,函數可以根據參數自動推導出類型而不必顯式指定。在這里,我需要保存三個值:地址、文件1中的數值、文件2中的數值。偷懶一點,我把兩個文件中的數值作為一個pair
(A),再把地址和pair(A)作為一個pair(B)。pair(B).first就是地址,pair(B).second就是pair(A),pair(A).first就是文件1中的數值,pair(A).second就是文件2中的數值。

  通過保存的文件我們可以得到地址,找到了藏身之地,事情就好辦多了。
 改進3 :手動批量修改

  上面介紹的方法( “自動修改文件”),每次只修改一個地址。假如要對某個文件的5555,6666,12352地址修改,用上面的方法也很煩瑣。假如能指定在哪些位置修改為哪些數值就方便多了。

  修改的要素:地址、新的數值、新數值的字節數。上述三個要素都是整形,一旦輸入數據不是整形(比如一個字母),就表示停止輸入。 比如:

5555 500000 4
6666 600000 4
12352 700000 4 x
  表示在5555地址上填寫4字節的500000,在6666地址上填寫4字節的600000,在12352地址上填寫4字節的700000。x導致輸入失敗,在此表示停止輸入。

  假如輸入的數據按照地址從小到大排列,那么編程就比較方便了,不過卻為難了客戶。還是善待你的上帝吧,對他們的要求越少越好。很多時候,自己就是自己程序的第一用戶,益人也同樣利己。

  因此,下面的輸入與上面的等價:

12352 700000 4
5555 500000 4
6666 600000 4 ~
template<class T>
class Modify
{
 public:
  typedef fstream::off_type AddressType;
  static const int MaxByte=sizeof(T);
  Modify();
  void Run() const;
 private:
  strUCt ModifyInfoUnit
  {
   //修改要素——地址
   AddressType Address;
   //修改要素——新的數值
   T NewValue;
   //修改要素——新數值的字節數
   int ByteNumber;
   //排序原則
   bool Operator<(const Modify<T>::ModifyInfoUnit& rhs) const;
   //從輸入流讀取一個單元
   void ReadFrom(istream&);
  };
  const int CharSize;
  EInputStream CIN;
  void Input();
  bool InputIsOk;
  mutable ifstream SourceFile;
  mutable ofstream DestFile;
  set<ModifyInfoUnit> ModifyInfoSet;//集合
};
template<class T>
const int Modify<T>::MaxByte;
  下面逐一解釋:

template<class T>,
AddressType,MaxByte;
  同上述

struct ModifyInfoUnit;
  修改要素——地址,新的數值,新數值的字節數。

  比較原則——為從頭到尾排序提供準則。

  輸入函數——從輸入流中讀取一個單元。

set<ModifyInfoUnit> ModifyInfoSet;
  修改要素的集合,按照地址從小到大自動排序,排序原則由ModifyInfoUnit 的bool operator<>提供。

template<class T>
Modify<T>::Modify():CharSize(sizeof(char)),CIN(cin)
{
 InputIsOk=true;
 Input();
}
  構造函數,設置輸入狀態。

template<class T>
void Modify<T>::Input()
{
 string fn;
 cout<<"Source binary file name:/t";
 CIN>>fn;
 SourceFile.open(fn.c_str(),ios::in ios::binary);
 if(!SourceFile)
 {
  cerr<<"Open "<<fn<<" failed./n";
  InputIsOk=false;
  return;
 }
 cout<<"Save file name:/t";
 CIN>>fn;
 DestFile.open(fn.c_str(),ios::out ios::binary);
 if(!DestFile)
 {
  cerr<<"Create "<<fn<<" failed./n";
  InputIsOk=false;
  return;
 }
 cout<<"Any character which makes format error will end the input progress.(etc a)/n";
 cout<<"Address(Dec)/tNewValue/tByteNumber(1--" <<Modify<T>::MaxByte<<")/n";
 while(true)
 {
  ModifyInfoUnit MIU;
  //從真實的輸入流中讀取一個ModifyInfoUnit
  MIU.ReadFrom(CIN.Actual());
  //輸入失敗就退出循環
  if(!CIN.Actual()) break;
  //把輸入成功的單元存入集合,自動排序
  ModifyInfoSet.insert(MIU);
 }
 CIN.ClearAndIgnore();//清除流的失敗狀態
}
  用戶輸入源文件名和目標文件名。有錯誤的話直接退出。從鍵盤輸入ModifyInfoUnit,輸入失敗表示停止輸入。CIN.Actual()返回真實的流。每次輸入一個MIU 就放入集合中自動排序。

  set在前面講了一點,在這里終于現身了。set是一種關聯式容器,其自動排序功能需要指定排序準則。對于內部數據類型(比如char 、int、double 等),比較大小的原則是內建的。但是對于用戶自定義的類型,就必須指定比較的方法了。set默認的比較法則是“小于”。在ModifyInfoUnit中間提供“小于”的成員函數(bool operator<),就為set使用默認的排序原則提供了定義。

  和上面對應,在此也能使用vector,不過使用vector意味著一旦重新分配內存,所有元素都要拷貝,對于int而言,開銷可能比較小,但對于這里的ModifyInfoUnit,開銷就要多一點了。set只是一種方法,還有一種常用的關聯式容器是map。map由要害字key和值value組成。

  根據key可以在對數時間內找到對應的value。map是按照key排序的,默認的排序準則是“小于”。假如在這里運用,key就是修改地址,value就是新值及其字節數。

  set<ModifyInfoUnit>;就變成map<AddressType,pair<T,int> >;這樣就不需要編寫比較準則了,其他相應修改就不在這里贅述了,讀者可以自己試一下。筆者認為,map和set相比在于能快捷的通過要害字來查找對應值,在這個應用場合還用不到通過地址來查看對應的新值和字節數,故沒有采用map。

  把ModifyInfoUnit設計為一個全公開的內嵌結構( 或者類), 作為一個私有成員也是常用的手法。

  ModifyInfoUnit對外而言是無需了解(私有成員),但是可以被Modify毫無限制的存取。


template<class T>
void Modify<T>::Run() const
{
 if(InputIsOk==false) return;
 set<ModifyInfoUnit>::const_iterator Beg=
 ModifyInfoSet.begin(),End=ModifyInfoSet.end();
 AddressType Address=0;
 char ch;
 while(SourceFile && Beg!=End)
 {
  //SourceFile沒有讀完并且集合也沒有遍歷結束
  if(Address==Beg->Address)
  {
   //到了指定的地址了
   const char*P=reinterpret_cast<const char*>(&(Beg->NewValue));
   for(int k=0;k<Beg->ByteNumber;++k)
   {
    //忽略源文件
    SourceFile.read(&ch,CharSize);
   }
   //寫新值
   DestFile.write(P,CharSize*Beg->ByteNumber);
   Address+=Beg->ByteNumber;
   ++Beg;
  }
  else
  {
   SourceFile.read(&ch,CharSize);
   DestFile.write(&ch,CharSize);
   ++Address;
  }
 }
 //源文件中可能還有剩余的內容
 while(SourceFile.read(&ch,CharSize))DestFile.write(&ch,CharSize);
}
  修改的核心函數。遍歷源文件, 當地址等于ModifyInfoSet集合當前元素的地址時,忽略源文件,把新值寫入目標文件。一旦源文件讀取到了末尾或者集合全部走過了,就跳出循環。

  這里的const_iterator,begin和end與前面講述的作用相似,只是本來是指向鏈表的,現在指向集合了。

template<class T>
bool Modify<T>::ModifyInfoUnit::operator<(const Modify<T>::
ModifyInfoUnit& rhs) const
{
 return Address<rhs.Address;
}
  定義排序原則,應該是一個const成員函數。

template<class T>
void Modify<T>::ModifyInfoUnit::ReadFrom(istream& IS)
{
 IS>>Address>>NewValue>>ByteNumber;
 if(ByteNumber<1ByteNumber>Modify<T>::MaxByte)
  ByteNumber=Modify<T>::MaxByte;
}
  從輸入流讀取一個ModifyInfoUnit,假如ByteNumber不符合就修正。手工批量修改的代碼也差不多了。這樣,對于若干個已知的地址假如要一次性修改,就用這個吧!方便又省事。 實戰《仙劍3 》

  看到這里也不輕易了,頭昏腦脹了吧?放松一下,來試試看我們的工具吧!實驗對象是《仙劍3》。選擇《仙劍3》是因為筆者正巧在玩這個游戲,雖然網上有《仙劍3》存檔的修改器,不過我還是授人以漁吧。

  修改存檔前要做好備份。所有文件名中間不能有空格等空白符號。游戲第一個存檔是pal00.arc,第二個存檔是pal01.arc,以此類推。

  選擇兩個文檔比如pal01.arc和pal02.arc,都是景天、雪見、龍葵、紫萱四人的組合。記錄下兩個文檔的如下數據:金錢,每個人的經驗值,都是4字節。再記錄下其中一個存檔(比如pal02.arc)中的每個人的“精”、“氣”、“神”的上限(4字節),“武”、“防”、“速”和“運” (字節數尚沒確定)。注重:“武”、“防”、“速”和“運” 應該是沒有使用武器和道具時候的數據。

  對于每一個屬性,比如景天的經驗值,在pal01.arc和pal02.arc 中用CheckBinaryFile找到地址,分別保存為a.txt和b.txt。再用取得交集的方法得到c.txt。那么c.txt的內容就是景天的經驗值在存檔中的地址,一般是1-2個。

  得到金錢和四個人的經驗值地址后,用手工批量處理的方法得到新的存檔文件,其中金錢可修改的大一點,四個人的經驗值不必過大,保證可以升級即可。我得到的數據是:

用C++制作自己的游戲修改器(下)(圖一)

  把新的文檔覆蓋原文檔,載入游戲后看看是否正確,然后打一仗后四個人全部升級。存檔為pal03.arc,再次記錄下每個人的“精”、“氣”、“神”的上限,“武”、“防”、“速”和“運”。

  由于pal02.arc 和pal03.arc之間存在升級,“精”、“氣”、“神”的上限,“武”、“防”都會變化,“速”和“運” 倒是沒有變,只能暫時放棄。

  故技重演,需要通過pal02.arc和pal03.arc找到四個人的“精”、“氣”、“神”的上限,“武”、“防”。于是先得到如下數據:

用C++制作自己的游戲修改器(下)(圖二)

  檢測到這里,有兩個發現:

  A. “武”、“防”相差4個地址,那么極有可能:“速”的地址是“防”的地址+4,“運”是“速”+4,而且“武”、“防”、“速”和“運”都是4 字節。4 字節意味著我可以修改為百萬,上億甚至更大的數值。

  B. 各屬性的地址相對固定。比如經驗值地址減去92就是“武”的地址,減去104 就是“精”的地址。這也是合情合理的,筆者猜測該游戲中每個人的屬性是一個結構(struct),假如四個人都采用相同的結構,那么每個人的屬性之間的地址差都是一樣的。

  有了上述推算,可以直接計算出剩下的地址了。從經驗值地址得到其他屬性的地址,筆者懶得自己用計算器重復勞動了,用Excel寫個模板,填入經驗值地址就能得到其他地址了。于是得到如左下表格所示的結果:


用C++制作自己的游戲修改器(下)(圖三)

  由于要修改的東西比較多,以后可能還要用到這些數據,我們可以把要修改的指令保存到一個文本文件(比如haha.txt),用輸入重定向的方法執行程序。該文本文件的內容就是使用該工具時,從鍵盤輸入的數據。為節省篇幅,我只列出修改金錢和男主角屬性的內容:

2
pal15.arc
pal15.bak
148 987654321 4
8929 987654321 4
1456 3000000 4
1364 1000001 4
1368 1000002 4
1372 1000003 4
1376 1000004 4
1352 1000005 4
1640 1000005 4
1356 1000007 4
1644 1000007 4
1360 1000009 4
1648 1000009 4 X
-1
h
  執行過程由于采用了輸入重定向,所以本來通過鍵盤輸入的數據現在從haha.txt讀?。?

用C++制作自己的游戲修改器(下)(圖四)

  覆蓋原文檔,載入游戲,戰斗勝利后觸發升級。給幾張截圖看看:

用C++制作自己的游戲修改器(下)(圖五)

  對于游戲中的龍精石,我還沒有找到修改方法,或許不能修改。根據我自己的實踐,“速”和“運”不要修改的太高(一兩百就夠了),或者干脆不要改了,否則會導致比較希奇的問題。當游戲中人物不同時候,存放地址可能不同,不過各個人物的屬性的相對地址還是一樣的。

  經驗值不必改得太高,只要可以觸發戰斗后的升級即可,一旦到了99級就不能升級了。對于每個人使用魔法的次數也能修改的,比如景天第一次使用“風咒”存盤一下,再使用一次再存盤。檢查兩個存盤文件的數值1和2,再用取得交集的方法得到一個唯一的地址,然后手動批量修改一下。我在網上看到說魔法次數最大顯示為255,因此修改成2字節的200就夠了。載入游戲再運用一次,就會變成級別4。像景天現在的“武”超過了一百萬,攻擊力起碼幾十萬,大概沒有人可以反抗了。

  對于好感度,戰斗中(景天處于陣中)可以通過援助來增加好感度、女戰友死亡會降低好感度,對話會影響好感度(比如在網上看到對話結束后的長音代表好感度+5,中音+3)。網上有些功略指出了對話的好感度增加值。我是這樣試驗的:選一個包含全部女主角的組合存檔(比
如pal01.arc),修改她們的生命值到比較低的值(比如1), 戰斗中讓她們全部死亡,唯獨自己活著,然后存檔(pal02.arc)。我估計死亡一次大概降低2個好感度,于是pal01.arc與pal02.arc的相對值為2,字節數也為2,運行程序找到好多個地址,打開一看,前面幾行是:

Relative value is 2
Address Value1 Value2
696 45 43
700 34 32
704 31 29
15962 2 0
19341 2 0
  估計這三個地址是696,700和704,于是批量修改為80、85、90,下面是一張截圖:

用C++制作自己的游戲修改器(下)(圖六)

  這個游戲筆者第一次只玩到鎖妖塔,覺得迷宮太復雜了沒有繼續下去,后來寫了這個程序后又重新開頭試了一下,AI進攻真是干脆利落,目前發現存在兩個問題:

 ?、?假如修改某人的“精氣神”的上限,后來她離開隊伍又加入了,這時“精氣神”上限只有幾百,這只出現在離開隊伍后來又加入的情況。

 ?、?在拿到土靈珠被大胡子搶走后,劇情要求戰敗的。我當時修改后四個人全部是AI進攻,每個人的“武”都超過了一百萬,硬是打不死
大胡子,但我每個人的“精”、“防”也都很高,這樣就造成了死循環,只能Ctrl+Alt+Del強制退出,看來只能把當前的“精”修改到最小才能戰敗。

  對于數值明確的對象,通過相對值查找也是一種方法,非凡是游戲初期,數值比較小,內容相同的地址很多,既可以通過“取交集”,也能使用“相對值”。

  總結

  修改游戲主要分為兩種:動態和靜態。本文介紹的是靜態法,在游戲存檔中目的明確的修改;動態法就是直接在游戲過程中修改內存數據了,還能進行一些模糊查找,兩者各有特點。筆者孤陋寡聞,沒發現比較便利的修改游戲存檔的工具,就自己寫了一個(版權所有,哈哈)。程序主要是模擬UE手工修改游戲存檔的原理來制作的,并陸續加入了一些自己想到的功能。一旦游戲對存檔文件進行了加密或者校驗就無能為力了(UE也應該如此吧?。?。

  程序的順利完工很大程度上得益于C++的STL,比如筆者運用了vector、list、set 等容器,sort、unique、copy和set_itersection等算法以及一些常用迭代器。使用STL的好處就是安全、高效、簡潔。編譯器選擇了Borland 的C++ Builder 6,這是Windows平臺中對標準C++支持較好的一種。

  筆者的C++是工作之余自學的,只有兩年左右時間,這個程序是一時心血來潮編寫的,不足之處肯定是有的。用編程來修改游戲算是學以致用,寓教于樂,還可以給自己玩游戲找借口。初衷是給自己用用,不怕丟臉,后來覺得還有點技術含量,就寫了這篇文章,希望對C++初學者有點幫助,給玩游戲的帶來點快樂。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品高潮在线| 国产精品日韩专区| 亚洲老头老太hd| 久久久999成人| 欧美做爰性生交视频| 在线免费观看羞羞视频一区二区| 精品视频在线播放色网色视频| 国产福利视频一区| 亚洲精品国偷自产在线99热| 亚洲第一级黄色片| 日韩亚洲欧美中文在线| 国产欧美在线视频| 一本色道久久综合狠狠躁篇的优点| 97国产精品人人爽人人做| 久久久久久18| 欧美视频国产精品| 2024亚洲男人天堂| 久久99久久99精品免观看粉嫩| 一区二区在线视频| 国产97色在线|日韩| 亚洲美女又黄又爽在线观看| 日av在线播放中文不卡| 亚洲最大的av网站| 欧美视频专区一二在线观看| 日本精品一区二区三区在线播放视频| 久久久久久中文字幕| 国产日韩在线看片| 国内外成人免费激情在线视频网站| 亚洲精品美女在线观看播放| 亚洲已满18点击进入在线看片| 久久久久久成人精品| 久久久电影免费观看完整版| 久久亚洲精品小早川怜子66| 91视频国产精品| 亚洲欧洲激情在线| 国产成人免费91av在线| 精品国产一区二区三区在线观看| 国产一区二区成人| 97精品欧美一区二区三区| 亚洲精品中文字| 成人有码在线视频| 日韩成人网免费视频| 亚洲最大福利视频网站| 国产精品99一区| 国产一区二区成人| 精品国产91乱高清在线观看| 91理论片午午论夜理片久久| 亚洲人成啪啪网站| 亚洲人永久免费| 2019亚洲男人天堂| 国产亚洲精品美女久久久久| 日本久久久久久| 中文字幕在线精品| 日本韩国欧美精品大片卡二| 国产欧美精品在线| 久久精品国产一区二区三区| www.日韩av.com| 狠狠色香婷婷久久亚洲精品| 中文字幕亚洲色图| 亚洲风情亚aⅴ在线发布| 久久久精品国产亚洲| 精品无人国产偷自产在线| 国产成人自拍视频在线观看| 欧美专区福利在线| 欧美在线视频播放| 日韩在线国产精品| 亚洲欧美中文字幕在线一区| 国产成人高潮免费观看精品| 91在线观看免费高清完整版在线观看| 国产精品一区久久久| 高清视频欧美一级| 91九色单男在线观看| 色先锋资源久久综合5566| 国产精品视频久久久久| 久久免费视频在线| 亚洲国产精品字幕| 国产成人一区二区在线| 久久网福利资源网站| 国产激情综合五月久久| 亚洲国产精品小视频| 日韩久久免费视频| 成人国内精品久久久久一区| 57pao精品| 久久久av电影| 国产精品96久久久久久| 欧美成人网在线| 欧美成人免费全部观看天天性色| 中文字幕日韩在线观看| 欧美国产视频一区二区| 亚洲精品日产aⅴ| 亚洲国产精品嫩草影院久久| 久久久久999| 亲子乱一区二区三区电影| 成人免费网站在线看| 欧美成aaa人片在线观看蜜臀| 国产精品高精视频免费| 精品久久久久久国产91| 精品久久久久久亚洲精品| 欧美成人一区在线| 欧美另类xxx| 国产亚洲综合久久| 精品日韩美女的视频高清| 亚洲免费视频网站| 中文字幕久久久| 亚洲精品视频网上网址在线观看| 欧美性极品xxxx娇小| 欧美极品少妇与黑人| 亚洲va电影大全| 欧美野外猛男的大粗鳮| 91沈先生在线观看| 国产成人黄色av| 亚洲精品国产综合久久| 国产精品久久久久久av福利软件| yw.139尤物在线精品视频| 日韩理论片久久| 亚洲欧美综合区自拍另类| 欧美激情xxxx| 国产视频自拍一区| 一区二区三区视频观看| 国产精品r级在线| 精品久久久久久久久久久久久久| 91在线网站视频| 中文字幕国内精品| 成人福利视频网| 欧美日韩电影在线观看| 最近2019中文免费高清视频观看www99| 日韩av大片在线| 久久国产精品久久久久| 91精品久久久久久久| 日韩成人高清在线| 欧美激情2020午夜免费观看| 国产69精品99久久久久久宅男| 日韩专区在线播放| 久久久久久久久久久网站| 久久久久久久久久久91| 92福利视频午夜1000合集在线观看| 日韩美女免费视频| 亚洲一区国产精品| 国产亚洲欧美一区| 日韩美女激情视频| 在线视频欧美日韩精品| 美女av一区二区三区| 中文字幕视频在线免费欧美日韩综合在线看| 国产亚洲欧美视频| 欧美精品福利视频| 亚洲成人亚洲激情| 日韩在线小视频| 亚洲精品福利免费在线观看| 国语自产在线不卡| 亚洲欧美色婷婷| 91国内在线视频| 欧美黑人又粗大| 欧美日韩国产区| 日韩欧美中文字幕在线播放| 国产精品一区二区久久久久| 黄网站色欧美视频| 欧美一级在线亚洲天堂| 亚洲自拍欧美另类| 国产成人精品综合久久久| 日韩高清a**址| 在线视频日本亚洲性| 亚洲综合日韩中文字幕v在线| 亚洲成人精品视频| 一区二区成人av|