Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions Auth/FakeBrowser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Playwright;

namespace BiliApi.Auth
{
internal class FakeBrowser
{
IPlaywright pw;
IBrowser browser;
IBrowserContext context;

public FakeBrowser()
{
}

public async Task InitAsync()
{
if (pw == null)
pw = await Playwright.CreateAsync();
if (browser == null)
browser = await pw.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
{
Headless = true
});
if (context == null)
context = await browser.NewContextAsync();
}

public async Task<IReadOnlyList<BrowserContextCookiesResult>> GetContextCookies(string url)
{
return await context.CookiesAsync(url);
}

public async Task<CookieCollection> GetContextCookies()
{
var cookies = await context.CookiesAsync();
CookieCollection result = new CookieCollection();
foreach(BrowserContextCookiesResult cc in cookies)
{
System.Net.Cookie ccc = new System.Net.Cookie();
ccc.Domain = cc.Domain;
ccc.Name = cc.Name;
ccc.Path = cc.Path;
ccc.Value = cc.Value;
ccc.HttpOnly = cc.HttpOnly;
result.Add(ccc);
}
return result;
}

public async Task AddContextCookies(CookieCollection cookies)
{
List<Microsoft.Playwright.Cookie> cookieList = new List<Microsoft.Playwright.Cookie>();
foreach(System.Net.Cookie c in cookies)
{
Microsoft.Playwright.Cookie cc = new Microsoft.Playwright.Cookie();
cc.Value = c.Value;
cc.Name = c.Name;
cc.Path = c.Path;
cc.Domain = c.Domain;
cc.HttpOnly = c.HttpOnly;
cookieList.Add(cc);
}
await context.AddCookiesAsync(cookieList);
}

public async Task AddContextCookies(List<Microsoft.Playwright.Cookie> cookies)
{
await context.AddCookiesAsync(cookies);
}

public async Task<string> GetPageAsync(string url)
{
var page = await context.NewPageAsync();
await page.GotoAsync(url, new PageGotoOptions
{
WaitUntil = WaitUntilState.NetworkIdle
});
return await page.ContentAsync();
}
}
}
24 changes: 19 additions & 5 deletions Auth/QRLogin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using BiliApi.Exceptions;
using System.Threading;
using System.Drawing;
using Microsoft.Playwright;

namespace BiliApi.Auth
{
Expand All @@ -17,11 +18,13 @@ public class QRLogin : IAuthBase
{
const string URL_GETKEY = "https://passport.bilibili.com/x/passport-login/web/qrcode/generate";
const string URL_STATUS = "https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=";

FakeBrowser fb = new FakeBrowser();
public CookieCollection Cookies { get; private set; }
public LoginQRCode QRToken { private set; get; }
public bool LoggedIn { get; private set; }

public bool UseFakeBrowser { get; private set; }

public struct LoginQRCode
{
public string ScanUrl, OAuthKey;
Expand Down Expand Up @@ -50,7 +53,7 @@ public enum QRState
public string Serilize()
{
JArray jb = new JArray();
foreach (Cookie c in Cookies)
foreach (System.Net.Cookie c in Cookies)
{
JObject j = new JObject();
j.Add("k", c.Name);
Expand All @@ -62,10 +65,11 @@ public string Serilize()
return jb.ToString();
}

public QRLogin()
public QRLogin(bool fake_browser = true)
{
QRToken = GetNewQRItem();
LoggedIn = false;
UseFakeBrowser = fake_browser;
}

public QRLogin(LoginQRCode code)
Expand All @@ -80,7 +84,7 @@ public QRLogin(string serilizedJson)
Cookies = new CookieCollection();
foreach (JObject jb in ja)
{
Cookies.Add(new Cookie(
Cookies.Add(new System.Net.Cookie(
jb.Value<string>("k"), jb.Value<string>("v"), jb.Value<string>("p"), jb.Value<string>("d")
));
}
Expand Down Expand Up @@ -168,7 +172,17 @@ public QRState GetQRState(LoginQRCode qr)
return QRState.Expired;
case 0:
{
Cookies = res.Cookies;
if (UseFakeBrowser)
{
fb.InitAsync().Wait();
fb.AddContextCookies(res.Cookies).Wait();
fb.GetPageAsync("https://bilibili.com").Wait();
Cookies = fb.GetContextCookies().Result;
}
else
{
Cookies = res.Cookies;
}
LoggedIn = IsOnline();
if (!LoggedIn) throw new AuthenticateFailedException(jb);
return QRState.LoggedIn;
Expand Down
5 changes: 3 additions & 2 deletions BiliApi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="System.Drawing.Common" Version="5.0.0" />
<PackageReference Include="Microsoft.Playwright" Version="1.53.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Drawing.Common" Version="8.0.1" />
</ItemGroup>

</Project>
7 changes: 4 additions & 3 deletions BiliPrivMessage/PrivMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ namespace BiliApi.BiliPrivMessage
{
public class PrivMessage : IComparable
{
public int recieiver_id, timestamp, msgtype;
public long recieiver_id, timestamp;
public int msgtype;
public long msg_seqno;
public long msg_key;
public BiliUser talker;
Expand All @@ -15,9 +16,9 @@ public class PrivMessage : IComparable

public PrivMessage(JToken json,BiliSession sess)
{
recieiver_id = json.Value<int>("receiver_id");
recieiver_id = json.Value<long>("receiver_id");
timestamp = json.Value<int>("timestamp");
talker = BiliUser.getUser(json.Value<int>("sender_uid"),sess);
talker = BiliUser.getUser(json.Value<long>("sender_uid"),sess);
msgtype = json.Value<int>("msg_type");
msg_seqno = json.Value<long>("msg_seqno");
msg_key = json.Value<long>("msg_key");
Expand Down
25 changes: 19 additions & 6 deletions BiliPrivMessage/PrivMessageSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace BiliApi.BiliPrivMessage
{
public class PrivMessageSession
public class PrivMessageSession : IEquatable<PrivMessageSession>
{
public bool loaded = false;
public long talker_id;
Expand Down Expand Up @@ -40,7 +40,7 @@ public PrivMessageSession(long targetuid, BiliSession sess)

public void init(JToken json)
{
talker_id = json.Value<int>("talker_id");
talker_id = json.Value<long>("talker_id");
sessiontype = json.Value<int>("session_type");
session_ts = json.Value<long>("session_ts");
unread_cnt = json.Value<int>("unread_count");
Expand Down Expand Up @@ -211,12 +211,20 @@ public bool sendMessage(JObject job)
public bool SendImage(Bitmap bmap)
{
//上传图片
MemoryStream ms = new MemoryStream();
bmap.Save(ms, ImageFormat.Png);
using (MemoryStream ms = new MemoryStream())
{
bmap.Save(ms, ImageFormat.Png);
return SendImage(ms.ToArray());
}
}

public bool SendImage(byte[] bmap)
{
//上传图片
var upload = sess.PostFile(
"https://api.vc.bilibili.com/api/v1/drawImage/upload",
"https://message.bilibili.com",
ms.ToArray(),
bmap,
"file_up",
"image/png",
"picturen.png",
Expand All @@ -237,7 +245,7 @@ public bool SendImage(Bitmap bmap)
payload.Add("height", jb["data"]["image_height"]);
payload.Add("imageType", "png");
payload.Add("original", "1");
payload.Add("size", ms.ToArray().Length / 1024);
payload.Add("size", bmap.Length / 1024);
return sendMessage(payload);
}

Expand Down Expand Up @@ -276,5 +284,10 @@ public override int GetHashCode()
{
return talker_id.GetHashCode();
}

public bool Equals(PrivMessageSession other)
{
return talker_id.Equals(other.talker_id);
}
}
}
50 changes: 50 additions & 0 deletions BiliPrivMessage/PrivMsgReceiverLite.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using BiliApi.Exceptions;

namespace BiliApi.BiliPrivMessage
{
public class PrivMsgReceiverLite
{
BiliSession sess;
public DateTime LastUpdate = new DateTime(1999, 12, 12);

public PrivMsgReceiverLite(BiliSession session)
{
sess = session;
}

/// <summary>
/// 获取(自上次更新以来)新的私信会话
/// </summary>
/// <returns>新会话列表</returns>
/// <exception cref="ApiRemoteException">API出错</exception>
public List<PrivMessageSession> GetNewSessions()
{
string rtv = sess._get_with_cookies("https://api.vc.bilibili.com/session_svr/v1/session_svr/new_sessions?begin_ts=" +
TimestampHandler.GetTimeStamp16(LastUpdate) + "&build=0&mobi_app=web");
sess._get_with_cookies("https://api.vc.bilibili.com/session_svr/v1/session_svr/ack_sessions?begin_ts=" +
TimestampHandler.GetTimeStamp16(LastUpdate) + "&build=0&mobi_app=web");
LastUpdate = DateTime.Now;
JObject raw_json = (JObject)JsonConvert.DeserializeObject(rtv);
if (raw_json.Value<int>("code") != 0)
{//发生错误
throw new ApiRemoteException(raw_json);
}
List<PrivMessageSession> rtvlist = new List<PrivMessageSession>();
foreach (JToken jobj in raw_json["data"]["session_list"])
{
var psess = new PrivMessageSession(jobj, sess);
if(psess.lastmessage.talker.uid == sess.getCurrentUserId())
{
continue;
}
rtvlist.Add(psess);
}
return rtvlist;
}
}
}
7 changes: 4 additions & 3 deletions BiliPrivMessage/PrivSessionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,11 @@ public void smartRefresh()

public void updateSessions()
{
sess._get_with_cookies("https://api.vc.bilibili.com/session_svr/v1/session_svr/new_sessions?begin_ts=" + last_refresh + "&build=0&mobi_app=web");
string rtv = sess._get_with_cookies("https://api.vc.bilibili.com/session_svr/v1/session_svr/ack_sessions?begin_ts=" + last_refresh + "&build=0&mobi_app=web");
lastjson = rtv;
string rtv = sess._get_with_cookies("https://api.vc.bilibili.com/session_svr/v1/session_svr/new_sessions?begin_ts=" + last_refresh + "&build=0&mobi_app=web");
JObject raw_json = (JObject)JsonConvert.DeserializeObject(rtv);
rtv = sess._get_with_cookies("https://api.vc.bilibili.com/session_svr/v1/session_svr/ack_sessions?begin_ts=" + last_refresh + "&build=0&mobi_app=web");
lastjson = rtv;
//JObject raw_json = (JObject)JsonConvert.DeserializeObject(rtv);
if (raw_json.Value<int>("code") != 0)
{//发生错误
throw new ApiRemoteException(raw_json);
Expand Down
2 changes: 1 addition & 1 deletion BiliUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ public List<Medal> getMedals()
return metals;
}

public static List<Medal> getMedals(BiliSession sess, long uid)
public static List<Medal> getMedals(BiliSession sess, long uid, bool _ = false)
{
List<Medal> metals = new List<Medal>();
JObject jb = JObject.Parse(sess.getBiliUserMedal(uid));
Expand Down
2 changes: 1 addition & 1 deletion TimestampHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static int GetTimeStamp(DateTime dateTime)
public static long GetTimeStamp16(DateTime dateTime)
{
#pragma warning disable CS0618 // '“TimeZone”已过时:“System.TimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo instead.”
return (long)(dateTime - TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1))).TotalMilliseconds;
return (long)(dateTime - TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1))).TotalMilliseconds * 1000;
#pragma warning restore CS0618 // '“TimeZone”已过时:“System.TimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo instead.”
}
}
Expand Down