You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
459 lines
16 KiB
459 lines
16 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Net.Sockets;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using System.Timers;
|
|
using System.Windows.Forms;
|
|
|
|
namespace rabiribi_splitter
|
|
{
|
|
public partial class Form1 : Form
|
|
{
|
|
private static TcpClient tcpclient;
|
|
private static NetworkStream networkStream;
|
|
private static System.Timers.Timer timer;
|
|
private bool bossbattle = false;
|
|
private int lastmusicid;
|
|
private Regex titleReg = new Regex(@"ver.*?(\d+\.?\d+.*)$");
|
|
private Thread memoryThread;
|
|
private int lastmoney;
|
|
private bool rabiribiready;
|
|
private string rabiribititle;
|
|
private string rabiver;
|
|
private int veridx;
|
|
private List<int> lastbosslist = new List<int>();
|
|
private int lastnoah3hp = -1;
|
|
private int lastmapid;
|
|
private int lastTM;
|
|
private DateTime LastTMAddTime=DateTime.MinValue;
|
|
void DebugLog(string log)
|
|
{
|
|
if (this.InvokeRequired)
|
|
{
|
|
this.Invoke(new Action(() =>
|
|
{
|
|
this.debugLog.AppendText(log + "\r\n");
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
this.debugLog.AppendText(log + "\r\n");
|
|
}
|
|
}
|
|
public Form1()
|
|
{
|
|
InitializeComponent();
|
|
LinkLabel.Link link = new LinkLabel.Link();
|
|
link.LinkData = "https://github.com/copyliu/rabiribi_splitter";
|
|
linkLabel1.Links.Add(link);
|
|
linkLabel1.LinkClicked += LinkLabel1_LinkClicked;
|
|
memoryThread = new Thread(() =>
|
|
{
|
|
while (true)
|
|
{
|
|
readmemory();
|
|
Thread.Sleep(1000/60);
|
|
}
|
|
|
|
});
|
|
memoryThread.IsBackground = true;
|
|
memoryThread.Start();
|
|
}
|
|
|
|
private void LinkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
|
{
|
|
// Send the URL to the operating system.
|
|
Process.Start(e.Link.LinkData as string);
|
|
}
|
|
|
|
|
|
private void readmemory()
|
|
{
|
|
|
|
var processlist = Process.GetProcessesByName("rabiribi");
|
|
if (processlist.Length > 0)
|
|
{
|
|
|
|
Process process = processlist[0];
|
|
if (process.MainWindowTitle != rabiribititle)
|
|
{
|
|
var result = titleReg.Match(process.MainWindowTitle);
|
|
if (result.Success)
|
|
{
|
|
|
|
rabiver = result.Groups[1].Value;
|
|
veridx = Array.IndexOf(StaticData.VerNames, rabiver);
|
|
if (veridx < 0)
|
|
{
|
|
this.Invoke(new Action(() =>
|
|
{
|
|
rbStatus.Text = rabiver + " Running (not support)";
|
|
this.musicLabel.Text = "N/A";
|
|
}));
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
veridx = -1;
|
|
this.Invoke(new Action(() =>
|
|
{
|
|
rbStatus.Text = rabiver + " Running (not support)";
|
|
this.musicLabel.Text = "N/A";
|
|
}));
|
|
return;
|
|
}
|
|
this.Invoke(new Action(() => rbStatus.Text = rabiver + " Running"));
|
|
rabiribititle = process.MainWindowTitle;
|
|
}
|
|
|
|
|
|
if (veridx < 0) return;
|
|
|
|
|
|
#region read igt
|
|
|
|
int igt = MemoryHelper.GetMemoryValue<int>(process, StaticData.IGTAddr[veridx]);
|
|
if (igt>0 && cbIGT.Checked )
|
|
{
|
|
sendigt((float)igt/60);
|
|
}
|
|
#endregion
|
|
|
|
#region CheckMoney
|
|
|
|
if (cbComputer.Checked)
|
|
{
|
|
var newmoney = MemoryHelper.GetMemoryValue<int>(process, StaticData.MoneyAddress[veridx]);
|
|
if (newmoney - lastmoney == 17500)
|
|
{
|
|
sendsplit();
|
|
DebugLog("get 17500 en, split");
|
|
}
|
|
lastmoney = newmoney;
|
|
}
|
|
|
|
#endregion
|
|
|
|
int mapid = MemoryHelper.GetMemoryValue<int>(process, StaticData.MapAddress[veridx]);
|
|
if (lastmapid != mapid)
|
|
{
|
|
DebugLog("newmap: "+mapid+":"+StaticData.MapNames[mapid]);
|
|
lastmapid = mapid;
|
|
}
|
|
|
|
|
|
#region checkTM
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
#region Music
|
|
|
|
int musicaddr = StaticData.MusicAddr[veridx];
|
|
int musicid = MemoryHelper.GetMemoryValue<int>(process, musicaddr);
|
|
if (musicid > 0 && musicid < StaticData.MusicNames.Length)
|
|
{
|
|
if (lastmusicid != musicid)
|
|
{
|
|
DebugLog("new music:"+musicid+":"+StaticData.MusicNames[musicid]);
|
|
this.Invoke(new Action(() => this.musicLabel.Text = StaticData.MusicNames[musicid]));
|
|
|
|
var bossmusicflag = StaticData.BossMusics.Contains(musicid);
|
|
if (bossmusicflag)
|
|
{
|
|
if (bossbattle)
|
|
{
|
|
//直接换boss曲
|
|
if (cbBossStart.Checked || cbBossEnd.Checked)
|
|
{
|
|
sendsplit();
|
|
DebugLog("new boss music, split");
|
|
}
|
|
|
|
this.Invoke(new Action(() => cbBoss.Checked = bossbattle));
|
|
lastmusicid = musicid;
|
|
return;
|
|
}
|
|
}
|
|
if (!bossbattle)
|
|
{
|
|
|
|
if (cbASG.Checked && musicid == 54)
|
|
{
|
|
bossbattle = false;
|
|
DebugLog("Alius music, ignore once");
|
|
this.Invoke(new Action(() => cbASG.Checked = false));
|
|
}
|
|
else
|
|
{
|
|
if (bossmusicflag)
|
|
{
|
|
if (mapid == 5 && musicid == 44 && cbSideCh.Checked )
|
|
{
|
|
bossbattle = false;
|
|
DebugLog("sidechapter, ignore");
|
|
|
|
}
|
|
else
|
|
{
|
|
bossbattle = true;
|
|
lastbosslist = new List<int>();
|
|
lastnoah3hp = -1;
|
|
if (cbBossStart.Checked)
|
|
{
|
|
sendsplit();
|
|
DebugLog("music start, split");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!bossmusicflag) //boss music end!
|
|
{
|
|
bossbattle = false;
|
|
if (cbBossEnd.Checked)
|
|
{
|
|
sendsplit();
|
|
DebugLog("music end, split");
|
|
}
|
|
}
|
|
}
|
|
lastmusicid = musicid;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.Invoke(new Action(() => this.musicLabel.Text = "N/A"));
|
|
}
|
|
|
|
#endregion Music
|
|
|
|
#region SpecialBOSS
|
|
|
|
if (bossbattle)
|
|
{
|
|
if (cbBoss1.Checked || cbBoss3.Checked)
|
|
{
|
|
int Noah3HP = -1;
|
|
|
|
if (mapid >= 0 && mapid < StaticData.MapNames.Length)
|
|
{
|
|
int ptr = MemoryHelper.GetMemoryValue<int>(process, StaticData.EnenyPtrAddr[veridx]);
|
|
List<int> bosses = new List<int>();
|
|
for (var i = 0; i < 50; i++)
|
|
{
|
|
ptr = ptr + StaticData.EnenyEntitySize[veridx];
|
|
|
|
var emyid = MemoryHelper.GetMemoryValue<int>(process,
|
|
ptr + StaticData.EnenyEnitiyIDOffset[veridx], false);
|
|
if (StaticData.BossNames.ContainsKey(emyid))
|
|
{
|
|
bosses.Add(emyid);
|
|
if (emyid == 1053)
|
|
{
|
|
Noah3HP = MemoryHelper.GetMemoryValue<int>(process,
|
|
ptr + StaticData.EnenyEnitiyHPOffset[veridx], false);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
if (cbBoss1.Checked)
|
|
{
|
|
foreach (var boss in lastbosslist)
|
|
{
|
|
|
|
if (boss == 1043)
|
|
{
|
|
if (!bosses.Contains(boss)) //despawn
|
|
{
|
|
sendsplit();
|
|
DebugLog("miru despawn, split");
|
|
bossbattle = false;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cbBoss3.Checked)
|
|
{
|
|
if (bosses.Contains(1053) && Noah3HP < lastnoah3hp && Noah3HP == 1)
|
|
{
|
|
sendsplit();
|
|
DebugLog("noah3 hp 1, split");
|
|
bossbattle = false;
|
|
}
|
|
}
|
|
if (cbTM.Checked && musicid==8)
|
|
{
|
|
bool f = true;
|
|
foreach (var boss in lastbosslist)
|
|
{
|
|
|
|
if (boss == 1024)
|
|
{
|
|
if (!bosses.Contains(boss)) //despawn
|
|
{
|
|
sendsplit();
|
|
DebugLog("nixie despawn, split");
|
|
bossbattle = false;
|
|
f = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
int newTM = MemoryHelper.GetMemoryValue<int>(process, StaticData.TownMemberAddr[veridx]);
|
|
if (newTM - lastTM == 1 && f) //for after 1.71 , 1.71 isn't TM+2 at once when skip Nixie, it's TM+1 twice
|
|
|
|
{
|
|
if (DateTime.Now- LastTMAddTime < TimeSpan.FromSeconds(1))
|
|
{
|
|
var d = DateTime.Now - LastTMAddTime;
|
|
bossbattle = false;
|
|
sendsplit();
|
|
DebugLog("TM+2 in "+d.TotalMilliseconds+" ms, split");
|
|
}
|
|
LastTMAddTime = DateTime.Now;
|
|
}
|
|
else if (newTM - lastTM == 2 && f)//for 1.65-1.70
|
|
{
|
|
bossbattle = false;
|
|
sendsplit();
|
|
DebugLog("TM+2, split");
|
|
}
|
|
lastTM = newTM;
|
|
}
|
|
lastbosslist = bosses;
|
|
lastnoah3hp = Noah3HP;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
#endregion SpecialBOSS
|
|
|
|
if (debugArea.Checked)
|
|
{
|
|
int ptr = MemoryHelper.GetMemoryValue<int>(process, StaticData.EnenyPtrAddr[veridx]);
|
|
List<int> bosses = new List<int>();
|
|
List<int> HPS = new List<int>();
|
|
ptr += StaticData.EnenyEntitySize[veridx]*3;
|
|
for (var i = 0; i < 5; i++)
|
|
{
|
|
ptr += StaticData.EnenyEntitySize[veridx];
|
|
|
|
|
|
bosses.Add(MemoryHelper.GetMemoryValue<int>(process,
|
|
ptr + StaticData.EnenyEnitiyIDOffset[veridx], false));
|
|
HPS.Add(MemoryHelper.GetMemoryValue<int>(process,
|
|
ptr + StaticData.EnenyEnitiyHPOffset[veridx], false));
|
|
|
|
|
|
this.Invoke(new Action(() =>
|
|
{
|
|
t1.Text = string.Join("\n", bosses);
|
|
t2.Text = string.Join("\n", HPS);
|
|
}));
|
|
|
|
}
|
|
}
|
|
this.Invoke(new Action(() => cbBoss.Checked = bossbattle));
|
|
}
|
|
else
|
|
{
|
|
|
|
rabiribititle = "";
|
|
|
|
|
|
this.Invoke(new Action(() =>
|
|
{
|
|
rbStatus.Text = "Not Found";
|
|
this.musicLabel.Text = "N/A";
|
|
}));
|
|
|
|
}
|
|
}
|
|
|
|
void sendsplit()
|
|
{
|
|
if (tcpclient != null && tcpclient.Connected)
|
|
{
|
|
try
|
|
{
|
|
var b = Encoding.UTF8.GetBytes("split\r\n");
|
|
networkStream.Write(b, 0, b.Length);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
disconnect();
|
|
}
|
|
}
|
|
}
|
|
|
|
void sendigt(float time)
|
|
{
|
|
if (tcpclient != null && tcpclient.Connected)
|
|
{
|
|
try
|
|
{
|
|
var b = Encoding.UTF8.GetBytes($"setgametime {time}\r\n");
|
|
networkStream.Write(b, 0, b.Length);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
disconnect();
|
|
}
|
|
}
|
|
}
|
|
void disconnect()
|
|
{
|
|
tcpclient = null;
|
|
connectBtn.Enabled = true;
|
|
|
|
}
|
|
|
|
private void button2_Click(object sender, EventArgs e)
|
|
{
|
|
if (tcpclient != null && tcpclient.Connected) return;
|
|
try
|
|
{
|
|
tcpclient = new TcpClient("127.0.0.1", Convert.ToInt32(portNum.Value));
|
|
networkStream = tcpclient.GetStream();
|
|
connectBtn.Enabled = false;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
tcpclient = null;
|
|
networkStream = null;
|
|
MessageBox.Show(this, "Connect Failed");
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|