Next Generation Emulation banner
361 - 380 of 406 Posts

· AI
Joined
·
10,692 Posts
Without revealing too much detail ;), this is part of the report, ban, and thread cleanup control code for the antispam moderator bot:

Code:
[NOPARSE]// ...

Map<Integer, String> postBBCodes = getPostBBCodes(postIDs);

Iterator<UserPost> postItr = posts.iterator();
while (postItr.hasNext()) {
  UserPost post = postItr.next();
  
  String postContent = postBBCodes.get(post.postID);
  
  // Post not found; containing thread may be closed and quote-reply inaccessible 
  if (postContent == null) {
    log.info("Cannot retrieve BB Code for " + post.postID + " -  Skipping");
    updateCheckedPosts(post.postID);
    continue;
  }
  
  Classifier classifier = new Classifier(postContent);
  if (classifier.classify()) {
    log.info("Potential spam found in post " + post.postID + " from user " + post.username + " (" + post.userID + "): ");
    log.info("---");
    log.info(postContent);
    log.info("---");
    log.info("Detection reason");
    for (Rule rule : classifier.getFlagged()) {
      log.info("\t" + rule.getDescription());
    }
    
    if (checkUserSufficientCredentials(post)) {
      updateCheckedPosts(post.postID);
      continue;
    }
    
    flaggedPosts.add(post.postID);
    volatilePosts.remove(post.postID);
    
    // Check reply credentials, if any
    boolean hasCredibleReplies = false;
    if (canModerate && post.postNumber == 1 && totalPostCount > 1) {
      Set<UserPost> replies = new HashSet<UserPost>(posts);
      replies.remove(post); // OP
      
      for (UserPost reply : replies) {
        if (checkUserSufficientCredentials(reply)) {
          hasCredibleReplies = true;
          log.info("Suspicious thread has credible replies");
          break;
        }
      }
    }
    
    if (canModerate && post.postNumber == 1 && !hasCredibleReplies) {
      
      try {
        StringBuilder reason = new StringBuilder("This thread has been classified and deleted as spam.\n\nDetection reason:\n");
        reason.append("[LIST=0]\n");
        for (Rule rule : classifier.getFlagged()) {
          reason.append("[*]" + rule.getDescription() + "\n");
        }
        reason.append("[/LIST]");
        
        // Quarantine thread
        moveThread(thread, quarantineForum);
        
        // Reply to thread before deleting
        ForumUtil forumUtil = new ForumUtil(fc);
        forumUtil.postReply(topURL + "showthread.php?t=" + thread, reason.toString(), false);
        
        // Ban only needed once
        if (!recentBannedUsers.contains(post.userID)) {
          if (checkUserInstantBannable(classifier.getFlagged())) {
            if (ban(post.username, "Spammer Instaban Tripwire")) {
              recentBannedUsers.add(post.userID);
              
              forumUtil.postReply(topURL + "showthread.php?t=" + thread, "User has been banned for this post.", false);
              
              // Log ban in log
              forumUtil.postReply(topURL + "showthread.php?t=" + banLogThread,
                  "[QUOTE="+post.username+";"+post.postID+"]" + unescapeHTML(postContent) + "[/QUOTE]\n\n" + 
                  "User " + post.username + " has been permanently banned due to Spammer Instaban Tripwire.", false);
              
              log.info("Banned user via spammer instaban tripwire");
            }
          } else if (checkUserChainSpammer(post.userID)) {
            if (ban(post.username, "Spam posts exceeded threshold")) {
              recentBannedUsers.add(post.userID);

              forumUtil.postReply(topURL + "showthread.php?t=" + thread, "User has been banned for chain spamming.", false);

              String lookupURL = topURLPublic + "search.php?do=finduser&u=" + post.userID;

              // Log ban in log
              forumUtil.postReply(topURL + "showthread.php?t=" + banLogThread,
                  "[QUOTE="+post.username+";"+post.postID+"]" + unescapeHTML(postContent) + "[/QUOTE]\n\n" + 
                      "User " + post.username + " has been permanently banned for chain spamming.  [URL=" + lookupURL + "][Review][/URL]", false);

              log.info("Banned user for chain spamming");
            }
          } else {
            log.info("User has not yet reached ban conditions");
          }
        }
        
        deleteThread(thread, classifier.getFlagged());
        
        // Log deletion in log
        forumUtil.postReply(topURL + "showthread.php?t=" + logThread,
            "[QUOTE="+post.username+";"+post.postID+"]" + unescapeHTML(postContent) + "[/QUOTE]\n\n" + 
            reason.toString(), false);
      } catch (Exception e) {
        // Post may have been deleted before replying
        log.log(Level.WARNING, "Unable to reply and delete due to an error", e);
      }
      
      // Thread head terminated; all remaining posts are pointless to check
      while (postItr.hasNext()) {
        postItr.next();
        postItr.remove();
      }
    } else {
      try {
        if ((System.currentTimeMillis() - lastReportTime) < 62000) {
          log.info("Unable to report another post within execution deadline -- Skip until next round");
          continue;
        }
        
        StringBuilder reason = new StringBuilder("This post is suspicious and has been reported as spam.\n\nDetection reason:\n");
        reason.append("[LIST=0]\n");
        for (Rule rule : classifier.getFlagged()) {
          reason.append("[*]" + rule.getDescription() + "\n");
        }
        reason.append("[/LIST]");
        
        ForumUtil forumUtil = new ForumUtil(fc);
        
        // Log report in log
        forumUtil.postReply(topURL + "showthread.php?t=" + logThread,
            "[QUOTE="+post.username+";"+post.postID+"]" + unescapeHTML(postContent) +	"[/QUOTE]\n\n" + 
            reason.toString(), false);
        
        report(post.postID, classifier.getFlagged());
      } catch (Exception e) {
        // Post may have been deleted before replying
        log.log(Level.WARNING, "Unable to reply and report due to an error", e);
      }
      
      lastReportTime = System.currentTimeMillis();
    }
    
    updateReportedPosts(post.postID, postContent, classifier.getFlagged());
    recheck = true; // Spam found
  } else {
    log.info("Post " + post.postID + " is not spam");
  }

  updateCheckedPosts(post.postID);
  volatilePosts.remove(post.postID);
}

// ...[/NOPARSE]
 

· Premium Member
Joined
·
19,572 Posts
Maps are great and kinda ugly sometimes for my taste.... eitherway why are you checking a String against null??? wouldn't be better to check if the Id exist in the first place? also why using "+" instead of formattng your string??? last but not least.... quite long function too i would keep it smaller and use separated methods for each purpose for a clearer readability :p

Now i know you want to kill me......

@ruantec runaway..... :innocent:
 

· Registered
Joined
·
197 Posts
Checking if the ID exists then retrieving the value associated with the key means doing the lookup twice...
(and not sure what's wrong with +, it's not like it'd change much to use a StringBuilder/Buffer there)
 

· Premium Member
Joined
·
19,572 Posts
The + looks kinda ugly to me and for instance it could be a memory eater in languages like C# when bulding dynamic database queries for example. I don't know about java tho. obviously is a different case here but usually i try to avoid the + for better readability for me since it could get ugly when adding several values toguether. I rarely do dynamic queries in my own projects tho.

What i meant about the ID check is that when getting stuff from the database(in case he's doing that here) you can request a ID check... in this case is a PostID which may be a primary key. If that's the case it would be better to check it before hence why i wrote that. Also i believe strings shouldn't expect a null but empty or "" as checking them against null looks kinda weird when using different languages.

It may be me because i use different languages at the same time and in some is just weird since Strings aren't null(well... usually). Eitherway i will re-read the code later again since maybe i misunderstood something because i read that post quite quick today before leaving. It wasn't meant as critic to the code but to comprehend why he is using those.
 

· AI
Joined
·
10,692 Posts
Yes, the +'s do look rather ugly. However, for something like this, the added overhead is not worth it, especially when running on Google App Engine and its quota limits. The rather large additional latency from piping through the proxy stresses the quota enough as it is, especially when running all this every 10 minutes for the entire day.

getPostBBCodes(...) does not access the forum database, but rather gets the BB code through the quote-reply feature that normal users would do, so this is quite an expensive operation. However, this is also what makes this automation unit special -- it requires no additional plugins into the forum, but accesses through the regular UI (like the spam bots do), and so does not require management from CrowdGather.
 

· Registered
Joined
·
79 Posts
A C-based linked list. Works rather well and always gets the job done for me.

*snip*

Hopefully it becomes of use to someone out there.
Just to let you know, your list_add_beginning function seems to be a little flawed, although not in a way that it wouldn't work:

Code:
/* Add a node at the beginning of the list */
void list_add_beginning( struct node_t** head, void* data )
{
	struct node_t* temp;

	temp = ( struct node_t* ) malloc( sizeof( struct node_t ) );
	temp->data = data;

	if( head == NULL )
	{
		(*head) = temp;
		(*head)->next = NULL;
	}
	else
	{
		temp->next = (*head);
		(*head) = temp;
	}
}
Passing a null pointer as the first argument wouldn't make any sense here, so for the if-test you probably meant to write:

Code:
	if( (*head) == NULL )
	{
		(*head) = temp;
		(*head)->next = NULL;
	}
	else
	{
		temp->next = (*head);
		(*head) = temp;
	}
But in this case, you can get rid of the branch altogether by just doing this instead:
Code:
	temp->next = (*head);
	(*head) = temp;
 

· Registered
Joined
·
197 Posts
Some code I'm working on at the moment:

Code:
void FunctionDecoder::updateCR(unsigned int index, llvm::Value * value) {
	if (value->getType() == llvm::Type::getIntNTy(context, 4)) {
		llvm::Value * crptr = builder.CreateStructGEP(processorState, llvm::TypeBuilder<ProcessorState, true>::CR, CR_NAMEPTR);
		llvm::Value * cr = builder.CreateLoad(crptr, false, CR_NAME);

		builder.CreateInsertValue(cr, value, index);
	} else {
		error(TAG, "invalid type used to set CR%d", index);
		value->getType()->dump();
	}
}

void FunctionDecoder::updateCR(unsigned int index, llvm::Value * lhs, llvm::Value * rhs) {
	llvm::BasicBlock * blockLT = builder.GetInsertBlock();
	llvm::BasicBlock * blockPHI = llvm::BasicBlock::Create(context, "updateCR.block.phi", blockLT->getParent(), blockLT->getNextNode());
	llvm::BasicBlock * blockGTEQ = llvm::BasicBlock::Create(context, "updateCR.block.gteq", blockLT->getParent(), blockPHI);
	llvm::PHINode * phi;
	llvm::Value * maskLT = builder.getInt(llvm::APInt(4, Register::CR::FIXED_LT));
	llvm::Value * maskGT = builder.getInt(llvm::APInt(4, Register::CR::FIXED_GT));
	llvm::Value * maskEQ = builder.getInt(llvm::APInt(4, Register::CR::FIXED_EQ));
	llvm::Value * condLT;
	llvm::Value * condGT;
	llvm::Value * maskGTEQ;
	llvm::Value * value;

	condLT = builder.CreateICmpSLT(lhs, rhs, "updateCR.lt");
	builder.CreateCondBr(condLT, blockPHI, blockGTEQ);

	builder.SetInsertPoint(blockGTEQ);
	condGT = builder.CreateICmpSGT(lhs, rhs, "updateCR.gt");
	maskGTEQ = builder.CreateSelect(condGT, maskGT, maskEQ, "updateCR.mask.gteq");
	builder.CreateBr(blockPHI);

	builder.SetInsertPoint(blockPHI);

	phi = builder.CreatePHI(llvm::Type::getIntNTy(context, 4), 2, "updateCR.phi");
	phi->addIncoming(maskLT, blockLT);
	phi->addIncoming(maskGTEQ, blockGTEQ);

	value = getSPR(Register::SPR::XER);
	value = builder.CreateLShr(value, Register::XER::SO, "XER.OV");
	value = builder.CreateIntCast(value, llvm::Type::getIntNTy(context, 4), false, "XER.OV.cast");
	value = builder.CreateOr(phi, value, "updateCR.final");

	updateCR(index, value);
}
Basically, it generates code that would do something along those lines:

Code:
CR[index] = lhs < rhs ? 0x8 : lhs > rhs ? 0x4 : 0x2;
CR[index] |= XER >> 31 & 0x1;
Where CR[x] is a 4-bit integer.

So it turns this PowerPC instruction:

Code:
loc_820103D4:
    cmpwi %r3, 0
Into... well, quite a lot of code heheh:

Code:
loc_820103d4:                                     ; preds = %loc_820103d0
  %r3_7 = load i64* getelementptr inbounds ({ [8 x i4], [32 x i64], [32 x i64] }* @cpuState, i32 0, i32 1, i32 3)
  %cmpi.lhs.cast = trunc i64 %r3_7 to i32
  %cmpi.lhs.sext = sext i32 %cmpi.lhs.cast to i64
  %updateCR.lt = icmp slt i64 %cmpi.lhs.sext, 0
  br i1 %updateCR.lt, label %updateCR.block.phi, label %updateCR.block.gteq

updateCR.block.gteq:                              ; preds = %loc_820103d4
  %updateCR.gt = icmp sgt i64 %cmpi.lhs.sext, 0
  %updateCR.mask.gteq = select i1 %updateCR.gt, i4 4, i4 2
  br label %updateCR.block.phi

updateCR.block.phi:                               ; preds = %updateCR.block.gteq, %loc_820103d4
  %updateCR.phi = phi i4 [ 8, %loc_820103d4 ], [ %updateCR.mask.gteq, %updateCR.block.gteq ]
  %XER.OV = lshr i64 %r12_, 31
  %XER.OV.cast = trunc i64 %XER.OV to i4
  %updateCR.final = or i4 %updateCR.phi, %XER.OV.cast
  %CR_ = load [8 x i4]* getelementptr inbounds ({ [8 x i4], [32 x i64], [32 x i64] }* @cpuState, i32 0, i32 0)
  %6 = insertvalue [8 x i4] %CR_, i4 %updateCR.final, 0
 

· Premium Member
Joined
·
8,437 Posts
Just to let you know, your list_add_beginning function seems to be a little flawed, although not in a way that it wouldn't work:
Code:
/* Add a node at the beginning of the list */
void list_add_beginning( struct node_t** head, void* data )
{
	struct node_t* temp;

	temp = ( struct node_t* ) malloc( sizeof( struct node_t ) );
	temp->data = data;

	if( head == NULL )
	{
		(*head) = temp;
		(*head)->next = NULL;
	}
	else
	{
		temp->next = (*head);
		(*head) = temp;
	}
}
Passing a null pointer as the first argument wouldn't make any sense here, so for the if-test you probably meant to write:

Code:
	if( (*head) == NULL )
	{
		(*head) = temp;
		(*head)->next = NULL;
	}
	else
	{
		temp->next = (*head);
		(*head) = temp;
	}
But in this case, you can get rid of the branch altogether by just doing this instead:
Code:
	temp->next = (*head);
	(*head) = temp;
Heh, can't believe I didn't catch that. Thanks.

Some code I'm working on at the moment:

Code:
void FunctionDecoder::updateCR(unsigned int index, llvm::Value * value) {
	if (value->getType() == llvm::Type::getIntNTy(context, 4)) {
		llvm::Value * crptr = builder.CreateStructGEP(processorState, llvm::TypeBuilder<ProcessorState, true>::CR, CR_NAMEPTR);
		llvm::Value * cr = builder.CreateLoad(crptr, false, CR_NAME);

		builder.CreateInsertValue(cr, value, index);
	} else {
		error(TAG, "invalid type used to set CR%d", index);
		value->getType()->dump();
	}
}

void FunctionDecoder::updateCR(unsigned int index, llvm::Value * lhs, llvm::Value * rhs) {
	llvm::BasicBlock * blockLT = builder.GetInsertBlock();
	llvm::BasicBlock * blockPHI = llvm::BasicBlock::Create(context, "updateCR.block.phi", blockLT->getParent(), blockLT->getNextNode());
	llvm::BasicBlock * blockGTEQ = llvm::BasicBlock::Create(context, "updateCR.block.gteq", blockLT->getParent(), blockPHI);
	llvm::PHINode * phi;
	llvm::Value * maskLT = builder.getInt(llvm::APInt(4, Register::CR::FIXED_LT));
	llvm::Value * maskGT = builder.getInt(llvm::APInt(4, Register::CR::FIXED_GT));
	llvm::Value * maskEQ = builder.getInt(llvm::APInt(4, Register::CR::FIXED_EQ));
	llvm::Value * condLT;
	llvm::Value * condGT;
	llvm::Value * maskGTEQ;
	llvm::Value * value;

	condLT = builder.CreateICmpSLT(lhs, rhs, "updateCR.lt");
	builder.CreateCondBr(condLT, blockPHI, blockGTEQ);

	builder.SetInsertPoint(blockGTEQ);
	condGT = builder.CreateICmpSGT(lhs, rhs, "updateCR.gt");
	maskGTEQ = builder.CreateSelect(condGT, maskGT, maskEQ, "updateCR.mask.gteq");
	builder.CreateBr(blockPHI);

	builder.SetInsertPoint(blockPHI);

	phi = builder.CreatePHI(llvm::Type::getIntNTy(context, 4), 2, "updateCR.phi");
	phi->addIncoming(maskLT, blockLT);
	phi->addIncoming(maskGTEQ, blockGTEQ);

	value = getSPR(Register::SPR::XER);
	value = builder.CreateLShr(value, Register::XER::SO, "XER.OV");
	value = builder.CreateIntCast(value, llvm::Type::getIntNTy(context, 4), false, "XER.OV.cast");
	value = builder.CreateOr(phi, value, "updateCR.final");

	updateCR(index, value);
}
Basically, it generates code that would do something along those lines:

Code:
CR[index] = lhs < rhs ? 0x8 : lhs > rhs ? 0x4 : 0x2;
CR[index] |= XER >> 31 & 0x1;
Where CR[x] is a 4-bit integer.

So it turns this PowerPC instruction:

Code:
loc_820103D4:
    cmpwi %r3, 0
Into... well, quite a lot of code heheh:

Code:
loc_820103d4:                                     ; preds = %loc_820103d0
  %r3_7 = load i64* getelementptr inbounds ({ [8 x i4], [32 x i64], [32 x i64] }* @cpuState, i32 0, i32 1, i32 3)
  %cmpi.lhs.cast = trunc i64 %r3_7 to i32
  %cmpi.lhs.sext = sext i32 %cmpi.lhs.cast to i64
  %updateCR.lt = icmp slt i64 %cmpi.lhs.sext, 0
  br i1 %updateCR.lt, label %updateCR.block.phi, label %updateCR.block.gteq

updateCR.block.gteq:                              ; preds = %loc_820103d4
  %updateCR.gt = icmp sgt i64 %cmpi.lhs.sext, 0
  %updateCR.mask.gteq = select i1 %updateCR.gt, i4 4, i4 2
  br label %updateCR.block.phi

updateCR.block.phi:                               ; preds = %updateCR.block.gteq, %loc_820103d4
  %updateCR.phi = phi i4 [ 8, %loc_820103d4 ], [ %updateCR.mask.gteq, %updateCR.block.gteq ]
  %XER.OV = lshr i64 %r12_, 31
  %XER.OV.cast = trunc i64 %XER.OV to i4
  %updateCR.final = or i4 %updateCR.phi, %XER.OV.cast
  %CR_ = load [8 x i4]* getelementptr inbounds ({ [8 x i4], [32 x i64], [32 x i64] }* @cpuState, i32 0, i32 0)
  %6 = insertvalue [8 x i4] %CR_, i4 %updateCR.final, 0
So your PPC emu is making progress? Good. I'm glad someone is proving me right for once. :)

Question: llvm? Are you using MacOSX?
 

· Premium Member
Joined
·
19,572 Posts
Finally MVVM without the annoyance of writing the property name on every setter change notify thanks to the recent changes in .Net 4.5 :) now i can create parametrized commands and manage them easily from my viewmodel base class as well as notify on change! awesomeness i tell ya ;)

Parametrized command class:
Code:
using System;
using System.Windows.Input;

namespace ViewModelBaseTest
{
    public class ParameterizedCommand : ICommand
    {
        public Action<String> DoIt
        { get; set; }

        public bool CanExecute(object parameter)
        {
            return (DoIt != null);
        }

        public void Execute(object parameter)
        {
            if (DoIt != null)
                DoIt(parameter as String ?? string.Empty);
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    }
}
Code:
using System.ComponentModel;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Windows.Input;

namespace ViewModelBaseTest
{
    public class ViewModelBase : INotifyPropertyChanged
    {
        private string _param;

        public string Param
        {
            get { return _param; }
            set { SetProperty(ref _param, value); InvokeCommandMethod(); }
        }

        public ICommand ParamCommand
        { get; set; }
        
        //---------------------- ViewModelBase implementation ------------------------
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var eventHandler = PropertyChanged;
            if (eventHandler != null)
                eventHandler(this, new PropertyChangedEventArgs(propertyName));
        }

        public bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (Equals(storage, value))
                return false;

            storage = value;
            if (propertyName != null)
                OnPropertyChanged(propertyName);

            return true;
        }

        public ViewModelBase()
        {
            var cmd = new ParameterizedCommand { DoIt = p => { Param = p; } };
            ParamCommand = cmd;
        }

        private void InvokeCommandMethod()
        {
            //Get the method information using the method info class
            var method = GetType().GetMethod(Param, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
            //Invoke the method
            // (null- no parameter for the method call
            // or you can pass the array of parameters...)
            if (method != null)
                method.Invoke(this, null);
        }
    }
}
From now on all i have to do is inherit from that base class and everything is handled automatically and without annoyances!
 

· Registered
Joined
·
197 Posts
Some more static rec progress (posting this is my 5am break), the generated code is starting to look somewhat nice; quick and small example (because PowerPC asm or LLVM IR can quickly turn into way too many lines):

Code:
.globl start
start:
lis     %r11, [email protected]
lbz     %r11, [email protected](%r11)
extsb   %r3, %r11
blr
(IDA sort of beautifies it, it's really lis %r11, 0x82000000 followed by lbz %r11, %r11+0x400)

Turns into

Code:
@cpuState = global { i32, [32 x i64], [32 x i64] } undef
@ExLoadedCommandLine = external constant i32

define i64 @sub_82010000() {
loc_82010000:
  %lbz.value = load i8* bitcast (i32* @ExLoadedCommandLine to i8*)
  %r11_ = zext i8 %lbz.value to i64
  %extsb.cast = trunc i64 %r11_ to i8
  %r3_ = sext i8 %extsb.cast to i64
  ret i64 %r3_
}
I skipped the debug metadata part of the LLVM IR, and the cpuState global is not used in this example since it doesn't need to save or restore registers between calls (they're tracked through basic blocks in order to keep them used via a "local" variable rather than retrieving them from a TLS slot).

Another nice thing is a - very simple - Pointer<> class which wraps a 32-bit integer and makes it look like a pointer (except, sadly, for assignment and constructors). This lets me do things like:

Code:
typedef Pointer<void> LPVOID; // taken from somewhere else
typedef Pointer<BYTE> LPBYTE; // same

#include <XboxKernel/main.h>
#include <XboxKernel/API.h>

namespace XboxKernel {

/**
 * Compares blocks of memory.
 * \note
 * \c xboxkrnl\@0x011a
 * @param[in] source1 Pointer to the first memory block.
 * @param[in] source2 Pointer to the second memory block.
 * @param[in] length Number of bytes to compare.
 * @return Length of the first byte at which \p source1 and \p source2 differ, or length if they are the same.
 */
UI32 RtlCompareMemory(LPVOID source1, LPVOID source2, UI32 length) {
    LPBYTE p1 = pointer_cast<LPBYTE>(source1);
    LPBYTE p2 = pointer_cast<LPBYTE>(source2);
    UI32 count;

    for (count = 0; count != length && * p1 == * p2; ++p1, ++p2, ++count) {

    }

    return count;
}

}
If the Pointer class had user-defined constructors, the 32-bit value passed as an argument to the function would be lost (since LLVM's generated code obviously doesn't know about those classes, it's just another meaningless i32 like any address). And since reinterpret_cast and friends can't be overloaded, a pointer_cast was needed as well:

Code:
template <typename T0, typename T1>
inline T0 pointer_cast(Common::Pointer<T1> & rhs) {
    return T0::construct(reinterpret_cast<typename T0::PointerType>(rhs.get()));
}

template <typename T0, typename T1>
inline T0 pointer_cast(Common::Pointer<T1> const & rhs) {
    return T0::construct(reinterpret_cast<typename T0::ConstantPointerType>(rhs.get()));
}
Obviously, being able to directly call functions from the generated code (rather than passing a structure with all the register or anything along those lines) clearly outweighted the slight annoyance of not having some nice constructor and operator =...
 

· I m meow desu! ^_^
Joined
·
5,632 Posts
Discussion Starter · #374 ·
This dont do much beside change input string to y and that's it.... useless but took me hour to figure out... tested for range loops, for and while.. It seem for range loops is easier to write and understand.

Code:
#include <iostream>
#include <string>
using namespace std;

void main(){
	string s;
	getline(cin,s);
	decltype(s.size()) index=0;
	
	while (index!=s.size())
	{
		s[index]='y';
		++index;
	}


	/*for(decltype(s.size()) index=0;index!=s.size();++index)
		s[index]='x';*/
	

	/*for(auto &a:s)
		a='x';*/

	cout<<s;

	system("pause");
}
 

· Premium Member
Joined
·
19,572 Posts
My video player interface:

Code:
using System.ComponentModel;
using System.Windows.Media;
using System.Windows.Shapes;
using ViewModelHandler;

namespace PlayerProvider.Interfaces
{
    public interface IPlayer : INotifyPropertyChanged
    {
        /// <summary>
        /// Player rect container
        /// </summary>
        Rectangle PlayerRect { get; set; }
        /// <summary>
        /// VisualBrush of the video element
        /// </summary>
        VisualBrush PlayerBrush { get; set; }
        /// <summary>
        /// Current file loaded
        /// </summary>
        object CurrentFile { get; set; }
        /// <summary>
        /// Player Volume
        /// </summary>
        double Volume { get; set; }
        /// <summary>
        /// Volume Maximum value
        /// </summary>
        double VolumeMax { get; set; }
        /// <summary>
        /// Media Position
        /// </summary>
        double Position { get; set; }
        /// <summary>
        /// Media maximum
        /// </summary>
        double MediaMaximum { get; set; }
        /// <summary>
        /// Replay state of the player
        /// </summary>
        PlayerProvider.Shared.SharedClass.ReplayState PlayState { get; set; }
        /// <summary>
        /// Title of the current media
        /// </summary>
        string CurrentTitle { get; set; }
        /// <summary>
        /// Time of the current media
        /// </summary>
        string CurrentTime { get; set; }
        /// <summary>
        /// Quality of the current media
        /// </summary>
        string CurrentQuality { get; set; }
        /// <summary>
        /// Check whatever the player is paused or not
        /// </summary>
        bool IsPlaying { get; set; }
        /// <summary>
        /// Set the media position of the player
        /// </summary>
        void SetPosition();
        /// <summary>
        /// Play command
        /// </summary>
        void Play();
        /// <summary>
        /// Stop command
        /// </summary>
        void Stop();
        /// <summary>
        /// Pause command
        /// </summary>
        void Pause();
        /// <summary>
        /// Play the file given
        /// </summary>
        /// <param name="file"></param>
        void Playfile(string file);
        /// <summary>
        /// Get a new visual brush copy of our player
        /// </summary>
        /// <returns></returns>
        VisualBrush GetPlayerBrush(Stretch stretch);
    }
}
Here the code of the DirectShow Renderer(is just that simple ^_^):
Code:
using PlayerProvider.Interfaces;
using PlayerProvider.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;
using ViewModelHandler;
using WPFMediaKit.DirectShow.Controls;

namespace PlayerProvider.Players
{
    public class DirectShowPlayer : ViewModelBase, IPlayer
    {
        private MediaUriElement player;
        private Rectangle playerRect;
        private VisualBrush playerbrush;
        private object currentFile;
        private double volumeMax;
        private double volume;
        private Shared.SharedClass.ReplayState playstate;
        private string currentTitle;
        private string currentTime;
        private string currentQuality;
        private double position;
        private double mediamaximum;
        private bool isPlaying;

        public System.Windows.Shapes.Rectangle PlayerRect
        {
            get { return playerRect; }
            set { SetProperty(ref playerRect, value); }
        }

        public System.Windows.Media.VisualBrush PlayerBrush
        {
            get { return playerbrush; }
            set { SetProperty(ref playerbrush, value); }
        }

        public object CurrentFile
        {
            get { return currentFile; }
            set { SetProperty(ref currentFile, value); }
        }

        public double Volume
        {
            get { return volume; }
            set 
            { 
                if(player != null)
                    player.Volume = ProviderTools.PercentToVolume((int)(value * 100));
                volume = value;
                InvokePropertyChanged("Volume"); 
            }
        }

        public double VolumeMax
        {
            get { return volumeMax; }
            set { SetProperty(ref volumeMax, value); }
        }

        public double Position
        {
            get { return position; }
            set { SetProperty(ref position, value); }
        }

        public double MediaMaximum
        {
            get { return mediamaximum; }
            set { SetProperty(ref mediamaximum, value); }
        }

        public Shared.SharedClass.ReplayState PlayState
        {
            get { return playstate; }
            set { SetProperty(ref playstate, value); }
        }

        public string CurrentTitle
        {
            get { return currentTitle; }
            set { SetProperty(ref currentTitle, value); }
        }

        public string CurrentTime
        {
            get { return currentTime; }
            set { SetProperty(ref currentTime, value); }
        }

        public string CurrentQuality
        {
            get { return currentQuality; }
            set { SetProperty(ref currentQuality, value); }
        }

        public bool IsPlaying
        {
            get { return isPlaying; }
            set { SetProperty(ref isPlaying, value); }
        }

        public DirectShowPlayer()
        {
            PlayerRect = new Rectangle();
            VolumeMax = 1;
            var Timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(1000) };
            Timer.Tick += Timer_Tick;
            Timer.Start();
        }

        void Timer_Tick(object sender, EventArgs e)
        {
            if (player != null && player.MediaDuration > 0)
            {
                CurrentTime = string.Format("{0} / {1}", ProviderTools.FormatTime(TimeSpan.FromTicks(player.MediaPosition)), ProviderTools.FormatTime(TimeSpan.FromTicks(player.MediaDuration)));
                MediaMaximum = player.MediaDuration;
                Position = player.MediaPosition;
            }
        }

        public void SetPosition()
        {
            player.MediaPosition = (long)Position;
        }

        public void Play()
        {
            player.Play();
            IsPlaying = true;
        }

        public void Stop()
        {
            player.Stop();
            player.Close();
        }

        public void Pause()
        {
            player.Pause();
            IsPlaying = false;
        }

        public void Playfile(string file)
        {
            InitializePlayer();
            player.BeginInit();
            player.Source = new Uri(file);
            player.EndInit();
            Play();
        }

        private void InitializePlayer()
        {
            if (player != null)
            {
                player.Stop();
                player.Close();
                player = null;
            }
            player = new MediaUriElement();
            var brush = new VisualBrush(player) { Stretch = Stretch.Uniform };
            PlayerRect.Fill = brush;
            PlayerBrush = brush.Clone();
            PlayerBrush.Stretch = Stretch.UniformToFill;
            player.MediaEnded -= player_MediaEnded;
            player.MediaEnded += player_MediaEnded;
        }

        void player_MediaEnded(object sender, System.Windows.RoutedEventArgs e)
        {
            InvokePropertyChanged("FileEnded");
        }

        public System.Windows.Media.VisualBrush GetPlayerBrush(System.Windows.Media.Stretch stretch)
        {
            return new VisualBrush(player) { Stretch = stretch };
        }
    }
}
 

· I m meow desu! ^_^
Joined
·
5,632 Posts
Discussion Starter · #376 ·
Still useless but fun to write ! :D
1-what this program do is display 5 choice of soft drink!
2-You select your choice!
3-if correct choice display product selected and display choice for modify existing product!
4-if no invalid input the console ask you to input again!
5-if input correct user name and password console smile at you and let you add more product to the list!!!!

PS: i added beer!
Code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;

void main(){
	vector<string> product(10);
	product[0]="1-CoCa";
	product[1]="2-Pepsi";
	product[2]="3-Soda";

	cout<<product[0]<<endl;
	cout<<product[1]<<endl;
	cout<<product[2]<<endl;
again:
	cout<<"Enter your choice:";
	while(1){
		int i;
		cin>>i;
		if(cin.fail()){
			cin.clear();
			cin.ignore(numeric_limits<streamsize>::max(),'\n');
			cout<<"wrong input!"<<endl;
			goto again;
		}

		if(i>5||i<1){

			cout<<"Error invalid number"<<endl;
			goto again;
		}
		else{
			if(i==1){
				cout<<"Thank you for choosing "<<product[0]<<endl;

			}
			if(i==2){
				cout<<"Thank you for choosing "<<product[1]<<endl;

			}
			if(i==3){
				cout<<"Thank you for choosing "<<product[2]<<endl;
			}}

		int addmore;

		cout<<"Do you wanna add more product?"<<endl;
		cout<<"1-yes"<<endl;
		cout<<"2-No"<<endl;

		cin>>addmore;

		if(addmore==1){
			cin.ignore();
			string user;
			string pass;
			string newProduct;

			cout<<"Input your username:";
			getline(cin,user,'\n');

			cout<<"Input your password:";
			getline(cin,pass,'\n');

			//bool user1=user=="hello", pass1=pass=="123";
			bool aprrove_user=user=="otani", appro_pass=pass=="12345";

			cout<<"welcome to the crazy system!!!"<<endl;
			cout<<"Creat new product!";
			cin>>newProduct;
			product.push_back(newProduct);
			
			
			for(int i=0;i<product.size();i++){
				
				cout<<product[i]<<endl;
				
			}
				
	}

		if(addmore==2){

			break;
		}


		break;
}
	
	system("pause");
	
	}
 

· I m meow desu! ^_^
Joined
·
5,632 Posts
Discussion Starter · #378 ·
As a small suggestion... try to replace the if's with a switch... guess it will be fun too ;)
Thank papa @auerentec but I hate switch it is not support string type :(
 

· Registered
Joined
·
79 Posts
Lots of small beginner mistakes. You should generally avoid using goto most of the time (in this case, using continue is more appropriate). You're specifying an initial size for your vector, which leads to the empty line between soda and beer in your screenshot (it's using the default constructor for std::string when creating your vector, which gives an empty string at index 3). Also:

Code:
		else{
			if(i==1){
				cout<<"Thank you for choosing "<<product[0]<<endl;

			}
			if(i==2){
				cout<<"Thank you for choosing " << product[1] << endl;

			}
			if(i==3){
				cout<<"Thank you for choosing "<<product[2]<<endl;
			}}
Code:
		else {
			cout<<"Thank you for choosing "<<product[i - 1]<<endl;
		}
 
361 - 380 of 406 Posts
This is an older thread, you may not receive a response, and could be reviving an old thread. Please consider creating a new thread.
Top