Compare commits
2 commits
263c0bc065
...
cb2ac7c469
| Author | SHA1 | Date | |
|---|---|---|---|
| cb2ac7c469 | |||
| 1fc263c931 |
12 changed files with 234 additions and 70 deletions
|
|
@ -7,5 +7,5 @@ edition = "2021"
|
|||
actix-web = "4"
|
||||
rust-discord-activity = { git = "https://github.com/AmokDev/rust-discord-activity", version = "0.3.1" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
tokio = "1.44.1"
|
||||
|
||||
serde_json = "1.0"
|
||||
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
||||
|
|
|
|||
1
app/data.json
Normal file
1
app/data.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"episode":6,"season":1,"timestamps":[18000,2597000],"name":"Элементарно","image_url":"https://statichdrezka.ac/i/2020/12/17/xe6ea25038d76rc83x59z.jpeg"}
|
||||
|
|
@ -10,31 +10,53 @@ use rust_discord_activity::{
|
|||
};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use tokio::time::Duration;
|
||||
use crate::utils::json_database::load_from_json;
|
||||
|
||||
pub async fn start_presence() {
|
||||
let mut client = DiscordClient::new("1351391108088987748");
|
||||
|
||||
let _ = client.connect();
|
||||
|
||||
let limg = Some(String::from("https://i.ibb.co/SDDCLdHN/discord-logo-discord-icon-transparent-free-png.png"));
|
||||
let asset = Asset::new(limg.clone(), Some(String::from("#noWar")), limg, None);
|
||||
let now_in_millis = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis();
|
||||
let timestamps = Timestamp::new(Some(now_in_millis - 10000), Some(now_in_millis + 100000));
|
||||
let mut activity = Activity::new();
|
||||
|
||||
activity
|
||||
.set_state(Some("Сезон 1 Серия 5".into()))
|
||||
.set_activity_type(Some(ActivityType::WATCHING))
|
||||
.set_details(Some("Элементарно".parse().unwrap()))
|
||||
.set_timestamps(Some(timestamps))
|
||||
.set_assets(Some(asset))
|
||||
.set_instance(Some(true));
|
||||
|
||||
let payload = Payload::new(EventName::Activity, EventData::Activity(activity));
|
||||
|
||||
let _ = client.send_payload(payload);
|
||||
println!(":: Rich Presence started!");
|
||||
|
||||
|
||||
loop {
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
let post_data = load_from_json();
|
||||
let mut episode: u8 = 0;
|
||||
let mut season: u8 = 0;
|
||||
let mut timestamps: [u128; 2] = [0, 0];
|
||||
let mut name: String = String::from("name");
|
||||
let mut image_url: String = String::from("hdrezcord-logo");
|
||||
if let Ok(data) = post_data {
|
||||
episode = data.episode;
|
||||
season = data.season;
|
||||
timestamps = data.timestamps;
|
||||
name = data.name;
|
||||
image_url = data.image_url;
|
||||
}
|
||||
|
||||
let asset = Asset::new(Some(image_url), Some(String::from("#noWar")), None, None);
|
||||
let now_in_millis = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis();
|
||||
let timestamp = Timestamp::new(Some(now_in_millis - timestamps[0]), Some(now_in_millis + (timestamps[1] - timestamps[0])));
|
||||
let mut activity = Activity::new();
|
||||
|
||||
let mut subtitle = format!("Сезон {season} Серия {episode}");
|
||||
if season == 0 && episode == 0 {
|
||||
subtitle = format!("Фильм");
|
||||
}
|
||||
activity
|
||||
.set_state(Some(subtitle).into())
|
||||
.set_activity_type(Some(ActivityType::WATCHING))
|
||||
.set_details(Some(name))
|
||||
.set_timestamps(Some(timestamp))
|
||||
.set_assets(Some(asset))
|
||||
.set_instance(Some(true));
|
||||
|
||||
let payload = Payload::new(EventName::Activity, EventData::Activity(activity));
|
||||
|
||||
if episode == 0 && timestamps[0] == 0 && timestamps[1] == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let _ = client.send_payload(payload);
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
mod network;
|
||||
mod discord;
|
||||
mod utils;
|
||||
|
||||
use network::api::start_api;
|
||||
use discord::rpc::start_presence;
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
tokio::spawn(start_presence());
|
||||
start_api().await?;
|
||||
let _ = tokio::join!(start_api(), start_presence());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,20 @@
|
|||
use actix_web::{get, App, HttpResponse, HttpServer, Responder};
|
||||
use serde::Serialize;
|
||||
use actix_web::{post, App, HttpResponse, HttpServer, web};
|
||||
use crate::utils::json_database::{save_to_json, PostData};
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct MyResponse {
|
||||
message: String,
|
||||
#[post("/set_presence")]
|
||||
async fn set_presence(data: web::Json<PostData>) -> HttpResponse {
|
||||
println!("{:?}", data);
|
||||
let _ = save_to_json(&data);
|
||||
HttpResponse::Ok().finish()
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
async fn hello() -> impl Responder {
|
||||
HttpResponse::Ok().json(MyResponse { message: "Hello, world!".to_string() })
|
||||
}
|
||||
|
||||
pub async fn start_api() -> std::io::Result<()> {
|
||||
pub async fn start_api() -> std::io::Result<()> {
|
||||
println!(":: API Started!");
|
||||
HttpServer::new(|| {
|
||||
App::new()
|
||||
.service(hello)
|
||||
.service(set_presence)
|
||||
})
|
||||
.bind("127.0.0.1:2006")?
|
||||
.run()
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
|
|||
27
app/src/utils/json_database.rs
Normal file
27
app/src/utils/json_database.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct PostData {
|
||||
pub episode: u8,
|
||||
pub season: u8,
|
||||
pub timestamps: [u128; 2],
|
||||
pub name: String,
|
||||
pub image_url: String,
|
||||
}
|
||||
|
||||
pub fn save_to_json(post_data: &PostData) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let json_string = serde_json::to_string(post_data)?;
|
||||
let mut file = File::create("data.json")?;
|
||||
file.write_all(json_string.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_from_json() -> Result<PostData, Box<dyn std::error::Error>> {
|
||||
let mut file = File::open("data.json")?;
|
||||
let mut json_string = String::new();
|
||||
file.read_to_string(&mut json_string)?;
|
||||
let post_data = serde_json::from_str(&json_string)?;
|
||||
Ok(post_data)
|
||||
}
|
||||
1
app/src/utils/mod.rs
Normal file
1
app/src/utils/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub mod json_database;
|
||||
95
content.js
Normal file
95
content.js
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
function get_episode() {
|
||||
const active = document.querySelector('li.b-simple_episode__item.active');
|
||||
|
||||
if (active) {
|
||||
const textContent = active.textContent.trim();
|
||||
const episodeNumberString = textContent.replace("Серия ", "");
|
||||
const episodeNumber = parseInt(episodeNumberString, 10);
|
||||
|
||||
if (!isNaN(episodeNumber)) {
|
||||
return episodeNumber;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function get_season() {
|
||||
const active = document.querySelector('li.b-simple_season__item.active');
|
||||
|
||||
if (active) {
|
||||
const textContent = active.textContent.trim();
|
||||
const episodeNumberString = textContent.replace("Сезон ", "");
|
||||
const episodeNumber = parseInt(episodeNumberString, 10);
|
||||
|
||||
if (!isNaN(episodeNumber)) {
|
||||
return episodeNumber;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function timeToMilliseconds(timeString) {
|
||||
const [hours, minutes, seconds] = timeString.split(':').map(Number);
|
||||
return (hours * 3600 + minutes * 60 + seconds) * 1000;
|
||||
}
|
||||
|
||||
function get_timestamps() {
|
||||
const timeElements = document.querySelectorAll('pjsdiv[style*="pointer-events: none;"] noindex');
|
||||
const times = [];
|
||||
|
||||
timeElements.forEach(element => {
|
||||
times.push(element.textContent);
|
||||
});
|
||||
|
||||
const currentTime = times[0];
|
||||
const totalTime = times[1].replace("/ ", "");
|
||||
|
||||
|
||||
if (currentTime == NaN || totalTime == NaN) {
|
||||
console.warn("timestamps not found");
|
||||
return [0, 0];
|
||||
}
|
||||
|
||||
return [timeToMilliseconds(currentTime), timeToMilliseconds(totalTime)];
|
||||
}
|
||||
|
||||
function get_name() {
|
||||
let element = document.querySelector('.b-post__title h1[itemprop="name"]');
|
||||
return element.textContent;
|
||||
}
|
||||
|
||||
function get_image_url() {
|
||||
const element = document.querySelector('.b-post__infotable_left .b-sidecover a img');
|
||||
return element.src;
|
||||
}
|
||||
|
||||
if (window.location.href.includes("flymaterez.net")) {
|
||||
setInterval(async () => {
|
||||
try {
|
||||
chrome.storage.local.get(['pluginEnabled'], function(result) {
|
||||
if (result.pluginEnabled === true) {
|
||||
chrome.runtime.sendMessage({
|
||||
type: "send_rpc_request",
|
||||
title: document.title,
|
||||
url: window.location.href,
|
||||
episode: get_episode(),
|
||||
season: get_season(),
|
||||
timestamps: get_timestamps(),
|
||||
name: get_name(),
|
||||
image_url: get_image_url(),
|
||||
});
|
||||
}
|
||||
console.log(result.pluginEnabled);
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
|
@ -13,15 +13,22 @@
|
|||
"default_popup":"popup.html"
|
||||
},
|
||||
"permissions": [
|
||||
"storage"
|
||||
"storage",
|
||||
"activeTab",
|
||||
"scripting",
|
||||
"tabs"
|
||||
],
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["<all_urls>"],
|
||||
"js": ["content.js"],
|
||||
"run_at": "document_end"
|
||||
}
|
||||
],
|
||||
"background": {
|
||||
"service_worker": "service-worker.js"
|
||||
},
|
||||
"web_accessible_resources": [
|
||||
{
|
||||
"resources": ["rpc.js"],
|
||||
"matches": ["<all_urls>"]
|
||||
}
|
||||
"host_permissions": [
|
||||
"<all_urls>"
|
||||
]
|
||||
}
|
||||
10
popup.js
10
popup.js
|
|
@ -1,3 +1,5 @@
|
|||
|
||||
|
||||
const on = document.getElementById("on");
|
||||
const off = document.getElementById("off");
|
||||
const plugin_status = document.getElementById("status");
|
||||
|
|
@ -24,9 +26,9 @@ function toggle_status() {
|
|||
function get_status() {
|
||||
chrome.storage.local.get(['pluginEnabled'], function(result) {
|
||||
if (result.pluginEnabled === true) {
|
||||
plugin_status.innerHTML = "Plugin is disabled";
|
||||
} else if (result.pluginEnabled === false) {
|
||||
plugin_status.innerHTML = "Plugin is enabled";
|
||||
} else if (result.pluginEnabled === false) {
|
||||
plugin_status.innerHTML = "Plugin is disabled";
|
||||
}
|
||||
console.log(result.pluginEnabled);
|
||||
});
|
||||
|
|
@ -37,9 +39,9 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||
if (result.pluginEnabled === undefined) {
|
||||
chrome.storage.local.set({ pluginEnabled: false });
|
||||
} else if (result.pluginEnabled === true) {
|
||||
on.classList.toggle("is-outlined");
|
||||
} else if (result.pluginEnabled === false) {
|
||||
off.classList.toggle("is-outlined");
|
||||
} else if (result.pluginEnabled === false) {
|
||||
on.classList.toggle("is-outlined");
|
||||
}
|
||||
});
|
||||
on.addEventListener("click", function() {
|
||||
|
|
|
|||
20
rpc.js
20
rpc.js
|
|
@ -1,20 +0,0 @@
|
|||
const rpc = require('discord-rpc');
|
||||
const clientId = '1351391108088987748';
|
||||
rpc.register(clientId);
|
||||
|
||||
const client = new rpc.Client({ transport: 'ipc' });
|
||||
|
||||
client.on('ready', () => {
|
||||
console.log('RPC запущен!');
|
||||
client.setActivity({
|
||||
details: 'Играю в вашу игру',
|
||||
state: 'Нахожусь на уровне 1',
|
||||
startTimestamp: new Date(),
|
||||
// largeImageKey: 'image_key', // замените на ключ изображения
|
||||
// largeImageText: 'Дополнительный текст',
|
||||
instance: false,
|
||||
});
|
||||
});
|
||||
|
||||
client.login({ clientId }).catch(console.error);
|
||||
|
||||
|
|
@ -1 +1,33 @@
|
|||
importScripts("rpc.js")
|
||||
async function send_rpc_request(data) {
|
||||
try {
|
||||
const response = await fetch('http://127.0.0.1:2006/set_presence', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
console.log(response.type)
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener(
|
||||
function(request, sender, sendResponse) {
|
||||
if (request.type === "send_rpc_request") {
|
||||
send_rpc_request({
|
||||
episode: request.episode,
|
||||
season: request.season,
|
||||
timestamps: request.timestamps,
|
||||
name: request.name,
|
||||
image_url: request.image_url
|
||||
})
|
||||
console.log(request.episode, request.season, request.timestamps)
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue