Skip to content

Commit

Permalink
gacha guild and server pg
Browse files Browse the repository at this point in the history
  • Loading branch information
HadziqM committed Dec 5, 2023
1 parent 6cc0bad commit 2d764ca
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 27 deletions.
36 changes: 9 additions & 27 deletions binding/src/postgres/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::utils::MyTime;
use super::{Db,PgCustomError};
use bcrypt::{hash, verify};
use chrono::NaiveDateTime;
use sqlx::{Pool, Postgres,Row, FromRow};
use sqlx::{Row, FromRow};

#[derive(Debug,FromRow)]
pub struct AccountData {
Expand All @@ -27,17 +27,9 @@ pub struct SaveData {
pub savemercenary: Option<Vec<u8>>,
}

pub enum FileSave{
Savedata(Vec<u8>),
Decomyset(Vec<u8>),
Hunternavi(Vec<u8>),
Otomoairou(Vec<u8>),
Partner(Vec<u8>),
Platedata(Vec<u8>),
Platebox(Vec<u8>),
Platemyset(Vec<u8>),
Eengokudata(Vec<u8>),
Savemercenary(Vec<u8>),
pub struct FileSave{
pub name:String,
pub bin: Vec<u8>
}


Expand Down Expand Up @@ -108,23 +100,13 @@ impl Db {
pub async fn send_save(&self,cid:i32)->Result<SaveData,PgCustomError>{
Ok(sqlx::query_as("SELECT * FROM characters WHERE id=$1").bind(cid).fetch_one(&**self).await?)
}
pub async fn transfer_cd(&self)->Result<(bool,i64),PgCustomError>{
let cd:i64 = sqlx::query("SELECT transfercd from discord where discord_id=$1").bind(&self.did).fetch_one(&self.pool).await?.try_get("transfercd")?;
let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
if now > cd as u64{
let week = now + 24*60*60;
sqlx::query("UPDATE discord SET transfercd=$2 where discord_id=$1").bind(&self.did).bind(week as i64).execute(&self.pool).await?;
return Ok((true,week as i64));
}
Ok((false,cd))
}
pub async fn transfer_file(&self,file:&FileSave,cid:i32)->Result<(),BitwiseError>{
sqlx::query(&format!("UPDATE characters SET {}=$1 WHERE id=$2",&file.name)).bind(file.bin.as_slice()).bind(cid).execute(&self.pool).await?;
pub async fn transfer_file(&self,file:&FileSave,cid:i32)->Result<(),PgCustomError>{
sqlx::query(&format!("UPDATE characters SET {}=$1 WHERE id=$2",&file.name)).bind(file.bin.as_slice()).bind(cid).execute(&**self).await?;
Ok(())
}
pub async fn purge(&self)->Result<(),BitwiseError>{
sqlx::query("DELETE from discord_register WHERE discord_id=$1").bind(&self.did).execute(&self.pool).await?;
sqlx::query("DELETE from discord WHERE discord_id=$1").bind(&self.did).execute(&self.pool).await?;
pub async fn purge(&self,did:&str)->Result<(),PgCustomError>{
sqlx::query("DELETE from discord_register WHERE discord_id=$1").bind(did).execute(&**self).await?;
sqlx::query("DELETE from discord WHERE discord_id=$1").bind(did).execute(&**self).await?;
Ok(())
}

Expand Down
75 changes: 75 additions & 0 deletions binding/src/postgres/custom.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use super::{Db,PgCustomError};
use sqlx::postgres::PgRow;
use sqlx::{Row,ValueRef,Column, Decode, Postgres};


impl Db {
pub async fn query(&self,qry:&str)->Result<String, PgCustomError>{
let fetch = sqlx::query(qry).fetch_all(&**self).await?;
Ok(row_to_table(fetch)?)
}
pub async fn execute(&self,qry:&str)->Result<(), PgCustomError>{
sqlx::query(qry).execute(&**self).await?;
Ok(())
}
}
fn get_name_type(row:&PgRow)->Result<String,PgCustomError>{
let mut string = Vec::new();
for i in row.columns(){
let name = i.name();
let typ = row.try_get_raw(i.ordinal())?;
string.push("\t".to_string());
string.push(format!("{}({})",name,typ.type_info().to_string()));
}
Ok(string[1..].concat())
}
fn get_value(row:PgRow)->Result<String,PgCustomError>{
let mut string = Vec::new();
for i in row.columns(){
let value = row.try_get_raw(i.ordinal())?;
let nam = value.type_info().to_string();
let name = nam.as_str();
let i32clust = vec!["INT","SERIAL","INT4"];
let i64clust = vec!["BIGINT","BIGSERIAL","INT8"];
let strclust = vec!["VARCHAR","CHAR(N)","TEXT","NAME"];
let boolclust = "BOOL";
let val;
if value.is_null(){
val = "NULL".to_string();
}else{
if i32clust.contains(&name){
val = <i32 as Decode<Postgres>>::decode(value).unwrap().to_string();
}else if i64clust.contains(&name){
val = <i64 as Decode<Postgres>>::decode(value).unwrap().to_string();
}else if strclust.contains(&name){
val = <&str as Decode<Postgres>>::decode(value).unwrap().to_string();
}else if name==boolclust{
val = <bool as Decode<Postgres>>::decode(value).unwrap().to_string();
}else if name=="TIMESTAMPTZ"{
val = format!("<t:{}:R>",<i64 as Decode<Postgres>>::decode(value).unwrap().to_string());
}else if name=="BYTEA"{
val = "[bytea]".to_owned();
}else{
let raw = <&[u8] as Decode<Postgres>>::decode(value).unwrap();
val = format!("{:?}",raw);
}
}
string.push("\t".to_string());
string.push(val);
}
Ok(string[1..].concat())
}
fn row_to_table(row:Vec<PgRow>)->Result<String,PgCustomError>{
let name = match row.first(){
Some(x)=>get_name_type(x)?,
None=>{return Err(PgCustomError::from("no row in the table"));}
};
let mut res = vec!["```".to_string(),name];
for pat in row {
let data = get_value(pat)?;
res.push("\n".to_string());
res.push(data)
}
res.push("```".to_string());
Ok(res.concat())
}
90 changes: 90 additions & 0 deletions binding/src/postgres/gacha.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use sqlx::{FromRow, Row};
use material::ItemPedia;
use super::{Db,PgCustomError};
use super::super::bitwise::{Bitwise,ItemCode};
use super::card::Event;

#[derive(FromRow,Debug)]
pub struct GachaPg{
pub pity:i32,
pub ticket:i32
}

impl Db {
pub async fn get_coin(&self,did:&str)->Result<i32,PgCustomError>{
Ok(sqlx::query("SELECT bounty From discord where discord_id=$1")
.bind(did).fetch_one(&**self).await?.get("bounty"))
}
pub async fn get_pity(&self,did:&str)->Result<GachaPg,PgCustomError>{
Ok(sqlx::query_as::<_,GachaPg>("SELECT gacha as ticket,pity From discord where discord_id=$1")
.bind(did).fetch_one(&**self).await?)
}
pub async fn buy_ticket(&self,did:&str,ticket:i32)->Result<(),PgCustomError>{
sqlx::query("update discord set gacha=gacha+$1 where discord_id=$2").bind(ticket).bind(did).execute(&**self).await?;
Ok(())
}
pub async fn ticket_all(&self,did:&str,ticket:i32)->Result<(),PgCustomError>{
sqlx::query("update discord set gacha=gacha+$1 where gacha is not null").bind(ticket).bind(did).execute(&**self).await?;
Ok(())
}
pub async fn send_item(&self,data:&[ItemCode],cid:i32,name:&str,desc:&str)->Result<(),PgCustomError>{
let byte = Bitwise::new(data);
sqlx::query("INSERT into distribution (character_id,data,type,bot,event_name,description) Values ($1,$2,1,true,$3,$4)").bind(cid).bind(byte.multiple_item().unwrap()).bind(name).bind(&format!("~C05 {}",desc)).execute(&**self).await?;
Ok(())
}
pub async fn send_distrib(&self,did:&str,pg:&GachaPg,data:&[ItemCode],cid:i32,pedia:&ItemPedia)->Result<(),PgCustomError>{
sqlx::query("UPDATE discord set gacha=$1,pity=$2 where discord_id=$3").bind(pg.ticket)
.bind(pg.pity).bind(did).execute(&**self).await?;
if data.len() == 1{
let text = match data.first().unwrap().text(pedia){
Some(x)=>x,
None=>{return Err(PgCustomError::from("no item in the data"));}
};
self.send_item(data, cid, &text, &format!("congratulation on getting {}",&text)).await?;
return Ok(());
}
self.send_item(data, cid, "Multi Gacha Rewards", "cant list all reward in description").await?;
Ok(())
}
pub async fn bounty_transaction(&self,did:&str,price:i32)->Result<(),PgCustomError>{
sqlx::query("UPDATE discord set bounty=bounty-$1 where discord_id=$2").bind(price)
.bind(did).execute(&**self).await?;
Ok(())
}
pub async fn bounty_event(&self,did:&str,event:&Event)->Result<(),PgCustomError>{
sqlx::query("UPDATE discord set bounty=$1,gacha=$2,gold=$3,silver=$4,bronze=$5,latest_bounty=$6
,latest_bounty_time=$7,title=$8 where discord_id=$9")
.bind(event.bounty).bind(event.gacha).bind(event.gold).bind(event.silver).bind(event.bronze)
.bind(&event.latest_bounty).bind(event.latest_bounty_time).bind(event.title).bind(did)
.execute(&**self).await?;
Ok(())
}
pub async fn bounty_all(&self,gift:i32)->Result<(),PgCustomError>{
sqlx::query("UPDATE discord set bounty=bounty+$1 where bounty is not null").bind(gift)
.execute(&**self).await?;
Ok(())
}
pub async fn jelewelry(&self,did:&str,bought:i32)->Result<(),PgCustomError>{
let user = self.get_user_data(did).await?;
sqlx::query("UPDATE users set gacha_premium=coalesce(gacha_premium,0)+$1 where id=$2").bind(bought)
.bind(user.rid).execute(&**self).await?;
Ok(())
}
pub async fn market(&self,did:&str,data:&ItemCode,cid:i32,price:Option<i32>,pedia:&ItemPedia)->Result<(),PgCustomError>{
if let Some(x) = price{
self.bounty_transaction(did,x).await?;
}
let array = [data.clone()];
let byte = Bitwise::new(&array);
sqlx::query("INSERT into distribution (character_id,data,type,bot,event_name,description) Values ($1,$2,1,true,$3,$4)").bind(cid).bind(byte.multiple_item().unwrap()).bind(data.text(pedia).unwrap()).bind("~C05 The item distributed by admin").execute(&**self).await?;
Ok(())
}
pub async fn market_user(&self,did:&str,data:&ItemCode,cid:i32,price:u32,pedia:&ItemPedia)->Result<(),PgCustomError>{
self.bounty_transaction(did,price as i32).await?;
let array = [data.clone()];
let byte = Bitwise::new(&array);
sqlx::query("INSERT into distribution (character_id,data,type,bot,event_name,description) Values ($1,$2,1,true,$3,$4)").bind(cid).bind(byte.multiple_item().unwrap()).bind(data.text(pedia).unwrap()).bind("~C05 The market transaction delivery").execute(&**self).await?;
Ok(())
}
}

77 changes: 77 additions & 0 deletions binding/src/postgres/guild.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use sqlx::Row;
use super::{PgCustomError,Db};

#[derive(sqlx::FromRow,Debug)]
pub struct GuildList{
pub id:i32,
pub name:String
}

#[derive(sqlx::FromRow)]
pub struct Guild{
pub id:i32,
pub name:String,
pub rank_rp:i32,
pub leader_id:i32,
pub created:chrono::DateTime<chrono::Utc>,
pub lead_name:String,
pub discord_id:Option<String>,

}

impl Db{
async fn guild_id(&self,cid:i32)->Result<i64,PgCustomError>{
if let Ok(x) = sqlx::query("select guild_id from guild_characters where character_id=$1").bind(cid).fetch_one(&**self).await{
return Ok(x.try_get("guild_id")?);
}
Ok(0)
}
async fn guild_count(&self,ids:i64)->Result<i64,PgCustomError>{
Ok(sqlx::query("select count(*) from guild_characters where guild_id=$1")
.bind(ids).fetch_one(&**self).await?.try_get("count")?)
}
pub async fn guild_food(&self,cid:i32,ids:i32,level:i32,exp:i32)->Result<bool,PgCustomError>{
let x = chrono::NaiveDateTime::from_timestamp_millis(exp as i64 * 1000).unwrap();
let z:chrono::DateTime<chrono::Utc> = chrono::DateTime::from_naive_utc_and_offset(x, chrono::Utc);
let gid = self.guild_id(cid).await?;
if gid != 0{
sqlx::query("insert into guild_meals (guild_id,meal_id,level,created_at) values ($1,$2,$3,$4)")
.bind(gid as i32).bind(ids).bind(level).bind(z).execute(&**self).await?;
return Ok(true)
}
Ok(false)
}
pub async fn guild_rp(&self,cid:i32,rp:i32)->Result<bool,PgCustomError>{
let gid = self.guild_id(cid).await?;
if gid==0{
return Ok(false);
}
sqlx::query("update guilds set rank_rp=rank_rp+$1 where id=$2").bind(rp).bind(gid as i32).execute(&**self).await?;
Ok(true)
}
pub async fn guild_list(&self)->Result<Vec<GuildList>,PgCustomError>{
Ok(sqlx::query_as::<_,GuildList>("select id,name from guilds").fetch_all(&**self).await?)
}
pub async fn guild_search(&self,ids:i64)->Result<(Guild,i64),PgCustomError>{
let guild = sqlx::query_as(
"select guilds.name as name,characters.name as lead_name,guilds.id as id,rank_rp,guilds.created_at as created,leader_id,discord_id
from guilds inner join characters on characters.id = guilds.leader_id
left outer join discord on discord.char_id = guilds.leader_id
where guilds.id=$1").bind(ids).fetch_one(&**self).await?;
Ok((guild,self.guild_count(ids).await?))
}
pub async fn guild_join(&self,ids:i64,cid:i32)->Result<(),PgCustomError>{
if self.guild_id(cid).await? != 0{
return Err(PgCustomError::Custom("you already have guild, leave your current guild to use this command".to_owned()));
}
if self.guild_count(ids).await? > 59{
return Err(PgCustomError::Custom("the guild you selected is already full".to_owned()));
}
if let Err(why) = sqlx::query("insert into guild_characters (guild_id,character_id,order_index)
values ($1,$2,(select max(order_index)+1 from guild_characters where guild_id = $1))")
.bind(ids).bind(cid).execute(&**self).await{
return Err(PgCustomError::from(why).into());
}
Ok(())
}
}
19 changes: 19 additions & 0 deletions binding/src/postgres/server.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use sqlx::FromRow;
use super::{Db,PgCustomError};



#[derive(Debug,FromRow)]
pub struct Servers {
pub name:String,
pub cp:i32,
pub land:i32,
pub description:String,
}
impl Db {
pub async fn get_server(&self)->Result<Vec<Servers>,PgCustomError>{
Ok(sqlx::query_as::<_,Servers>("Select current_players as cp,land,
world_name as name
,world_description as description from servers").fetch_all(&**self).await?)
}
}

0 comments on commit 2d764ca

Please sign in to comment.