-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
270 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(()) | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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?) | ||
} | ||
} |